vendor: 14,975 bytes, lines 1-273
1var n, l$1, u$1, i$1, t, r$1, o, f$1, e$1, c$1 = {}, s = [], a$1 = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i; 2function h(n2, l2) { 3 for (var u2 in l2) n2[u2] = l2[u2]; 4 return n2; 5} 6function v$1(n2) { 7 var l2 = n2.parentNode; 8 l2 && l2.removeChild(n2); 9} 10function y(l2, u2, i2) { 11 var t2, r2, o2, f2 = {}; 12 for (o2 in u2) "key" == o2 ? t2 = u2[o2] : "ref" == o2 ? r2 = u2[o2] : f2[o2] = u2[o2]; 13 if (arguments.length > 2 && (f2.children = arguments.length > 3 ? n.call(arguments, 2) : i2), "function" == typeof l2 && null != l2.defaultProps) for (o2 in l2.defaultProps) void 0 === f2[o2] && (f2[o2] = l2.defaultProps[o2]); 14 return p(l2, f2, t2, r2, null); 15} 16function p(n2, i2, t2, r2, o2) { 17 var f2 = { type: n2, props: i2, key: t2, ref: r2, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, __h: null, constructor: void 0, __v: null == o2 ? ++u$1 : o2 }; 18 return null == o2 && null != l$1.vnode && l$1.vnode(f2), f2; 19} 20function d() { 21 return { current: null }; 22} 23function _(n2) { 24 return n2.children; 25} 26function k$1(n2, l2, u2, i2, t2) { 27 var r2; 28 for (r2 in u2) "children" === r2 || "key" === r2 || r2 in l2 || g$2(n2, r2, null, u2[r2], i2); 29 for (r2 in l2) t2 && "function" != typeof l2[r2] || "children" === r2 || "key" === r2 || "value" === r2 || "checked" === r2 || u2[r2] === l2[r2] || g$2(n2, r2, l2[r2], u2[r2], i2); 30} 31function b$1(n2, l2, u2) { 32 "-" === l2[0] ? n2.setProperty(l2, null == u2 ? "" : u2) : n2[l2] = null == u2 ? "" : "number" != typeof u2 || a$1.test(l2) ? u2 : u2 + "px"; 33} 34function g$2(n2, l2, u2, i2, t2) { 35 var r2; 36 n: if ("style" === l2) if ("string" == typeof u2) n2.style.cssText = u2; 37 else { 38 if ("string" == typeof i2 && (n2.style.cssText = i2 = ""), i2) for (l2 in i2) u2 && l2 in u2 || b$1(n2.style, l2, ""); 39 if (u2) for (l2 in u2) i2 && u2[l2] === i2[l2] || b$1(n2.style, l2, u2[l2]); 40 } 41 else if ("o" === l2[0] && "n" === l2[1]) r2 = l2 !== (l2 = l2.replace(/Capture$/, "")), l2 = l2.toLowerCase() in n2 ? l2.toLowerCase().slice(2) : l2.slice(2), n2.l || (n2.l = {}), n2.l[l2 + r2] = u2, u2 ? i2 || n2.addEventListener(l2, r2 ? w$2 : m$1, r2) : n2.removeEventListener(l2, r2 ? w$2 : m$1, r2); 42 else if ("dangerouslySetInnerHTML" !== l2) { 43 if (t2) l2 = l2.replace(/xlink(H|:h)/, "h").replace(/sName$/, "s"); 44 else if ("width" !== l2 && "height" !== l2 && "href" !== l2 && "list" !== l2 && "form" !== l2 && "tabIndex" !== l2 && "download" !== l2 && l2 in n2) try { 45 n2[l2] = null == u2 ? "" : u2; 46 break n; 47 } catch (n3) { 48 } 49 "function" == typeof u2 || (null == u2 || false === u2 && -1 == l2.indexOf("-") ? n2.removeAttribute(l2) : n2.setAttribute(l2, u2)); 50 } 51} 52function m$1(n2) { 53 t = true; 54 try { 55 return this.l[n2.type + false](l$1.event ? l$1.event(n2) : n2); 56 } finally { 57 t = false; 58 } 59} 60function w$2(n2) { 61 t = true; 62 try { 63 return this.l[n2.type + true](l$1.event ? l$1.event(n2) : n2); 64 } finally { 65 t = false; 66 } 67} 68function x$1(n2, l2) { 69 this.props = n2, this.context = l2; 70} 71function A(n2, l2) { 72 if (null == l2) return n2.__ ? A(n2.__, n2.__.__k.indexOf(n2) + 1) : null; 73 for (var u2; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) return u2.__e; 74 return "function" == typeof n2.type ? A(n2) : null; 75} 76function P$1(n2) { 77 var l2, u2; 78 if (null != (n2 = n2.__) && null != n2.__c) { 79 for (n2.__e = n2.__c.base = null, l2 = 0; l2 < n2.__k.length; l2++) if (null != (u2 = n2.__k[l2]) && null != u2.__e) { 80 n2.__e = n2.__c.base = u2.__e; 81 break; 82 } 83 return P$1(n2); 84 } 85} 86function C$1(n2) { 87 t ? setTimeout(n2) : f$1(n2); 88} 89function T$1(n2) { 90 (!n2.__d && (n2.__d = true) && r$1.push(n2) && !$$1.__r++ || o !== l$1.debounceRendering) && ((o = l$1.debounceRendering) || C$1)($$1); 91} 92function $$1() { 93 var n2, l2, u2, i2, t2, o2, f2, e2; 94 for (r$1.sort(function(n3, l3) { 95 return n3.__v.__b - l3.__v.__b; 96 }); n2 = r$1.shift(); ) n2.__d && (l2 = r$1.length, i2 = void 0, t2 = void 0, f2 = (o2 = (u2 = n2).__v).__e, (e2 = u2.__P) && (i2 = [], (t2 = h({}, o2)).__v = o2.__v + 1, M(e2, o2, t2, u2.__n, void 0 !== e2.ownerSVGElement, null != o2.__h ? [f2] : null, i2, null == f2 ? A(o2) : f2, o2.__h), N(i2, o2), o2.__e != f2 && P$1(o2)), r$1.length > l2 && r$1.sort(function(n3, l3) { 97 return n3.__v.__b - l3.__v.__b; 98 })); 99 $$1.__r = 0; 100} 101function H$1(n2, l2, u2, i2, t2, r2, o2, f2, e2, a2) { 102 var h2, v2, y2, d2, k2, b2, g2, m2 = i2 && i2.__k || s, w2 = m2.length; 103 for (u2.__k = [], h2 = 0; h2 < l2.length; h2++) if (null != (d2 = u2.__k[h2] = null == (d2 = l2[h2]) || "boolean" == typeof d2 ? null : "string" == typeof d2 || "number" == typeof d2 || "bigint" == typeof d2 ? p(null, d2, null, null, d2) : Array.isArray(d2) ? p(_, { children: d2 }, null, null, null) : d2.__b > 0 ? p(d2.type, d2.props, d2.key, d2.ref ? d2.ref : null, d2.__v) : d2)) { 104 if (d2.__ = u2, d2.__b = u2.__b + 1, null === (y2 = m2[h2]) || y2 && d2.key == y2.key && d2.type === y2.type) m2[h2] = void 0; 105 else for (v2 = 0; v2 < w2; v2++) { 106 if ((y2 = m2[v2]) && d2.key == y2.key && d2.type === y2.type) { 107 m2[v2] = void 0; 108 break; 109 } 110 y2 = null; 111 } 112 M(n2, d2, y2 = y2 || c$1, t2, r2, o2, f2, e2, a2), k2 = d2.__e, (v2 = d2.ref) && y2.ref != v2 && (g2 || (g2 = []), y2.ref && g2.push(y2.ref, null, d2), g2.push(v2, d2.__c || k2, d2)), null != k2 ? (null == b2 && (b2 = k2), "function" == typeof d2.type && d2.__k === y2.__k ? d2.__d = e2 = I$1(d2, e2, n2) : e2 = z$1(n2, d2, y2, m2, k2, e2), "function" == typeof u2.type && (u2.__d = e2)) : e2 && y2.__e == e2 && e2.parentNode != n2 && (e2 = A(y2)); 113 } 114 for (u2.__e = b2, h2 = w2; h2--; ) null != m2[h2] && ("function" == typeof u2.type && null != m2[h2].__e && m2[h2].__e == u2.__d && (u2.__d = L$1(i2).nextSibling), q(m2[h2], m2[h2])); 115 if (g2) for (h2 = 0; h2 < g2.length; h2++) S(g2[h2], g2[++h2], g2[++h2]); 116} 117function I$1(n2, l2, u2) { 118 for (var i2, t2 = n2.__k, r2 = 0; t2 && r2 < t2.length; r2++) (i2 = t2[r2]) && (i2.__ = n2, l2 = "function" == typeof i2.type ? I$1(i2, l2, u2) : z$1(u2, i2, i2, t2, i2.__e, l2)); 119 return l2; 120} 121function j$2(n2, l2) { 122 return l2 = l2 || [], null == n2 || "boolean" == typeof n2 || (Array.isArray(n2) ? n2.some(function(n3) { 123 j$2(n3, l2); 124 }) : l2.push(n2)), l2; 125} 126function z$1(n2, l2, u2, i2, t2, r2) { 127 var o2, f2, e2; 128 if (void 0 !== l2.__d) o2 = l2.__d, l2.__d = void 0; 129 else if (null == u2 || t2 != r2 || null == t2.parentNode) n: if (null == r2 || r2.parentNode !== n2) n2.appendChild(t2), o2 = null; 130 else { 131 for (f2 = r2, e2 = 0; (f2 = f2.nextSibling) && e2 < i2.length; e2 += 1) if (f2 == t2) break n; 132 n2.insertBefore(t2, r2), o2 = r2; 133 } 134 return void 0 !== o2 ? o2 : t2.nextSibling; 135} 136function L$1(n2) { 137 var l2, u2, i2; 138 if (null == n2.type || "string" == typeof n2.type) return n2.__e; 139 if (n2.__k) { 140 for (l2 = n2.__k.length - 1; l2 >= 0; l2--) if ((u2 = n2.__k[l2]) && (i2 = L$1(u2))) return i2; 141 } 142 return null; 143} 144function M(n2, u2, i2, t2, r2, o2, f2, e2, c2) { 145 var s2, a2, v2, y2, p2, d2, k2, b2, g2, m2, w2, A2, P2, C2, T2, $2 = u2.type; 146 if (void 0 !== u2.constructor) return null; 147 null != i2.__h && (c2 = i2.__h, e2 = u2.__e = i2.__e, u2.__h = null, o2 = [e2]), (s2 = l$1.__b) && s2(u2); 148 try { 149 n: if ("function" == typeof $2) { 150 if (b2 = u2.props, g2 = (s2 = $2.contextType) && t2[s2.__c], m2 = s2 ? g2 ? g2.props.value : s2.__ : t2, i2.__c ? k2 = (a2 = u2.__c = i2.__c).__ = a2.__E : ("prototype" in $2 && $2.prototype.render ? u2.__c = a2 = new $2(b2, m2) : (u2.__c = a2 = new x$1(b2, m2), a2.constructor = $2, a2.render = B$1), g2 && g2.sub(a2), a2.props = b2, a2.state || (a2.state = {}), a2.context = m2, a2.__n = t2, v2 = a2.__d = true, a2.__h = [], a2._sb = []), null == a2.__s && (a2.__s = a2.state), null != $2.getDerivedStateFromProps && (a2.__s == a2.state && (a2.__s = h({}, a2.__s)), h(a2.__s, $2.getDerivedStateFromProps(b2, a2.__s))), y2 = a2.props, p2 = a2.state, a2.__v = u2, v2) null == $2.getDerivedStateFromProps && null != a2.componentWillMount && a2.componentWillMount(), null != a2.componentDidMount && a2.__h.push(a2.componentDidMount); 151 else { 152 if (null == $2.getDerivedStateFromProps && b2 !== y2 && null != a2.componentWillReceiveProps && a2.componentWillReceiveProps(b2, m2), !a2.__e && null != a2.shouldComponentUpdate && false === a2.shouldComponentUpdate(b2, a2.__s, m2) || u2.__v === i2.__v) { 153 for (u2.__v !== i2.__v && (a2.props = b2, a2.state = a2.__s, a2.__d = false), u2.__e = i2.__e, u2.__k = i2.__k, u2.__k.forEach(function(n3) { 154 n3 && (n3.__ = u2); 155 }), w2 = 0; w2 < a2._sb.length; w2++) a2.__h.push(a2._sb[w2]); 156 a2._sb = [], a2.__h.length && f2.push(a2); 157 break n; 158 } 159 null != a2.componentWillUpdate && a2.componentWillUpdate(b2, a2.__s, m2), null != a2.componentDidUpdate && a2.__h.push(function() { 160 a2.componentDidUpdate(y2, p2, d2); 161 }); 162 } 163 if (a2.context = m2, a2.props = b2, a2.__P = n2, A2 = l$1.__r, P2 = 0, "prototype" in $2 && $2.prototype.render) { 164 for (a2.state = a2.__s, a2.__d = false, A2 && A2(u2), s2 = a2.render(a2.props, a2.state, a2.context), C2 = 0; C2 < a2._sb.length; C2++) a2.__h.push(a2._sb[C2]); 165 a2._sb = []; 166 } else do { 167 a2.__d = false, A2 && A2(u2), s2 = a2.render(a2.props, a2.state, a2.context), a2.state = a2.__s; 168 } while (a2.__d && ++P2 < 25); 169 a2.state = a2.__s, null != a2.getChildContext && (t2 = h(h({}, t2), a2.getChildContext())), v2 || null == a2.getSnapshotBeforeUpdate || (d2 = a2.getSnapshotBeforeUpdate(y2, p2)), T2 = null != s2 && s2.type === _ && null == s2.key ? s2.props.children : s2, H$1(n2, Array.isArray(T2) ? T2 : [T2], u2, i2, t2, r2, o2, f2, e2, c2), a2.base = u2.__e, u2.__h = null, a2.__h.length && f2.push(a2), k2 && (a2.__E = a2.__ = null), a2.__e = false; 170 } else null == o2 && u2.__v === i2.__v ? (u2.__k = i2.__k, u2.__e = i2.__e) : u2.__e = O(i2.__e, u2, i2, t2, r2, o2, f2, c2); 171 (s2 = l$1.diffed) && s2(u2); 172 } catch (n3) { 173 u2.__v = null, (c2 || null != o2) && (u2.__e = e2, u2.__h = !!c2, o2[o2.indexOf(e2)] = null), l$1.__e(n3, u2, i2); 174 } 175} 176function N(n2, u2) { 177 l$1.__c && l$1.__c(u2, n2), n2.some(function(u3) { 178 try { 179 n2 = u3.__h, u3.__h = [], n2.some(function(n3) { 180 n3.call(u3); 181 }); 182 } catch (n3) { 183 l$1.__e(n3, u3.__v); 184 } 185 }); 186} 187function O(l2, u2, i2, t2, r2, o2, f2, e2) { 188 var s2, a2, h2, y2 = i2.props, p2 = u2.props, d2 = u2.type, _2 = 0; 189 if ("svg" === d2 && (r2 = true), null != o2) { 190 for (; _2 < o2.length; _2++) if ((s2 = o2[_2]) && "setAttribute" in s2 == !!d2 && (d2 ? s2.localName === d2 : 3 === s2.nodeType)) { 191 l2 = s2, o2[_2] = null; 192 break; 193 } 194 } 195 if (null == l2) { 196 if (null === d2) return document.createTextNode(p2); 197 l2 = r2 ? document.createElementNS("http://www.w3.org/2000/svg", d2) : document.createElement(d2, p2.is && p2), o2 = null, e2 = false; 198 } 199 if (null === d2) y2 === p2 || e2 && l2.data === p2 || (l2.data = p2); 200 else { 201 if (o2 = o2 && n.call(l2.childNodes), a2 = (y2 = i2.props || c$1).dangerouslySetInnerHTML, h2 = p2.dangerouslySetInnerHTML, !e2) { 202 if (null != o2) for (y2 = {}, _2 = 0; _2 < l2.attributes.length; _2++) y2[l2.attributes[_2].name] = l2.attributes[_2].value; 203 (h2 || a2) && (h2 && (a2 && h2.__html == a2.__html || h2.__html === l2.innerHTML) || (l2.innerHTML = h2 && h2.__html || "")); 204 } 205 if (k$1(l2, p2, y2, r2, e2), h2) u2.__k = []; 206 else if (_2 = u2.props.children, H$1(l2, Array.isArray(_2) ? _2 : [_2], u2, i2, t2, r2 && "foreignObject" !== d2, o2, f2, o2 ? o2[0] : i2.__k && A(i2, 0), e2), null != o2) for (_2 = o2.length; _2--; ) null != o2[_2] && v$1(o2[_2]); 207 e2 || ("value" in p2 && void 0 !== (_2 = p2.value) && (_2 !== l2.value || "progress" === d2 && !_2 || "option" === d2 && _2 !== y2.value) && g$2(l2, "value", _2, y2.value, false), "checked" in p2 && void 0 !== (_2 = p2.checked) && _2 !== l2.checked && g$2(l2, "checked", _2, y2.checked, false)); 208 } 209 return l2; 210} 211function S(n2, u2, i2) { 212 try { 213 "function" == typeof n2 ? n2(u2) : n2.current = u2; 214 } catch (n3) { 215 l$1.__e(n3, i2); 216 } 217} 218function q(n2, u2, i2) { 219 var t2, r2; 220 if (l$1.unmount && l$1.unmount(n2), (t2 = n2.ref) && (t2.current && t2.current !== n2.__e || S(t2, null, u2)), null != (t2 = n2.__c)) { 221 if (t2.componentWillUnmount) try { 222 t2.componentWillUnmount(); 223 } catch (n3) { 224 l$1.__e(n3, u2); 225 } 226 t2.base = t2.__P = null, n2.__c = void 0; 227 } 228 if (t2 = n2.__k) for (r2 = 0; r2 < t2.length; r2++) t2[r2] && q(t2[r2], u2, i2 || "function" != typeof n2.type); 229 i2 || null == n2.__e || v$1(n2.__e), n2.__ = n2.__e = n2.__d = void 0; 230} 231function B$1(n2, l2, u2) { 232 return this.constructor(n2, u2); 233} 234function D$1(u2, i2, t2) { 235 var r2, o2, f2; 236 l$1.__ && l$1.__(u2, i2), o2 = (r2 = "function" == typeof t2) ? null : i2.__k, f2 = [], M(i2, u2 = (!r2 && t2 || i2).__k = y(_, null, [u2]), o2 || c$1, c$1, void 0 !== i2.ownerSVGElement, !r2 && t2 ? [t2] : o2 ? null : i2.firstChild ? n.call(i2.childNodes) : null, f2, !r2 && t2 ? t2 : o2 ? o2.__e : i2.firstChild, r2), N(f2, u2); 237} 238function G$1(n2, l2) { 239 var u2 = { __c: l2 = "__cC" + e$1++, __: n2, Consumer: function(n3, l3) { 240 return n3.children(l3); 241 }, Provider: function(n3) { 242 var u3, i2; 243 return this.getChildContext || (u3 = [], (i2 = {})[l2] = this, this.getChildContext = function() { 244 return i2; 245 }, this.shouldComponentUpdate = function(n4) { 246 this.props.value !== n4.value && u3.some(function(n5) { 247 n5.__e = true, T$1(n5); 248 }); 249 }, this.sub = function(n4) { 250 u3.push(n4); 251 var l3 = n4.componentWillUnmount; 252 n4.componentWillUnmount = function() { 253 u3.splice(u3.indexOf(n4), 1), l3 && l3.call(n4); 254 }; 255 }), n3.children; 256 } }; 257 return u2.Provider.__ = u2.Consumer.contextType = u2; 258} 259n = s.slice, l$1 = { __e: function(n2, l2, u2, i2) { 260 for (var t2, r2, o2; l2 = l2.__; ) if ((t2 = l2.__c) && !t2.__) try { 261 if ((r2 = t2.constructor) && null != r2.getDerivedStateFromError && (t2.setState(r2.getDerivedStateFromError(n2)), o2 = t2.__d), null != t2.componentDidCatch && (t2.componentDidCatch(n2, i2 || {}), o2 = t2.__d), o2) return t2.__E = t2; 262 } catch (l3) { 263 n2 = l3; 264 } 265 throw n2; 266} }, u$1 = 0, i$1 = function(n2) { 267 return null != n2 && void 0 === n2.constructor; 268}, t = false, x$1.prototype.setState = function(n2, l2) { 269 var u2; 270 u2 = null != this.__s && this.__s !== this.state ? this.__s : this.__s = h({}, this.state), "function" == typeof n2 && (n2 = n2(h({}, u2), this.props)), n2 && h(u2, n2), null != n2 && this.__v && (l2 && this._sb.push(l2), T$1(this)); 271}, x$1.prototype.forceUpdate = function(n2) { 272 this.__v && (this.__e = true, n2 && this.__h.push(n2), T$1(this)); 273}, x$1.prototype.render = _, r$1 = [], f$1 = "function" == typeof Promise ? Promise.prototype.then.bind(Prom
273ise.resolve()) : setTimeout, $$1.__r = 0, e$1 = 0; 274var r, u, i, f = [], c = [], e = l$1.__b, a = l$1.__r, v = l$1.diffed, l = l$1.__c, m = l$1.unmount; 275function b() { 276 for (var t2; t2 = f.shift(); ) if (t2.__P && t2.__H) try { 277 t2.__H.__h.forEach(k), t2.__H.__h.forEach(w$1), t2.__H.__h = []; 278 } catch (r2) { 279 t2.__H.__h = [], l$1.__e(r2, t2.__v); 280 } 281} 282l$1.__b = function(n2) { 283 r = null, e && e(n2); 284}, l$1.__r = function(n2) { 285 a && a(n2); 286 var i2 = (r = n2.__c).__H; 287 i2 && (u === r ? (i2.__h = [], r.__h = [], i2.__.forEach(function(n3) { 288 n3.__N && (n3.__ = n3.__N), n3.__V = c, n3.__N = n3.i = void 0; 289 })) : (i2.__h.forEach(k), i2.__h.forEach(w$1), i2.__h = [])), u = r; 290}, l$1.diffed = function(t2) { 291 v && v(t2); 292 var o2 = t2.__c; 293 o2 && o2.__H && (o2.__H.__h.length && (1 !== f.push(o2) && i === l$1.requestAnimationFrame || ((i = l$1.requestAnimationFrame) || j$1)(b)), o2.__H.__.forEach(function(n2) { 294 n2.i && (n2.__H = n2.i), n2.__V !== c && (n2.__ = n2.__V), n2.i = void 0, n2.__V = c; 295 })), u = r = null; 296}, l$1.__c = function(t2, r2) { 297 r2.some(function(t3) { 298 try { 299 t3.__h.forEach(k), t3.__h = t3.__h.filter(function(n2) { 300 return !n2.__ || w$1(n2); 301 }); 302 } catch (u2) { 303 r2.some(function(n2) { 304 n2.__h && (n2.__h = []); 305 }), r2 = [], l$1.__e(u2, t3.__v); 306 } 307 }), l && l(t2, r2); 308}, l$1.unmount = function(t2) { 309 m && m(t2); 310 var r2, u2 = t2.__c; 311 u2 && u2.__H && (u2.__H.__.forEach(function(n2) { 312 try { 313 k(n2); 314 } catch (n3) { 315 r2 = n3; 316 } 317 }), u2.__H = void 0, r2 && l$1.__e(r2, u2.__v)); 318}; 319var g$1 = "function" == typeof requestAnimationFrame; 320function j$1(n2) { 321 var t2, r2 = function() { 322 clearTimeout(u2), g$1 && cancelAnimationFrame(t2), setTimeout(n2); 323 }, u2 = setTimeout(r2, 100); 324 g$1 && (t2 = requestAnimationFrame(r2)); 325} 326function k(n2) { 327 var t2 = r, u2 = n2.__c; 328 "function" == typeof u2 && (n2.__c = void 0, u2()), r = t2; 329} 330function w$1(n2) { 331 var t2 = r; 332 n2.__c = n2.__(), r = t2; 333} 334function g(n2, t2) { 335 for (var e2 in t2) n2[e2] = t2[e2]; 336 return n2; 337} 338function C(n2, t2) { 339 for (var e2 in n2) if ("__source" !== e2 && !(e2 in t2)) return true; 340 for (var r2 in t2) if ("__source" !== r2 && n2[r2] !== t2[r2]) return true; 341 return false; 342} 343function w(n2) { 344 this.props = n2; 345} 346(w.prototype = new x$1()).isPureReactComponent = true, w.prototype.shouldComponentUpdate = function(n2, t2) { 347 return C(this.props, n2) || C(this.state, t2); 348}; 349var x = l$1.__b; 350l$1.__b = function(n2) { 351 n2.type && n2.type.__f && n2.ref && (n2.props.ref = n2.ref, n2.ref = null), x && x(n2); 352}; 353var T = l$1.__e; 354l$1.__e = function(n2, t2, e2, r2) { 355 if (n2.then) { 356 for (var u2, o2 = t2; o2 = o2.__; ) if ((u2 = o2.__c) && u2.__c) return null == t2.__e && (t2.__e = e2.__e, t2.__k = e2.__k), u2.__c(n2, t2); 357 } 358 T(n2, t2, e2, r2); 359}; 360var I = l$1.unmount; 361function L(n2, t2, e2) { 362 return n2 && (n2.__c && n2.__c.__H && (n2.__c.__H.__.forEach(function(n3) { 363 "function" == typeof n3.__c && n3.__c(); 364 }), n2.__c.__H = null), null != (n2 = g({}, n2)).__c && (n2.__c.__P === e2 && (n2.__c.__P = t2), n2.__c = null), n2.__k = n2.__k && n2.__k.map(function(n3) { 365 return L(n3, t2, e2); 366 })), n2; 367} 368function U(n2, t2, e2) { 369 return n2 && (n2.__v = null, n2.__k = n2.__k && n2.__k.map(function(n3) { 370 return U(n3, t2, e2); 371 }), n2.__c && n2.__c.__P === t2 && (n2.__e && e2.insertBefore(n2.__e, n2.__d), n2.__c.__e = true, n2.__c.__P = e2)), n2; 372} 373function D() { 374 this.__u = 0, this.t = null, this.__b = null; 375} 376function F(n2) { 377 var t2 = n2.__.__c; 378 return t2 && t2.__a && t2.__a(n2); 379} 380function V() { 381 this.u = null, this.o = null; 382} 383l$1.unmount = function(n2) { 384 var t2 = n2.__c; 385 t2 && t2.__R && t2.__R(), t2 && true === n2.__h && (n2.type = null), I && I(n2); 386}, (D.prototype = new x$1()).__c = function(n2, t2) { 387 var e2 = t2.__c, r2 = this; 388 null == r2.t && (r2.t = []), r2.t.push(e2); 389 var u2 = F(r2.__v), o2 = false, i2 = function() { 390 o2 || (o2 = true, e2.__R = null, u2 ? u2(l2) : l2()); 391 }; 392 e2.__R = i2; 393 var l2 = function() { 394 if (!--r2.__u) { 395 if (r2.state.__a) { 396 var n3 = r2.state.__a; 397 r2.__v.__k[0] = U(n3, n3.__c.__P, n3.__c.__O); 398 } 399 var t3; 400 for (r2.setState({ __a: r2.__b = null }); t3 = r2.t.pop(); ) t3.forceUpdate(); 401 } 402 }, c2 = true === t2.__h; 403 r2.__u++ || c2 || r2.setState({ __a: r2.__b = r2.__v.__k[0] }), n2.then(i2, i2); 404}, D.prototype.componentWillUnmount = function() { 405 this.t = []; 406}, D.prototype.render = function(n2, e2) { 407 if (this.__b) { 408 if (this.__v.__k) { 409 var r2 = document.createElement("div"), o2 = this.__v.__k[0].__c; 410 this.__v.__k[0] = L(this.__b, r2, o2.__O = o2.__P); 411 } 412 this.__b = null; 413 } 414 var i2 = e2.__a && y(_, null, n2.fallback); 415 return i2 && (i2.__h = null), [y(_, null, e2.__a ? null : n2.children), i2]; 416}; 417var W = function(n2, t2, e2) { 418 if (++e2[1] === e2[0] && n2.o.delete(t2), n2.props.revealOrder && ("t"
418!== n2.props.revealOrder[0] || !n2.o.size)) for (e2 = n2.u; e2; ) { 419 for (; e2.length > 3; ) e2.pop()(); 420 if (e2[1] < e2[0]) break; 421 n2.u = e2 = e2[2]; 422 } 423}; 424function P(n2) { 425 return this.getChildContext = function() { 426 return n2.context; 427 }, n2.children; 428} 429function $(n2) { 430 var e2 = this, r2 = n2.i; 431 e2.componentWillUnmount = function() { 432 D$1(null, e2.l), e2.l = null, e2.i = null; 433 }, e2.i && e2.i !== r2 && e2.componentWillUnmount(), n2.__v ? (e2.l || (e2.i = r2, e2.l = { nodeType: 1, parentNode: r2, childNodes: [], appendChild: function(n3) { 434 this.childNodes.push(n3), e2.i.appendChild(n3); 435 }, insertBefore: function(n3, t2) { 436 this.childNodes.push(n3), e2.i.appendChild(n3); 437 }, removeChild: function(n3) { 438 this.childNodes.splice(this.childNodes.indexOf(n3) >>> 1, 1), e2.i.removeChild(n3); 439 } }), D$1(y(P, { context: e2.context }, n2.__v), e2.l)) : e2.l && e2.componentWillUnmount(); 440} 441function j(n2, e2) { 442 var r2 = y($, { __v: n2, i: e2 }); 443 return r2.containerInfo = e2, r2; 444} 445(V.prototype = new x$1()).__a = function(n2) { 446 var t2 = this, e2 = F(t2.__v), r2 = t2.o.get(n2); 447 return r2[0]++, function(u2) { 448 var o2 = function() { 449 t2.props.revealOrder ? (r2.push(u2), W(t2, n2, r2)) : u2(); 450 }; 451 e2 ? e2(o2) : o2(); 452 }; 453}, V.prototype.render = function(n2) { 454 this.u = null, this.o = /* @__PURE__ */ new Map(); 455 var t2 = j$2(n2.children); 456 n2.revealOrder && "b" === n2.revealOrder[0] && t2.reverse(); 457 for (var e2 = t2.length; e2--; ) this.o.set(t2[e2], this.u = [1, 0, this.u]); 458 return n2.children; 459}, V.prototype.componentDidUpdate = V.prototype.componentDidMount = function() { 460 var n2 = this; 461 this.o.forEach(function(t2, e2) { 462 W(n2, e2, t2); 463 }); 464}; 465var z = "undefined" != typeof Symbol && Symbol.for && Symbol.for("react.element") || 60103, B = /^(?:accent|alignment|arabic|baseline|cap|clip(?!PathU)|color|dominant|fill|flood|font|glyph(?!R)|horiz|image|letter|lighting|marker(?!H|W|U)|overline|paint|pointer|shape|stop|strikethrough|stroke|text(?!L)|transform|underline|unicode|units|v|vector|vert|word|writing|x(?!C))[A-Z]/, H = "undefined" != typeof document, Z = function(n2) { 466 return ("undefined" != typeof Symbol && "symbol" == typeof Symbol() ? /fil|che|rad/i : /fil|che|ra/i).test(n2); 467}; 468x$1.prototype.isReactComponent = {}, ["componentWillMount", "componentWillReceiveProps", "componentWillUpdate"].forEach(function(t2) { 469 Object.defineProperty(x$1.prototype, t2, { configurable: true, get: function() { 470 return this["UNSAFE_" + t2]; 471 }, set: function(n2) { 472 Object.defineProperty(this, t2, { configurable: true, writable: true, value: n2 }); 473 } }); 474}); 475var G = l$1.event; 476function J() { 477} 478function K() { 479 return this.cancelBubble; 480} 481function Q() { 482 return this.defaultPrevented; 483} 484l$1.event = function(n2) { 485 return G && (n2 = G(n2)), n2.persist = J, n2.isPropagationStopped = K, n2.isDefaultPrevented = Q, n2.nativeEvent = n2; 486}; 487var nn = { configurable: true, get: function() { 488 return this.class; 489} }, tn = l$1.vnode; 490l$1.vnode = function(n2) { 491 var t2 = n2.type, e2 = n2.props, u2 = e2; 492 if ("string" == typeof t2) { 493 var o2 = -1 === t2.indexOf("-"); 494 for (var i2 in u2 = {}, e2) { 495 var l2 = e2[i2]; 496 H && "children" === i2 && "noscript" === t2 || "value" === i2 && "defaultValue" in e2 && null == l2 || ("defaultValue" === i2 && "value" in e2 && null == e2.value ? i2 = "value" : "download" === i2 && true === l2 ? l2 = "" : /ondoubleclick/i.test(i2) ? i2 = "ondblclick" : /^onchange(textarea|input)/i.test(i2 + t2) && !Z(e2.type) ? i2 = "oninput" : /^onfocus$/i.test(i2) ? i2 = "onfocusin" : /^onblur$/i.test(i2) ? i2 = "onfocusout" : /^on(Ani|Tra|Tou|BeforeInp|Compo)/.test(i2) ? i2 = i2.toLowerCase() : o2 && B.test(i2) ? i2 = i2.replace(/[A-Z0-9]/g, "-$&").toLowerCase() : null === l2 && (l2 = void 0), /^oninput$/i.test(i2) && (i2 = i2.toLowerCase(), u2[i2] && (i2 = "oninputCapture")), u2[i2] = l2); 497 } 498 "select" == t2 && u2.multiple && Array.isArray(u2.value) && (u2.value = j$2(e2.children).forEach(function(n3) { 499 n3.props.selected = -1 != u2.value.indexOf(n3.props.value); 500 })), "select" == t2 && null != u2.defaultValue && (u2.value = j$2(e2.children).forEac
vendor: 5,083 bytes, lines 500-579
500h(function(n3) { 501 n3.props.selected = u2.multiple ? -1 != u2.defaultValue.indexOf(n3.props.value) : u2.defaultValue == n3.props.value; 502 })), n2.props = u2, e2.class != e2.className && (nn.enumerable = "className" in e2, null != e2.className && (u2.class = e2.className), Object.defineProperty(u2, "className", nn)); 503 } 504 n2.$$typeof = z, tn && tn(n2); 505}; 506var en = l$1.__r; 507l$1.__r = function(n2) { 508 en && en(n2), n2.__c; 509}; 510const styleTexts = []; 511const styleEls = /* @__PURE__ */ new Map(); 512function injectStyles(styleText) { 513 styleTexts.push(styleText); 514 styleEls.forEach((styleEl) => { 515 appendStylesTo(styleEl, styleText); 516 }); 517} 518function ensureElHasStyles(el) { 519 if (el.isConnected && // sometimes true if SSR system simulates DOM 520 el.getRootNode) { 521 registerStylesRoot(el.getRootNode()); 522 } 523} 524function registerStylesRoot(rootNode) { 525 let styleEl = styleEls.get(rootNode); 526 if (!styleEl || !styleEl.isConnected) { 527 styleEl = rootNode.querySelector("style[data-fullcalendar]"); 528 if (!styleEl) { 529 styleEl = document.createElement("style"); 530 styleEl.setAttribute("data-fullcalendar", ""); 531 const nonce = getNonceValue(); 532 if (nonce) { 533 styleEl.nonce = nonce; 534 } 535 const parentEl = rootNode === document ? document.head : rootNode; 536 const insertBefore = rootNode === document ? parentEl.querySelector("script,link[rel=stylesheet],link[as=style],style") : parentEl.firstChild; 537 parentEl.insertBefore(styleEl, insertBefore); 538 } 539 styleEls.set(rootNode, styleEl); 540 hydrateStylesRoot(styleEl); 541 } 542} 543function hydrateStylesRoot(styleEl) { 544 for (const styleText of styleTexts) { 545 appendStylesTo(styleEl, styleText); 546 } 547} 548function appendStylesTo(styleEl, styleText) { 549 const { sheet } = styleEl; 550 const ruleCnt = sheet.cssRules.length; 551 styleText.split("}").forEach((styleStr, i2) => { 552 styleStr = styleStr.trim(); 553 if (styleStr) { 554 sheet.insertRule(styleStr + "}", ruleCnt + i2); 555 } 556 }); 557} 558let queriedNonceValue; 559function getNonceValue() { 560 if (queriedNonceValue === void 0) { 561 queriedNonceValue = queryNonceValue(); 562 } 563 return queriedNonceValue; 564} 565function queryNonceValue() { 566 const metaWithNonce = document.querySelector('meta[name="csp-nonce"]'); 567 if (metaWithNonce && metaWithNonce.hasAttribute("content")) { 568 return metaWithNonce.getAttribute("content"); 569 } 570 const elWithNonce = document.querySelector("script[nonce]"); 571 if (elWithNonce) { 572 return elWithNonce.nonce || ""; 573 } 574 return ""; 575} 576if (typeof document !== "undefined") { 577 registerStylesRoot(document); 578} 579var css_248z$2 = ':root{--fc-small-font-size:.85em;--fc-page-bg-color:#fff;--fc-neutral-bg-color:hsla(0,0%,82%,.3);--fc-neutral-text-color:grey;--fc-border-color:#ddd;--fc-button-text-color:#fff;--fc-button-bg-color:#2c3e50;--fc-button-border-color:#2c3e50;--fc-button-hover-bg-color:#1e2b37;--fc-button-hover-border-color:#1a252f;--fc-button-active-bg-color:#1a252f;--fc-button-active-border-color:#151e27;--fc-event-bg-color:#3788d8;--fc-event-border-color:#3788d8;--fc-event-text-color:#fff;--fc-event-selected-overlay-color:rgba(0,0,0,.25);--fc-more-link-bg-color:#d0d0d0;--fc-more-link-text-color:inherit;--fc-event-resizer-thickness:8px;--fc-event-resizer-dot-total-width:8px;--fc-event-resizer-dot-border-width:1px;--fc-non-business-color:hsla(0,0%,84%,.3);--fc-bg-event-color:#8fdf82;--fc-bg-event-opacity:0.3;--fc-highlight-color:rgba(188,232,241,.3);--fc-today-bg-color:rgba(255,220,40,.15);--fc-now-indicator-color:red}.fc-not-allowed,.fc-not-allowed .fc-event{cursor:not-allowed}.fc{display:flex;flex-direction:column;font-size:1em}.fc,.fc *,.fc :after,.fc :before{box-sizing:border-box}.fc table{border-collapse:collapse;border-spacing:0;font-size:1em}.fc th{text-align:center}.fc td,.fc th{padding:0;vertical-align:top}.fc a[data-navlink]{cursor:pointer}.fc a[data-navlink]:hover{text-decoration:underline}.fc-direction-ltr{direction:ltr;text-align:left}.fc-direction-rtl{direction:rtl;text-align:right}.fc-theme-standard td,.fc-theme-standard th{border:1px solid var(--fc-border-color)}.fc-liquid-hack td,.fc-liquid-hack th{position:relative}@font-face{font-family:fcicons;font-style:normal;font-weight:400;src:url("data:application/x-font-ttf;charset=utf-8;base64,AAEAAAALAIAAAwAwT1MvMg8SBfAAAAC8AAAAYGNtYXAXVtKNAAABHAAAAFRnYXNwAAAAEAAAAXAAAAAIZ2x5ZgYydxIAAAF4AAAFNGhlYWQUJ7cIAAAGrAAAADZoaGVhB20DzAAABuQAAAAkaG10eCIABhQAAAcIAAAALGxvY2ED4AU6AAAHNAAAABhtYXhwAA8AjAAAB0wAAAAgbmFtZXsr690AAAdsAAABhnBvc3QAAwAAAAAI9AAAACAAAwPAAZAABQAAApkCzAAAAI8CmQLMAAAB6wAzAQkAAAAAAAAAAAAAAAAAAAABEAAAAAAAAAAAAAAAAAAAAABAAADpBgPA/8AAQAPAAEAAAAABAAAAAAAAAAAAAAAgAAAAAAADAAAAAwAAABwAAQADAAAAHAADAAEAAAAcAAQAOAAAAAoACAACAAIAAQAg6Qb//f//AAAAAAAg6QD//f//AAH/4xcEAAMAAQAAAAAAAAAAAAAAAQAB//8ADwABAAAAAAAAAAAAAgAANzkBAAAAAAEAAAAAAAAAAAACAAA3OQEAAAAAAQAAAAAAAAAAAAIAADc5AQAAAAABAWIAjQKeAskAEwAAJSc3NjQnJiIHAQYUFwEWMjc2NCcCnuLiDQ0MJAz/AA0NAQAMJAwNDcni4gwjDQwM/wANIwz/AA0NDCMNAAAAAQFiAI0CngLJABMAACUBNjQnASYiBwYUHwEHBhQXFjI3AZ4BAA0N/wAMJAwNDeLiDQ0MJAyNAQAMIw0BAAwMDSMM4uINIwwNDQAAAAIA4gC3Ax4CngATACcAACUnNzY0JyY
579iDwEGFB8BFjI3NjQnISc3NjQnJiIPAQYUHwEWMjc2NCcB87e3DQ0MIw3VDQ3VDSMMDQ0BK7e3DQ0MJAzVDQ3VDCQMDQ3zuLcMJAwNDdUNIwzWDAwNIwy4twwkDA0N1Q0jDNYMDA0jDAAAAgDiALcDHgKeABMAJwAAJTc2NC8BJiIHBhQfAQcGFBcWMjchNzY0LwEmIgcGFB8BBwYUFxYyNwJJ1Q0N1Q0jDA0Nt7cNDQwjDf7V1Q0N1QwkDA0Nt7cNDQwkDLfWDCMN1Q0NDCQMt7gMIw0MDNYMIw3VDQ0MJAy3uAwjDQwMAAADAFUAAAOrA1UAMwBoAHcAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMhMjY1NCYjISIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAAVYRGRkR/qoRGRkRA1UFBAUOCQkVDAsZDf2rDRkLDBUJCA4FBQUFBQUOCQgVDAsZDQJVDRkLDBUJCQ4FBAVVAgECBQMCBwQECAX9qwQJAwQHAwMFAQICAgIBBQMDBwQDCQQCVQUIBAQHAgMFAgEC/oAZEhEZGRESGQAAAAADAFUAAAOrA1UAMwBoAIkAABMiBgcOAQcOAQcOARURFBYXHgEXHgEXHgEzITI2Nz4BNz4BNz4BNRE0JicuAScuAScuASMFITIWFx4BFx4BFx4BFREUBgcOAQcOAQcOASMhIiYnLgEnLgEnLgE1ETQ2Nz4BNz4BNz4BMxMzFRQWMzI2PQEzMjY1NCYrATU0JiMiBh0BIyIGFRQWM9UNGAwLFQkJDgUFBQUFBQ4JCRULDBgNAlYNGAwLFQkJDgUFBQUFBQ4JCRULDBgN/aoCVgQIBAQHAwMFAQIBAQIBBQMDBwQECAT9qgQIBAQHAwMFAQIBAQIBBQMDBwQECASAgBkSEhmAERkZEYAZEhIZgBEZGREDVQUEBQ4JCRUMCxkN/asNGQsMFQkIDgUFBQUFBQ4JCBUMCxkNAlUNGQsMFQkJDgUEBVUCAQIFAwIHBAQIBf2rBAkDBAcDAwUBAgICAgEFAwMHBAMJBAJVBQgEBAcCAwUCAQL+gIASGRkSgBkSERmAEhkZEoAZERIZAAABAOIAjQMeAskAIAAAExcHBhQXFjI/ARcWMjc2NC8BNzY0JyYiDwEnJiIHBhQX4uLiDQ0MJAzi4gwkDA0N4uINDQwkDOLiDCQMDQ0CjeLiDSMMDQ3h4Q0NDCMN4uIMIw0MDOLiDAwNIwwAAAABAAAAAQAAa5n0y18PPPUACwQAAAAAANivOVsAAAAA2K85WwAAAAADqwNVAAAACAACAAAAAAAAAAEAAAPA/8AAAAQAAAAAAAOrAAEAAAAAAAAAAAAAAAAAAAALBAAAAAAAAAAAAAAAAgAAAAQAAWIEAAFiBAAA4gQAAOIEAABVBAAAVQQAAOIAAAAAAAoAFAAeAEQAagCqAOoBngJkApoAAQAAAAsAigADAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAA4ArgABAAAAAAABAAcAAAABAAAAAAACAAcAYAABAAAAAAADAAcANgABAAAAAAAEAAcAdQABAAAAAAAFAAsAFQABAAAAAAAGAAcASwABAAAAAAAKABoAigADAAEECQABAA4ABwADAAEECQACAA4AZwADAAEECQADAA4APQADAAEECQAEAA4AfAADAAEECQAFABYAIAADAAEECQAGAA4AUgADAAEECQAKADQApGZjaWNvbnMAZgBjAGkAYwBvAG4Ac1ZlcnNpb24gMS4wAFYAZQByAHMAaQBvAG4AIAAxAC4AMGZjaWNvbnMAZgBjAGkAYwBvAG4Ac2ZjaWNvbnMAZgBjAGkAYwBvAG4Ac1JlZ3VsYXIAUgBlAGcAdQBsAGEAcmZjaWNvbnMAZgBjAGkAYwBvAG4Ac0ZvbnQgZ2VuZXJhdGVkIGJ5IEljb01vb24uAEYAbwBuAHQAIABnAGUAbgBlAHIAYQB0AGUAZAAgAGIAeQAgAEkAYwBvAE0AbwBvAG4ALgAAAAMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=") format("truetype")}.fc-icon{speak:none;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;font-family:fcicons!important;font-style:normal;font-variant:normal;font-weight:400;height:1em;line-height:1;text-align:center;text-transform:none;-moz-user-select:none;user-select:none;width:1em}.fc-icon-chevron-left:before{content:"\\e900"}.fc-icon-chevron-right:before{content:"\\e901"}.fc-icon-chevrons-left:before{content:"\\e902"}.fc-icon-chevrons-right:before{content:"\\e903"}.fc-icon-minus-square:before{content:"\\e904"}.fc-icon-plus-square:before{content:"\\e905"}.fc-icon-x:before{content:"\\e906"}.fc .fc-button{border-radius:0;font-family:inherit;font-size:inherit;line-height:inherit;margin:0;overflow:visible;text-transform:none}.fc .fc-button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}.fc .fc-button{-webkit-appearance:button}.fc .fc-button:not(:disabled){cursor:pointer}.fc .fc-button{background-color:transparent;border:1px solid transparent;border-radius:.25em;display:inline-block;font-size:1em;font-weight:400;line-height:1.5;padding:.4em .65em;text-align:center
vendor: 8,348 bytes, line 579
579;-moz-user-select:none;user-select:none;vertical-align:middle}.fc .fc-button:hover{text-decoration:none}.fc .fc-button:focus{box-shadow:0 0 0 .2rem rgba(44,62,80,.25);outline:0}.fc .fc-button:disabled{opacity:.65}.fc .fc-button-primary{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:hover{background-color:var(--fc-button-hover-bg-color);border-color:var(--fc-button-hover-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:disabled{background-color:var(--fc-button-bg-color);border-color:var(--fc-button-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button-primary:not(:disabled).fc-button-active,.fc .fc-button-primary:not(:disabled):active{background-color:var(--fc-button-active-bg-color);border-color:var(--fc-button-active-border-color);color:var(--fc-button-text-color)}.fc .fc-button-primary:not(:disabled).fc-button-active:focus,.fc .fc-button-primary:not(:disabled):active:focus{box-shadow:0 0 0 .2rem rgba(76,91,106,.5)}.fc .fc-button .fc-icon{font-size:1.5em;vertical-align:middle}.fc .fc-button-group{display:inline-flex;position:relative;vertical-align:middle}.fc .fc-button-group>.fc-button{flex:1 1 auto;position:relative}.fc .fc-button-group>.fc-button.fc-button-active,.fc .fc-button-group>.fc-button:active,.fc .fc-button-group>.fc-button:focus,.fc .fc-button-group>.fc-button:hover{z-index:1}.fc-direction-ltr .fc-button-group>.fc-button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0;margin-left:-1px}.fc-direction-ltr .fc-button-group>.fc-button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0}.fc-direction-rtl .fc-button-group>.fc-button:not(:first-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.fc-direction-rtl .fc-button-group>.fc-button:not(:last-child){border-bottom-left-radius:0;border-top-left-radius:0}.fc .fc-toolbar{align-items:center;display:flex;justify-content:space-between}.fc .fc-toolbar.fc-header-toolbar{margin-bottom:1.5em}.fc .fc-toolbar.fc-footer-toolbar{margin-top:1.5em}.fc .fc-toolbar-title{font-size:1.75em;margin:0}.fc-direction-ltr .fc-toolbar>*>:not(:first-child){margin-left:.75em}.fc-direction-rtl .fc-toolbar>*>:not(:first-child){margin-right:.75em}.fc-direction-rtl .fc-toolbar-ltr{flex-direction:row-reverse}.fc .fc-scroller{-webkit-overflow-scrolling:touch;position:relative}.fc .fc-scroller-liquid{height:100%}.fc .fc-scroller-liquid-absolute{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-scroller-harness{direction:ltr;overflow:hidden;position:relative}.fc .fc-scroller-harness-liquid{height:100%}.fc-direction-rtl .fc-scroller-harness>.fc-scroller{direction:rtl}.fc-theme-standard .fc-scrollgrid{border:1px solid var(--fc-border-color)}.fc .fc-scrollgrid,.fc .fc-scrollgrid table{table-layout:fixed;width:100%}.fc .fc-scrollgrid table{border-left-style:hidden;border-right-style:hidden;border-top-style:hidden}.fc .fc-scrollgrid{border-bottom-width:0;border-collapse:separate;border-right-width:0}.fc .fc-scrollgrid-liquid{height:100%}.fc .fc-scrollgrid-section,.fc .fc-scrollgrid-section table,.fc .fc-scrollgrid-section>td{height:1px}.fc .fc-scrollgrid-section-liquid>td{height:100%}.fc .fc-scrollgrid-section>*{border-left-width:0;border-top-width:0}.fc .fc-scrollgrid-section-footer>*,.fc .fc-scrollgrid-section-header>*{border-bottom-width:0}.fc .fc-scrollgrid-section-body table,.fc .fc-scrollgrid-section-footer table{border-bottom-style:hidden}.fc .fc-scrollgrid-section-sticky>*{background:var(--fc-page-bg-color);position:sticky;z-index:3}.fc .fc-scrollgrid-section-header.fc-scrollgrid-section-sticky>*{top:0}.fc .fc-scrollgrid-section-footer.fc-scrollgrid-section-sticky>*{bottom:0}.fc .fc-scrollgrid-sticky-shim{height:1px;margin-bottom:-1px}.fc-sticky{position:sticky}.fc .fc-view-harness{flex-grow:1;position:relative}.fc .fc-view-harness-active>.fc-view{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-col-header-cell-cushion{display:inline-block;padding:2px 4px}.fc .fc-bg-event,.fc .fc-highlight,.fc .fc-non-business{bottom:0;left:0;position:absolute;right:0;top:0}.fc .fc-non-business{background:var(--fc-non-business-color)}.fc .fc-bg-event{background:var(--fc-bg-event-color);opacity:var(--fc-bg-event-opacity)}.fc .fc-bg-event .fc-event-title{font-size:var(--fc-small-font-size);font-style:italic;margin:.5em}.fc .fc-highlight{background:var(--fc-highlight-color)}.fc .fc-cell-shaded,.fc .fc-day-disabled{background:var(--fc-neutral-bg-color)}a.fc-event,a.fc-event:hover{text-decoration:none}.fc-event.fc-event-draggable,.fc-event[href]{cursor:pointer}.fc-event .fc-event-main{position:relative;z-index:2}.fc-event-dragging:not(.fc-event-selected){opacity:.75}.fc-event-dragging.fc-event-selected{box-shadow:0 2px 7px rgba(0,0,0,.3)}.fc-event .fc-event-resizer{display:none;position:absolute;z-index:4}.fc-event-selected .fc-event-resizer,.fc-event:hover .fc-event-resizer{display:block}.fc-event-selected .fc-event-resizer{background:var(--fc-page-bg-color);border-color:inherit;border-radius:calc(var(--fc-event-resizer-dot-total-width)/2);border-style:solid;border-width:var(--fc-event-resizer-dot-border-width);height:var(--fc-event-resizer-dot-total-width);width:var(--fc-event-resizer-dot-total-width)}.fc-event-selected .fc-event-resizer:before{bottom:-20px;content:"";left:-20px;position:absolute;right:-20px;top:-20px}.fc-event-selected,.fc-event:focus{box-shadow:0 2px 5px rgba(0,0,0,.2)}.fc-event-selected:before,.fc-event:focus:before{bottom:0;content:"";left:0;position:absolute;right:0;top:0;z-index:3}.fc-event-selected:after,.fc-event:focus:after{background:var(--fc-event-selected-overlay-color);bottom:-1px;content:"";left:-1px;position:absolute;right:-1px;top:-1px;z-index:1}.fc-h-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-h-event .fc-event-main{color:var(--fc-event-text-color)}.fc-h-event .fc-event-main-frame{display:flex}.fc-h-event .fc-event-time{max-width:100%;overflow:hidden}.fc-h-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-width:0}.fc-h-event .fc-event-title{display:inline-block;left:0;max-width:100%;overflow:hidden;right:0;vertical-align:top}.fc-h-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-start),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-end){border-bottom-left-radius:0;border-left-width:0;border-top-left-radius:0}.fc-direction-ltr .fc-daygrid-block-event:not(.fc-event-end),.fc-direction-rtl .fc-daygrid-block-event:not(.fc-event-start){border-bottom-right-radius:0;border-right-width:0;border-top-right-radius:0}.fc-h-event:not(.fc-event-selected) .fc-event-resizer{bottom:0;top:0;width:var(--fc-event-resizer-thickness)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end{cursor:w-resize;left:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-direction-ltr .fc-h-event:not(.fc-event-selected) .fc-event-resizer-end,.fc-direction-rtl .fc-h-event:not(.fc-event-selected) .fc-event-resizer-start{cursor:e-resize;right:calc(var(--fc-event-resizer-thickness)*-.5)}.fc-h-event.fc-event-selected .fc-event-resizer{margin-top:calc(var(--fc-event-resizer-dot-total-width)*-.5);top:50%}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-start,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-end{left:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc-direction-ltr .fc-h-event.fc-event-selected .fc-event-resizer-end,.fc-direction-rtl .fc-h-event.fc-event-selected .fc-event-resizer-start{right:calc(var(--fc-event-resizer-dot-total-width)*-.5)}.fc .fc-popover{box-shadow:0 2px 6px rgba(0,0,0,.15);position:absolute;z-index:9999}.fc .fc-popover-header{align-items:center;display:flex;flex-direction:row;justify-content:space-between;padding:3px 4px}.fc .fc-popover-title{margin:0 2px}.fc .fc-popover-close{cursor:pointer;font-size:1.1em;opacity:.65}.fc-theme-standard .fc-popover{background:var(--fc-page-bg-color);border:1px solid var(--fc-border-color)}.fc-theme-standard .fc-popover-header{background:var(--fc-neutral-bg-color)}';
vendor: 2,796 bytes, lines 579-692
579 580injectStyles(css_248z$2); 581class DelayedRunner { 582 constructor(drainedOption) { 583 this.drainedOption = drainedOption; 584 this.isRunning = false; 585 this.isDirty = false; 586 this.pauseDepths = {}; 587 this.timeoutId = 0; 588 } 589 request(delay) { 590 this.isDirty = true; 591 if (!this.isPaused()) { 592 this.clearTimeout(); 593 if (delay == null) { 594 this.tryDrain(); 595 } else { 596 this.timeoutId = setTimeout( 597 // NOT OPTIMAL! TODO: look at debounce 598 this.tryDrain.bind(this), 599 delay 600 ); 601 } 602 } 603 } 604 pause(scope = "") { 605 let { pauseDepths } = this; 606 pauseDepths[scope] = (pauseDepths[scope] || 0) + 1; 607 this.clearTimeout(); 608 } 609 resume(scope = "", force) { 610 let { pauseDepths } = this; 611 if (scope in pauseDepths) { 612 if (force) { 613 delete pauseDepths[scope]; 614 } else { 615 pauseDepths[scope] -= 1; 616 let depth = pauseDepths[scope]; 617 if (depth <= 0) { 618 delete pauseDepths[scope]; 619 } 620 } 621 this.tryDrain(); 622 } 623 } 624 isPaused() { 625 return Object.keys(this.pauseDepths).length; 626 } 627 tryDrain() { 628 if (!this.isRunning && !this.isPaused()) { 629 this.isRunning = true; 630 while (this.isDirty) { 631 this.isDirty = false; 632 this.drained(); 633 } 634 this.isRunning = false; 635 } 636 } 637 clear() { 638 this.clearTimeout(); 639 this.isDirty = false; 640 this.pauseDepths = {}; 641 } 642 clearTimeout() { 643 if (this.timeoutId) { 644 clearTimeout(this.timeoutId); 645 this.timeoutId = 0; 646 } 647 } 648 drained() { 649 if (this.drainedOption) { 650 this.drainedOption(); 651 } 652 } 653} 654function removeElement(el) { 655 if (el.parentNode) { 656 el.parentNode.removeChild(el); 657 } 658} 659function elementClosest(el, selector) { 660 if (el.closest) { 661 return el.closest(selector); 662 } 663 if (!document.documentElement.contains(el)) { 664 return null; 665 } 666 do { 667 if (elementMatches(el, selector)) { 668 return el; 669 } 670 el = el.parentElement || el.parentNode; 671 } while (el !== null && el.nodeType === 1); 672 return null; 673} 674function elementMatches(el, selector) { 675 let method = el.matches || el.matchesSelector || el.msMatchesSelector; 676 return method.call(el, selector); 677} 678function findElements(container, selector) { 679 let containers = container instanceof HTMLElement ? [container] : container; 680 let allMatches = []; 681 for (let i2 = 0; i2 < containers.length; i2 += 1) { 682 let matches = containers[i2].querySelectorAll(selector); 683 for (let j2 = 0; j2 < matches.length; j2 += 1) { 684 allMatches.push(matches[j2]); 685 } 686 } 687 return allMatches; 688} 689function findDirectChildren(parent, selector) { 690 let parents = parent instanceof HTMLElement ? [parent] : parent; 691 let allMatches = []; 692 for (let i2 = 0; i2 < parents.length; i2 += 1) {
vendor: 6,173 bytes, lines 693-904
693 let childNodes = parents[i2].children; 694 for (let j2 = 0; j2 < childNodes.length; j2 += 1) { 695 let childNode = childNodes[j2]; 696 if (elementMatches(childNode, selector)) { 697 allMatches.push(childNode); 698 } 699 } 700 } 701 return allMatches; 702} 703const PIXEL_PROP_RE = /(top|left|right|bottom|width|height)$/i; 704function applyStyle(el, props) { 705 for (let propName in props) { 706 applyStyleProp(el, propName, props[propName]); 707 } 708} 709function applyStyleProp(el, name, val) { 710 if (val == null) { 711 el.style[name] = ""; 712 } else if (typeof val === "number" && PIXEL_PROP_RE.test(name)) { 713 el.style[name] = `${val}px`; 714 } else { 715 el.style[name] = val; 716 } 717} 718function getEventTargetViaRoot(ev) { 719 var _a, _b; 720 return (_b = (_a = ev.composedPath) === null || _a === void 0 ? void 0 : _a.call(ev)[0]) !== null && _b !== void 0 ? _b : ev.target; 721} 722let guid$1 = 0; 723function getUniqueDomId() { 724 guid$1 += 1; 725 return "fc-dom-" + guid$1; 726} 727function preventDefault(ev) { 728 ev.preventDefault(); 729} 730function buildDelegationHandler(selector, handler) { 731 return (ev) => { 732 let matchedChild = elementClosest(ev.target, selector); 733 if (matchedChild) { 734 handler.call(matchedChild, ev, matchedChild); 735 } 736 }; 737} 738function listenBySelector(container, eventType, selector, handler) { 739 let attachedHandler = buildDelegationHandler(selector, handler); 740 container.addEventListener(eventType, attachedHandler); 741 return () => { 742 container.removeEventListener(eventType, attachedHandler); 743 }; 744} 745function listenToHoverBySelector(container, selector, onMouseEnter, onMouseLeave) { 746 let currentMatchedChild; 747 return listenBySelector(container, "mouseover", selector, (mouseOverEv, matchedChild) => { 748 if (matchedChild !== currentMatchedChild) { 749 currentMatchedChild = matchedChild; 750 onMouseEnter(mouseOverEv, matchedChild); 751 let realOnMouseLeave = (mouseLeaveEv) => { 752 currentMatchedChild = null; 753 onMouseLeave(mouseLeaveEv, matchedChild); 754 matchedChild.removeEventListener("mouseleave", realOnMouseLeave); 755 }; 756 matchedChild.addEventListener("mouseleave", realOnMouseLeave); 757 } 758 }); 759} 760const transitionEventNames = [ 761 "webkitTransitionEnd", 762 "otransitionend", 763 "oTransitionEnd", 764 "msTransitionEnd", 765 "transitionend" 766]; 767function whenTransitionDone(el, callback) { 768 let realCallback = (ev) => { 769 callback(ev); 770 transitionEventNames.forEach((eventName) => { 771 el.removeEventListener(eventName, realCallback); 772 }); 773 }; 774 transitionEventNames.forEach((eventName) => { 775 el.addEventListener(eventName, realCallback); 776 }); 777} 778function createAriaClickAttrs(handler) { 779 return Object.assign({ onClick: handler }, createAriaKeyboardAttrs(handler)); 780} 781function createAriaKeyboardAttrs(handler) { 782 return { 783 tabIndex: 0, 784 onKeyDown(ev) { 785 if (ev.key === "Enter" || ev.key === " ") { 786 handler(ev); 787 ev.preventDefault(); 788 } 789 } 790 }; 791} 792let guidNumber = 0; 793function guid() { 794 guidNumber += 1; 795 return String(guidNumber); 796} 797function disableCursor() { 798 document.body.classList.add("fc-not-allowed"); 799} 800function enableCursor() { 801 document.body.classList.remove("fc-not-allowed"); 802} 803function preventSelection(el) { 804 el.style.userSelect = "none"; 805 el.style.webkitUserSelect = "none"; 806 el.addEventListener("selectstart", preventDefault); 807} 808function allowSelection(el) { 809 el.style.userSelect = ""; 810 el.style.webkitUserSelect = ""; 811 el.removeEventListener("selectstart", preventDefault); 812} 813function preventContextMenu(el) { 814 el.addEventListener("contextmenu", preventDefault); 815} 816function allowContextMenu(el) { 817 el.removeEventListener("contextmenu", preventDefault); 818} 819function parseFieldSpecs(input) { 820 let specs = []; 821 let tokens = []; 822 let i2; 823 let token; 824 if (typeof input === "string") { 825 tokens = input.split(/\s*,\s*/); 826 } else if (typeof input === "function") { 827 tokens = [input]; 828 } else if (Array.isArray(input)) { 829 tokens = input; 830 } 831 for (i2 = 0; i2 < tokens.length; i2 += 1) { 832 token = tokens[i2]; 833 if (typeof token === "string") { 834 specs.push(token.charAt(0) === "-" ? { field: token.substring(1), order: -1 } : { field: token, order: 1 }); 835 } else if (typeof token === "function") { 836 specs.push({ func: token }); 837 } 838 } 839 return specs; 840} 841function compareByFieldSpecs(obj0, obj1, fieldSpecs) { 842 let i2; 843 let cmp; 844 for (i2 = 0; i2 < fieldSpecs.length; i2 += 1) { 845 cmp = compareByFieldSpec(obj0, obj1, fieldSpecs[i2]); 846 if (cmp) { 847 return cmp; 848 } 849 } 850 return 0; 851} 852function compareByFieldSpec(obj0, obj1, fieldSpec) { 853 if (fieldSpec.func) { 854 return fieldSpec.func(obj0, obj1); 855 } 856 return flexibleCompare(obj0[fieldSpec.field], obj1[fieldSpec.field]) * (fieldSpec.order || 1); 857} 858function flexibleCompare(a2, b2) { 859 if (!a2 && !b2) { 860 return 0; 861 } 862 if (b2 == null) { 863 return -1; 864 } 865 if (a2 == null) { 866 return 1; 867 } 868 if (typeof a2 === "string" || typeof b2 === "string") { 869 return String(a2).localeCompare(String(b2)); 870 } 871 return a2 - b2; 872} 873function padStart(val, len) { 874 let s2 = String(val); 875 return "000".substr(0, len - s2.length) + s2; 876} 877function formatWithOrdinals(formatter, args, fallbackText) { 878 if (typeof formatter === "function") { 879 return formatter(...args); 880 } 881 if (typeof formatter === "string") { 882 return args.reduce((str, arg, index2) => str.replace("$" + index2, arg || ""), formatter); 883 } 884 return fallbackText; 885} 886function compareNumbers(a2, b2) { 887 return a2 - b2; 888} 889function isInt(n2) { 890 return n2 % 1 === 0; 891} 892function computeSmallestCellWidth(cellEl) { 893 let allWidthEl = cellEl.querySelector(".fc-scrollgrid-shrink-frame"); 894 let contentWidthEl = cellEl.querySelector(".fc-scrollgrid-shrink-cushion"); 895 if (!allWidthEl) { 896 throw new Error("needs fc-scrollgrid-shrink-frame className"); 897 } 898 if (!contentWidthEl) { 899 throw new Error("needs fc-scrollgrid-shrink-cushion className"); 900 } 901 return cellEl.getBoundingClientRect().width - allWidthEl.getBoundingClientRect().width + // the cell padding+border 902 contentWidthEl.getBoundingClientRect().width; 903} 904const INTERNAL_UNITS = ["years", "months", "days", "milliseconds"];
905const PARSE_RE = /^(-?)(?:(\d+)\.)?(\d+):(\d\d)(?::(\d\d)(?:\.(\d\d\d))?)?/; 906function createDuration(input, unit) { 907 if (typeof input === "string") { 908 return parseString(input); 909 } 910 if (typeof input === "object" && input) { 911 return parseObject(input); 912 } 913 if (typeof input === "number") { 914 return parseObject({ [unit || "milliseconds"]: input }); 915 } 916 return null; 917} 918function parseString(s2) { 919 let m2 = PARSE_RE.exec(s2); 920 if (m2) { 921 let sign = m2[1] ? -1 : 1; 922 return { 923 years: 0, 924 months: 0, 925 days: sign * (m2[2] ? parseInt(m2[2], 10) : 0), 926 milliseconds: sign * ((m2[3] ? parseInt(m2[3], 10) : 0) * 60 * 60 * 1e3 + // hours 927 (m2[4] ? parseInt(m2[4], 10) : 0) * 60 * 1e3 + // minutes 928 (m2[5] ? parseInt(m2[5], 10) : 0) * 1e3 + // seconds 929 (m2[6] ? parseInt(m2[6], 10) : 0)) 930 }; 931 } 932 return null; 933} 934function parseObject(obj) { 935 let duration = { 936 years: obj.years || obj.year || 0, 937 months: obj.months || obj.month || 0, 938 days: obj.days || obj.day || 0, 939 milliseconds: (obj.hours || obj.hour || 0) * 60 * 60 * 1e3 + // hours 940 (obj.minutes || obj.minute || 0) * 60 * 1e3 + // minutes 941 (obj.seconds || obj.second || 0) * 1e3 + // seconds 942 (obj.milliseconds || obj.millisecond || obj.ms || 0) 943 // ms 944 }; 945 let weeks = obj.weeks || obj.week; 946 if (weeks) { 947 duration.days += weeks * 7; 948 duration.specifiedWeeks = true; 949 } 950 return duration; 951} 952function durationsEqual(d0, d1) { 953 return d0.years === d1.years && d0.months === d1.months && d0.days === d1.days && d0.milliseconds === d1.milliseconds; 954} 955function asCleanDays(dur) { 956 if (!dur.years && !dur.months && !dur.milliseconds) { 957 return dur.days; 958 } 959 return 0; 960} 961function addDurations(d0, d1) { 962 return { 963 years: d0.years + d1.years, 964 months: d0.months + d1.months, 965 days: d0.days + d1.days, 966 milliseconds: d0.milliseconds + d1.milliseconds 967 }; 968} 969function subtractDurations(d1, d0) { 970 return { 971 years: d1.years - d0.years, 972 months: d1.months - d0.months, 973 days: d1.days - d0.days, 974 milliseconds: d1.milliseconds - d0.milliseconds 975 }; 976} 977function multiplyDuration(d2, n2) { 978 return { 979 years: d2.years * n2, 980 months: d2.months * n2, 981 days: d2.days * n2, 982 milliseconds: d2.milliseconds * n2 983 }; 984} 985function asRoughYears(dur) { 986 return asRoughDays(dur) / 365; 987} 988function asRoughMonths(dur) { 989 return asRoughDays(dur) / 30; 990} 991function asRoughDays(dur) { 992 return asRoughMs(dur) / 864e5; 993} 994function asRoughMinutes(dur) { 995 return asRoughMs(dur) / (1e3 * 60); 996} 997function asRoughSeconds(dur) { 998 return asRoughMs(dur) / 1e3; 999} 1000function asRoughMs(dur) { 1001 return dur.years * (365 * 864e5) + dur.months * (30 * 864e5) + dur.days * 864e5 + dur.milliseconds; 1002} 1003function wholeDivideDurations(numerator, denominator) { 1004 let res = null; 1005 for (let i2 = 0; i2 < INTERNAL_UNITS.length; i2 += 1) { 1006 let unit = INTERNAL_UNITS[i2]; 1007 if (denominator[unit]) { 1008 let localRes = numerator[unit] / denominator[unit]; 1009 if (!isInt(localRes) || res !== null && res !== localRes) { 1010 return null; 1011 } 1012 res = localRes; 1013 } else if (numerator[unit]) { 1014 return null; 1015 } 1016 } 1017 return res; 1018} 1019function greatestDurationDenominator(dur) { 1020 let ms = dur.milliseconds; 1021 if (ms) { 1022 if (ms % 1e3 !== 0) { 1023 return { unit: "millisecond", value: ms }; 1024 } 1025 if (ms % (1e3 * 60) !== 0) { 1026 return { unit: "second", value: ms / 1e3 }; 1027 } 1028 if (ms % (1e3 * 60 * 60) !== 0) { 1029 return { unit: "minute", value: ms / (1e3 * 60) }; 1030 } 1031 if (ms) { 1032 return { unit: "hour", value: ms / (1e3 * 60 * 60) }; 1033 } 1034 } 1035 if (dur.days) { 1036 if (dur.specifiedWeeks && dur.days % 7 === 0) { 1037 return { unit: "week", value: dur.days / 7 }; 1038 } 1039 return { unit: "day", value: dur.days }; 1040 } 1041 if (dur.months) { 1042 return { unit: "month", value: dur.months }; 1043 } 1044 if (dur.years) { 1045 return { unit: "year", value: dur.years }; 1046 } 1047 return { unit: "millisecond", value: 0 }; 1048} 1049function isArraysEqual(a0, a1, equalityFunc) { 1050 if (a0 === a1) { 1051 return true; 1052 } 1053 let len = a0.length; 1054 let i2; 1055 if (len !== a1.length) { 1056 return false;
vendor: 5,179 bytes, lines 1057-1259
1057 } 1058 for (i2 = 0; i2 < len; i2 += 1) { 1059 if (!(equalityFunc ? equalityFunc(a0[i2], a1[i2]) : a0[i2] === a1[i2])) { 1060 return false; 1061 } 1062 } 1063 return true; 1064} 1065const DAY_IDS = ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]; 1066function addWeeks(m2, n2) { 1067 let a2 = dateToUtcArray(m2); 1068 a2[2] += n2 * 7; 1069 return arrayToUtcDate(a2); 1070} 1071function addDays(m2, n2) { 1072 let a2 = dateToUtcArray(m2); 1073 a2[2] += n2; 1074 return arrayToUtcDate(a2); 1075} 1076function addMs(m2, n2) { 1077 let a2 = dateToUtcArray(m2); 1078 a2[6] += n2; 1079 return arrayToUtcDate(a2); 1080} 1081function diffWeeks(m0, m1) { 1082 return diffDays(m0, m1) / 7; 1083} 1084function diffDays(m0, m1) { 1085 return (m1.valueOf() - m0.valueOf()) / (1e3 * 60 * 60 * 24); 1086} 1087function diffHours(m0, m1) { 1088 return (m1.valueOf() - m0.valueOf()) / (1e3 * 60 * 60); 1089} 1090function diffMinutes(m0, m1) { 1091 return (m1.valueOf() - m0.valueOf()) / (1e3 * 60); 1092} 1093function diffSeconds(m0, m1) { 1094 return (m1.valueOf() - m0.valueOf()) / 1e3; 1095} 1096function diffDayAndTime(m0, m1) { 1097 let m0day = startOfDay(m0); 1098 let m1day = startOfDay(m1); 1099 return { 1100 years: 0, 1101 months: 0, 1102 days: Math.round(diffDays(m0day, m1day)), 1103 milliseconds: m1.valueOf() - m1day.valueOf() - (m0.valueOf() - m0day.valueOf()) 1104 }; 1105} 1106function diffWholeWeeks(m0, m1) { 1107 let d2 = diffWholeDays(m0, m1); 1108 if (d2 !== null && d2 % 7 === 0) { 1109 return d2 / 7; 1110 } 1111 return null; 1112} 1113function diffWholeDays(m0, m1) { 1114 if (timeAsMs(m0) === timeAsMs(m1)) { 1115 return Math.round(diffDays(m0, m1)); 1116 } 1117 return null; 1118} 1119function startOfDay(m2) { 1120 return arrayToUtcDate([ 1121 m2.getUTCFullYear(), 1122 m2.getUTCMonth(), 1123 m2.getUTCDate() 1124 ]); 1125} 1126function startOfHour(m2) { 1127 return arrayToUtcDate([ 1128 m2.getUTCFullYear(), 1129 m2.getUTCMonth(), 1130 m2.getUTCDate(), 1131 m2.getUTCHours() 1132 ]); 1133} 1134function startOfMinute(m2) { 1135 return arrayToUtcDate([ 1136 m2.getUTCFullYear(), 1137 m2.getUTCMonth(), 1138 m2.getUTCDate(), 1139 m2.getUTCHours(), 1140 m2.getUTCMinutes() 1141 ]); 1142} 1143function startOfSecond(m2) { 1144 return arrayToUtcDate([ 1145 m2.getUTCFullYear(), 1146 m2.getUTCMonth(), 1147 m2.getUTCDate(), 1148 m2.getUTCHours(), 1149 m2.getUTCMinutes(), 1150 m2.getUTCSeconds() 1151 ]); 1152} 1153function weekOfYear(marker, dow, doy) { 1154 let y2 = marker.getUTCFullYear(); 1155 let w2 = weekOfGivenYear(marker, y2, dow, doy); 1156 if (w2 < 1) { 1157 return weekOfGivenYear(marker, y2 - 1, dow, doy); 1158 } 1159 let nextW = weekOfGivenYear(marker, y2 + 1, dow, doy); 1160 if (nextW >= 1) { 1161 return Math.min(w2, nextW); 1162 } 1163 return w2; 1164} 1165function weekOfGivenYear(marker, year, dow, doy) { 1166 let firstWeekStart = arrayToUtcDate([year, 0, 1 + firstWeekOffset(year, dow, doy)]); 1167 let dayStart = startOfDay(marker); 1168 let days = Math.round(diffDays(firstWeekStart, dayStart)); 1169 return Math.floor(days / 7) + 1; 1170} 1171function firstWeekOffset(year, dow, doy) { 1172 let fwd = 7 + dow - doy; 1173 let fwdlw = (7 + arrayToUtcDate([year, 0, fwd]).getUTCDay() - dow) % 7; 1174 return -fwdlw + fwd - 1; 1175} 1176function dateToLocalArray(date) { 1177 return [ 1178 date.getFullYear(), 1179 date.getMonth(), 1180 date.getDate(), 1181 date.getHours(), 1182 date.getMinutes(), 1183 date.getSeconds(), 1184 date.getMilliseconds() 1185 ]; 1186} 1187function arrayToLocalDate(a2) { 1188 return new Date( 1189 a2[0], 1190 a2[1] || 0, 1191 a2[2] == null ? 1 : a2[2], 1192 // day of month 1193 a2[3] || 0, 1194 a2[4] || 0, 1195 a2[5] || 0 1196 ); 1197} 1198function dateToUtcArray(date) { 1199 return [ 1200 date.getUTCFullYear(), 1201 date.getUTCMonth(), 1202 date.getUTCDate(), 1203 date.getUTCHours(), 1204 date.getUTCMinutes(), 1205 date.getUTCSeconds(), 1206 date.getUTCMilliseconds() 1207 ]; 1208} 1209function arrayToUtcDate(a2) { 1210 if (a2.length === 1) { 1211 a2 = a2.concat([0]); 1212 } 1213 return new Date(Date.UTC(...a2)); 1214} 1215function isValidDate(m2) { 1216 return !isNaN(m2.valueOf()); 1217} 1218function timeAsMs(m2) { 1219 return m2.getUTCHours() * 1e3 * 60 * 60 + m2.getUTCMinutes() * 1e3 * 60 + m2.getUTCSeconds() * 1e3 + m2.getUTCMilliseconds(); 1220} 1221function buildIsoString(marker, timeZoneOffset, stripZeroTime = false) { 1222 let s2 = marker.toISOString(); 1223 s2 = s2.replace(".000", ""); 1224 if (stripZeroTime) { 1225 s2 = s2.replace("T00:00:00Z", ""); 1226 } 1227 if (s2.length > 10) { 1228 if (timeZoneOffset == null) { 1229 s2 = s2.replace("Z", ""); 1230 } else if (timeZoneOffset !== 0) { 1231 s2 = s2.replace("Z", formatTimeZoneOffset(timeZoneOffset, true)); 1232 } 1233 } 1234 return s2; 1235} 1236function formatDayString(marker) { 1237 return marker.toISOString().replace(/T.*$/, ""); 1238} 1239function formatIsoMonthStr(marker) { 1240 return marker.toISOString().match(/^\d{4}-\d{2}/)[0]; 1241} 1242function formatIsoTimeString(marker) { 1243 return padStart(marker.getUTCHours(), 2) + ":" + padStart(marker.getUTCMinutes(), 2) + ":" + padStart(marker.getUTCSeconds(), 2); 1244} 1245function formatTimeZoneOffset(minutes, doIso = false) { 1246 let sign = minutes < 0 ? "-" : "+"; 1247 let abs = Math.abs(minutes); 1248 let hours = Math.floor(abs / 60); 1249 let mins = Math.round(abs % 60); 1250 if (doIso) { 1251 return `${sign + padStart(hours, 2)}:${padStart(mins, 2)}`; 1252 } 1253 return `GMT${sign}${hours}${mins ? `:${padStart(mins, 2)}` : ""}`; 1254} 1255function memoize(workerFunc, resEquality, teardownFunc) { 1256 let currentArgs; 1257 let currentRes; 1258 return function(...newArgs) { 1259 if (!currentArgs) {
1260 currentRes = workerFunc.apply(this, newArgs); 1261 } else if (!isArraysEqual(currentArgs, newArgs)) { 1262 let res = workerFunc.apply(this, newArgs); 1263 if (!resEquality || !resEquality(res, currentRes)) { 1264 currentRes = res; 1265 } 1266 } 1267 currentArgs = newArgs; 1268 return currentRes; 1269 }; 1270} 1271function memoizeObjArg(workerFunc, resEquality, teardownFunc) { 1272 let currentArg; 1273 let currentRes; 1274 return (newArg) => { 1275 if (!currentArg) { 1276 currentRes = workerFunc.call(this, newArg); 1277 } else if (!isPropsEqual(currentArg, newArg)) { 1278 let res = workerFunc.call(this, newArg); 1279 { 1280 currentRes = res; 1281 } 1282 } 1283 currentArg = newArg; 1284 return currentRes; 1285 }; 1286} 1287function memoizeArraylike(workerFunc, resEquality, teardownFunc) { 1288 let currentArgSets = []; 1289 let currentResults = []; 1290 return (newArgSets) => { 1291 let currentLen = currentArgSets.length; 1292 let newLen = newArgSets.length; 1293 let i2 = 0; 1294 for (; i2 < currentLen; i2 += 1) { 1295 if (!newArgSets[i2]) ; 1296 else if (!isArraysEqual(currentArgSets[i2], newArgSets[i2])) { 1297 let res = workerFunc.apply(this, newArgSets[i2]); 1298 if (!resEquality || !resEquality(res, currentResults[i2])) { 1299 currentResults[i2] = res; 1300 } 1301 } 1302 } 1303 for (; i2 < newLen; i2 += 1) { 1304 currentResults[i2] = workerFunc.apply(this, newArgSets[i2]); 1305 } 1306 currentArgSets = newArgSets; 1307 currentResults.splice(newLen); 1308 return currentResults; 1309 }; 1310} 1311function memoizeHashlike(workerFunc, resEquality, teardownFunc) { 1312 let currentArgHash = {}; 1313 let currentResHash = {}; 1314 return (newArgHash) => { 1315 let newResHash = {}; 1316 for (let key in newArgHash) { 1317 if (!currentResHash[key]) { 1318 newResHash[key] = workerFunc.apply(this, newArgHash[key]); 1319 } else if (!isArraysEqual(currentArgHash[key], newArgHash[key])) { 1320 if (teardownFunc) { 1321 teardownFunc(currentResHash[key]); 1322 } 1323 let res = workerFunc.apply(this, newArgHash[key]); 1324 newResHash[key] = res; 1325 } else { 1326 newResHash[key] = currentResHash[key]; 1327 } 1328 } 1329 currentArgHash = newArgHash; 1330 currentResHash = newResHash; 1331 return newResHash; 1332 }; 1333} 1334const EXTENDED_SETTINGS_AND_SEVERITIES = { 1335 week: 3, 1336 separator: 0, 1337 omitZeroMinute: 0, 1338 meridiem: 0, 1339 omitCommas: 0 1340}; 1341const STANDARD_DATE_PROP_SEVERITIES = { 1342 timeZoneName: 7, 1343 era: 6, 1344 year: 5, 1345 month: 4, 1346 day: 2, 1347 weekday: 2, 1348 hour: 1, 1349 minute: 1, 1350 second: 1 1351}; 1352const MERIDIEM_RE = /\s*([ap])\.?m\.?/i; 1353const COMMA_RE = /,/g; 1354const MULTI_SPACE_RE = /\s+/g; 1355const LTR_RE = /\u200e/g; 1356const UTC_RE = /UTC|GMT/; 1357class NativeFormatter { 1358 constructor(formatSettings) { 1359 let standardDateProps = {}; 1360 let extendedSettings = {}; 1361 let severity = 0; 1362 for (let name in formatSettings) { 1363 if (name in EXTENDED_SETTINGS_AND_SEVERITIES) { 1364 extendedSettings[name] = formatSettings[name]; 1365 severity = Math.max(EXTENDED_SETTINGS_AND_SEVERITIES[name], severity); 1366 } else { 1367 standardDateProps[name] = formatSettings[name]; 1368 if (name in STANDARD_DATE_PROP_SEVERITIES) { 1369 severity = Math.max(STANDARD_DATE_PROP_SEVERITIES[name], severity); 1370 } 1371 } 1372 } 1373 this.standardDateProps = standardDateProps; 1374 this.extendedSettings = extendedSettings; 1375 this.severity = severity; 1376 this.buildFormattingFunc = memoize(buildFormattingFunc); 1377 } 1378 format(date, context) { 1379 return this.buildFormattingFunc(this.standardDateProps, this.extendedSettings, context)(date); 1380 } 1381 formatRange(start, end, context, betterDefaultSeparator) { 1382 let { standardDateProps, extendedSettings } = this; 1383 let diffSeverity = computeMarkerDiffSeverity(start.marker, end.marker, context.calendarSystem); 1384 if (!diffSeverity) { 1385 return this.format(start, context); 1386 } 1387 let biggestUnitForPartial = diffSeverity; 1388 if (biggestUnitForPartial > 1 && // the two dates are different in a way that's larger scale than time 1389 (standardDateProps.year === "numeric" || standardDateProps.year === "2-digit") && (standardDateProps.month === "numeric" || standardDateProps.month === "2-digit") && (standardDateProps.day === "numeric" || standardDateProps.day === "2-digit")) {
1390 biggestUnitForPartial = 1; 1391 } 1392 let full0 = this.format(start, context); 1393 let full1 = this.format(end, context); 1394 if (full0 === full1) { 1395 return full0; 1396 } 1397 let partialDateProps = computePartialFormattingOptions(standardDateProps, biggestUnitForPartial); 1398 let partialFormattingFunc = buildFormattingFunc(partialDateProps, extendedSettings, context); 1399 let partial0 = partialFormattingFunc(start); 1400 let partial1 = partialFormattingFunc(end); 1401 let insertion = findCommonInsertion(full0, partial0, full1, partial1); 1402 let separator = extendedSettings.separator || betterDefaultSeparator || context.defaultSeparator || ""; 1403 if (insertion) { 1404 return insertion.before + partial0 + separator + partial1 + insertion.after; 1405 } 1406 return full0 + separator + full1; 1407 } 1408 getLargestUnit() { 1409 switch (this.severity) { 1410 case 7: 1411 case 6: 1412 case 5: 1413 return "year"; 1414 case 4: 1415 return "month"; 1416 case 3: 1417 return "week"; 1418 case 2: 1419 return "day"; 1420 default: 1421 return "time"; 1422 } 1423 } 1424} 1425function buildFormattingFunc(standardDateProps, extendedSettings, context) { 1426 let standardDatePropCnt = Object.keys(standardDateProps).length; 1427 if (standardDatePropCnt === 1 && standardDateProps.timeZoneName === "short") { 1428 return (date) => formatTimeZoneOffset(date.timeZoneOffset); 1429 } 1430 if (standardDatePropCnt === 0 && extendedSettings.week) { 1431 return (date) => formatWeekNumber(context.computeWeekNumber(date.marker), context.weekText, context.weekTextLong, context.locale, extendedSettings.week); 1432 } 1433 return buildNativeFormattingFunc(standardDateProps, extendedSettings, context); 1434} 1435function buildNativeFormattingFunc(standardDateProps, extendedSettings, context) { 1436 standardDateProps = Object.assign({}, standardDateProps); 1437 extendedSettings = Object.assign({}, extendedSettings); 1438 sanitizeSettings(standardDateProps, extendedSettings); 1439 standardDateProps.timeZone = "UTC"; 1440 let normalFormat = new Intl.DateTimeFormat(context.locale.codes, standardDateProps); 1441 let zeroFormat; 1442 if (extendedSettings.omitZeroMinute) { 1443 let zeroProps = Object.assign({}, standardDateProps); 1444 delete zeroProps.minute; 1445 zeroFormat = new Intl.DateTimeFormat(context.locale.codes, zeroProps); 1446 } 1447 return (date) => { 1448 let { marker } = date; 1449 let format; 1450 if (zeroFormat && !marker.getUTCMinutes()) { 1451 format = zeroFormat; 1452 } else { 1453 format = normalFormat; 1454 } 1455 let s2 = format.format(marker); 1456 return postProcess(s2, date, standardDateProps, extendedSettings, context); 1457 }; 1458} 1459function sanitizeSettings(standardDateProps, extendedSettings) { 1460 if (standardDateProps.timeZoneName) { 1461 if (!standardDateProps.hour) { 1462 standardDateProps.hour = "2-digit"; 1463 } 1464 if (!standardDateProps.minute) { 1465 standardDateProps.minute = "2-digit"; 1466 } 1467 } 1468 if (standardDateProps.timeZoneName === "long") { 1469 standardDateProps.timeZoneName = "short"; 1470 } 1471 if (extendedSettings.omitZeroMinute && (standardDateProps.second || standardDateProps.millisecond)) { 1472 delete extendedSettings.omitZeroMinute; 1473 } 1474} 1475function postProcess(s2, date, standardDateProps, extendedSettings, context) { 1476 s2 = s2.replace(LTR_RE, ""); 1477 if (standardDateProps.timeZoneName === "short") { 1478 s2 = injectTzoStr(s2, context.timeZone === "UTC" || date.timeZoneOffset == null ? "UTC" : ( 1479 // important to normalize for IE, which does "GMT" 1480 formatTimeZoneOffset(date.timeZoneOffset) 1481 )); 1482 } 1483 if (extendedSettings.omitCommas) { 1484 s2 = s2.replace(COMMA_RE, "").trim(); 1485 } 1486 if (extendedSettings.omitZeroMinute) { 1487 s2 = s2.replace(":00", ""); 1488 } 1489 if (extendedSettings.meridiem === false) { 1490 s2 = s2.replace(MERIDIEM_RE, "").trim(); 1491 } else if (extendedSettings.meridiem === "narrow") { 1492 s2 = s2.replace(MERIDIEM_RE, (m0, m1) => m1.toLocaleLowerCase()); 1493 } else if (extendedSettings.meridiem === "short") { 1494 s2 = s2.replace(MERIDIEM_RE, (m0, m1) => `${m1.toLocaleLowerCase()}m`); 1495 } else if (extendedSettings.meridiem === "lowercase") { 1496 s2 = s2.replace(MERIDIEM_RE, (m0) => m0.toLocaleLowerCase()); 1497 } 1498 s2 = s2.replace(MULTI_SPACE_RE, " "); 1499 s2 = s2.trim(); 1500 return s2; 1501} 1502function injectTzoStr(s2, tzoStr) { 1503 let replaced = false;
vendor: 6,760 bytes, lines 1504-1740
1504 s2 = s2.replace(UTC_RE, () => { 1505 replaced = true; 1506 return tzoStr; 1507 }); 1508 if (!replaced) { 1509 s2 += ` ${tzoStr}`; 1510 } 1511 return s2; 1512} 1513function formatWeekNumber(num, weekText, weekTextLong, locale, display) { 1514 let parts = []; 1515 if (display === "long") { 1516 parts.push(weekTextLong); 1517 } else if (display === "short" || display === "narrow") { 1518 parts.push(weekText); 1519 } 1520 if (display === "long" || display === "short") { 1521 parts.push(" "); 1522 } 1523 parts.push(locale.simpleNumberFormat.format(num)); 1524 if (locale.options.direction === "rtl") { 1525 parts.reverse(); 1526 } 1527 return parts.join(""); 1528} 1529function computeMarkerDiffSeverity(d0, d1, ca) { 1530 if (ca.getMarkerYear(d0) !== ca.getMarkerYear(d1)) { 1531 return 5; 1532 } 1533 if (ca.getMarkerMonth(d0) !== ca.getMarkerMonth(d1)) { 1534 return 4; 1535 } 1536 if (ca.getMarkerDay(d0) !== ca.getMarkerDay(d1)) { 1537 return 2; 1538 } 1539 if (timeAsMs(d0) !== timeAsMs(d1)) { 1540 return 1; 1541 } 1542 return 0; 1543} 1544function computePartialFormattingOptions(options, biggestUnit) { 1545 let partialOptions = {}; 1546 for (let name in options) { 1547 if (!(name in STANDARD_DATE_PROP_SEVERITIES) || // not a date part prop (like timeZone) 1548 STANDARD_DATE_PROP_SEVERITIES[name] <= biggestUnit) { 1549 partialOptions[name] = options[name]; 1550 } 1551 } 1552 return partialOptions; 1553} 1554function findCommonInsertion(full0, partial0, full1, partial1) { 1555 let i0 = 0; 1556 while (i0 < full0.length) { 1557 let found0 = full0.indexOf(partial0, i0); 1558 if (found0 === -1) { 1559 break; 1560 } 1561 let before0 = full0.substr(0, found0); 1562 i0 = found0 + partial0.length; 1563 let after0 = full0.substr(i0); 1564 let i1 = 0; 1565 while (i1 < full1.length) { 1566 let found1 = full1.indexOf(partial1, i1); 1567 if (found1 === -1) { 1568 break; 1569 } 1570 let before1 = full1.substr(0, found1); 1571 i1 = found1 + partial1.length; 1572 let after1 = full1.substr(i1); 1573 if (before0 === before1 && after0 === after1) { 1574 return { 1575 before: before0, 1576 after: after0 1577 }; 1578 } 1579 } 1580 } 1581 return null; 1582} 1583function expandZonedMarker(dateInfo, calendarSystem) { 1584 let a2 = calendarSystem.markerToArray(dateInfo.marker); 1585 return { 1586 marker: dateInfo.marker, 1587 timeZoneOffset: dateInfo.timeZoneOffset, 1588 array: a2, 1589 year: a2[0], 1590 month: a2[1], 1591 day: a2[2], 1592 hour: a2[3], 1593 minute: a2[4], 1594 second: a2[5], 1595 millisecond: a2[6] 1596 }; 1597} 1598function createVerboseFormattingArg(start, end, context, betterDefaultSeparator) { 1599 let startInfo = expandZonedMarker(start, context.calendarSystem); 1600 let endInfo = end ? expandZonedMarker(end, context.calendarSystem) : null; 1601 return { 1602 date: startInfo, 1603 start: startInfo, 1604 end: endInfo, 1605 timeZone: context.timeZone, 1606 localeCodes: context.locale.codes, 1607 defaultSeparator: betterDefaultSeparator || context.defaultSeparator 1608 }; 1609} 1610class CmdFormatter { 1611 constructor(cmdStr) { 1612 this.cmdStr = cmdStr; 1613 } 1614 format(date, context, betterDefaultSeparator) { 1615 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1616 } 1617 formatRange(start, end, context, betterDefaultSeparator) { 1618 return context.cmdFormatter(this.cmdStr, createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1619 } 1620} 1621class FuncFormatter { 1622 constructor(func) { 1623 this.func = func; 1624 } 1625 format(date, context, betterDefaultSeparator) { 1626 return this.func(createVerboseFormattingArg(date, null, context, betterDefaultSeparator)); 1627 } 1628 formatRange(start, end, context, betterDefaultSeparator) { 1629 return this.func(createVerboseFormattingArg(start, end, context, betterDefaultSeparator)); 1630 } 1631} 1632function createFormatter(input) { 1633 if (typeof input === "object" && input) { 1634 return new NativeFormatter(input); 1635 } 1636 if (typeof input === "string") { 1637 return new CmdFormatter(input); 1638 } 1639 if (typeof input === "function") { 1640 return new FuncFormatter(input); 1641 } 1642 return null; 1643} 1644const BASE_OPTION_REFINERS = { 1645 navLinkDayClick: identity, 1646 navLinkWeekClick: identity, 1647 duration: createDuration, 1648 bootstrapFontAwesome: identity, 1649 buttonIcons: identity, 1650 customButtons: identity, 1651 defaultAllDayEventDuration: createDuration, 1652 defaultTimedEventDuration: createDuration, 1653 nextDayThreshold: createDuration, 1654 scrollTime: createDuration, 1655 scrollTimeReset: Boolean, 1656 slotMinTime: createDuration, 1657 slotMaxTime: createDuration, 1658 dayPopoverFormat: createFormatter, 1659 slotDuration: createDuration, 1660 snapDuration: createDuration, 1661 headerToolbar: identity, 1662 footerToolbar: identity, 1663 defaultRangeSeparator: String, 1664 titleRangeSeparator: String, 1665 forceEventDuration: Boolean, 1666 dayHeaders: Boolean, 1667 dayHeaderFormat: createFormatter, 1668 dayHeaderClassNames: identity, 1669 dayHeaderContent: identity, 1670 dayHeaderDidMount: identity, 1671 dayHeaderWillUnmount: identity, 1672 dayCellClassNames: identity, 1673 dayCellContent: identity, 1674 dayCellDidMount: identity, 1675 dayCellWillUnmount: identity, 1676 initialView: String, 1677 aspectRatio: Number, 1678 weekends: Boolean, 1679 weekNumberCalculation: identity, 1680 weekNumbers: Boolean, 1681 weekNumberClassNames: identity, 1682 weekNumberContent: identity, 1683 weekNumberDidMount: identity, 1684 weekNumberWillUnmount: identity, 1685 editable: Boolean, 1686 viewClassNames: identity, 1687 viewDidMount: identity, 1688 viewWillUnmount: identity, 1689 nowIndicator: Boolean, 1690 nowIndicatorClassNames: identity, 1691 nowIndicatorContent: identity, 1692 nowIndicatorDidMount: identity, 1693 nowIndicatorWillUnmount: identity, 1694 showNonCurrentDates: Boolean, 1695 lazyFetching: Boolean, 1696 startParam: String, 1697 endParam: String, 1698 timeZoneParam: String, 1699 timeZone: String, 1700 locales: identity, 1701 locale: identity, 1702 themeSystem: String, 1703 dragRevertDuration: Number, 1704 dragScroll: Boolean, 1705 allDayMaintainDuration: Boolean, 1706 unselectAuto: Boolean, 1707 dropAccept: identity, 1708 eventOrder: parseFieldSpecs, 1709 eventOrderStrict: Boolean, 1710 handleWindowResize: Boolean, 1711 windowResizeDelay: Number, 1712 longPressDelay: Number, 1713 eventDragMinDistance: Number, 1714 expandRows: Boolean, 1715 height: identity, 1716 contentHeight: identity, 1717 direction: String, 1718 weekNumberFormat: createFormatter, 1719 eventResizableFromStart: Boolean, 1720 displayEventTime: Boolean, 1721 displayEventEnd: Boolean, 1722 weekText: String, 1723 weekTextLong: String, 1724 progressiveEventRendering: Boolean, 1725 businessHours: identity, 1726 initialDate: identity, 1727 now: identity, 1728 eventDataTransform: identity, 1729 stickyHeaderDates: identity, 1730 stickyFooterScrollbar: identity, 1731 viewHeight: identity, 1732 defaultAllDay: Boolean, 1733 eventSourceFailure: identity, 1734 eventSourceSuccess: identity, 1735 eventDisplay: String, 1736 eventStartEditable: Boolean, 1737 eventDurationEditable: Boolean, 1738 eventOverlap: identity, 1739 eventConstraint: identity, 1740 eventAllow: identity,
1741 eventBackgroundColor: String, 1742 eventBorderColor: String, 1743 eventTextColor: String, 1744 eventColor: String, 1745 eventClassNames: identity, 1746 eventContent: identity, 1747 eventDidMount: identity, 1748 eventWillUnmount: identity, 1749 selectConstraint: identity, 1750 selectOverlap: identity, 1751 selectAllow: identity, 1752 droppable: Boolean, 1753 unselectCancel: String, 1754 slotLabelFormat: identity, 1755 slotLaneClassNames: identity, 1756 slotLaneContent: identity, 1757 slotLaneDidMount: identity, 1758 slotLaneWillUnmount: identity, 1759 slotLabelClassNames: identity, 1760 slotLabelContent: identity, 1761 slotLabelDidMount: identity, 1762 slotLabelWillUnmount: identity, 1763 dayMaxEvents: identity, 1764 dayMaxEventRows: identity, 1765 dayMinWidth: Number, 1766 slotLabelInterval: createDuration, 1767 allDayText: String, 1768 allDayClassNames: identity, 1769 allDayContent: identity, 1770 allDayDidMount: identity, 1771 allDayWillUnmount: identity, 1772 slotMinWidth: Number, 1773 navLinks: Boolean, 1774 eventTimeFormat: createFormatter, 1775 rerenderDelay: Number, 1776 moreLinkText: identity, 1777 moreLinkHint: identity, 1778 selectMinDistance: Number, 1779 selectable: Boolean, 1780 selectLongPressDelay: Number, 1781 eventLongPressDelay: Number, 1782 selectMirror: Boolean, 1783 eventMaxStack: Number, 1784 eventMinHeight: Number, 1785 eventMinWidth: Number, 1786 eventShortHeight: Number, 1787 slotEventOverlap: Boolean, 1788 plugins: identity, 1789 firstDay: Number, 1790 dayCount: Number, 1791 dateAlignment: String, 1792 dateIncrement: createDuration, 1793 hiddenDays: identity, 1794 fixedWeekCount: Boolean, 1795 validRange: identity, 1796 visibleRange: identity, 1797 titleFormat: identity, 1798 eventInteractive: Boolean, 1799 // only used by list-view, but languages define the value, so we need it in base options 1800 noEventsText: String, 1801 viewHint: identity, 1802 navLinkHint: identity, 1803 closeHint: String, 1804 timeHint: String, 1805 eventHint: String, 1806 moreLinkClick: identity, 1807 moreLinkClassNames: identity, 1808 moreLinkContent: identity, 1809 moreLinkDidMount: identity, 1810 moreLinkWillUnmount: identity, 1811 monthStartFormat: createFormatter, 1812 // for connectors 1813 // (can't be part of plugin system b/c must be provided at runtime) 1814 handleCustomRendering: identity, 1815 customRenderingMetaMap: identity, 1816 customRenderingReplaces: Boolean 1817}; 1818const BASE_OPTION_DEFAULTS = { 1819 eventDisplay: "auto", 1820 defaultRangeSeparator: " - ", 1821 titleRangeSeparator: " – ", 1822 defaultTimedEventDuration: "01:00:00", 1823 defaultAllDayEventDuration: { day: 1 }, 1824 forceEventDuration: false, 1825 nextDayThreshold: "00:00:00", 1826 dayHeaders: true, 1827 initialView: "", 1828 aspectRatio: 1.35, 1829 headerToolbar: { 1830 start: "title", 1831 center: "", 1832 end: "today prev,next" 1833 }, 1834 weekends: true, 1835 weekNumbers: false, 1836 weekNumberCalculation: "local", 1837 editable: false, 1838 nowIndicator: false, 1839 scrollTime: "06:00:00", 1840 scrollTimeReset: true, 1841 slotMinTime: "00:00:00", 1842 slotMaxTime: "24:00:00", 1843 showNonCurrentDates: true, 1844 lazyFetching: true, 1845 startParam: "start", 1846 endParam: "end", 1847 timeZoneParam: "timeZone", 1848 timeZone: "local", 1849 locales: [], 1850 locale: "", 1851 themeSystem: "standard", 1852 dragRevertDuration: 500, 1853 dragScroll: true, 1854 allDayMaintainDuration: false, 1855 unselectAuto: true, 1856 dropAccept: "*", 1857 eventOrder: "start,-duration,allDay,title", 1858 dayPopoverFormat: { month: "long", day: "numeric", year: "numeric" }, 1859 handleWindowResize: true, 1860 windowResizeDelay: 100, 1861 longPressDelay: 1e3, 1862 eventDragMinDistance: 5, 1863 expandRows: false, 1864 navLinks: false, 1865 selectable: false, 1866 eventMinHeight: 15, 1867 eventMinWidth: 30, 1868 eventShortHeight: 30, 1869 monthStartFormat: { month: "long", day: "numeric" } 1870}; 1871const CALENDAR_LISTENER_REFINERS = { 1872 datesSet: identity, 1873 eventsSet: identity, 1874 eventAdd: identity, 1875 eventChange: identity, 1876 eventRemove: identity, 1877 windowResize: identity, 1878 eventClick: identity, 1879 eventMouseEnter: identity, 1880 eventMouseLeave: identity, 1881 select: identity, 1882 unselect: identity, 1883 loading: identity, 1884 // internal 1885 _unmount: identity, 1886 _beforeprint: identity, 1887 _afterprint: identity, 1888 _noEventDrop: identity, 1889 _noEventResize: identity, 1890 _resize: identity, 1891 _scrollRequest: identity 1892}; 1893const CALENDAR_OPTION_REFINERS = { 1894 buttonText: identity, 1895 buttonHints: identity, 1896 views: identity, 1897 plugins: identity, 1898 initialEvents: identity,
vendor: 8,506 bytes, lines 1899-2218
1899 events: identity, 1900 eventSources: identity 1901}; 1902const COMPLEX_OPTION_COMPARATORS = { 1903 headerToolbar: isMaybeObjectsEqual, 1904 footerToolbar: isMaybeObjectsEqual, 1905 buttonText: isMaybeObjectsEqual, 1906 buttonHints: isMaybeObjectsEqual, 1907 buttonIcons: isMaybeObjectsEqual, 1908 dateIncrement: isMaybeObjectsEqual, 1909 plugins: isMaybeArraysEqual, 1910 events: isMaybeArraysEqual, 1911 eventSources: isMaybeArraysEqual, 1912 ["resources"]: isMaybeArraysEqual 1913}; 1914function isMaybeObjectsEqual(a2, b2) { 1915 if (typeof a2 === "object" && typeof b2 === "object" && a2 && b2) { 1916 return isPropsEqual(a2, b2); 1917 } 1918 return a2 === b2; 1919} 1920function isMaybeArraysEqual(a2, b2) { 1921 if (Array.isArray(a2) && Array.isArray(b2)) { 1922 return isArraysEqual(a2, b2); 1923 } 1924 return a2 === b2; 1925} 1926const VIEW_OPTION_REFINERS = { 1927 type: String, 1928 component: identity, 1929 buttonText: String, 1930 buttonTextKey: String, 1931 dateProfileGeneratorClass: identity, 1932 usesMinMaxTime: Boolean, 1933 classNames: identity, 1934 content: identity, 1935 didMount: identity, 1936 willUnmount: identity 1937}; 1938function mergeRawOptions(optionSets) { 1939 return mergeProps(optionSets, COMPLEX_OPTION_COMPARATORS); 1940} 1941function refineProps(input, refiners) { 1942 let refined = {}; 1943 let extra = {}; 1944 for (let propName in refiners) { 1945 if (propName in input) { 1946 refined[propName] = refiners[propName](input[propName]); 1947 } 1948 } 1949 for (let propName in input) { 1950 if (!(propName in refiners)) { 1951 extra[propName] = input[propName]; 1952 } 1953 } 1954 return { refined, extra }; 1955} 1956function identity(raw) { 1957 return raw; 1958} 1959const { hasOwnProperty } = Object.prototype; 1960function mergeProps(propObjs, complexPropsMap) { 1961 let dest = {}; 1962 if (complexPropsMap) { 1963 for (let name in complexPropsMap) { 1964 if (complexPropsMap[name] === isMaybeObjectsEqual) { 1965 let complexObjs = []; 1966 for (let i2 = propObjs.length - 1; i2 >= 0; i2 -= 1) { 1967 let val = propObjs[i2][name]; 1968 if (typeof val === "object" && val) { 1969 complexObjs.unshift(val); 1970 } else if (val !== void 0) { 1971 dest[name] = val; 1972 break; 1973 } 1974 } 1975 if (complexObjs.length) { 1976 dest[name] = mergeProps(complexObjs); 1977 } 1978 } 1979 } 1980 } 1981 for (let i2 = propObjs.length - 1; i2 >= 0; i2 -= 1) { 1982 let props = propObjs[i2]; 1983 for (let name in props) { 1984 if (!(name in dest)) { 1985 dest[name] = props[name]; 1986 } 1987 } 1988 } 1989 return dest; 1990} 1991function filterHash(hash, func) { 1992 let filtered = {}; 1993 for (let key in hash) { 1994 if (func(hash[key], key)) { 1995 filtered[key] = hash[key]; 1996 } 1997 } 1998 return filtered; 1999} 2000function mapHash(hash, func) { 2001 let newHash = {}; 2002 for (let key in hash) { 2003 newHash[key] = func(hash[key], key); 2004 } 2005 return newHash; 2006} 2007function arrayToHash(a2) { 2008 let hash = {}; 2009 for (let item of a2) { 2010 hash[item] = true; 2011 } 2012 return hash; 2013} 2014function hashValuesToArray(obj) { 2015 let a2 = []; 2016 for (let key in obj) { 2017 a2.push(obj[key]); 2018 } 2019 return a2; 2020} 2021function isPropsEqual(obj0, obj1) { 2022 if (obj0 === obj1) { 2023 return true; 2024 } 2025 for (let key in obj0) { 2026 if (hasOwnProperty.call(obj0, key)) { 2027 if (!(key in obj1)) { 2028 return false; 2029 } 2030 } 2031 } 2032 for (let key in obj1) { 2033 if (hasOwnProperty.call(obj1, key)) { 2034 if (obj0[key] !== obj1[key]) { 2035 return false; 2036 } 2037 } 2038 } 2039 return true; 2040} 2041const HANDLER_RE = /^on[A-Z]/; 2042function isNonHandlerPropsEqual(obj0, obj1) { 2043 const keys = getUnequalProps(obj0, obj1); 2044 for (let key of keys) { 2045 if (!HANDLER_RE.test(key)) { 2046 return false; 2047 } 2048 } 2049 return true; 2050} 2051function getUnequalProps(obj0, obj1) { 2052 let keys = []; 2053 for (let key in obj0) { 2054 if (hasOwnProperty.call(obj0, key)) { 2055 if (!(key in obj1)) { 2056 keys.push(key); 2057 } 2058 } 2059 } 2060 for (let key in obj1) { 2061 if (hasOwnProperty.call(obj1, key)) { 2062 if (obj0[key] !== obj1[key]) { 2063 keys.push(key); 2064 } 2065 } 2066 } 2067 return keys; 2068} 2069function compareObjs(oldProps, newProps, equalityFuncs = {}) { 2070 if (oldProps === newProps) { 2071 return true; 2072 } 2073 for (let key in newProps) { 2074 if (key in oldProps && isObjValsEqual(oldProps[key], newProps[key], equalityFuncs[key])) ; 2075 else { 2076 return false; 2077 } 2078 } 2079 for (let key in oldProps) { 2080 if (!(key in newProps)) { 2081 return false; 2082 } 2083 } 2084 return true; 2085} 2086function isObjValsEqual(val0, val1, comparator) { 2087 if (val0 === val1 || comparator === true) { 2088 return true; 2089 } 2090 if (comparator) { 2091 return comparator(val0, val1); 2092 } 2093 return false; 2094} 2095function collectFromHash(hash, startIndex = 0, endIndex, step = 1) { 2096 let res = []; 2097 if (endIndex == null) { 2098 endIndex = Object.keys(hash).length; 2099 } 2100 for (let i2 = startIndex; i2 < endIndex; i2 += step) { 2101 let val = hash[i2]; 2102 if (val !== void 0) { 2103 res.push(val); 2104 } 2105 } 2106 return res; 2107} 2108let calendarSystemClassMap = {}; 2109function registerCalendarSystem(name, theClass) { 2110 calendarSystemClassMap[name] = theClass; 2111} 2112function createCalendarSystem(name) { 2113 return new calendarSystemClassMap[name](); 2114} 2115class GregorianCalendarSystem { 2116 getMarkerYear(d2) { 2117 return d2.getUTCFullYear(); 2118 } 2119 getMarkerMonth(d2) { 2120 return d2.getUTCMonth(); 2121 } 2122 getMarkerDay(d2) { 2123 return d2.getUTCDate(); 2124 } 2125 arrayToMarker(arr) { 2126 return arrayToUtcDate(arr); 2127 } 2128 markerToArray(marker) { 2129 return dateToUtcArray(marker); 2130 } 2131} 2132registerCalendarSystem("gregory", GregorianCalendarSystem); 2133const ISO_RE = /^\s*(\d{4})(-?(\d{2})(-?(\d{2})([T ](\d{2}):?(\d{2})(:?(\d{2})(\.(\d+))?)?(Z|(([-+])(\d{2})(:?(\d{2}))?))?)?)?)?$/; 2134function parse(str) { 2135 let m2 = ISO_RE.exec(str); 2136 if (m2) { 2137 let marker = new Date(Date.UTC(Number(m2[1]), m2[3] ? Number(m2[3]) - 1 : 0, Number(m2[5] || 1), Number(m2[7] || 0), Number(m2[8] || 0), Number(m2[10] || 0), m2[12] ? Number(`0.${m2[12]}`) * 1e3 : 0)); 2138 if (isValidDate(marker)) { 2139 let timeZoneOffset = null; 2140 if (m2[13]) { 2141 timeZoneOffset = (m2[15] === "-" ? -1 : 1) * (Number(m2[16] || 0) * 60 + Number(m2[18] || 0)); 2142 } 2143 return { 2144 marker, 2145 isTimeUnspecified: !m2[6], 2146 timeZoneOffset 2147 }; 2148 } 2149 } 2150 return null; 2151} 2152class DateEnv { 2153 constructor(settings) { 2154 let timeZone = this.timeZone = settings.timeZone; 2155 let isNamedTimeZone = timeZone !== "local" && timeZone !== "UTC"; 2156 if (settings.namedTimeZoneImpl && isNamedTimeZone) { 2157 this.namedTimeZoneImpl = new settings.namedTimeZoneImpl(timeZone); 2158 } 2159 this.canComputeOffset = Boolean(!isNamedTimeZone || this.namedTimeZoneImpl); 2160 this.calendarSystem = createCalendarSystem(settings.calendarSystem); 2161 this.locale = settings.locale; 2162 this.weekDow = settings.locale.week.dow; 2163 this.weekDoy = settings.locale.week.doy; 2164 if (settings.weekNumberCalculation === "ISO") { 2165 this.weekDow = 1; 2166 this.weekDoy = 4; 2167 } 2168 if (typeof settings.firstDay === "number") { 2169 this.weekDow = settings.firstDay; 2170 } 2171 if (typeof settings.weekNumberCalculation === "function") { 2172 this.weekNumberFunc = settings.weekNumberCalculation; 2173 } 2174 this.weekText = settings.weekText != null ? settings.weekText : settings.locale.options.weekText; 2175 this.weekTextLong = (settings.weekTextLong != null ? settings.weekTextLong : settings.locale.options.weekTextLong) || this.weekText; 2176 this.cmdFormatter = settings.cmdFormatter; 2177 this.defaultSeparator = settings.defaultSeparator; 2178 } 2179 // Creating / Parsing 2180 createMarker(input) { 2181 let meta = this.createMarkerMeta(input); 2182 if (meta === null) { 2183 return null; 2184 } 2185 return meta.marker; 2186 } 2187 createNowMarker() { 2188 if (this.canComputeOffset) { 2189 return this.timestampToMarker((/* @__PURE__ */ new Date()).valueOf()); 2190 } 2191 return arrayToUtcDate(dateToLocalArray(/* @__PURE__ */ new Date())); 2192 } 2193 createMarkerMeta(input) { 2194 if (typeof input === "string") { 2195 return this.parse(input); 2196 } 2197 let marker = null; 2198 if (typeof input === "number") { 2199 marker = this.timestampToMarker(input); 2200 } else if (input instanceof Date) { 2201 input = input.valueOf(); 2202 if (!isNaN(input)) { 2203 marker = this.timestampToMarker(input); 2204 } 2205 } else if (Array.isArray(input)) { 2206 marker = arrayToUtcDate(input); 2207 } 2208 if (marker === null || !isValidDate(marker)) { 2209 return null; 2210 } 2211 return { marker, isTimeUnspecified: false, forcedTzo: null }; 2212 } 2213 parse(s2) { 2214 let parts = parse(s2); 2215 if (parts === null) { 2216 return null; 2217 } 2218 let { marker } = parts;
vendor: 8,521 bytes, lines 2219-2497
2219 let forcedTzo = null; 2220 if (parts.timeZoneOffset !== null) { 2221 if (this.canComputeOffset) { 2222 marker = this.timestampToMarker(marker.valueOf() - parts.timeZoneOffset * 60 * 1e3); 2223 } else { 2224 forcedTzo = parts.timeZoneOffset; 2225 } 2226 } 2227 return { marker, isTimeUnspecified: parts.isTimeUnspecified, forcedTzo }; 2228 } 2229 // Accessors 2230 getYear(marker) { 2231 return this.calendarSystem.getMarkerYear(marker); 2232 } 2233 getMonth(marker) { 2234 return this.calendarSystem.getMarkerMonth(marker); 2235 } 2236 getDay(marker) { 2237 return this.calendarSystem.getMarkerDay(marker); 2238 } 2239 // Adding / Subtracting 2240 add(marker, dur) { 2241 let a2 = this.calendarSystem.markerToArray(marker); 2242 a2[0] += dur.years; 2243 a2[1] += dur.months; 2244 a2[2] += dur.days; 2245 a2[6] += dur.milliseconds; 2246 return this.calendarSystem.arrayToMarker(a2); 2247 } 2248 subtract(marker, dur) { 2249 let a2 = this.calendarSystem.markerToArray(marker); 2250 a2[0] -= dur.years; 2251 a2[1] -= dur.months; 2252 a2[2] -= dur.days; 2253 a2[6] -= dur.milliseconds; 2254 return this.calendarSystem.arrayToMarker(a2); 2255 } 2256 addYears(marker, n2) { 2257 let a2 = this.calendarSystem.markerToArray(marker); 2258 a2[0] += n2; 2259 return this.calendarSystem.arrayToMarker(a2); 2260 } 2261 addMonths(marker, n2) { 2262 let a2 = this.calendarSystem.markerToArray(marker); 2263 a2[1] += n2; 2264 return this.calendarSystem.arrayToMarker(a2); 2265 } 2266 // Diffing Whole Units 2267 diffWholeYears(m0, m1) { 2268 let { calendarSystem } = this; 2269 if (timeAsMs(m0) === timeAsMs(m1) && calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1) && calendarSystem.getMarkerMonth(m0) === calendarSystem.getMarkerMonth(m1)) { 2270 return calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0); 2271 } 2272 return null; 2273 } 2274 diffWholeMonths(m0, m1) { 2275 let { calendarSystem } = this; 2276 if (timeAsMs(m0) === timeAsMs(m1) && calendarSystem.getMarkerDay(m0) === calendarSystem.getMarkerDay(m1)) { 2277 return calendarSystem.getMarkerMonth(m1) - calendarSystem.getMarkerMonth(m0) + (calendarSystem.getMarkerYear(m1) - calendarSystem.getMarkerYear(m0)) * 12; 2278 } 2279 return null; 2280 } 2281 // Range / Duration 2282 greatestWholeUnit(m0, m1) { 2283 let n2 = this.diffWholeYears(m0, m1); 2284 if (n2 !== null) { 2285 return { unit: "year", value: n2 }; 2286 } 2287 n2 = this.diffWholeMonths(m0, m1); 2288 if (n2 !== null) { 2289 return { unit: "month", value: n2 }; 2290 } 2291 n2 = diffWholeWeeks(m0, m1); 2292 if (n2 !== null) { 2293 return { unit: "week", value: n2 }; 2294 } 2295 n2 = diffWholeDays(m0, m1); 2296 if (n2 !== null) { 2297 return { unit: "day", value: n2 }; 2298 } 2299 n2 = diffHours(m0, m1); 2300 if (isInt(n2)) { 2301 return { unit: "hour", value: n2 }; 2302 } 2303 n2 = diffMinutes(m0, m1); 2304 if (isInt(n2)) { 2305 return { unit: "minute", value: n2 }; 2306 } 2307 n2 = diffSeconds(m0, m1); 2308 if (isInt(n2)) { 2309 return { unit: "second", value: n2 }; 2310 } 2311 return { unit: "millisecond", value: m1.valueOf() - m0.valueOf() }; 2312 } 2313 countDurationsBetween(m0, m1, d2) { 2314 let diff; 2315 if (d2.years) { 2316 diff = this.diffWholeYears(m0, m1); 2317 if (diff !== null) { 2318 return diff / asRoughYears(d2); 2319 } 2320 } 2321 if (d2.months) { 2322 diff = this.diffWholeMonths(m0, m1); 2323 if (diff !== null) { 2324 return diff / asRoughMonths(d2); 2325 } 2326 } 2327 if (d2.days) { 2328 diff = diffWholeDays(m0, m1); 2329 if (diff !== null) { 2330 return diff / asRoughDays(d2); 2331 } 2332 } 2333 return (m1.valueOf() - m0.valueOf()) / asRoughMs(d2); 2334 } 2335 // Start-Of 2336 // these DON'T return zoned-dates. only UTC start-of dates 2337 startOf(m2, unit) { 2338 if (unit === "year") { 2339 return this.startOfYear(m2); 2340 } 2341 if (unit === "month") { 2342 return this.startOfMonth(m2); 2343 } 2344 if (unit === "week") { 2345 return this.startOfWeek(m2); 2346 } 2347 if (unit === "day") { 2348 return startOfDay(m2); 2349 } 2350 if (unit === "hour") { 2351 return startOfHour(m2); 2352 } 2353 if (unit === "minute") { 2354 return startOfMinute(m2); 2355 } 2356 if (unit === "second") { 2357 return startOfSecond(m2); 2358 } 2359 return null; 2360 } 2361 startOfYear(m2) { 2362 return this.calendarSystem.arrayToMarker([ 2363 this.calendarSystem.getMarkerYear(m2) 2364 ]); 2365 } 2366 startOfMonth(m2) { 2367 return this.calendarSystem.arrayToMarker([ 2368 this.calendarSystem.getMarkerYear(m2), 2369 this.calendarSystem.getMarkerMonth(m2) 2370 ]); 2371 } 2372 startOfWeek(m2) { 2373 return this.calendarSystem.arrayToMarker([ 2374 this.calendarSystem.getMarkerYear(m2), 2375 this.calendarSystem.getMarkerMonth(m2), 2376 m2.getUTCDate() - (m2.getUTCDay() - this.weekDow + 7) % 7 2377 ]); 2378 } 2379 // Week Number 2380 computeWeekNumber(marker) { 2381 if (this.weekNumberFunc) { 2382 return this.weekNumberFunc(this.toDate(marker)); 2383 } 2384 return weekOfYear(marker, this.weekDow, this.weekDoy); 2385 } 2386 // TODO: choke on timeZoneName: long 2387 format(marker, formatter, dateOptions = {}) { 2388 return formatter.format({ 2389 marker, 2390 timeZoneOffset: dateOptions.forcedTzo != null ? dateOptions.forcedTzo : this.offsetForMarker(marker) 2391 }, this); 2392 } 2393 formatRange(start, end, formatter, dateOptions = {}) { 2394 if (dateOptions.isEndExclusive) { 2395 end = addMs(end, -1); 2396 } 2397 return formatter.formatRange({ 2398 marker: start, 2399 timeZoneOffset: dateOptions.forcedStartTzo != null ? dateOptions.forcedStartTzo : this.offsetForMarker(start) 2400 }, { 2401 marker: end, 2402 timeZoneOffset: dateOptions.forcedEndTzo != null ? dateOptions.forcedEndTzo : this.offsetForMarker(end) 2403 }, this, dateOptions.defaultSeparator); 2404 } 2405 /* 2406 DUMB: the omitTime arg is dumb. if we omit the time, we want to omit the timezone offset. and if we do that, 2407 might as well use buildIsoString or some other util directly 2408 */ 2409 formatIso(marker, extraOptions = {}) { 2410 let timeZoneOffset = null; 2411 if (!extraOptions.omitTimeZoneOffset) { 2412 if (extraOptions.forcedTzo != null) { 2413 timeZoneOffset = extraOptions.forcedTzo; 2414 } else { 2415 timeZoneOffset = this.offsetForMarker(marker); 2416 } 2417 } 2418 return buildIsoString(marker, timeZoneOffset, extraOptions.omitTime); 2419 } 2420 // TimeZone 2421 timestampToMarker(ms) { 2422 if (this.timeZone === "local") { 2423 return arrayToUtcDate(dateToLocalArray(new Date(ms))); 2424 } 2425 if (this.timeZone === "UTC" || !this.namedTimeZoneImpl) { 2426 return new Date(ms); 2427 } 2428 return arrayToUtcDate(this.namedTimeZoneImpl.timestampToArray(ms)); 2429 } 2430 offsetForMarker(m2) { 2431 if (this.timeZone === "local") { 2432 return -arrayToLocalDate(dateToUtcArray(m2)).getTimezoneOffset(); 2433 } 2434 if (this.timeZone === "UTC") { 2435 return 0; 2436 } 2437 if (this.namedTimeZoneImpl) { 2438 return this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m2)); 2439 } 2440 return null; 2441 } 2442 // Conversion 2443 toDate(m2, forcedTzo) { 2444 if (this.timeZone === "local") { 2445 return arrayToLocalDate(dateToUtcArray(m2)); 2446 } 2447 if (this.timeZone === "UTC") { 2448 return new Date(m2.valueOf()); 2449 } 2450 if (!this.namedTimeZoneImpl) { 2451 return new Date(m2.valueOf() - (forcedTzo || 0)); 2452 } 2453 return new Date(m2.valueOf() - this.namedTimeZoneImpl.offsetForArray(dateToUtcArray(m2)) * 1e3 * 60); 2454 } 2455} 2456class Theme { 2457 constructor(calendarOptions) { 2458 if (this.iconOverrideOption) { 2459 this.setIconOverride(calendarOptions[this.iconOverrideOption]); 2460 } 2461 } 2462 setIconOverride(iconOverrideHash) { 2463 let iconClassesCopy; 2464 let buttonName; 2465 if (typeof iconOverrideHash === "object" && iconOverrideHash) { 2466 iconClassesCopy = Object.assign({}, this.iconClasses); 2467 for (buttonName in iconOverrideHash) { 2468 iconClassesCopy[buttonName] = this.applyIconOverridePrefix(iconOverrideHash[buttonName]); 2469 } 2470 this.iconClasses = iconClassesCopy; 2471 } else if (iconOverrideHash === false) { 2472 this.iconClasses = {}; 2473 } 2474 } 2475 applyIconOverridePrefix(className) { 2476 let prefix = this.iconOverridePrefix; 2477 if (prefix && className.indexOf(prefix) !== 0) { 2478 className = prefix + className; 2479 } 2480 return className; 2481 } 2482 getClass(key) { 2483 return this.classes[key] || ""; 2484 } 2485 getIconClass(buttonName, isRtl) { 2486 let className; 2487 if (isRtl && this.rtlIconClasses) { 2488 className = this.rtlIconClasses[buttonName] || this.iconClasses[buttonName]; 2489 } else { 2490 className = this.iconClasses[buttonName]; 2491 } 2492 if (className) { 2493 return `${this.baseIconClass} ${className}`; 2494 } 2495 return ""; 2496 } 2497 getCustomButtonIconClass(customButtonProps) {
vendor: 17,400 bytes, lines 2498-3007
2498 let className; 2499 if (this.iconOverrideCustomButtonOption) { 2500 className = customButtonProps[this.iconOverrideCustomButtonOption]; 2501 if (className) { 2502 return `${this.baseIconClass} ${this.applyIconOverridePrefix(className)}`; 2503 } 2504 } 2505 return ""; 2506 } 2507} 2508Theme.prototype.classes = {}; 2509Theme.prototype.iconClasses = {}; 2510Theme.prototype.baseIconClass = ""; 2511Theme.prototype.iconOverridePrefix = ""; 2512function flushSync(runBeforeFlush) { 2513 runBeforeFlush(); 2514 let oldDebounceRendering = l$1.debounceRendering; 2515 let callbackQ = []; 2516 function execCallbackSync(callback) { 2517 callbackQ.push(callback); 2518 } 2519 l$1.debounceRendering = execCallbackSync; 2520 D$1(y(FakeComponent, {}), document.createElement("div")); 2521 while (callbackQ.length) { 2522 callbackQ.shift()(); 2523 } 2524 l$1.debounceRendering = oldDebounceRendering; 2525} 2526class FakeComponent extends x$1 { 2527 render() { 2528 return y("div", {}); 2529 } 2530 componentDidMount() { 2531 this.setState({}); 2532 } 2533} 2534function createContext(defaultValue) { 2535 let ContextType = G$1(defaultValue); 2536 let origProvider = ContextType.Provider; 2537 ContextType.Provider = function() { 2538 let isNew = !this.getChildContext; 2539 let children = origProvider.apply(this, arguments); 2540 if (isNew) { 2541 let subs = []; 2542 this.shouldComponentUpdate = (_props) => { 2543 if (this.props.value !== _props.value) { 2544 subs.forEach((c2) => { 2545 c2.context = _props.value; 2546 c2.forceUpdate(); 2547 }); 2548 } 2549 }; 2550 this.sub = (c2) => { 2551 subs.push(c2); 2552 let old = c2.componentWillUnmount; 2553 c2.componentWillUnmount = () => { 2554 subs.splice(subs.indexOf(c2), 1); 2555 old && old.call(c2); 2556 }; 2557 }; 2558 } 2559 return children; 2560 }; 2561 return ContextType; 2562} 2563class ScrollResponder { 2564 constructor(execFunc, emitter, scrollTime, scrollTimeReset) { 2565 this.execFunc = execFunc; 2566 this.emitter = emitter; 2567 this.scrollTime = scrollTime; 2568 this.scrollTimeReset = scrollTimeReset; 2569 this.handleScrollRequest = (request) => { 2570 this.queuedRequest = Object.assign({}, this.queuedRequest || {}, request); 2571 this.drain(); 2572 }; 2573 emitter.on("_scrollRequest", this.handleScrollRequest); 2574 this.fireInitialScroll(); 2575 } 2576 detach() { 2577 this.emitter.off("_scrollRequest", this.handleScrollRequest); 2578 } 2579 update(isDatesNew) { 2580 if (isDatesNew && this.scrollTimeReset) { 2581 this.fireInitialScroll(); 2582 } else { 2583 this.drain(); 2584 } 2585 } 2586 fireInitialScroll() { 2587 this.handleScrollRequest({ 2588 time: this.scrollTime 2589 }); 2590 } 2591 drain() { 2592 if (this.queuedRequest && this.execFunc(this.queuedRequest)) { 2593 this.queuedRequest = null; 2594 } 2595 } 2596} 2597const ViewContextType = createContext({}); 2598function buildViewContext(viewSpec, viewApi, viewOptions, dateProfileGenerator, dateEnv, theme, pluginHooks, dispatch, getCurrentData, emitter, calendarApi, registerInteractiveComponent, unregisterInteractiveComponent) { 2599 return { 2600 dateEnv, 2601 options: viewOptions, 2602 pluginHooks, 2603 emitter, 2604 dispatch, 2605 getCurrentData, 2606 calendarApi, 2607 viewSpec, 2608 viewApi, 2609 dateProfileGenerator, 2610 theme, 2611 isRtl: viewOptions.direction === "rtl", 2612 addResizeHandler(handler) { 2613 emitter.on("_resize", handler); 2614 }, 2615 removeResizeHandler(handler) { 2616 emitter.off("_resize", handler); 2617 }, 2618 createScrollResponder(execFunc) { 2619 return new ScrollResponder(execFunc, emitter, createDuration(viewOptions.scrollTime), viewOptions.scrollTimeReset); 2620 }, 2621 registerInteractiveComponent, 2622 unregisterInteractiveComponent 2623 }; 2624} 2625class PureComponent extends x$1 { 2626 shouldComponentUpdate(nextProps, nextState) { 2627 if (this.debug) { 2628 console.log(getUnequalProps(nextProps, this.props), getUnequalProps(nextState, this.state)); 2629 } 2630 return !compareObjs(this.props, nextProps, this.propEquality) || !compareObjs(this.state, nextState, this.stateEquality); 2631 } 2632 // HACK for freakin' React StrictMode 2633 safeSetState(newState) { 2634 if (!compareObjs(this.state, Object.assign(Object.assign({}, this.state), newState), this.stateEquality)) { 2635 this.setState(newState); 2636 } 2637 } 2638} 2639PureComponent.addPropsEquality = addPropsEquality; 2640PureComponent.addStateEquality = addStateEquality; 2641PureComponent.contextType = ViewContextType; 2642PureComponent.prototype.propEquality = {}; 2643PureComponent.prototype.stateEquality = {}; 2644class BaseComponent extends PureComponent { 2645} 2646BaseComponent.contextType = ViewContextType; 2647function addPropsEquality(propEquality) { 2648 let hash = Object.create(this.prototype.propEquality); 2649 Object.assign(hash, propEquality); 2650 this.prototype.propEquality = hash; 2651} 2652function addStateEquality(stateEquality) { 2653 let hash = Object.create(this.prototype.stateEquality); 2654 Object.assign(hash, stateEquality); 2655 this.prototype.stateEquality = hash; 2656} 2657function setRef(ref, current) { 2658 if (typeof ref === "function") { 2659 ref(current); 2660 } else if (ref) { 2661 ref.current = current; 2662 } 2663} 2664class ContentInjector extends BaseComponent { 2665 constructor() { 2666 super(...arguments); 2667 this.id = guid(); 2668 this.queuedDomNodes = []; 2669 this.currentDomNodes = []; 2670 this.handleEl = (el) => { 2671 const { options } = this.context; 2672 const { generatorName } = this.props; 2673 if (!options.customRenderingReplaces || !hasCustomRenderingHandler(generatorName, options)) { 2674 this.updateElRef(el); 2675 } 2676 }; 2677 this.updateElRef = (el) => { 2678 if (this.props.elRef) { 2679 setRef(this.props.elRef, el); 2680 } 2681 }; 2682 } 2683 render() { 2684 const { props, context } = this; 2685 const { options } = context; 2686 const { customGenerator, defaultGenerator, renderProps } = props; 2687 const attrs = buildElAttrs(props, [], this.handleEl); 2688 let useDefault = false; 2689 let innerContent; 2690 let queuedDomNodes = []; 2691 let currentGeneratorMeta; 2692 if (customGenerator != null) { 2693 const customGeneratorRes = typeof customGenerator === "function" ? customGenerator(renderProps, y) : customGenerator; 2694 if (customGeneratorRes === true) { 2695 useDefault = true; 2696 } else { 2697 const isObject = customGeneratorRes && typeof customGeneratorRes === "object"; 2698 if (isObject && "html" in customGeneratorRes) { 2699 attrs.dangerouslySetInnerHTML = { __html: customGeneratorRes.html }; 2700 } else if (isObject && "domNodes" in customGeneratorRes) { 2701 queuedDomNodes = Array.prototype.slice.call(customGeneratorRes.domNodes); 2702 } else if (isObject ? i$1(customGeneratorRes) : typeof customGeneratorRes !== "function") { 2703 innerContent = customGeneratorRes; 2704 } else { 2705 currentGeneratorMeta = customGeneratorRes; 2706 } 2707 } 2708 } else { 2709 useDefault = !hasCustomRenderingHandler(props.generatorName, options); 2710 } 2711 if (useDefault && defaultGenerator) { 2712 innerContent = defaultGenerator(renderProps); 2713 } 2714 this.queuedDomNodes = queuedDomNodes; 2715 this.currentGeneratorMeta = currentGeneratorMeta; 2716 return y(props.elTag, attrs, innerContent); 2717 } 2718 componentDidMount() { 2719 this.applyQueueudDomNodes(); 2720 this.triggerCustomRendering(true); 2721 } 2722 componentDidUpdate() { 2723 this.applyQueueudDomNodes(); 2724 this.triggerCustomRendering(true); 2725 } 2726 componentWillUnmount() { 2727 this.triggerCustomRendering(false); 2728 } 2729 triggerCustomRendering(isActive) { 2730 var _a; 2731 const { props, context } = this; 2732 const { handleCustomRendering, customRenderingMetaMap } = context.options; 2733 if (handleCustomRendering) { 2734 const generatorMeta = (_a = this.currentGeneratorMeta) !== null && _a !== void 0 ? _a : customRenderingMetaMap === null || customRenderingMetaMap === void 0 ? void 0 : customRenderingMetaMap[props.generatorName]; 2735 if (generatorMeta) { 2736 handleCustomRendering(Object.assign(Object.assign({ 2737 id: this.id, 2738 isActive, 2739 containerEl: this.base, 2740 reportNewContainerEl: this.updateElRef, 2741 // front-end framework tells us about new container els 2742 generatorMeta 2743 }, props), { elClasses: (props.elClasses || []).filter(isTruthy) })); 2744 } 2745 } 2746 } 2747 applyQueueudDomNodes() { 2748 const { queuedDomNodes, currentDomNodes } = this; 2749 const el = this.base; 2750 if (!isArraysEqual(queuedDomNodes, currentDomNodes)) { 2751 currentDomNodes.forEach(removeElement); 2752 for (let newNode of queuedDomNodes) { 2753 el.appendChild(newNode); 2754 } 2755 this.currentDomNodes = queuedDomNodes; 2756 } 2757 } 2758} 2759ContentInjector.addPropsEquality({ 2760 elClasses: isArraysEqual, 2761 elStyle: isPropsEqual, 2762 elAttrs: isNonHandlerPropsEqual, 2763 renderProps: isPropsEqual 2764}); 2765function hasCustomRenderingHandler(generatorName, options) { 2766 var _a; 2767 return Boolean(options.handleCustomRendering && generatorName && ((_a = options.customRenderingMetaMap) === null || _a === void 0 ? void 0 : _a[generatorName])); 2768} 2769function buildElAttrs(props, extraClassNames, elRef) { 2770 const attrs = Object.assign(Object.assign({}, props.elAttrs), { ref: elRef }); 2771 if (props.elClasses || extraClassNames) { 2772 attrs.className = (props.elClasses || []).concat(extraClassNames || []).concat(attrs.className || []).filter(Boolean).join(" "); 2773 } 2774 if (props.elStyle) { 2775 attrs.style = props.elStyle; 2776 } 2777 return attrs; 2778} 2779function isTruthy(val) { 2780 return Boolean(val); 2781} 2782const RenderId = createContext(0); 2783class ContentContainer extends x$1 { 2784 constructor() { 2785 super(...arguments); 2786 this.InnerContent = InnerContentInjector.bind(void 0, this); 2787 this.handleEl = (el) => { 2788 this.el = el; 2789 if (this.props.elRef) { 2790 setRef(this.props.elRef, el); 2791 if (el && this.didMountMisfire) { 2792 this.componentDidMount(); 2793 } 2794 } 2795 }; 2796 } 2797 render() { 2798 const { props } = this; 2799 const generatedClassNames = generateClassNames(props.classNameGenerator, props.renderProps); 2800 if (props.children) { 2801 const elAttrs = buildElAttrs(props, generatedClassNames, this.handleEl); 2802 const children = props.children(this.InnerContent, props.renderProps, elAttrs); 2803 if (props.elTag) { 2804 return y(props.elTag, elAttrs, children); 2805 } else { 2806 return children; 2807 } 2808 } else { 2809 return y(ContentInjector, Object.assign(Object.assign({}, props), { elRef: this.handleEl, elTag: props.elTag || "div", elClasses: (props.elClasses || []).concat(generatedClassNames), renderId: this.context })); 2810 } 2811 } 2812 componentDidMount() { 2813 var _a, _b; 2814 if (this.el) { 2815 (_b = (_a = this.props).didMount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.el })); 2816 } else { 2817 this.didMountMisfire = true; 2818 } 2819 } 2820 componentWillUnmount() { 2821 var _a, _b; 2822 (_b = (_a = this.props).willUnmount) === null || _b === void 0 ? void 0 : _b.call(_a, Object.assign(Object.assign({}, this.props.renderProps), { el: this.el })); 2823 } 2824} 2825ContentContainer.contextType = RenderId; 2826function InnerContentInjector(containerComponent, props) { 2827 const parentProps = containerComponent.props; 2828 return y(ContentInjector, Object.assign({ renderProps: parentProps.renderProps, generatorName: parentProps.generatorName, customGenerator: parentProps.customGenerator, defaultGenerator: parentProps.defaultGenerator, renderId: containerComponent.context }, props)); 2829} 2830function generateClassNames(classNameGenerator, renderProps) { 2831 const classNames = typeof classNameGenerator === "function" ? classNameGenerator(renderProps) : classNameGenerator || []; 2832 return typeof classNames === "string" ? [classNames] : classNames; 2833} 2834class ViewContainer extends BaseComponent { 2835 render() { 2836 let { props, context } = this; 2837 let { options } = context; 2838 let renderProps = { view: context.viewApi }; 2839 return y(ContentContainer, Object.assign({}, props, { elTag: props.elTag || "div", elClasses: [ 2840 ...buildViewClassNames(props.viewSpec), 2841 ...props.elClasses || [] 2842 ], renderProps, classNameGenerator: options.viewClassNames, generatorName: void 0, didMount: options.viewDidMount, willUnmount: options.viewWillUnmount }), () => props.children); 2843 } 2844} 2845function buildViewClassNames(viewSpec) { 2846 return [ 2847 `fc-${viewSpec.type}-view`, 2848 "fc-view" 2849 ]; 2850} 2851function parseRange(input, dateEnv) { 2852 let start = null; 2853 let end = null; 2854 if (input.start) { 2855 start = dateEnv.createMarker(input.start); 2856 } 2857 if (input.end) { 2858 end = dateEnv.createMarker(input.end); 2859 } 2860 if (!start && !end) { 2861 return null; 2862 } 2863 if (start && end && end < start) { 2864 return null; 2865 } 2866 return { start, end }; 2867} 2868function invertRanges(ranges, constraintRange) { 2869 let invertedRanges = []; 2870 let { start } = constraintRange; 2871 let i2; 2872 let dateRange; 2873 ranges.sort(compareRanges); 2874 for (i2 = 0; i2 < ranges.length; i2 += 1) { 2875 dateRange = ranges[i2]; 2876 if (dateRange.start > start) { 2877 invertedRanges.push({ start, end: dateRange.start }); 2878 } 2879 if (dateRange.end > start) { 2880 start = dateRange.end; 2881 } 2882 } 2883 if (start < constraintRange.end) { 2884 invertedRanges.push({ start, end: constraintRange.end }); 2885 } 2886 return invertedRanges; 2887} 2888function compareRanges(range0, range1) { 2889 return range0.start.valueOf() - range1.start.valueOf(); 2890} 2891function intersectRanges(range0, range1) { 2892 let { start, end } = range0; 2893 let newRange = null; 2894 if (range1.start !== null) { 2895 if (start === null) { 2896 start = range1.start; 2897 } else { 2898 start = new Date(Math.max(start.valueOf(), range1.start.valueOf())); 2899 } 2900 } 2901 if (range1.end != null) { 2902 if (end === null) { 2903 end = range1.end; 2904 } else { 2905 end = new Date(Math.min(end.valueOf(), range1.end.valueOf())); 2906 } 2907 } 2908 if (start === null || end === null || start < end) { 2909 newRange = { start, end }; 2910 } 2911 return newRange; 2912} 2913function rangesEqual(range0, range1) { 2914 return (range0.start === null ? null : range0.start.valueOf()) === (range1.start === null ? null : range1.start.valueOf()) && (range0.end === null ? null : range0.end.valueOf()) === (range1.end === null ? null : range1.end.valueOf()); 2915} 2916function rangesIntersect(range0, range1) { 2917 return (range0.end === null || range1.start === null || range0.end > range1.start) && (range0.start === null || range1.end === null || range0.start < range1.end); 2918} 2919function rangeContainsRange(outerRange, innerRange) { 2920 return (outerRange.start === null || innerRange.start !== null && innerRange.start >= outerRange.start) && (outerRange.end === null || innerRange.end !== null && innerRange.end <= outerRange.end); 2921} 2922function rangeContainsMarker(range, date) { 2923 return (range.start === null || date >= range.start) && (range.end === null || date < range.end); 2924} 2925function constrainMarkerToRange(date, range) { 2926 if (range.start != null && date < range.start) { 2927 return range.start; 2928 } 2929 if (range.end != null && date >= range.end) { 2930 return new Date(range.end.valueOf() - 1); 2931 } 2932 return date; 2933} 2934function computeAlignedDayRange(timedRange) { 2935 let dayCnt = Math.floor(diffDays(timedRange.start, timedRange.end)) || 1; 2936 let start = startOfDay(timedRange.start); 2937 let end = addDays(start, dayCnt); 2938 return { start, end }; 2939} 2940function computeVisibleDayRange(timedRange, nextDayThreshold = createDuration(0)) { 2941 let startDay = null; 2942 let endDay = null; 2943 if (timedRange.end) { 2944 endDay = startOfDay(timedRange.end); 2945 let endTimeMS = timedRange.end.valueOf() - endDay.valueOf(); 2946 if (endTimeMS && endTimeMS >= asRoughMs(nextDayThreshold)) { 2947 endDay = addDays(endDay, 1); 2948 } 2949 } 2950 if (timedRange.start) { 2951 startDay = startOfDay(timedRange.start); 2952 if (endDay && endDay <= startDay) { 2953 endDay = addDays(startDay, 1); 2954 } 2955 } 2956 return { start: startDay, end: endDay }; 2957} 2958function isMultiDayRange(range) { 2959 let visibleRange = computeVisibleDayRange(range); 2960 return diffDays(visibleRange.start, visibleRange.end) > 1; 2961} 2962function diffDates(date0, date1, dateEnv, largeUnit) { 2963 if (largeUnit === "year") { 2964 return createDuration(dateEnv.diffWholeYears(date0, date1), "year"); 2965 } 2966 if (largeUnit === "month") { 2967 return createDuration(dateEnv.diffWholeMonths(date0, date1), "month"); 2968 } 2969 return diffDayAndTime(date0, date1); 2970} 2971function reduceCurrentDate(currentDate, action) { 2972 switch (action.type) { 2973 case "CHANGE_DATE": 2974 return action.dateMarker; 2975 default: 2976 return currentDate; 2977 } 2978} 2979function getInitialDate(options, dateEnv) { 2980 let initialDateInput = options.initialDate; 2981 if (initialDateInput != null) { 2982 return dateEnv.createMarker(initialDateInput); 2983 } 2984 return getNow(options.now, dateEnv); 2985} 2986function getNow(nowInput, dateEnv) { 2987 if (typeof nowInput === "function") { 2988 nowInput = nowInput(); 2989 } 2990 if (nowInput == null) { 2991 return dateEnv.createNowMarker(); 2992 } 2993 return dateEnv.createMarker(nowInput); 2994} 2995class DateProfileGenerator { 2996 constructor(props) { 2997 this.props = props; 2998 this.nowDate = getNow(props.nowInput, props.dateEnv); 2999 this.initHiddenDays(); 3000 } 3001 /* Date Range Computation 3002 ------------------------------------------------------------------------------------------------------------------*/ 3003 // Builds a structure with info about what the dates/ranges will be for the "prev" view. 3004 buildPrev(currentDateProfile, currentDate, forceToValid) { 3005 let { dateEnv } = this.props; 3006 let prevDate = dateEnv.subtract( 3007 dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit),
vendor: 10,332 bytes, lines 3008-3285
3008 // important for start-of-month 3009 currentDateProfile.dateIncrement 3010 ); 3011 return this.build(prevDate, -1, forceToValid); 3012 } 3013 // Builds a structure with info about what the dates/ranges will be for the "next" view. 3014 buildNext(currentDateProfile, currentDate, forceToValid) { 3015 let { dateEnv } = this.props; 3016 let nextDate = dateEnv.add( 3017 dateEnv.startOf(currentDate, currentDateProfile.currentRangeUnit), 3018 // important for start-of-month 3019 currentDateProfile.dateIncrement 3020 ); 3021 return this.build(nextDate, 1, forceToValid); 3022 } 3023 // Builds a structure holding dates/ranges for rendering around the given date. 3024 // Optional direction param indicates whether the date is being incremented/decremented 3025 // from its previous value. decremented = -1, incremented = 1 (default). 3026 build(currentDate, direction, forceToValid = true) { 3027 let { props } = this; 3028 let validRange; 3029 let currentInfo; 3030 let isRangeAllDay; 3031 let renderRange; 3032 let activeRange; 3033 let isValid; 3034 validRange = this.buildValidRange(); 3035 validRange = this.trimHiddenDays(validRange); 3036 if (forceToValid) { 3037 currentDate = constrainMarkerToRange(currentDate, validRange); 3038 } 3039 currentInfo = this.buildCurrentRangeInfo(currentDate, direction); 3040 isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit); 3041 renderRange = this.buildRenderRange(this.trimHiddenDays(currentInfo.range), currentInfo.unit, isRangeAllDay); 3042 renderRange = this.trimHiddenDays(renderRange); 3043 activeRange = renderRange; 3044 if (!props.showNonCurrentDates) { 3045 activeRange = intersectRanges(activeRange, currentInfo.range); 3046 } 3047 activeRange = this.adjustActiveRange(activeRange); 3048 activeRange = intersectRanges(activeRange, validRange); 3049 isValid = rangesIntersect(currentInfo.range, validRange); 3050 if (!rangeContainsMarker(renderRange, currentDate)) { 3051 currentDate = renderRange.start; 3052 } 3053 return { 3054 currentDate, 3055 // constraint for where prev/next operations can go and where events can be dragged/resized to. 3056 // an object with optional start and end properties. 3057 validRange, 3058 // range the view is formally responsible for. 3059 // for example, a month view might have 1st-31st, excluding padded dates 3060 currentRange: currentInfo.range, 3061 // name of largest unit being displayed, like "month" or "week" 3062 currentRangeUnit: currentInfo.unit, 3063 isRangeAllDay, 3064 // dates that display events and accept drag-n-drop 3065 // will be `null` if no dates accept events 3066 activeRange, 3067 // date range with a rendered skeleton 3068 // includes not-active days that need some sort of DOM 3069 renderRange, 3070 // Duration object that denotes the first visible time of any given day 3071 slotMinTime: props.slotMinTime, 3072 // Duration object that denotes the exclusive visible end time of any given day 3073 slotMaxTime: props.slotMaxTime, 3074 isValid, 3075 // how far the current date will move for a prev/next operation 3076 dateIncrement: this.buildDateIncrement(currentInfo.duration) 3077 // pass a fallback (might be null) ^ 3078 }; 3079 } 3080 // Builds an object with optional start/end properties. 3081 // Indicates the minimum/maximum dates to display. 3082 // not responsible for trimming hidden days. 3083 buildValidRange() { 3084 let input = this.props.validRangeInput; 3085 let simpleInput = typeof input === "function" ? input.call(this.props.calendarApi, this.nowDate) : input; 3086 return this.refineRange(simpleInput) || { start: null, end: null }; 3087 } 3088 // Builds a structure with info about the "current" range, the range that is 3089 // highlighted as being the current month for example. 3090 // See build() for a description of `direction`. 3091 // Guaranteed to have `range` and `unit` properties. `duration` is optional. 3092 buildCurrentRangeInfo(date, direction) { 3093 let { props } = this; 3094 let duration = null; 3095 let unit = null; 3096 let range = null; 3097 let dayCount; 3098 if (props.duration) { 3099 duration = props.duration; 3100 unit = props.durationUnit; 3101 range = this.buildRangeFromDuration(date, direction, duration, unit); 3102 } else if (dayCount = this.props.dayCount) { 3103 unit = "day"; 3104 range = this.buildRangeFromDayCount(date, direction, dayCount); 3105 } else if (range = this.buildCustomVisibleRange(date)) { 3106 unit = props.dateEnv.greatestWholeUnit(range.start, range.end).unit; 3107 } else { 3108 duration = this.getFallbackDuration(); 3109 unit = greatestDurationDenominator(duration).unit; 3110 range = this.buildRangeFromDuration(date, direction, duration, unit); 3111 } 3112 return { duration, unit, range }; 3113 } 3114 getFallbackDuration() { 3115 return createDuration({ day: 1 }); 3116 } 3117 // Returns a new activeRange to have time values (un-ambiguate) 3118 // slotMinTime or slotMaxTime causes the range to expand. 3119 adjustActiveRange(range) { 3120 let { dateEnv, usesMinMaxTime, slotMinTime, slotMaxTime } = this.props; 3121 let { start, end } = range; 3122 if (usesMinMaxTime) { 3123 if (asRoughDays(slotMinTime) < 0) { 3124 start = startOfDay(start); 3125 start = dateEnv.add(start, slotMinTime); 3126 } 3127 if (asRoughDays(slotMaxTime) > 1) { 3128 end = startOfDay(end); 3129 end = addDays(end, -1); 3130 end = dateEnv.add(end, slotMaxTime); 3131 } 3132 } 3133 return { start, end }; 3134 } 3135 // Builds the "current" range when it is specified as an explicit duration. 3136 // `unit` is the already-computed greatestDurationDenominator unit of duration. 3137 buildRangeFromDuration(date, direction, duration, unit) { 3138 let { dateEnv, dateAlignment } = this.props; 3139 let start; 3140 let end; 3141 let res; 3142 if (!dateAlignment) { 3143 let { dateIncrement } = this.props; 3144 if (dateIncrement) { 3145 if (asRoughMs(dateIncrement) < asRoughMs(duration)) { 3146 dateAlignment = greatestDurationDenominator(dateIncrement).unit; 3147 } else { 3148 dateAlignment = unit; 3149 } 3150 } else { 3151 dateAlignment = unit; 3152 } 3153 } 3154 if (asRoughDays(duration) <= 1) { 3155 if (this.isHiddenDay(start)) { 3156 start = this.skipHiddenDays(start, direction); 3157 start = startOfDay(start); 3158 } 3159 } 3160 function computeRes() { 3161 start = dateEnv.startOf(date, dateAlignment); 3162 end = dateEnv.add(start, duration); 3163 res = { start, end }; 3164 } 3165 computeRes(); 3166 if (!this.trimHiddenDays(res)) { 3167 date = this.skipHiddenDays(date, direction); 3168 computeRes(); 3169 } 3170 return res; 3171 } 3172 // Builds the "current" range when a dayCount is specified. 3173 buildRangeFromDayCount(date, direction, dayCount) { 3174 let { dateEnv, dateAlignment } = this.props; 3175 let runningCount = 0; 3176 let start = date; 3177 let end; 3178 if (dateAlignment) { 3179 start = dateEnv.startOf(start, dateAlignment); 3180 } 3181 start = startOfDay(start); 3182 start = this.skipHiddenDays(start, direction); 3183 end = start; 3184 do { 3185 end = addDays(end, 1); 3186 if (!this.isHiddenDay(end)) { 3187 runningCount += 1; 3188 } 3189 } while (runningCount < dayCount); 3190 return { start, end }; 3191 } 3192 // Builds a normalized range object for the "visible" range, 3193 // which is a way to define the currentRange and activeRange at the same time. 3194 buildCustomVisibleRange(date) { 3195 let { props } = this; 3196 let input = props.visibleRangeInput; 3197 let simpleInput = typeof input === "function" ? input.call(props.calendarApi, props.dateEnv.toDate(date)) : input; 3198 let range = this.refineRange(simpleInput); 3199 if (range && (range.start == null || range.end == null)) { 3200 return null; 3201 } 3202 return range; 3203 } 3204 // Computes the range that will represent the element/cells for *rendering*, 3205 // but which may have voided days/times. 3206 // not responsible for trimming hidden days. 3207 buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) { 3208 return currentRange; 3209 } 3210 // Compute the duration value that should be added/substracted to the current date 3211 // when a prev/next operation happens. 3212 buildDateIncrement(fallback) { 3213 let { dateIncrement } = this.props; 3214 let customAlignment; 3215 if (dateIncrement) { 3216 return dateIncrement; 3217 } 3218 if (customAlignment = this.props.dateAlignment) { 3219 return createDuration(1, customAlignment); 3220 } 3221 if (fallback) { 3222 return fallback; 3223 } 3224 return createDuration({ days: 1 }); 3225 } 3226 refineRange(rangeInput) { 3227 if (rangeInput) { 3228 let range = parseRange(rangeInput, this.props.dateEnv); 3229 if (range) { 3230 range = computeVisibleDayRange(range); 3231 } 3232 return range; 3233 } 3234 return null; 3235 } 3236 /* Hidden Days 3237 ------------------------------------------------------------------------------------------------------------------*/ 3238 // Initializes internal variables related to calculating hidden days-of-week 3239 initHiddenDays() { 3240 let hiddenDays = this.props.hiddenDays || []; 3241 let isHiddenDayHash = []; 3242 let dayCnt = 0; 3243 let i2; 3244 if (this.props.weekends === false) { 3245 hiddenDays.push(0, 6); 3246 } 3247 for (i2 = 0; i2 < 7; i2 += 1) { 3248 if (!(isHiddenDayHash[i2] = hiddenDays.indexOf(i2) !== -1)) { 3249 dayCnt += 1; 3250 } 3251 } 3252 if (!dayCnt) { 3253 throw new Error("invalid hiddenDays"); 3254 } 3255 this.isHiddenDayHash = isHiddenDayHash; 3256 } 3257 // Remove days from the beginning and end of the range that are computed as hidden. 3258 // If the whole range is trimmed off, returns null 3259 trimHiddenDays(range) { 3260 let { start, end } = range; 3261 if (start) { 3262 start = this.skipHiddenDays(start); 3263 } 3264 if (end) { 3265 end = this.skipHiddenDays(end, -1, true); 3266 } 3267 if (start == null || end == null || start < end) { 3268 return { start, end }; 3269 } 3270 return null; 3271 } 3272 // Is the current day hidden? 3273 // `day` is a day-of-week index (0-6), or a Date (used for UTC) 3274 isHiddenDay(day) { 3275 if (day instanceof Date) { 3276 day = day.getUTCDay(); 3277 } 3278 return this.isHiddenDayHash[day]; 3279 } 3280 // Incrementing the current day until it is no longer a hidden day, returning a copy. 3281 // DOES NOT CONSIDER validRange! 3282 // If the initial value of `date` is not a hidden day, don't do anything. 3283 // Pass `isExclusive` as `true` if you are dealing with an end date. 3284 // `inc` defaults to `1` (increment one day forward each time) 3285 skipHiddenDays(date, inc = 1, isExclusive = false) {
3286 while (this.isHiddenDayHash[(date.getUTCDay() + (isExclusive ? inc : 0) + 7) % 7]) { 3287 date = addDays(date, inc); 3288 } 3289 return date; 3290 } 3291} 3292function createEventInstance(defId, range, forcedStartTzo, forcedEndTzo) { 3293 return { 3294 instanceId: guid(), 3295 defId, 3296 range, 3297 forcedStartTzo: forcedStartTzo == null ? null : forcedStartTzo, 3298 forcedEndTzo: forcedEndTzo == null ? null : forcedEndTzo 3299 }; 3300} 3301function parseRecurring(refined, defaultAllDay, dateEnv, recurringTypes) { 3302 for (let i2 = 0; i2 < recurringTypes.length; i2 += 1) { 3303 let parsed = recurringTypes[i2].parse(refined, dateEnv); 3304 if (parsed) { 3305 let { allDay } = refined; 3306 if (allDay == null) { 3307 allDay = defaultAllDay; 3308 if (allDay == null) { 3309 allDay = parsed.allDayGuess; 3310 if (allDay == null) { 3311 allDay = false; 3312 } 3313 } 3314 } 3315 return { 3316 allDay, 3317 duration: parsed.duration, 3318 typeData: parsed.typeData, 3319 typeId: i2 3320 }; 3321 } 3322 } 3323 return null; 3324} 3325function expandRecurring(eventStore, framingRange, context) { 3326 let { dateEnv, pluginHooks, options } = context; 3327 let { defs, instances } = eventStore; 3328 instances = filterHash(instances, (instance) => !defs[instance.defId].recurringDef); 3329 for (let defId in defs) { 3330 let def = defs[defId]; 3331 if (def.recurringDef) { 3332 let { duration } = def.recurringDef; 3333 if (!duration) { 3334 duration = def.allDay ? options.defaultAllDayEventDuration : options.defaultTimedEventDuration; 3335 } 3336 let starts = expandRecurringRanges(def, duration, framingRange, dateEnv, pluginHooks.recurringTypes); 3337 for (let start of starts) { 3338 let instance = createEventInstance(defId, { 3339 start, 3340 end: dateEnv.add(start, duration) 3341 }); 3342 instances[instance.instanceId] = instance; 3343 } 3344 } 3345 } 3346 return { defs, instances }; 3347} 3348function expandRecurringRanges(eventDef, duration, framingRange, dateEnv, recurringTypes) { 3349 let typeDef = recurringTypes[eventDef.recurringDef.typeId]; 3350 let markers = typeDef.expand(eventDef.recurringDef.typeData, { 3351 start: dateEnv.subtract(framingRange.start, duration), 3352 end: framingRange.end 3353 }, dateEnv); 3354 if (eventDef.allDay) { 3355 markers = markers.map(startOfDay); 3356 } 3357 return markers; 3358} 3359const EVENT_NON_DATE_REFINERS = { 3360 id: String, 3361 groupId: String, 3362 title: String, 3363 url: String, 3364 interactive: Boolean 3365}; 3366const EVENT_DATE_REFINERS = { 3367 start: identity, 3368 end: identity, 3369 date: identity, 3370 allDay: Boolean 3371}; 3372const EVENT_REFINERS = Object.assign(Object.assign(Object.assign({}, EVENT_NON_DATE_REFINERS), EVENT_DATE_REFINERS), { extendedProps: identity }); 3373function parseEvent(raw, eventSource, context, allowOpenRange, refiners = buildEventRefiners(context), defIdMap, instanceIdMap) { 3374 let { refined, extra } = refineEventDef(raw, context, refiners); 3375 let defaultAllDay = computeIsDefaultAllDay(eventSource, context); 3376 let recurringRes = parseRecurring(refined, defaultAllDay, context.dateEnv, context.pluginHooks.recurringTypes); 3377 if (recurringRes) { 3378 let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : "", recurringRes.allDay, Boolean(recurringRes.duration), context, defIdMap); 3379 def.recurringDef = { 3380 typeId: recurringRes.typeId, 3381 typeData: recurringRes.typeData, 3382 duration: recurringRes.duration 3383 }; 3384 return { def, instance: null }; 3385 } 3386 let singleRes = parseSingle(refined, defaultAllDay, context, allowOpenRange); 3387 if (singleRes) { 3388 let def = parseEventDef(refined, extra, eventSource ? eventSource.sourceId : "", singleRes.allDay, singleRes.hasEnd, context, defIdMap); 3389 let instance = createEventInstance(def.defId, singleRes.range, singleRes.forcedStartTzo, singleRes.forcedEndTzo); 3390 if (instanceIdMap && def.publicId && instanceIdMap[def.publicId]) { 3391 instance.instanceId = instanceIdMap[def.publicId]; 3392 } 3393 return { def, instance }; 3394 } 3395 return null; 3396} 3397function refineEventDef(raw, context, refiners = buildEventRefiners(context)) { 3398 return refineProps(raw, refiners); 3399} 3400function buildEventRefiners(context) { 3401 return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_REFINERS), context.pluginHooks.eventRefiners); 3402} 3403function parseEventDef(refined, extra, sourceId, allDay, hasEnd, context, defIdMap) { 3404 let def = { 3405 title: refined.title || "", 3406 groupId: refined.groupId || "", 3407 publicId: refined.id || "", 3408 url: refined.url || "", 3409 recurringDef: null, 3410 defId: (defIdMap && refined.id ? defIdMap[refined.id] : "") || guid(), 3411 sourceId, 3412 allDay, 3413 hasEnd, 3414 interactive: refined.interactive,
vendor: 4,937 bytes, lines 3415-3576
3415 ui: createEventUi(refined, context), 3416 extendedProps: Object.assign(Object.assign({}, refined.extendedProps || {}), extra) 3417 }; 3418 for (let memberAdder of context.pluginHooks.eventDefMemberAdders) { 3419 Object.assign(def, memberAdder(refined)); 3420 } 3421 Object.freeze(def.ui.classNames); 3422 Object.freeze(def.extendedProps); 3423 return def; 3424} 3425function parseSingle(refined, defaultAllDay, context, allowOpenRange) { 3426 let { allDay } = refined; 3427 let startMeta; 3428 let startMarker = null; 3429 let hasEnd = false; 3430 let endMeta; 3431 let endMarker = null; 3432 let startInput = refined.start != null ? refined.start : refined.date; 3433 startMeta = context.dateEnv.createMarkerMeta(startInput); 3434 if (startMeta) { 3435 startMarker = startMeta.marker; 3436 } else if (!allowOpenRange) { 3437 return null; 3438 } 3439 if (refined.end != null) { 3440 endMeta = context.dateEnv.createMarkerMeta(refined.end); 3441 } 3442 if (allDay == null) { 3443 if (defaultAllDay != null) { 3444 allDay = defaultAllDay; 3445 } else { 3446 allDay = (!startMeta || startMeta.isTimeUnspecified) && (!endMeta || endMeta.isTimeUnspecified); 3447 } 3448 } 3449 if (allDay && startMarker) { 3450 startMarker = startOfDay(startMarker); 3451 } 3452 if (endMeta) { 3453 endMarker = endMeta.marker; 3454 if (allDay) { 3455 endMarker = startOfDay(endMarker); 3456 } 3457 if (startMarker && endMarker <= startMarker) { 3458 endMarker = null; 3459 } 3460 } 3461 if (endMarker) { 3462 hasEnd = true; 3463 } else if (!allowOpenRange) { 3464 hasEnd = context.options.forceEventDuration || false; 3465 endMarker = context.dateEnv.add(startMarker, allDay ? context.options.defaultAllDayEventDuration : context.options.defaultTimedEventDuration); 3466 } 3467 return { 3468 allDay, 3469 hasEnd, 3470 range: { start: startMarker, end: endMarker }, 3471 forcedStartTzo: startMeta ? startMeta.forcedTzo : null, 3472 forcedEndTzo: endMeta ? endMeta.forcedTzo : null 3473 }; 3474} 3475function computeIsDefaultAllDay(eventSource, context) { 3476 let res = null; 3477 if (eventSource) { 3478 res = eventSource.defaultAllDay; 3479 } 3480 if (res == null) { 3481 res = context.options.defaultAllDay; 3482 } 3483 return res; 3484} 3485function parseEvents(rawEvents, eventSource, context, allowOpenRange, defIdMap, instanceIdMap) { 3486 let eventStore = createEmptyEventStore(); 3487 let eventRefiners = buildEventRefiners(context); 3488 for (let rawEvent of rawEvents) { 3489 let tuple = parseEvent(rawEvent, eventSource, context, allowOpenRange, eventRefiners, defIdMap, instanceIdMap); 3490 if (tuple) { 3491 eventTupleToStore(tuple, eventStore); 3492 } 3493 } 3494 return eventStore; 3495} 3496function eventTupleToStore(tuple, eventStore = createEmptyEventStore()) { 3497 eventStore.defs[tuple.def.defId] = tuple.def; 3498 if (tuple.instance) { 3499 eventStore.instances[tuple.instance.instanceId] = tuple.instance; 3500 } 3501 return eventStore; 3502} 3503function getRelevantEvents(eventStore, instanceId) { 3504 let instance = eventStore.instances[instanceId]; 3505 if (instance) { 3506 let def = eventStore.defs[instance.defId]; 3507 let newStore = filterEventStoreDefs(eventStore, (lookDef) => isEventDefsGrouped(def, lookDef)); 3508 newStore.defs[def.defId] = def; 3509 newStore.instances[instance.instanceId] = instance; 3510 return newStore; 3511 } 3512 return createEmptyEventStore(); 3513} 3514function isEventDefsGrouped(def0, def1) { 3515 return Boolean(def0.groupId && def0.groupId === def1.groupId); 3516} 3517function createEmptyEventStore() { 3518 return { defs: {}, instances: {} }; 3519} 3520function mergeEventStores(store0, store1) { 3521 return { 3522 defs: Object.assign(Object.assign({}, store0.defs), store1.defs), 3523 instances: Object.assign(Object.assign({}, store0.instances), store1.instances) 3524 }; 3525} 3526function filterEventStoreDefs(eventStore, filterFunc) { 3527 let defs = filterHash(eventStore.defs, filterFunc); 3528 let instances = filterHash(eventStore.instances, (instance) => defs[instance.defId]); 3529 return { defs, instances }; 3530} 3531function excludeSubEventStore(master, sub) { 3532 let { defs, instances } = master; 3533 let filteredDefs = {}; 3534 let filteredInstances = {}; 3535 for (let defId in defs) { 3536 if (!sub.defs[defId]) { 3537 filteredDefs[defId] = defs[defId]; 3538 } 3539 } 3540 for (let instanceId in instances) { 3541 if (!sub.instances[instanceId] && // not explicitly excluded 3542 filteredDefs[instances[instanceId].defId]) { 3543 filteredInstances[instanceId] = instances[instanceId]; 3544 } 3545 } 3546 return { 3547 defs: filteredDefs, 3548 instances: filteredInstances 3549 }; 3550} 3551function normalizeConstraint(input, context) { 3552 if (Array.isArray(input)) { 3553 return parseEvents(input, null, context, true); 3554 } 3555 if (typeof input === "object" && input) { 3556 return parseEvents([input], null, context, true); 3557 } 3558 if (input != null) { 3559 return String(input); 3560 } 3561 return null; 3562} 3563function parseClassNames(raw) { 3564 if (Array.isArray(raw)) { 3565 return raw; 3566 } 3567 if (typeof raw === "string") { 3568 return raw.split(/\s+/); 3569 } 3570 return []; 3571} 3572const EVENT_UI_REFINERS = { 3573 display: String, 3574 editable: Boolean, 3575 startEditable: Boolean, 3576 durationEditable: Boolean,
vendor: 4,800 bytes, lines 3577-3715
3577 constraint: identity, 3578 overlap: identity, 3579 allow: identity, 3580 className: parseClassNames, 3581 classNames: parseClassNames, 3582 color: String, 3583 backgroundColor: String, 3584 borderColor: String, 3585 textColor: String 3586}; 3587const EMPTY_EVENT_UI = { 3588 display: null, 3589 startEditable: null, 3590 durationEditable: null, 3591 constraints: [], 3592 overlap: null, 3593 allows: [], 3594 backgroundColor: "", 3595 borderColor: "", 3596 textColor: "", 3597 classNames: [] 3598}; 3599function createEventUi(refined, context) { 3600 let constraint = normalizeConstraint(refined.constraint, context); 3601 return { 3602 display: refined.display || null, 3603 startEditable: refined.startEditable != null ? refined.startEditable : refined.editable, 3604 durationEditable: refined.durationEditable != null ? refined.durationEditable : refined.editable, 3605 constraints: constraint != null ? [constraint] : [], 3606 overlap: refined.overlap != null ? refined.overlap : null, 3607 allows: refined.allow != null ? [refined.allow] : [], 3608 backgroundColor: refined.backgroundColor || refined.color || "", 3609 borderColor: refined.borderColor || refined.color || "", 3610 textColor: refined.textColor || "", 3611 classNames: (refined.className || []).concat(refined.classNames || []) 3612 // join singular and plural 3613 }; 3614} 3615function combineEventUis(uis) { 3616 return uis.reduce(combineTwoEventUis, EMPTY_EVENT_UI); 3617} 3618function combineTwoEventUis(item0, item1) { 3619 return { 3620 display: item1.display != null ? item1.display : item0.display, 3621 startEditable: item1.startEditable != null ? item1.startEditable : item0.startEditable, 3622 durationEditable: item1.durationEditable != null ? item1.durationEditable : item0.durationEditable, 3623 constraints: item0.constraints.concat(item1.constraints), 3624 overlap: typeof item1.overlap === "boolean" ? item1.overlap : item0.overlap, 3625 allows: item0.allows.concat(item1.allows), 3626 backgroundColor: item1.backgroundColor || item0.backgroundColor, 3627 borderColor: item1.borderColor || item0.borderColor, 3628 textColor: item1.textColor || item0.textColor, 3629 classNames: item0.classNames.concat(item1.classNames) 3630 }; 3631} 3632const EVENT_SOURCE_REFINERS = { 3633 id: String, 3634 defaultAllDay: Boolean, 3635 url: String, 3636 format: String, 3637 events: identity, 3638 eventDataTransform: identity, 3639 // for any network-related sources 3640 success: identity, 3641 failure: identity 3642}; 3643function parseEventSource(raw, context, refiners = buildEventSourceRefiners(context)) { 3644 let rawObj; 3645 if (typeof raw === "string") { 3646 rawObj = { url: raw }; 3647 } else if (typeof raw === "function" || Array.isArray(raw)) { 3648 rawObj = { events: raw }; 3649 } else if (typeof raw === "object" && raw) { 3650 rawObj = raw; 3651 } 3652 if (rawObj) { 3653 let { refined, extra } = refineProps(rawObj, refiners); 3654 let metaRes = buildEventSourceMeta(refined, context); 3655 if (metaRes) { 3656 return { 3657 _raw: raw, 3658 isFetching: false, 3659 latestFetchId: "", 3660 fetchRange: null, 3661 defaultAllDay: refined.defaultAllDay, 3662 eventDataTransform: refined.eventDataTransform, 3663 success: refined.success, 3664 failure: refined.failure, 3665 publicId: refined.id || "", 3666 sourceId: guid(), 3667 sourceDefId: metaRes.sourceDefId, 3668 meta: metaRes.meta, 3669 ui: createEventUi(refined, context), 3670 extendedProps: extra 3671 }; 3672 } 3673 } 3674 return null; 3675} 3676function buildEventSourceRefiners(context) { 3677 return Object.assign(Object.assign(Object.assign({}, EVENT_UI_REFINERS), EVENT_SOURCE_REFINERS), context.pluginHooks.eventSourceRefiners); 3678} 3679function buildEventSourceMeta(raw, context) { 3680 let defs = context.pluginHooks.eventSourceDefs; 3681 for (let i2 = defs.length - 1; i2 >= 0; i2 -= 1) { 3682 let def = defs[i2]; 3683 let meta = def.parseMeta(raw); 3684 if (meta) { 3685 return { sourceDefId: i2, meta }; 3686 } 3687 } 3688 return null; 3689} 3690function reduceEventStore(eventStore, action, eventSources, dateProfile, context) { 3691 switch (action.type) { 3692 case "RECEIVE_EVENTS": 3693 return receiveRawEvents(eventStore, eventSources[action.sourceId], action.fetchId, action.fetchRange, action.rawEvents, context); 3694 case "RESET_RAW_EVENTS": 3695 return resetRawEvents(eventStore, eventSources[action.sourceId], action.rawEvents, dateProfile.activeRange, context); 3696 case "ADD_EVENTS": 3697 return addEvent( 3698 eventStore, 3699 action.eventStore, 3700 // new ones 3701 dateProfile ? dateProfile.activeRange : null, 3702 context 3703 ); 3704 case "RESET_EVENTS": 3705 return action.eventStore; 3706 case "MERGE_EVENTS": 3707 return mergeEventStores(eventStore, action.eventStore); 3708 case "PREV": 3709 case "NEXT": 3710 case "CHANGE_DATE": 3711 case "CHANGE_VIEW_TYPE": 3712 if (dateProfile) { 3713 return expandRecurring(eventStore, dateProfile.activeRange, context); 3714 } 3715 return eventStore;
vendor: 4,556 bytes, lines 3716-3843
3716 case "REMOVE_EVENTS": 3717 return excludeSubEventStore(eventStore, action.eventStore); 3718 case "REMOVE_EVENT_SOURCE": 3719 return excludeEventsBySourceId(eventStore, action.sourceId); 3720 case "REMOVE_ALL_EVENT_SOURCES": 3721 return filterEventStoreDefs(eventStore, (eventDef) => !eventDef.sourceId); 3722 case "REMOVE_ALL_EVENTS": 3723 return createEmptyEventStore(); 3724 default: 3725 return eventStore; 3726 } 3727} 3728function receiveRawEvents(eventStore, eventSource, fetchId, fetchRange, rawEvents, context) { 3729 if (eventSource && // not already removed 3730 fetchId === eventSource.latestFetchId) { 3731 let subset = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context); 3732 if (fetchRange) { 3733 subset = expandRecurring(subset, fetchRange, context); 3734 } 3735 return mergeEventStores(excludeEventsBySourceId(eventStore, eventSource.sourceId), subset); 3736 } 3737 return eventStore; 3738} 3739function resetRawEvents(existingEventStore, eventSource, rawEvents, activeRange, context) { 3740 const { defIdMap, instanceIdMap } = buildPublicIdMaps(existingEventStore); 3741 let newEventStore = parseEvents(transformRawEvents(rawEvents, eventSource, context), eventSource, context, false, defIdMap, instanceIdMap); 3742 return expandRecurring(newEventStore, activeRange, context); 3743} 3744function transformRawEvents(rawEvents, eventSource, context) { 3745 let calEachTransform = context.options.eventDataTransform; 3746 let sourceEachTransform = eventSource ? eventSource.eventDataTransform : null; 3747 if (sourceEachTransform) { 3748 rawEvents = transformEachRawEvent(rawEvents, sourceEachTransform); 3749 } 3750 if (calEachTransform) { 3751 rawEvents = transformEachRawEvent(rawEvents, calEachTransform); 3752 } 3753 return rawEvents; 3754} 3755function transformEachRawEvent(rawEvents, func) { 3756 let refinedEvents; 3757 if (!func) { 3758 refinedEvents = rawEvents; 3759 } else { 3760 refinedEvents = []; 3761 for (let rawEvent of rawEvents) { 3762 let refinedEvent = func(rawEvent); 3763 if (refinedEvent) { 3764 refinedEvents.push(refinedEvent); 3765 } else if (refinedEvent == null) { 3766 refinedEvents.push(rawEvent); 3767 } 3768 } 3769 } 3770 return refinedEvents; 3771} 3772function addEvent(eventStore, subset, expandRange, context) { 3773 if (expandRange) { 3774 subset = expandRecurring(subset, expandRange, context); 3775 } 3776 return mergeEventStores(eventStore, subset); 3777} 3778function rezoneEventStoreDates(eventStore, oldDateEnv, newDateEnv) { 3779 let { defs } = eventStore; 3780 let instances = mapHash(eventStore.instances, (instance) => { 3781 let def = defs[instance.defId]; 3782 if (def.allDay) { 3783 return instance; 3784 } 3785 return Object.assign(Object.assign({}, instance), { range: { 3786 start: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.start, instance.forcedStartTzo)), 3787 end: newDateEnv.createMarker(oldDateEnv.toDate(instance.range.end, instance.forcedEndTzo)) 3788 }, forcedStartTzo: newDateEnv.canComputeOffset ? null : instance.forcedStartTzo, forcedEndTzo: newDateEnv.canComputeOffset ? null : instance.forcedEndTzo }); 3789 }); 3790 return { defs, instances }; 3791} 3792function excludeEventsBySourceId(eventStore, sourceId) { 3793 return filterEventStoreDefs(eventStore, (eventDef) => eventDef.sourceId !== sourceId); 3794} 3795function excludeInstances(eventStore, removals) { 3796 return { 3797 defs: eventStore.defs, 3798 instances: filterHash(eventStore.instances, (instance) => !removals[instance.instanceId]) 3799 }; 3800} 3801function buildPublicIdMaps(eventStore) { 3802 const { defs, instances } = eventStore; 3803 const defIdMap = {}; 3804 const instanceIdMap = {}; 3805 for (let defId in defs) { 3806 const def = defs[defId]; 3807 const { publicId } = def; 3808 if (publicId) { 3809 defIdMap[publicId] = defId; 3810 } 3811 } 3812 for (let instanceId in instances) { 3813 const instance = instances[instanceId]; 3814 const def = defs[instance.defId]; 3815 const { publicId } = def; 3816 if (publicId) { 3817 instanceIdMap[publicId] = instanceId; 3818 } 3819 } 3820 return { defIdMap, instanceIdMap }; 3821} 3822class Emitter { 3823 constructor() { 3824 this.handlers = {}; 3825 this.thisContext = null; 3826 } 3827 setThisContext(thisContext) { 3828 this.thisContext = thisContext; 3829 } 3830 setOptions(options) { 3831 this.options = options; 3832 } 3833 on(type, handler) { 3834 addToHash(this.handlers, type, handler); 3835 } 3836 off(type, handler) { 3837 removeFromHash(this.handlers, type, handler); 3838 } 3839 trigger(type, ...args) { 3840 let attachedHandlers = this.handlers[type] || []; 3841 let optionHandler = this.options && this.options[type]; 3842 let handlers = [].concat(optionHandler || [], attachedHandlers); 3843 for (let handler of handlers) {
3844 handler.apply(this.thisContext, args); 3845 } 3846 } 3847 hasHandlers(type) { 3848 return Boolean(this.handlers[type] && this.handlers[type].length || this.options && this.options[type]); 3849 } 3850} 3851function addToHash(hash, type, handler) { 3852 (hash[type] || (hash[type] = [])).push(handler); 3853} 3854function removeFromHash(hash, type, handler) { 3855 if (handler) { 3856 if (hash[type]) { 3857 hash[type] = hash[type].filter((func) => func !== handler); 3858 } 3859 } else { 3860 delete hash[type]; 3861 } 3862} 3863const DEF_DEFAULTS = { 3864 startTime: "09:00", 3865 endTime: "17:00", 3866 daysOfWeek: [1, 2, 3, 4, 5], 3867 display: "inverse-background", 3868 classNames: "fc-non-business", 3869 groupId: "_businessHours" 3870 // so multiple defs get grouped 3871}; 3872function parseBusinessHours(input, context) { 3873 return parseEvents(refineInputs(input), null, context); 3874} 3875function refineInputs(input) { 3876 let rawDefs; 3877 if (input === true) { 3878 rawDefs = [{}]; 3879 } else if (Array.isArray(input)) { 3880 rawDefs = input.filter((rawDef) => rawDef.daysOfWeek); 3881 } else if (typeof input === "object" && input) { 3882 rawDefs = [input]; 3883 } else { 3884 rawDefs = []; 3885 } 3886 rawDefs = rawDefs.map((rawDef) => Object.assign(Object.assign({}, DEF_DEFAULTS), rawDef)); 3887 return rawDefs; 3888} 3889function triggerDateSelect(selection, pev, context) { 3890 context.emitter.trigger("select", Object.assign(Object.assign({}, buildDateSpanApiWithContext(selection, context)), { jsEvent: pev ? pev.origEvent : null, view: context.viewApi || context.calendarApi.view })); 3891} 3892function triggerDateUnselect(pev, context) { 3893 context.emitter.trigger("unselect", { 3894 jsEvent: pev ? pev.origEvent : null, 3895 view: context.viewApi || context.calendarApi.view 3896 }); 3897} 3898function buildDateSpanApiWithContext(dateSpan, context) { 3899 let props = {}; 3900 for (let transform of context.pluginHooks.dateSpanTransforms) { 3901 Object.assign(props, transform(dateSpan, context)); 3902 } 3903 Object.assign(props, buildDateSpanApi(dateSpan, context.dateEnv)); 3904 return props; 3905} 3906function getDefaultEventEnd(allDay, marker, context) { 3907 let { dateEnv, options } = context; 3908 let end = marker; 3909 if (allDay) { 3910 end = startOfDay(end); 3911 end = dateEnv.add(end, options.defaultAllDayEventDuration); 3912 } else { 3913 end = dateEnv.add(end, options.defaultTimedEventDuration); 3914 } 3915 return end; 3916} 3917function applyMutationToEventStore(eventStore, eventConfigBase, mutation, context) { 3918 let eventConfigs = compileEventUis(eventStore.defs, eventConfigBase); 3919 let dest = createEmptyEventStore(); 3920 for (let defId in eventStore.defs) { 3921 let def = eventStore.defs[defId]; 3922 dest.defs[defId] = applyMutationToEventDef(def, eventConfigs[defId], mutation, context); 3923 } 3924 for (let instanceId in eventStore.instances) { 3925 let instance = eventStore.instances[instanceId]; 3926 let def = dest.defs[instance.defId]; 3927 dest.instances[instanceId] = applyMutationToEventInstance(instance, def, eventConfigs[instance.defId], mutation, context); 3928 } 3929 return dest; 3930} 3931function applyMutationToEventDef(eventDef, eventConfig, mutation, context) { 3932 let standardProps = mutation.standardProps || {}; 3933 if (standardProps.hasEnd == null && eventConfig.durationEditable && (mutation.startDelta || mutation.endDelta)) { 3934 standardProps.hasEnd = true; 3935 } 3936 let copy = Object.assign(Object.assign(Object.assign({}, eventDef), standardProps), { ui: Object.assign(Object.assign({}, eventDef.ui), standardProps.ui) }); 3937 if (mutation.extendedProps) { 3938 copy.extendedProps = Object.assign(Object.assign({}, copy.extendedProps), mutation.extendedProps); 3939 } 3940 for (let applier of context.pluginHooks.eventDefMutationAppliers) { 3941 applier(copy, mutation, context); 3942 } 3943 if (!copy.hasEnd && context.options.forceEventDuration) { 3944 copy.hasEnd = true; 3945 } 3946 return copy; 3947} 3948function applyMutationToEventInstance(eventInstance, eventDef, eventConfig, mutation, context) { 3949 let { dateEnv } = context; 3950 let forceAllDay = mutation.standardProps && mutation.standardProps.allDay === true; 3951 let clearEnd = mutation.standardProps && mutation.standardProps.hasEnd === false; 3952 let copy = Object.assign({}, eventInstance); 3953 if (forceAllDay) { 3954 copy.range = computeAlignedDayRange(copy.range); 3955 } 3956 if (mutation.datesDelta && eventConfig.startEditable) { 3957 copy.range = { 3958 start: dateEnv.add(copy.range.start, mutation.datesDelta), 3959 end: dateEnv.add(copy.range.end, mutation.datesDelta) 3960 }; 3961 } 3962 if (mutation.startDelta && eventConfig.durationEditable) { 3963 copy.range = { 3964 start: dateEnv.add(copy.range.start, mutation.startDelta), 3965 end: copy.range.end 3966 }; 3967 } 3968 if (mutation.endDelta && eventConfig.durationEditable) { 3969 copy.range = { 3970 start: copy.range.start, 3971 end: dateEnv.add(copy.range.end, mutation.endDelta) 3972 }; 3973 } 3974 if (clearEnd) { 3975 copy.range = { 3976 start: copy.range.start, 3977 end: getDefaultEventEnd(eventDef.allDay, copy.range.start, context) 3978 }; 3979 } 3980 if (eventDef.allDay) { 3981 copy.range = { 3982 start: startOfDay(copy.range.start), 3983 end: startOfDay(copy.range.end) 3984 }; 3985 } 3986 if (copy.range.end < copy.range.start) { 3987 copy.range.end = getDefaultEventEnd(eventDef.allDay, copy.range.start, context); 3988 } 3989 return copy; 3990} 3991class EventSourceImpl {
vendor: 20,863 bytes, lines 3992-4681
3992 constructor(context, internalEventSource) { 3993 this.context = context; 3994 this.internalEventSource = internalEventSource; 3995 } 3996 remove() { 3997 this.context.dispatch({ 3998 type: "REMOVE_EVENT_SOURCE", 3999 sourceId: this.internalEventSource.sourceId 4000 }); 4001 } 4002 refetch() { 4003 this.context.dispatch({ 4004 type: "FETCH_EVENT_SOURCES", 4005 sourceIds: [this.internalEventSource.sourceId], 4006 isRefetch: true 4007 }); 4008 } 4009 get id() { 4010 return this.internalEventSource.publicId; 4011 } 4012 get url() { 4013 return this.internalEventSource.meta.url; 4014 } 4015 get format() { 4016 return this.internalEventSource.meta.format; 4017 } 4018} 4019class EventImpl { 4020 // instance will be null if expressing a recurring event that has no current instances, 4021 // OR if trying to validate an incoming external event that has no dates assigned 4022 constructor(context, def, instance) { 4023 this._context = context; 4024 this._def = def; 4025 this._instance = instance || null; 4026 } 4027 /* 4028 TODO: make event struct more responsible for this 4029 */ 4030 setProp(name, val) { 4031 if (name in EVENT_DATE_REFINERS) { 4032 console.warn("Could not set date-related prop 'name'. Use one of the date-related methods instead."); 4033 } else if (name === "id") { 4034 val = EVENT_NON_DATE_REFINERS[name](val); 4035 this.mutate({ 4036 standardProps: { publicId: val } 4037 // hardcoded internal name 4038 }); 4039 } else if (name in EVENT_NON_DATE_REFINERS) { 4040 val = EVENT_NON_DATE_REFINERS[name](val); 4041 this.mutate({ 4042 standardProps: { [name]: val } 4043 }); 4044 } else if (name in EVENT_UI_REFINERS) { 4045 let ui = EVENT_UI_REFINERS[name](val); 4046 if (name === "color") { 4047 ui = { backgroundColor: val, borderColor: val }; 4048 } else if (name === "editable") { 4049 ui = { startEditable: val, durationEditable: val }; 4050 } else { 4051 ui = { [name]: val }; 4052 } 4053 this.mutate({ 4054 standardProps: { ui } 4055 }); 4056 } else { 4057 console.warn(`Could not set prop '${name}'. Use setExtendedProp instead.`); 4058 } 4059 } 4060 setExtendedProp(name, val) { 4061 this.mutate({ 4062 extendedProps: { [name]: val } 4063 }); 4064 } 4065 setStart(startInput, options = {}) { 4066 let { dateEnv } = this._context; 4067 let start = dateEnv.createMarker(startInput); 4068 if (start && this._instance) { 4069 let instanceRange = this._instance.range; 4070 let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 4071 if (options.maintainDuration) { 4072 this.mutate({ datesDelta: startDelta }); 4073 } else { 4074 this.mutate({ startDelta }); 4075 } 4076 } 4077 } 4078 setEnd(endInput, options = {}) { 4079 let { dateEnv } = this._context; 4080 let end; 4081 if (endInput != null) { 4082 end = dateEnv.createMarker(endInput); 4083 if (!end) { 4084 return; 4085 } 4086 } 4087 if (this._instance) { 4088 if (end) { 4089 let endDelta = diffDates(this._instance.range.end, end, dateEnv, options.granularity); 4090 this.mutate({ endDelta }); 4091 } else { 4092 this.mutate({ standardProps: { hasEnd: false } }); 4093 } 4094 } 4095 } 4096 setDates(startInput, endInput, options = {}) { 4097 let { dateEnv } = this._context; 4098 let standardProps = { allDay: options.allDay }; 4099 let start = dateEnv.createMarker(startInput); 4100 let end; 4101 if (!start) { 4102 return; 4103 } 4104 if (endInput != null) { 4105 end = dateEnv.createMarker(endInput); 4106 if (!end) { 4107 return; 4108 } 4109 } 4110 if (this._instance) { 4111 let instanceRange = this._instance.range; 4112 if (options.allDay === true) { 4113 instanceRange = computeAlignedDayRange(instanceRange); 4114 } 4115 let startDelta = diffDates(instanceRange.start, start, dateEnv, options.granularity); 4116 if (end) { 4117 let endDelta = diffDates(instanceRange.end, end, dateEnv, options.granularity); 4118 if (durationsEqual(startDelta, endDelta)) { 4119 this.mutate({ datesDelta: startDelta, standardProps }); 4120 } else { 4121 this.mutate({ startDelta, endDelta, standardProps }); 4122 } 4123 } else { 4124 standardProps.hasEnd = false; 4125 this.mutate({ datesDelta: startDelta, standardProps }); 4126 } 4127 } 4128 } 4129 moveStart(deltaInput) { 4130 let delta = createDuration(deltaInput); 4131 if (delta) { 4132 this.mutate({ startDelta: delta }); 4133 } 4134 } 4135 moveEnd(deltaInput) { 4136 let delta = createDuration(deltaInput); 4137 if (delta) { 4138 this.mutate({ endDelta: delta }); 4139 } 4140 } 4141 moveDates(deltaInput) { 4142 let delta = createDuration(deltaInput); 4143 if (delta) { 4144 this.mutate({ datesDelta: delta }); 4145 } 4146 } 4147 setAllDay(allDay, options = {}) { 4148 let standardProps = { allDay }; 4149 let { maintainDuration } = options; 4150 if (maintainDuration == null) { 4151 maintainDuration = this._context.options.allDayMaintainDuration; 4152 } 4153 if (this._def.allDay !== allDay) { 4154 standardProps.hasEnd = maintainDuration; 4155 } 4156 this.mutate({ standardProps }); 4157 } 4158 formatRange(formatInput) { 4159 let { dateEnv } = this._context; 4160 let instance = this._instance; 4161 let formatter = createFormatter(formatInput); 4162 if (this._def.hasEnd) { 4163 return dateEnv.formatRange(instance.range.start, instance.range.end, formatter, { 4164 forcedStartTzo: instance.forcedStartTzo, 4165 forcedEndTzo: instance.forcedEndTzo 4166 }); 4167 } 4168 return dateEnv.format(instance.range.start, formatter, { 4169 forcedTzo: instance.forcedStartTzo 4170 }); 4171 } 4172 mutate(mutation) { 4173 let instance = this._instance; 4174 if (instance) { 4175 let def = this._def; 4176 let context = this._context; 4177 let { eventStore } = context.getCurrentData(); 4178 let relevantEvents = getRelevantEvents(eventStore, instance.instanceId); 4179 let eventConfigBase = { 4180 "": { 4181 display: "", 4182 startEditable: true, 4183 durationEditable: true, 4184 constraints: [], 4185 overlap: null, 4186 allows: [], 4187 backgroundColor: "", 4188 borderColor: "", 4189 textColor: "", 4190 classNames: [] 4191 } 4192 }; 4193 relevantEvents = applyMutationToEventStore(relevantEvents, eventConfigBase, mutation, context); 4194 let oldEvent = new EventImpl(context, def, instance); 4195 this._def = relevantEvents.defs[def.defId]; 4196 this._instance = relevantEvents.instances[instance.instanceId]; 4197 context.dispatch({ 4198 type: "MERGE_EVENTS", 4199 eventStore: relevantEvents 4200 }); 4201 context.emitter.trigger("eventChange", { 4202 oldEvent, 4203 event: this, 4204 relatedEvents: buildEventApis(relevantEvents, context, instance), 4205 revert() { 4206 context.dispatch({ 4207 type: "RESET_EVENTS", 4208 eventStore 4209 // the ORIGINAL store 4210 }); 4211 } 4212 }); 4213 } 4214 } 4215 remove() { 4216 let context = this._context; 4217 let asStore = eventApiToStore(this); 4218 context.dispatch({ 4219 type: "REMOVE_EVENTS", 4220 eventStore: asStore 4221 }); 4222 context.emitter.trigger("eventRemove", { 4223 event: this, 4224 relatedEvents: [], 4225 revert() { 4226 context.dispatch({ 4227 type: "MERGE_EVENTS", 4228 eventStore: asStore 4229 }); 4230 } 4231 }); 4232 } 4233 get source() { 4234 let { sourceId } = this._def; 4235 if (sourceId) { 4236 return new EventSourceImpl(this._context, this._context.getCurrentData().eventSources[sourceId]); 4237 } 4238 return null; 4239 } 4240 get start() { 4241 return this._instance ? this._context.dateEnv.toDate(this._instance.range.start) : null; 4242 } 4243 get end() { 4244 return this._instance && this._def.hasEnd ? this._context.dateEnv.toDate(this._instance.range.end) : null; 4245 } 4246 get startStr() { 4247 let instance = this._instance; 4248 if (instance) { 4249 return this._context.dateEnv.formatIso(instance.range.start, { 4250 omitTime: this._def.allDay, 4251 forcedTzo: instance.forcedStartTzo 4252 }); 4253 } 4254 return ""; 4255 } 4256 get endStr() { 4257 let instance = this._instance; 4258 if (instance && this._def.hasEnd) { 4259 return this._context.dateEnv.formatIso(instance.range.end, { 4260 omitTime: this._def.allDay, 4261 forcedTzo: instance.forcedEndTzo 4262 }); 4263 } 4264 return ""; 4265 } 4266 // computable props that all access the def 4267 // TODO: find a TypeScript-compatible way to do this at scale 4268 get id() { 4269 return this._def.publicId; 4270 } 4271 get groupId() { 4272 return this._def.groupId; 4273 } 4274 get allDay() { 4275 return this._def.allDay; 4276 } 4277 get title() { 4278 return this._def.title; 4279 } 4280 get url() { 4281 return this._def.url; 4282 } 4283 get display() { 4284 return this._def.ui.display || "auto"; 4285 } 4286 // bad. just normalize the type earlier 4287 get startEditable() { 4288 return this._def.ui.startEditable; 4289 } 4290 get durationEditable() { 4291 return this._def.ui.durationEditable; 4292 } 4293 get constraint() { 4294 return this._def.ui.constraints[0] || null; 4295 } 4296 get overlap() { 4297 return this._def.ui.overlap; 4298 } 4299 get allow() { 4300 return this._def.ui.allows[0] || null; 4301 } 4302 get backgroundColor() { 4303 return this._def.ui.backgroundColor; 4304 } 4305 get borderColor() { 4306 return this._def.ui.borderColor; 4307 } 4308 get textColor() { 4309 return this._def.ui.textColor; 4310 } 4311 // NOTE: user can't modify these because Object.freeze was called in event-def parsing 4312 get classNames() { 4313 return this._def.ui.classNames; 4314 } 4315 get extendedProps() { 4316 return this._def.extendedProps; 4317 } 4318 toPlainObject(settings = {}) { 4319 let def = this._def; 4320 let { ui } = def; 4321 let { startStr, endStr } = this; 4322 let res = { 4323 allDay: def.allDay 4324 }; 4325 if (def.title) { 4326 res.title = def.title; 4327 } 4328 if (startStr) { 4329 res.start = startStr; 4330 } 4331 if (endStr) { 4332 res.end = endStr; 4333 } 4334 if (def.publicId) { 4335 res.id = def.publicId; 4336 } 4337 if (def.groupId) { 4338 res.groupId = def.groupId; 4339 } 4340 if (def.url) { 4341 res.url = def.url; 4342 } 4343 if (ui.display && ui.display !== "auto") { 4344 res.display = ui.display; 4345 } 4346 if (settings.collapseColor && ui.backgroundColor && ui.backgroundColor === ui.borderColor) { 4347 res.color = ui.backgroundColor; 4348 } else { 4349 if (ui.backgroundColor) { 4350 res.backgroundColor = ui.backgroundColor; 4351 } 4352 if (ui.borderColor) { 4353 res.borderColor = ui.borderColor; 4354 } 4355 } 4356 if (ui.textColor) { 4357 res.textColor = ui.textColor; 4358 } 4359 if (ui.classNames.length) { 4360 res.classNames = ui.classNames; 4361 } 4362 if (Object.keys(def.extendedProps).length) { 4363 if (settings.collapseExtendedProps) { 4364 Object.assign(res, def.extendedProps); 4365 } else { 4366 res.extendedProps = def.extendedProps; 4367 } 4368 } 4369 return res; 4370 } 4371 toJSON() { 4372 return this.toPlainObject(); 4373 } 4374} 4375function eventApiToStore(eventApi) { 4376 let def = eventApi._def; 4377 let instance = eventApi._instance; 4378 return { 4379 defs: { [def.defId]: def }, 4380 instances: instance ? { [instance.instanceId]: instance } : {} 4381 }; 4382} 4383function buildEventApis(eventStore, context, excludeInstance) { 4384 let { defs, instances } = eventStore; 4385 let eventApis = []; 4386 let excludeInstanceId = excludeInstance ? excludeInstance.instanceId : ""; 4387 for (let id in instances) { 4388 let instance = instances[id]; 4389 let def = defs[instance.defId]; 4390 if (instance.instanceId !== excludeInstanceId) { 4391 eventApis.push(new EventImpl(context, def, instance)); 4392 } 4393 } 4394 return eventApis; 4395} 4396function sliceEventStore(eventStore, eventUiBases, framingRange, nextDayThreshold) { 4397 let inverseBgByGroupId = {}; 4398 let inverseBgByDefId = {}; 4399 let defByGroupId = {}; 4400 let bgRanges = []; 4401 let fgRanges = []; 4402 let eventUis = compileEventUis(eventStore.defs, eventUiBases); 4403 for (let defId in eventStore.defs) { 4404 let def = eventStore.defs[defId]; 4405 let ui = eventUis[def.defId]; 4406 if (ui.display === "inverse-background") { 4407 if (def.groupId) { 4408 inverseBgByGroupId[def.groupId] = []; 4409 if (!defByGroupId[def.groupId]) { 4410 defByGroupId[def.groupId] = def; 4411 } 4412 } else { 4413 inverseBgByDefId[defId] = []; 4414 } 4415 } 4416 } 4417 for (let instanceId in eventStore.instances) { 4418 let instance = eventStore.instances[instanceId]; 4419 let def = eventStore.defs[instance.defId]; 4420 let ui = eventUis[def.defId]; 4421 let origRange = instance.range; 4422 let normalRange = !def.allDay && nextDayThreshold ? computeVisibleDayRange(origRange, nextDayThreshold) : origRange; 4423 let slicedRange = intersectRanges(normalRange, framingRange); 4424 if (slicedRange) { 4425 if (ui.display === "inverse-background") { 4426 if (def.groupId) { 4427 inverseBgByGroupId[def.groupId].push(slicedRange); 4428 } else { 4429 inverseBgByDefId[instance.defId].push(slicedRange); 4430 } 4431 } else if (ui.display !== "none") { 4432 (ui.display === "background" ? bgRanges : fgRanges).push({ 4433 def, 4434 ui, 4435 instance, 4436 range: slicedRange, 4437 isStart: normalRange.start && normalRange.start.valueOf() === slicedRange.start.valueOf(), 4438 isEnd: normalRange.end && normalRange.end.valueOf() === slicedRange.end.valueOf() 4439 }); 4440 } 4441 } 4442 } 4443 for (let groupId in inverseBgByGroupId) { 4444 let ranges = inverseBgByGroupId[groupId]; 4445 let invertedRanges = invertRanges(ranges, framingRange); 4446 for (let invertedRange of invertedRanges) { 4447 let def = defByGroupId[groupId]; 4448 let ui = eventUis[def.defId]; 4449 bgRanges.push({ 4450 def, 4451 ui, 4452 instance: null, 4453 range: invertedRange, 4454 isStart: false, 4455 isEnd: false 4456 }); 4457 } 4458 } 4459 for (let defId in inverseBgByDefId) { 4460 let ranges = inverseBgByDefId[defId]; 4461 let invertedRanges = invertRanges(ranges, framingRange); 4462 for (let invertedRange of invertedRanges) { 4463 bgRanges.push({ 4464 def: eventStore.defs[defId], 4465 ui: eventUis[defId], 4466 instance: null, 4467 range: invertedRange, 4468 isStart: false, 4469 isEnd: false 4470 }); 4471 } 4472 } 4473 return { bg: bgRanges, fg: fgRanges }; 4474} 4475function hasBgRendering(def) { 4476 return def.ui.display === "background" || def.ui.display === "inverse-background"; 4477} 4478function setElSeg(el, seg) { 4479 el.fcSeg = seg; 4480} 4481function getElSeg(el) { 4482 return el.fcSeg || el.parentNode.fcSeg || // for the harness 4483 null; 4484} 4485function compileEventUis(eventDefs, eventUiBases) { 4486 return mapHash(eventDefs, (eventDef) => compileEventUi(eventDef, eventUiBases)); 4487} 4488function compileEventUi(eventDef, eventUiBases) { 4489 let uis = []; 4490 if (eventUiBases[""]) { 4491 uis.push(eventUiBases[""]); 4492 } 4493 if (eventUiBases[eventDef.defId]) { 4494 uis.push(eventUiBases[eventDef.defId]); 4495 } 4496 uis.push(eventDef.ui); 4497 return combineEventUis(uis); 4498} 4499function sortEventSegs(segs, eventOrderSpecs) { 4500 let objs = segs.map(buildSegCompareObj); 4501 objs.sort((obj0, obj1) => compareByFieldSpecs(obj0, obj1, eventOrderSpecs)); 4502 return objs.map((c2) => c2._seg); 4503} 4504function buildSegCompareObj(seg) { 4505 let { eventRange } = seg; 4506 let eventDef = eventRange.def; 4507 let range = eventRange.instance ? eventRange.instance.range : eventRange.range; 4508 let start = range.start ? range.start.valueOf() : 0; 4509 let end = range.end ? range.end.valueOf() : 0; 4510 return Object.assign(Object.assign(Object.assign({}, eventDef.extendedProps), eventDef), { 4511 id: eventDef.publicId, 4512 start, 4513 end, 4514 duration: end - start, 4515 allDay: Number(eventDef.allDay), 4516 _seg: seg 4517 }); 4518} 4519function computeSegDraggable(seg, context) { 4520 let { pluginHooks } = context; 4521 let transformers = pluginHooks.isDraggableTransformers; 4522 let { def, ui } = seg.eventRange; 4523 let val = ui.startEditable; 4524 for (let transformer of transformers) { 4525 val = transformer(val, def, ui, context); 4526 } 4527 return val; 4528} 4529function computeSegStartResizable(seg, context) { 4530 return seg.isStart && seg.eventRange.ui.durationEditable && context.options.eventResizableFromStart; 4531} 4532function computeSegEndResizable(seg, context) { 4533 return seg.isEnd && seg.eventRange.ui.durationEditable; 4534} 4535function buildSegTimeText(seg, timeFormat, context, defaultDisplayEventTime, defaultDisplayEventEnd, startOverride, endOverride) { 4536 let { dateEnv, options } = context; 4537 let { displayEventTime, displayEventEnd } = options; 4538 let eventDef = seg.eventRange.def; 4539 let eventInstance = seg.eventRange.instance; 4540 if (displayEventTime == null) { 4541 displayEventTime = defaultDisplayEventTime !== false; 4542 } 4543 if (displayEventEnd == null) { 4544 displayEventEnd = defaultDisplayEventEnd !== false; 4545 } 4546 let wholeEventStart = eventInstance.range.start; 4547 let wholeEventEnd = eventInstance.range.end; 4548 let segStart = startOverride || seg.start || seg.eventRange.range.start; 4549 let segEnd = endOverride || seg.end || seg.eventRange.range.end; 4550 let isStartDay = startOfDay(wholeEventStart).valueOf() === startOfDay(segStart).valueOf(); 4551 let isEndDay = startOfDay(addMs(wholeEventEnd, -1)).valueOf() === startOfDay(addMs(segEnd, -1)).valueOf(); 4552 if (displayEventTime && !eventDef.allDay && (isStartDay || isEndDay)) { 4553 segStart = isStartDay ? wholeEventStart : segStart; 4554 segEnd = isEndDay ? wholeEventEnd : segEnd; 4555 if (displayEventEnd && eventDef.hasEnd) { 4556 return dateEnv.formatRange(segStart, segEnd, timeFormat, { 4557 forcedStartTzo: startOverride ? null : eventInstance.forcedStartTzo, 4558 forcedEndTzo: endOverride ? null : eventInstance.forcedEndTzo 4559 }); 4560 } 4561 return dateEnv.format(segStart, timeFormat, { 4562 forcedTzo: startOverride ? null : eventInstance.forcedStartTzo 4563 // nooooo, same 4564 }); 4565 } 4566 return ""; 4567} 4568function getSegMeta(seg, todayRange, nowDate) { 4569 let segRange = seg.eventRange.range; 4570 return { 4571 isPast: segRange.end <= (nowDate || todayRange.start), 4572 isFuture: segRange.start >= (nowDate || todayRange.end), 4573 isToday: todayRange && rangeContainsMarker(todayRange, segRange.start) 4574 }; 4575} 4576function getEventClassNames(props) { 4577 let classNames = ["fc-event"]; 4578 if (props.isMirror) { 4579 classNames.push("fc-event-mirror"); 4580 } 4581 if (props.isDraggable) { 4582 classNames.push("fc-event-draggable"); 4583 } 4584 if (props.isStartResizable || props.isEndResizable) { 4585 classNames.push("fc-event-resizable"); 4586 } 4587 if (props.isDragging) { 4588 classNames.push("fc-event-dragging"); 4589 } 4590 if (props.isResizing) { 4591 classNames.push("fc-event-resizing"); 4592 } 4593 if (props.isSelected) { 4594 classNames.push("fc-event-selected"); 4595 } 4596 if (props.isStart) { 4597 classNames.push("fc-event-start"); 4598 } 4599 if (props.isEnd) { 4600 classNames.push("fc-event-end"); 4601 } 4602 if (props.isPast) { 4603 classNames.push("fc-event-past"); 4604 } 4605 if (props.isToday) { 4606 classNames.push("fc-event-today"); 4607 } 4608 if (props.isFuture) { 4609 classNames.push("fc-event-future"); 4610 } 4611 return classNames; 4612} 4613function buildEventRangeKey(eventRange) { 4614 return eventRange.instance ? eventRange.instance.instanceId : `${eventRange.def.defId}:${eventRange.range.start.toISOString()}`; 4615} 4616function getSegAnchorAttrs(seg, context) { 4617 let { def, instance } = seg.eventRange; 4618 let { url } = def; 4619 if (url) { 4620 return { href: url }; 4621 } 4622 let { emitter, options } = context; 4623 let { eventInteractive } = options; 4624 if (eventInteractive == null) { 4625 eventInteractive = def.interactive; 4626 if (eventInteractive == null) { 4627 eventInteractive = Boolean(emitter.hasHandlers("eventClick")); 4628 } 4629 } 4630 if (eventInteractive) { 4631 return createAriaKeyboardAttrs((ev) => { 4632 emitter.trigger("eventClick", { 4633 el: ev.target, 4634 event: new EventImpl(context, def, instance), 4635 jsEvent: ev, 4636 view: context.viewApi 4637 }); 4638 }); 4639 } 4640 return {}; 4641} 4642const STANDARD_PROPS = { 4643 start: identity, 4644 end: identity, 4645 allDay: Boolean 4646}; 4647function parseDateSpan(raw, dateEnv, defaultDuration) { 4648 let span = parseOpenDateSpan(raw, dateEnv); 4649 let { range } = span; 4650 if (!range.start) { 4651 return null; 4652 } 4653 if (!range.end) { 4654 if (defaultDuration == null) { 4655 return null; 4656 } 4657 range.end = dateEnv.add(range.start, defaultDuration); 4658 } 4659 return span; 4660} 4661function parseOpenDateSpan(raw, dateEnv) { 4662 let { refined: standardProps, extra } = refineProps(raw, STANDARD_PROPS); 4663 let startMeta = standardProps.start ? dateEnv.createMarkerMeta(standardProps.start) : null; 4664 let endMeta = standardProps.end ? dateEnv.createMarkerMeta(standardProps.end) : null; 4665 let { allDay } = standardProps; 4666 if (allDay == null) { 4667 allDay = startMeta && startMeta.isTimeUnspecified && (!endMeta || endMeta.isTimeUnspecified); 4668 } 4669 return Object.assign({ range: { 4670 start: startMeta ? startMeta.marker : null, 4671 end: endMeta ? endMeta.marker : null 4672 }, allDay }, extra); 4673} 4674function isDateSpansEqual(span0, span1) { 4675 return rangesEqual(span0.range, span1.range) && span0.allDay === span1.allDay && isSpanPropsEqual(span0, span1); 4676} 4677function isSpanPropsEqual(span0, span1) { 4678 for (let propName in span1) { 4679 if (propName !== "range" && propName !== "allDay") { 4680 if (span0[propName] !== span1[propName]) { 4681 return false;
4682 } 4683 } 4684 } 4685 for (let propName in span0) { 4686 if (!(propName in span1)) { 4687 return false; 4688 } 4689 } 4690 return true; 4691} 4692function buildDateSpanApi(span, dateEnv) { 4693 return Object.assign(Object.assign({}, buildRangeApi(span.range, dateEnv, span.allDay)), { allDay: span.allDay }); 4694} 4695function buildRangeApiWithTimeZone(range, dateEnv, omitTime) { 4696 return Object.assign(Object.assign({}, buildRangeApi(range, dateEnv, omitTime)), { timeZone: dateEnv.timeZone }); 4697} 4698function buildRangeApi(range, dateEnv, omitTime) { 4699 return { 4700 start: dateEnv.toDate(range.start), 4701 end: dateEnv.toDate(range.end), 4702 startStr: dateEnv.formatIso(range.start, { omitTime }), 4703 endStr: dateEnv.formatIso(range.end, { omitTime }) 4704 }; 4705} 4706function fabricateEventRange(dateSpan, eventUiBases, context) { 4707 let res = refineEventDef({ editable: false }, context); 4708 let def = parseEventDef( 4709 res.refined, 4710 res.extra, 4711 "", 4712 // sourceId 4713 dateSpan.allDay, 4714 true, 4715 // hasEnd 4716 context 4717 ); 4718 return { 4719 def, 4720 ui: compileEventUi(def, eventUiBases), 4721 instance: createEventInstance(def.defId, dateSpan.range), 4722 range: dateSpan.range, 4723 isStart: true, 4724 isEnd: true 4725 }; 4726} 4727function unpromisify(func, normalizedSuccessCallback, normalizedFailureCallback) { 4728 let isResolved = false; 4729 let wrappedSuccess = function(res2) { 4730 if (!isResolved) { 4731 isResolved = true; 4732 normalizedSuccessCallback(res2); 4733 } 4734 }; 4735 let wrappedFailure = function(error) { 4736 if (!isResolved) { 4737 isResolved = true; 4738 normalizedFailureCallback(error); 4739 } 4740 }; 4741 let res = func(wrappedSuccess, wrappedFailure); 4742 if (res && typeof res.then === "function") { 4743 res.then(wrappedSuccess, wrappedFailure); 4744 } 4745} 4746class JsonRequestError extends Error { 4747 constructor(message, response) { 4748 super(message); 4749 this.response = response; 4750 } 4751} 4752function requestJson(method, url, params) { 4753 method = method.toUpperCase(); 4754 const fetchOptions = { 4755 method 4756 }; 4757 if (method === "GET") { 4758 url += (url.indexOf("?") === -1 ? "?" : "&") + new URLSearchParams(params); 4759 } else { 4760 fetchOptions.body = new URLSearchParams(params); 4761 fetchOptions.headers = { 4762 "Content-Type": "application/x-www-form-urlencoded" 4763 }; 4764 } 4765 return fetch(url, fetchOptions).then((fetchRes) => { 4766 if (fetchRes.ok) { 4767 return fetchRes.json().then((parsedResponse) => { 4768 return [parsedResponse, fetchRes]; 4769 }, () => { 4770 throw new JsonRequestError("Failure parsing JSON", fetchRes); 4771 }); 4772 } else { 4773 throw new JsonRequestError("Request failed", fetchRes); 4774 } 4775 }); 4776} 4777let canVGrowWithinCell; 4778function getCanVGrowWithinCell() { 4779 if (canVGrowWithinCell == null) { 4780 canVGrowWithinCell = computeCanVGrowWithinCell(); 4781 } 4782 return canVGrowWithinCell; 4783} 4784function computeCanVGrowWithinCell() { 4785 if (typeof document === "undefined") { 4786 return true; 4787 } 4788 let el = document.createElement("div"); 4789 el.style.position = "absolute"; 4790 el.style.top = "0px"; 4791 el.style.left = "0px"; 4792 el.innerHTML = "<table><tr><td><div></div></td></tr></table>"; 4793 el.querySelector("table").style.height = "100px"; 4794 el.querySelector("div").style.height = "100%"; 4795 document.body.appendChild(el); 4796 let div = el.querySelector("div"); 4797 let possible = div.offsetHeight > 0; 4798 document.body.removeChild(el); 4799 return possible; 4800} 4801class CalendarRoot extends BaseComponent { 4802 constructor() { 4803 super(...arguments); 4804 this.state = { 4805 forPrint: false 4806 }; 4807 this.handleBeforePrint = () => { 4808 flushSync(() => { 4809 this.setState({ forPrint: true }); 4810 }); 4811 }; 4812 this.handleAfterPrint = () => { 4813 flushSync(() => { 4814 this.setState({ forPrint: false }); 4815 }); 4816 }; 4817 } 4818 render() { 4819 let { props } = this; 4820 let { options } = props; 4821 let { forPrint } = this.state; 4822 let isHeightAuto = forPrint || options.height === "auto" || options.contentHeight === "auto"; 4823 let height = !isHeightAuto && options.height != null ? options.height : ""; 4824 let classNames = [ 4825 "fc", 4826 forPrint ? "fc-media-print" : "fc-media-screen", 4827 `fc-direction-${options.direction}`, 4828 props.theme.getClass("root") 4829 ]; 4830 if (!getCanVGrowWithinCell()) { 4831 classNames.push("fc-liquid-hack"); 4832 } 4833 return props.children(classNames, height, isHeightAuto, forPrint); 4834 } 4835 componentDidMount() { 4836 let { emitter } = this.props; 4837 emitter.on("_beforeprint", this.handleBeforePrint); 4838 emitter.on("_afterprint", this.handleAfterPrint); 4839 } 4840 componentWillUnmount() { 4841 let { emitter } = this.props; 4842 emitter.off("_beforeprint", this.handleBeforePrint); 4843 emitter.off("_afterprint", this.handleAfterPrint); 4844 } 4845} 4846class Interaction { 4847 constructor(settings) { 4848 this.component = settings.component; 4849 this.isHitComboAllowed = settings.isHitComboAllowed || null; 4850 } 4851 destroy() { 4852 } 4853} 4854function parseInteractionSettings(component, input) { 4855 return { 4856 component, 4857 el: input.el, 4858 useEventCenter: input.useEventCenter != null ? input.useEventCenter : true, 4859 isHitComboAllowed: input.isHitComboAllowed || null 4860 }; 4861} 4862function interactionSettingsToStore(settings) { 4863 return { 4864 [settings.component.uid]: settings 4865 }; 4866} 4867const interactionSettingsStore = {}; 4868class CalendarImpl { 4869 getCurrentData() { 4870 return this.currentDataManager.getCurrentData(); 4871 } 4872 dispatch(action) { 4873 this.currentDataManager.dispatch(action); 4874 } 4875 get view() { 4876 return this.getCurrentData().viewApi; 4877 } 4878 batchRendering(callback) { 4879 callback(); 4880 } 4881 updateSize() { 4882 this.trigger("_resize", true); 4883 } 4884 // Options 4885 // ----------------------------------------------------------------------------------------------------------------- 4886 setOption(name, val) { 4887 this.dispatch({ 4888 type: "SET_OPTION", 4889 optionName: name, 4890 rawOptionValue: val 4891 }); 4892 } 4893 getOption(name) { 4894 return this.currentDataManager.currentCalendarOptionsInput[name]; 4895 } 4896 getAvailableLocaleCodes() { 4897 return Object.keys(this.getCurrentData().availableRawLocales); 4898 } 4899 // Trigger 4900 // ----------------------------------------------------------------------------------------------------------------- 4901 on(handlerName, handler) { 4902 let { currentDataManager } = this; 4903 if (currentDataManager.currentCalendarOptionsRefiners[handlerName]) { 4904 currentDataManager.emitter.on(handlerName, handler); 4905 } else { 4906 console.warn(`Unknown listener name '${handlerName}'`); 4907 } 4908 } 4909 off(handlerName, handler) { 4910 this.currentDataManager.emitter.off(handlerName, handler); 4911 } 4912 // not meant for public use 4913 trigger(handlerName, ...args) { 4914 this.currentDataManager.emitter.trigger(handlerName, ...args); 4915 } 4916 // View 4917 // ----------------------------------------------------------------------------------------------------------------- 4918 changeView(viewType, dateOrRange) { 4919 this.batchRendering(() => { 4920 this.unselect(); 4921 if (dateOrRange) { 4922 if (dateOrRange.start && dateOrRange.end) { 4923 this.dispatch({ 4924 type: "CHANGE_VIEW_TYPE", 4925 viewType 4926 }); 4927 this.dispatch({ 4928 type: "SET_OPTION", 4929 optionName: "visibleRange", 4930 rawOptionValue: dateOrRange 4931 }); 4932 } else { 4933 let { dateEnv } = this.getCurrentData(); 4934 this.dispatch({ 4935 type: "CHANGE_VIEW_TYPE", 4936 viewType, 4937 dateMarker: dateEnv.createMarker(dateOrRange) 4938 }); 4939 } 4940 } else { 4941 this.dispatch({ 4942 type: "CHANGE_VIEW_TYPE", 4943 viewType 4944 }); 4945 } 4946 }); 4947 }
4948 // Forces navigation to a view for the given date. 4949 // `viewType` can be a specific view name or a generic one like "week" or "day". 4950 // needs to change 4951 zoomTo(dateMarker, viewType) { 4952 let state = this.getCurrentData(); 4953 let spec; 4954 viewType = viewType || "day"; 4955 spec = state.viewSpecs[viewType] || this.getUnitViewSpec(viewType); 4956 this.unselect(); 4957 if (spec) { 4958 this.dispatch({ 4959 type: "CHANGE_VIEW_TYPE", 4960 viewType: spec.type, 4961 dateMarker 4962 }); 4963 } else { 4964 this.dispatch({ 4965 type: "CHANGE_DATE", 4966 dateMarker 4967 }); 4968 } 4969 } 4970 // Given a duration singular unit, like "week" or "day", finds a matching view spec. 4971 // Preference is given to views that have corresponding buttons. 4972 getUnitViewSpec(unit) { 4973 let { viewSpecs, toolbarConfig } = this.getCurrentData(); 4974 let viewTypes = [].concat(toolbarConfig.header ? toolbarConfig.header.viewsWithButtons : [], toolbarConfig.footer ? toolbarConfig.footer.viewsWithButtons : []); 4975 let i2; 4976 let spec; 4977 for (let viewType in viewSpecs) { 4978 viewTypes.push(viewType); 4979 } 4980 for (i2 = 0; i2 < viewTypes.length; i2 += 1) { 4981 spec = viewSpecs[viewTypes[i2]]; 4982 if (spec) { 4983 if (spec.singleUnit === unit) { 4984 return spec; 4985 } 4986 } 4987 } 4988 return null; 4989 } 4990 // Current Date 4991 // ----------------------------------------------------------------------------------------------------------------- 4992 prev() { 4993 this.unselect(); 4994 this.dispatch({ type: "PREV" }); 4995 } 4996 next() { 4997 this.unselect(); 4998 this.dispatch({ type: "NEXT" }); 4999 } 5000 prevYear() { 5001 let state = this.getCurrentData(); 5002 this.unselect(); 5003 this.dispatch({ 5004 type: "CHANGE_DATE", 5005 dateMarker: state.dateEnv.addYears(state.currentDate, -1) 5006 }); 5007 } 5008 nextYear() { 5009 let state = this.getCurrentData(); 5010 this.unselect(); 5011 this.dispatch({ 5012 type: "CHANGE_DATE", 5013 dateMarker: state.dateEnv.addYears(state.currentDate, 1) 5014 }); 5015 } 5016 today() { 5017 let state = this.getCurrentData(); 5018 this.unselect(); 5019 this.dispatch({ 5020 type: "CHANGE_DATE", 5021 dateMarker: getNow(state.calendarOptions.now, state.dateEnv) 5022 }); 5023 } 5024 gotoDate(zonedDateInput) { 5025 let state = this.getCurrentData(); 5026 this.unselect(); 5027 this.dispatch({ 5028 type: "CHANGE_DATE", 5029 dateMarker: state.dateEnv.createMarker(zonedDateInput) 5030 }); 5031 } 5032 incrementDate(deltaInput) { 5033 let state = this.getCurrentData(); 5034 let delta = createDuration(deltaInput); 5035 if (delta) { 5036 this.unselect(); 5037 this.dispatch({ 5038 type: "CHANGE_DATE", 5039 dateMarker: state.dateEnv.add(state.currentDate, delta) 5040 }); 5041 } 5042 } 5043 getDate() { 5044 let state = this.getCurrentData(); 5045 return state.dateEnv.toDate(state.currentDate); 5046 } 5047 // Date Formatting Utils 5048 // ----------------------------------------------------------------------------------------------------------------- 5049 formatDate(d2, formatter) { 5050 let { dateEnv } = this.getCurrentData(); 5051 return dateEnv.format(dateEnv.createMarker(d2), createFormatter(formatter)); 5052 } 5053 // `settings` is for formatter AND isEndExclusive 5054 formatRange(d0, d1, settings) { 5055 let { dateEnv } = this.getCurrentData(); 5056 return dateEnv.formatRange(dateEnv.createMarker(d0), dateEnv.createMarker(d1), createFormatter(settings), settings); 5057 } 5058 formatIso(d2, omitTime) { 5059 let { dateEnv } = this.getCurrentData(); 5060 return dateEnv.formatIso(dateEnv.createMarker(d2), { omitTime }); 5061 } 5062 // Date Selection / Event Selection / DayClick 5063 // ----------------------------------------------------------------------------------------------------------------- 5064 select(dateOrObj, endDate) { 5065 let selectionInput; 5066 if (endDate == null) { 5067 if (dateOrObj.start != null) { 5068 selectionInput = dateOrObj; 5069 } else { 5070 selectionInput = { 5071 start: dateOrObj, 5072 end: null 5073 }; 5074 } 5075 } else { 5076 selectionInput = { 5077 start: dateOrObj, 5078 end: endDate 5079 }; 5080 } 5081 let state = this.getCurrentData(); 5082 let selection = parseDateSpan(selectionInput, state.dateEnv, createDuration({ days: 1 })); 5083 if (selection) { 5084 this.dispatch({ type: "SELECT_DATES", selection }); 5085 triggerDateSelect(selection, null, state); 5086 } 5087 } 5088 unselect(pev) { 5089 let state = this.getCurrentData(); 5090 if (state.dateSelection) { 5091 this.dispatch({ type: "UNSELECT_DATES" }); 5092 triggerDateUnselect(pev, state); 5093 } 5094 } 5095 // Public Events API 5096 // -----------------------------------------------------------------------------------------------------------------
vendor: 2,411 bytes, lines 5097-5174
5097 addEvent(eventInput, sourceInput) { 5098 if (eventInput instanceof EventImpl) { 5099 let def = eventInput._def; 5100 let instance = eventInput._instance; 5101 let currentData = this.getCurrentData(); 5102 if (!currentData.eventStore.defs[def.defId]) { 5103 this.dispatch({ 5104 type: "ADD_EVENTS", 5105 eventStore: eventTupleToStore({ def, instance }) 5106 // TODO: better util for two args? 5107 }); 5108 this.triggerEventAdd(eventInput); 5109 } 5110 return eventInput; 5111 } 5112 let state = this.getCurrentData(); 5113 let eventSource; 5114 if (sourceInput instanceof EventSourceImpl) { 5115 eventSource = sourceInput.internalEventSource; 5116 } else if (typeof sourceInput === "boolean") { 5117 if (sourceInput) { 5118 [eventSource] = hashValuesToArray(state.eventSources); 5119 } 5120 } else if (sourceInput != null) { 5121 let sourceApi = this.getEventSourceById(sourceInput); 5122 if (!sourceApi) { 5123 console.warn(`Could not find an event source with ID "${sourceInput}"`); 5124 return null; 5125 } 5126 eventSource = sourceApi.internalEventSource; 5127 } 5128 let tuple = parseEvent(eventInput, eventSource, state, false); 5129 if (tuple) { 5130 let newEventApi = new EventImpl(state, tuple.def, tuple.def.recurringDef ? null : tuple.instance); 5131 this.dispatch({ 5132 type: "ADD_EVENTS", 5133 eventStore: eventTupleToStore(tuple) 5134 }); 5135 this.triggerEventAdd(newEventApi); 5136 return newEventApi; 5137 } 5138 return null; 5139 } 5140 triggerEventAdd(eventApi) { 5141 let { emitter } = this.getCurrentData(); 5142 emitter.trigger("eventAdd", { 5143 event: eventApi, 5144 relatedEvents: [], 5145 revert: () => { 5146 this.dispatch({ 5147 type: "REMOVE_EVENTS", 5148 eventStore: eventApiToStore(eventApi) 5149 }); 5150 } 5151 }); 5152 } 5153 // TODO: optimize 5154 getEventById(id) { 5155 let state = this.getCurrentData(); 5156 let { defs, instances } = state.eventStore; 5157 id = String(id); 5158 for (let defId in defs) { 5159 let def = defs[defId]; 5160 if (def.publicId === id) { 5161 if (def.recurringDef) { 5162 return new EventImpl(state, def, null); 5163 } 5164 for (let instanceId in instances) { 5165 let instance = instances[instanceId]; 5166 if (instance.defId === def.defId) { 5167 return new EventImpl(state, def, instance); 5168 } 5169 } 5170 } 5171 } 5172 return null; 5173 } 5174 getEvents() {
5175 let currentData = this.getCurrentData(); 5176 return buildEventApis(currentData.eventStore, currentData); 5177 } 5178 removeAllEvents() { 5179 this.dispatch({ type: "REMOVE_ALL_EVENTS" }); 5180 } 5181 // Public Event Sources API 5182 // ----------------------------------------------------------------------------------------------------------------- 5183 getEventSources() { 5184 let state = this.getCurrentData(); 5185 let sourceHash = state.eventSources; 5186 let sourceApis = []; 5187 for (let internalId in sourceHash) { 5188 sourceApis.push(new EventSourceImpl(state, sourceHash[internalId])); 5189 } 5190 return sourceApis; 5191 } 5192 getEventSourceById(id) { 5193 let state = this.getCurrentData(); 5194 let sourceHash = state.eventSources; 5195 id = String(id); 5196 for (let sourceId in sourceHash) { 5197 if (sourceHash[sourceId].publicId === id) { 5198 return new EventSourceImpl(state, sourceHash[sourceId]); 5199 } 5200 } 5201 return null; 5202 } 5203 addEventSource(sourceInput) { 5204 let state = this.getCurrentData(); 5205 if (sourceInput instanceof EventSourceImpl) { 5206 if (!state.eventSources[sourceInput.internalEventSource.sourceId]) { 5207 this.dispatch({ 5208 type: "ADD_EVENT_SOURCES", 5209 sources: [sourceInput.internalEventSource] 5210 }); 5211 } 5212 return sourceInput; 5213 } 5214 let eventSource = parseEventSource(sourceInput, state); 5215 if (eventSource) { 5216 this.dispatch({ type: "ADD_EVENT_SOURCES", sources: [eventSource] }); 5217 return new EventSourceImpl(state, eventSource); 5218 } 5219 return null; 5220 } 5221 removeAllEventSources() { 5222 this.dispatch({ type: "REMOVE_ALL_EVENT_SOURCES" }); 5223 } 5224 refetchEvents() { 5225 this.dispatch({ type: "FETCH_EVENT_SOURCES", isRefetch: true }); 5226 } 5227 // Scroll 5228 // ----------------------------------------------------------------------------------------------------------------- 5229 scrollToTime(timeInput) { 5230 let time = createDuration(timeInput); 5231 if (time) { 5232 this.trigger("_scrollRequest", { time }); 5233 } 5234 } 5235} 5236function pointInsideRect(point, rect) { 5237 return point.left >= rect.left && point.left < rect.right && point.top >= rect.top && point.top < rect.bottom; 5238} 5239function intersectRects(rect1, rect2) { 5240 let res = { 5241 left: Math.max(rect1.left, rect2.left), 5242 right: Math.min(rect1.right, rect2.right), 5243 top: Math.max(rect1.top, rect2.top), 5244 bottom: Math.min(rect1.bottom, rect2.bottom) 5245 }; 5246 if (res.left < res.right && res.top < res.bottom) { 5247 return res; 5248 } 5249 return false; 5250} 5251function translateRect(rect, deltaX, deltaY) { 5252 return { 5253 left: rect.left + deltaX, 5254 right: rect.right + deltaX, 5255 top: rect.top + deltaY, 5256 bottom: rect.bottom + deltaY 5257 }; 5258} 5259function constrainPoint(point, rect) { 5260 return { 5261 left: Math.min(Math.max(point.left, rect.left), rect.right), 5262 top: Math.min(Math.max(point.top, rect.top), rect.bottom) 5263 }; 5264} 5265function getRectCenter(rect) { 5266 return { 5267 left: (rect.left + rect.right) / 2, 5268 top: (rect.top + rect.bottom) / 2 5269 }; 5270} 5271function diffPoints(point1, point2) { 5272 return { 5273 left: point1.left - point2.left, 5274 top: point1.top - point2.top 5275 }; 5276} 5277const EMPTY_EVENT_STORE = createEmptyEventStore(); 5278class Splitter { 5279 constructor() { 5280 this.getKeysForEventDefs = memoize(this._getKeysForEventDefs); 5281 this.splitDateSelection = memoize(this._splitDateSpan); 5282 this.splitEventStore = memoize(this._splitEventStore); 5283 this.splitIndividualUi = memoize(this._splitIndividualUi); 5284 this.splitEventDrag = memoize(this._splitInteraction); 5285 this.splitEventResize = memoize(this._splitInteraction); 5286 this.eventUiBuilders = {}; 5287 } 5288 splitProps(props) { 5289 let keyInfos = this.getKeyInfo(props); 5290 let defKeys = this.getKeysForEventDefs(props.eventStore); 5291 let dateSelections = this.splitDateSelection(props.dateSelection); 5292 let individualUi = this.splitIndividualUi(props.eventUiBases, defKeys); 5293 let eventStores = this.splitEventStore(props.eventStore, defKeys); 5294 let eventDrags = this.splitEventDrag(props.eventDrag); 5295 let eventResizes = this.splitEventResize(props.eventResize); 5296 let splitProps = {}; 5297 this.eventUiBuilders = mapHash(keyInfos, (info, key) => this.eventUiBuilders[key] || memoize(buildEventUiForKey)); 5298 for (let key in keyInfos) { 5299 let keyInfo = keyInfos[key]; 5300 let eventStore = eventStores[key] || EMPTY_EVENT_STORE; 5301 let buildEventUi = this.eventUiBuilders[key]; 5302 splitProps[key] = { 5303 businessHours: keyInfo.businessHours || props.businessHours, 5304 dateSelection: dateSelections[key] || null, 5305 eventStore, 5306 eventUiBases: buildEventUi(props.eventUiBases[""], keyInfo.ui, individualUi[key]), 5307 eventSelection: eventStore.instances[props.eventSelection] ? props.eventSelection : "", 5308 eventDrag: eventDrags[key] || null, 5309 eventResize: eventResizes[key] || null 5310 }; 5311 } 5312 return splitProps; 5313 } 5314 _splitDateSpan(dateSpan) { 5315 let dateSpans = {}; 5316 if (dateSpan) {
5317 let keys = this.getKeysForDateSpan(dateSpan); 5318 for (let key of keys) { 5319 dateSpans[key] = dateSpan; 5320 } 5321 } 5322 return dateSpans; 5323 } 5324 _getKeysForEventDefs(eventStore) { 5325 return mapHash(eventStore.defs, (eventDef) => this.getKeysForEventDef(eventDef)); 5326 } 5327 _splitEventStore(eventStore, defKeys) { 5328 let { defs, instances } = eventStore; 5329 let splitStores = {}; 5330 for (let defId in defs) { 5331 for (let key of defKeys[defId]) { 5332 if (!splitStores[key]) { 5333 splitStores[key] = createEmptyEventStore(); 5334 } 5335 splitStores[key].defs[defId] = defs[defId]; 5336 } 5337 } 5338 for (let instanceId in instances) { 5339 let instance = instances[instanceId]; 5340 for (let key of defKeys[instance.defId]) { 5341 if (splitStores[key]) { 5342 splitStores[key].instances[instanceId] = instance; 5343 } 5344 } 5345 } 5346 return splitStores; 5347 } 5348 _splitIndividualUi(eventUiBases, defKeys) { 5349 let splitHashes = {}; 5350 for (let defId in eventUiBases) { 5351 if (defId) { 5352 for (let key of defKeys[defId]) { 5353 if (!splitHashes[key]) { 5354 splitHashes[key] = {}; 5355 } 5356 splitHashes[key][defId] = eventUiBases[defId]; 5357 } 5358 } 5359 } 5360 return splitHashes; 5361 } 5362 _splitInteraction(interaction) { 5363 let splitStates = {}; 5364 if (interaction) { 5365 let affectedStores = this._splitEventStore(interaction.affectedEvents, this._getKeysForEventDefs(interaction.affectedEvents)); 5366 let mutatedKeysByDefId = this._getKeysForEventDefs(interaction.mutatedEvents); 5367 let mutatedStores = this._splitEventStore(interaction.mutatedEvents, mutatedKeysByDefId); 5368 let populate = (key) => { 5369 if (!splitStates[key]) { 5370 splitStates[key] = { 5371 affectedEvents: affectedStores[key] || EMPTY_EVENT_STORE, 5372 mutatedEvents: mutatedStores[key] || EMPTY_EVENT_STORE, 5373 isEvent: interaction.isEvent 5374 }; 5375 } 5376 }; 5377 for (let key in affectedStores) { 5378 populate(key); 5379 } 5380 for (let key in mutatedStores) { 5381 populate(key); 5382 } 5383 } 5384 return splitStates; 5385 } 5386} 5387function buildEventUiForKey(allUi, eventUiForKey, individualUi) { 5388 let baseParts = []; 5389 if (allUi) { 5390 baseParts.push(allUi); 5391 } 5392 if (eventUiForKey) { 5393 baseParts.push(eventUiForKey); 5394 } 5395 let stuff = { 5396 "": combineEventUis(baseParts) 5397 }; 5398 if (individualUi) { 5399 Object.assign(stuff, individualUi); 5400 } 5401 return stuff; 5402} 5403function getDateMeta(date, todayRange, nowDate, dateProfile) { 5404 return { 5405 dow: date.getUTCDay(), 5406 isDisabled: Boolean(dateProfile && !rangeContainsMarker(dateProfile.activeRange, date)), 5407 isOther: Boolean(dateProfile && !rangeContainsMarker(dateProfile.currentRange, date)), 5408 isToday: Boolean(todayRange && rangeContainsMarker(todayRange, date)), 5409 isPast: Boolean(nowDate ? date < nowDate : todayRange ? date < todayRange.start : false), 5410 isFuture: Boolean(nowDate ? date > nowDate : todayRange ? date >= todayRange.end : false) 5411 }; 5412} 5413function getDayClassNames(meta, theme) { 5414 let classNames = [ 5415 "fc-day", 5416 `fc-day-${DAY_IDS[meta.dow]}` 5417 ]; 5418 if (meta.isDisabled) { 5419 classNames.push("fc-day-disabled"); 5420 } else { 5421 if (meta.isToday) { 5422 classNames.push("fc-day-today"); 5423 classNames.push(theme.getClass("today")); 5424 } 5425 if (meta.isPast) { 5426 classNames.push("fc-day-past"); 5427 } 5428 if (meta.isFuture) { 5429 classNames.push("fc-day-future"); 5430 } 5431 if (meta.isOther) { 5432 classNames.push("fc-day-other"); 5433 } 5434 } 5435 return classNames; 5436} 5437function getSlotClassNames(meta, theme) { 5438 let classNames = [ 5439 "fc-slot", 5440 `fc-slot-${DAY_IDS[meta.dow]}` 5441 ]; 5442 if (meta.isDisabled) { 5443 classNames.push("fc-slot-disabled"); 5444 } else { 5445 if (meta.isToday) { 5446 classNames.push("fc-slot-today"); 5447 classNames.push(theme.getClass("today")); 5448 } 5449 if (meta.isPast) { 5450 classNames.push("fc-slot-past"); 5451 } 5452 if (meta.isFuture) { 5453 classNames.push("fc-slot-future"); 5454 } 5455 } 5456 return classNames; 5457} 5458const DAY_FORMAT = createFormatter({ year: "numeric", month: "long", day: "
5458numeric" }); 5459const WEEK_FORMAT = createFormatter({ week: "long" }); 5460function buildNavLinkAttrs(context, dateMarker, viewType = "day", isTabbable = true) { 5461 const { dateEnv, options, calendarApi } = context; 5462 let dateStr = dateEnv.format(dateMarker, viewType === "week" ? WEEK_FORMAT : DAY_FORMAT); 5463 if (options.navLinks) { 5464 let zonedDate = dateEnv.toDate(dateMarker); 5465 const handleInteraction = (ev) => { 5466 let customAction = viewType === "day" ? options.navLinkDayClick : viewType === "week" ? options.navLinkWeekClick : null; 5467 if (typeof customAction === "function") { 5468 customAction.call(calendarApi, dateEnv.toDate(dateMarker), ev); 5469 } else { 5470 if (typeof customAction === "string") { 5471 viewType = customAction; 5472 } 5473 calendarApi.zoomTo(dateMarker, viewType); 5474 } 5475 }; 5476 return Object.assign({ title: formatWithOrdinals(options.navLinkHint, [dateStr, zonedDate], dateStr), "data-navlink": "" }, isTabbable ? createAriaClickAttrs(handleInteraction) : { onClick: handleInteraction }); 5477 } 5478 return { "aria-label": dateStr }; 5479} 5480let _isRtlScrollbarOnLeft = null; 5481function getIsRtlScrollbarOnLeft() { 5482 if (_isRtlScrollbarOnLeft === null) { 5483 _isRtlScrollbarOnLeft = computeIsRtlScrollbarOnLeft(); 5484 } 5485 return _isRtlScrollbarOnLeft; 5486} 5487function computeIsRtlScrollbarOnLeft() { 5488 let outerEl = document.createElement("div"); 5489 applyStyle(outerEl, { 5490 position: "absolute", 5491 top: -1e3, 5492 left: 0, 5493 border: 0, 5494 padding: 0, 5495 overflow: "scroll", 5496 direction: "rtl" 5497 }); 5498 outerEl.innerHTML = "<div></div>"; 5499 document.body.appendChild(outerEl); 5500 let innerEl = outerEl.firstChild; 5501 let res = innerEl.getBoundingClientRect().left > outerEl.getBoundingClientRect().left; 5502 removeElement(outerEl); 5503 return res; 5504} 5505let _scrollbarWidths; 5506function getScrollbarWidths() { 5507 if (!_scrollbarWidths) { 5508 _scrollbarWidths = computeScrollbarWidths(); 5509 } 5510 return _scrollbarWidths; 5511} 5512function computeScrollbarWidths() { 5513 let el = document.createElement("div"); 5514 el.style.overflow = "scroll"; 5515 el.style.position = "absolute"; 5516 el.style.top = "-9999px"; 5517 el.style.left = "-9999px"; 5518 document.body.appendChild(el); 5519 let res = computeScrollbarWidthsForEl(el); 5520 document.body.removeChild(el); 5521 return res; 5522} 5523function computeScrollbarWidthsForEl(el) { 5524 return { 5525 x: el.offsetHeight - el.clientHeight, 5526 y: el.offsetWidth - el.clientWidth 5527 }; 5528} 5529function computeEdges(el, getPadding = false) { 5530 let computedStyle = window.getComputedStyle(el); 5531 let borderLeft = parseInt(computedStyle.borderLeftWidth, 10) || 0; 5532 let borderRight = parseInt(computedStyle.borderRightWidth, 10) || 0; 5533 let borderTop = parseInt(computedStyle.borderTopWidth, 10) || 0; 5534 let borderBottom = parseInt(computedStyle.borderBottomWidth, 10) || 0; 5535 let badScrollbarWidths = computeScrollbarWidthsForEl(el); 5536 let scrollbarLeftRight = badScrollbarWidths.y - borderLeft - borderRight; 5537 let scrollbarBottom = badScrollbarWidths.x - borderTop - borderBottom; 5538 let res = { 5539 borderLeft, 5540 borderRight, 5541 borderTop, 5542 borderBottom, 5543 scrollbarBottom, 5544 scrollbarLeft: 0, 5545 scrollbarRight: 0 5546 }; 5547 if (getIsRtlScrollbarOnLeft() && computedStyle.direction === "rtl") { 5548 res.scrollbarLeft = scrollbarLeftRight; 5549 } else { 5550 res.scrollbarRight = scrollbarLeftRight; 5551 } 5552 if (getPadding) { 5553 res.paddingLeft = parseInt(computedStyle.paddingLeft, 10) || 0; 5554 res.paddingRight = parseInt(computedStyle.paddingRight, 10) || 0; 5555 res.paddingTop = parseInt(computedStyle.paddingTop, 10) || 0; 5556 res.paddingBottom = parseInt(computedStyle.paddingBottom, 10) || 0; 5557 } 5558 return res; 5559} 5560function computeInnerRect(el, goWithinPadding = false, doFromWindowViewport) { 5561 let outerRect = doFromWindowViewport ? el.getBoundingClientRect() : computeRect(el); 5562 let edges = computeEdges(el, goWithinPadding); 5563 let res = { 5564 left: outerRect.left + edges.borderLeft + edges.scrollbarLeft, 5565 right: outerRect.right - edges.borderRight - edges.scrollbarRight, 5566 top: outerRect.top + edges.borderTop, 5567 bottom: outerRect.bottom - edges.borderBottom - edges.scrollbarBottom 5568 }; 5569 if (goWithinPadding) { 5570 res.left += edges.paddingLeft; 5571 res.right -= edges.paddingRight; 5572 res.top += edges.paddingTop; 5573 res.bottom -= edges.paddingBottom; 5574 } 5575 return res; 5576} 5577function computeRect(el) { 5578 let rect = el.getBoundingClientRect(); 5579 return { 5580 left: rect.left + window.scrollX, 5581 top: rect.top + window.scrollY, 5582 right: rect.right + window.scrollX, 5583 bottom: rect.bottom + window.scrollY 5584 }; 5585} 5586function computeClippedClientRect(el) { 5587 let clippingParents = getClippingParents(el); 5588 let rect = el.getBoundingClientRect(); 5589 for (let clippingParent of clippingParents) { 5590 let intersection = intersectRects(rect, clippingParent.getBoundingClientRect()); 5591 if (intersection) { 5592 rect = intersection; 5593 } else { 5594 return null; 5595 } 5596 } 5597 return rect; 5598} 5599function getClippingParents(el) { 5600 let parents = []; 5601 while (el instanceof HTMLElement) {
vendor: 8,442 bytes, lines 5602-5881
5602 let computedStyle = window.getComputedStyle(el); 5603 if (computedStyle.position === "fixed") { 5604 break; 5605 } 5606 if (/(auto|scroll)/.test(computedStyle.overflow + computedStyle.overflowY + computedStyle.overflowX)) { 5607 parents.push(el); 5608 } 5609 el = el.parentNode; 5610 } 5611 return parents; 5612} 5613class PositionCache { 5614 constructor(originEl, els, isHorizontal, isVertical) { 5615 this.els = els; 5616 let originClientRect = this.originClientRect = originEl.getBoundingClientRect(); 5617 if (isHorizontal) { 5618 this.buildElHorizontals(originClientRect.left); 5619 } 5620 if (isVertical) { 5621 this.buildElVerticals(originClientRect.top); 5622 } 5623 } 5624 // Populates the left/right internal coordinate arrays 5625 buildElHorizontals(originClientLeft) { 5626 let lefts = []; 5627 let rights = []; 5628 for (let el of this.els) { 5629 let rect = el.getBoundingClientRect(); 5630 lefts.push(rect.left - originClientLeft); 5631 rights.push(rect.right - originClientLeft); 5632 } 5633 this.lefts = lefts; 5634 this.rights = rights; 5635 } 5636 // Populates the top/bottom internal coordinate arrays 5637 buildElVerticals(originClientTop) { 5638 let tops = []; 5639 let bottoms = []; 5640 for (let el of this.els) { 5641 let rect = el.getBoundingClientRect(); 5642 tops.push(rect.top - originClientTop); 5643 bottoms.push(rect.bottom - originClientTop); 5644 } 5645 this.tops = tops; 5646 this.bottoms = bottoms; 5647 } 5648 // Given a left offset (from document left), returns the index of the el that it horizontally intersects. 5649 // If no intersection is made, returns undefined. 5650 leftToIndex(leftPosition) { 5651 let { lefts, rights } = this; 5652 let len = lefts.length; 5653 let i2; 5654 for (i2 = 0; i2 < len; i2 += 1) { 5655 if (leftPosition >= lefts[i2] && leftPosition < rights[i2]) { 5656 return i2; 5657 } 5658 } 5659 return void 0; 5660 } 5661 // Given a top offset (from document top), returns the index of the el that it vertically intersects. 5662 // If no intersection is made, returns undefined. 5663 topToIndex(topPosition) { 5664 let { tops, bottoms } = this; 5665 let len = tops.length; 5666 let i2; 5667 for (i2 = 0; i2 < len; i2 += 1) { 5668 if (topPosition >= tops[i2] && topPosition < bottoms[i2]) { 5669 return i2; 5670 } 5671 } 5672 return void 0; 5673 } 5674 // Gets the width of the element at the given index 5675 getWidth(leftIndex) { 5676 return this.rights[leftIndex] - this.lefts[leftIndex]; 5677 } 5678 // Gets the height of the element at the given index 5679 getHeight(topIndex) { 5680 return this.bottoms[topIndex] - this.tops[topIndex]; 5681 } 5682 similarTo(otherCache) { 5683 return similarNumArrays(this.tops || [], otherCache.tops || []) && similarNumArrays(this.bottoms || [], otherCache.bottoms || []) && similarNumArrays(this.lefts || [], otherCache.lefts || []) && similarNumArrays(this.rights || [], otherCache.rights || []); 5684 } 5685} 5686function similarNumArrays(a2, b2) { 5687 const len = a2.length; 5688 if (len !== b2.length) { 5689 return false; 5690 } 5691 for (let i2 = 0; i2 < len; i2++) { 5692 if (Math.round(a2[i2]) !== Math.round(b2[i2])) { 5693 return false; 5694 } 5695 } 5696 return true; 5697} 5698class ScrollController { 5699 getMaxScrollTop() { 5700 return this.getScrollHeight() - this.getClientHeight(); 5701 } 5702 getMaxScrollLeft() { 5703 return this.getScrollWidth() - this.getClientWidth(); 5704 } 5705 canScrollVertically() { 5706 return this.getMaxScrollTop() > 0; 5707 } 5708 canScrollHorizontally() { 5709 return this.getMaxScrollLeft() > 0; 5710 } 5711 canScrollUp() { 5712 return this.getScrollTop() > 0; 5713 } 5714 canScrollDown() { 5715 return this.getScrollTop() < this.getMaxScrollTop(); 5716 } 5717 canScrollLeft() { 5718 return this.getScrollLeft() > 0; 5719 } 5720 canScrollRight() { 5721 return this.getScrollLeft() < this.getMaxScrollLeft(); 5722 } 5723} 5724class ElementScrollController extends ScrollController { 5725 constructor(el) { 5726 super(); 5727 this.el = el; 5728 } 5729 getScrollTop() { 5730 return this.el.scrollTop; 5731 } 5732 getScrollLeft() { 5733 return this.el.scrollLeft; 5734 } 5735 setScrollTop(top) { 5736 this.el.scrollTop = top; 5737 } 5738 setScrollLeft(left) { 5739 this.el.scrollLeft = left; 5740 } 5741 getScrollWidth() { 5742 return this.el.scrollWidth; 5743 } 5744 getScrollHeight() { 5745 return this.el.scrollHeight; 5746 } 5747 getClientHeight() { 5748 return this.el.clientHeight; 5749 } 5750 getClientWidth() { 5751 return this.el.clientWidth; 5752 } 5753} 5754class WindowScrollController extends ScrollController { 5755 getScrollTop() { 5756 return window.scrollY; 5757 } 5758 getScrollLeft() { 5759 return window.scrollX; 5760 } 5761 setScrollTop(n2) { 5762 window.scroll(window.scrollX, n2); 5763 } 5764 setScrollLeft(n2) { 5765 window.scroll(n2, window.scrollY); 5766 } 5767 getScrollWidth() { 5768 return document.documentElement.scrollWidth; 5769 } 5770 getScrollHeight() { 5771 return document.documentElement.scrollHeight; 5772 } 5773 getClientHeight() { 5774 return document.documentElement.clientHeight; 5775 } 5776 getClientWidth() { 5777 return document.documentElement.clientWidth; 5778 } 5779} 5780class DateComponent extends BaseComponent { 5781 constructor() { 5782 super(...arguments); 5783 this.uid = guid(); 5784 } 5785 // Hit System 5786 // ----------------------------------------------------------------------------------------------------------------- 5787 prepareHits() { 5788 } 5789 queryHit(positionLeft, positionTop, elWidth, elHeight) { 5790 return null; 5791 } 5792 // Pointer Interaction Utils 5793 // ----------------------------------------------------------------------------------------------------------------- 5794 isValidSegDownEl(el) { 5795 return !this.props.eventDrag && // HACK 5796 !this.props.eventResize && // HACK 5797 !elementClosest(el, ".fc-event-mirror"); 5798 } 5799 isValidDateDownEl(el) { 5800 return !elementClosest(el, ".fc-event:not(.fc-bg-event)") && !elementClosest(el, ".fc-more-link") && // a "more.." link 5801 !elementClosest(el, "a[data-navlink]") && // a clickable nav link 5802 !elementClosest(el, ".fc-popover"); 5803 } 5804} 5805class SegHierarchy { 5806 constructor(getEntryThickness = (entry) => { 5807 return entry.thickness || 1; 5808 }) { 5809 this.getEntryThickness = getEntryThickness; 5810 this.strictOrder = false; 5811 this.allowReslicing = false; 5812 this.maxCoord = -1; 5813 this.maxStackCnt = -1; 5814 this.levelCoords = []; 5815 this.entriesByLevel = []; 5816 this.stackCnts = {}; 5817 } 5818 addSegs(inputs) { 5819 let hiddenEntries = []; 5820 for (let input of inputs) { 5821 this.insertEntry(input, hiddenEntries); 5822 } 5823 return hiddenEntries; 5824 } 5825 insertEntry(entry, hiddenEntries) { 5826 let insertion = this.findInsertion(entry); 5827 if (this.isInsertionValid(insertion, entry)) { 5828 this.insertEntryAt(entry, insertion); 5829 } else { 5830 this.handleInvalidInsertion(insertion, entry, hiddenEntries); 5831 } 5832 } 5833 isInsertionValid(insertion, entry) { 5834 return (this.maxCoord === -1 || insertion.levelCoord + this.getEntryThickness(entry) <= this.maxCoord) && (this.maxStackCnt === -1 || insertion.stackCnt < this.maxStackCnt); 5835 } 5836 handleInvalidInsertion(insertion, entry, hiddenEntries) { 5837 if (this.allowReslicing && insertion.touchingEntry) { 5838 const hiddenEntry = Object.assign(Object.assign({}, entry), { span: intersectSpans(entry.span, insertion.touchingEntry.span) }); 5839 hiddenEntries.push(hiddenEntry); 5840 this.splitEntry(entry, insertion.touchingEntry, hiddenEntries); 5841 } else { 5842 hiddenEntries.push(entry); 5843 } 5844 } 5845 /* 5846 Does NOT add what hit the `barrier` into hiddenEntries. Should already be done. 5847 */ 5848 splitEntry(entry, barrier, hiddenEntries) { 5849 let entrySpan = entry.span; 5850 let barrierSpan = barrier.span; 5851 if (entrySpan.start < barrierSpan.start) { 5852 this.insertEntry({ 5853 index: entry.index, 5854 thickness: entry.thickness, 5855 span: { start: entrySpan.start, end: barrierSpan.start } 5856 }, hiddenEntries); 5857 } 5858 if (entrySpan.end > barrierSpan.end) { 5859 this.insertEntry({ 5860 index: entry.index, 5861 thickness: entry.thickness, 5862 span: { start: barrierSpan.end, end: entrySpan.end } 5863 }, hiddenEntries); 5864 } 5865 } 5866 insertEntryAt(entry, insertion) { 5867 let { entriesByLevel, levelCoords } = this; 5868 if (insertion.lateral === -1) { 5869 insertAt(levelCoords, insertion.level, insertion.levelCoord); 5870 insertAt(entriesByLevel, insertion.level, [entry]); 5871 } else { 5872 insertAt(entriesByLevel[insertion.level], insertion.lateral, entry); 5873 } 5874 this.stackCnts[buildEntryKey(entry)] = insertion.stackCnt; 5875 } 5876 /* 5877 does not care about limits 5878 */ 5879 findInsertion(newEntry) { 5880 let { levelCoords, entriesByLevel, strictOrder, stackCnts } = this; 5881 let levelCnt = levelCoords.length;
5882 let candidateCoord = 0; 5883 let touchingLevel = -1; 5884 let touchingLateral = -1; 5885 let touchingEntry = null; 5886 let stackCnt = 0; 5887 for (let trackingLevel = 0; trackingLevel < levelCnt; trackingLevel += 1) { 5888 const trackingCoord = levelCoords[trackingLevel]; 5889 if (!strictOrder && trackingCoord >= candidateCoord + this.getEntryThickness(newEntry)) { 5890 break; 5891 } 5892 let trackingEntries = entriesByLevel[trackingLevel]; 5893 let trackingEntry; 5894 let searchRes = binarySearch(trackingEntries, newEntry.span.start, getEntrySpanEnd); 5895 let lateralIndex = searchRes[0] + searchRes[1]; 5896 while ( 5897 // loop through entries that horizontally intersect 5898 (trackingEntry = trackingEntries[lateralIndex]) && // but not past the whole entry list 5899 trackingEntry.span.start < newEntry.span.end 5900 ) { 5901 let trackingEntryBottom = trackingCoord + this.getEntryThickness(trackingEntry); 5902 if (trackingEntryBottom > candidateCoord) { 5903 candidateCoord = trackingEntryBottom; 5904 touchingEntry = trackingEntry; 5905 touchingLevel = trackingLevel; 5906 touchingLateral = lateralIndex; 5907 } 5908 if (trackingEntryBottom === candidateCoord) { 5909 stackCnt = Math.max(stackCnt, stackCnts[buildEntryKey(trackingEntry)] + 1); 5910 } 5911 lateralIndex += 1; 5912 } 5913 } 5914 let destLevel = 0; 5915 if (touchingEntry) { 5916 destLevel = touchingLevel + 1; 5917 while (destLevel < levelCnt && levelCoords[destLevel] < candidateCoord) { 5918 destLevel += 1; 5919 } 5920 } 5921 let destLateral = -1; 5922 if (destLevel < levelCnt && levelCoords[destLevel] === candidateCoord) { 5923 destLateral = binarySearch(entriesByLevel[destLevel], newEntry.span.end, getEntrySpanEnd)[0]; 5924 } 5925 return { 5926 touchingLevel, 5927 touchingLateral, 5928 touchingEntry, 5929 stackCnt, 5930 levelCoord: candidateCoord, 5931 level: destLevel, 5932 lateral: destLateral 5933 }; 5934 } 5935 // sorted by levelCoord (lowest to highest) 5936 toRects() { 5937 let { entriesByLevel, levelCoords } = this; 5938 let levelCnt = entriesByLevel.length; 5939 let rects = []; 5940 for (let level = 0; level < levelCnt; level += 1) { 5941 let entries = entriesByLevel[level]; 5942 let levelCoord = levelCoords[level]; 5943 for (let entry of entries) { 5944 rects.push(Object.assign(Object.assign({}, entry), { thickness: this.getEntryThickness(entry), levelCoord })); 5945 } 5946 } 5947 return rects; 5948 } 5949} 5950function getEntrySpanEnd(entry) { 5951 return entry.span.end; 5952} 5953function buildEntryKey(entry) { 5954 return entry.index + ":" + entry.span.start; 5955} 5956function groupIntersectingEntries(entries) { 5957 let merges = []; 5958 for (let entry of entries) { 5959 let filteredMerges = []; 5960 let hungryMerge = { 5961 span: entry.span, 5962 entries: [entry] 5963 }; 5964 for (let merge of merges) { 5965 if (intersectSpans(merge.span, hungryMerge.span)) { 5966 hungryMerge = { 5967 entries: merge.entries.concat(hungryMerge.entries), 5968 span: joinSpans(merge.span, hungryMerge.span) 5969 }; 5970 } else { 5971 filteredMerges.push(merge); 5972 } 5973 } 5974 filteredMerges.push(hungryMerge); 5975 merges = filteredMerges; 5976 } 5977 return merges; 5978} 5979function joinSpans(span0, span1) { 5980 return { 5981 start: Math.min(span0.start, span1.start), 5982 end: Math.max(span0.end, span1.end) 5983 }; 5984} 5985function intersectSpans(span0, span1) { 5986 let start = Math.max(span0.start, span1.start); 5987 let end = Math.min(span0.end, span1.end); 5988 if (start < end) { 5989 return { start, end }; 5990 } 5991 return null; 5992} 5993function insertAt(arr, index2, item) { 5994 arr.splice(index2, 0, item); 5995} 5996function binarySearch(a2, searchVal, getItemVal) { 5997 let startIndex = 0; 5998 let endIndex = a2.length; 5999 if (!endIndex || searchVal < getItemVal(a2[startIndex])) { 6000 return [0, 0]; 6001 } 6002 if (searchVal > getItemVal(a2[endIndex - 1])) { 6003 return [endIndex, 0]; 6004 } 6005 while (startIndex < endIndex) { 6006 let middleIndex = Math.floor(startIndex + (endIndex - startIndex) / 2); 6007 let middleVal = getItemVal(a2[middleIndex]); 6008 if (searchVal < middleVal) { 6009 endIndex = middleIndex; 6010 } else if (searchVal > middleVal) { 6011 startIndex = middleIndex + 1; 6012 } else { 6013 return [middleIndex, 1]; 6014 } 6015 } 6016 return [startIndex, 0]; 6017} 6018class ElementDragging { 6019 constructor(el, selector) { 6020 this.emitter = new Emitter(); 6021 } 6022 destroy() { 6023 } 6024 setMirrorIsVisible(bool) { 6025 } 6026 setMirrorNeedsRevert(bool) { 6027 } 6028 setAutoScrollEnabled(bool) { 6029 } 6030} 6031const config = {}; 6032function computeFallbackHeaderFormat(datesRepDistinctDays, dayCnt) { 6033 if (!datesRepDistinctDays || dayCnt > 10) { 6034 return createFormatter({ weekday: "short" }); 6035 } 6036 if (dayCnt > 1) { 6037 return createFormatter({ weekday: "short", month: "numeric", day: "
6037numeric", omitCommas: true }); 6038 } 6039 return createFormatter({ weekday: "long" }); 6040} 6041const CLASS_NAME = "fc-col-header-cell"; 6042function renderInner$1(renderProps) { 6043 return renderProps.text; 6044} 6045class TableDateCell extends BaseComponent { 6046 render() { 6047 let { dateEnv, options, theme, viewApi } = this.context; 6048 let { props } = this; 6049 let { date, dateProfile } = props; 6050 let dayMeta = getDateMeta(date, props.todayRange, null, dateProfile); 6051 let classNames = [CLASS_NAME].concat(getDayClassNames(dayMeta, theme)); 6052 let text = dateEnv.format(date, props.dayHeaderFormat); 6053 let navLinkAttrs = !dayMeta.isDisabled && props.colCnt > 1 ? buildNavLinkAttrs(this.context, date) : {}; 6054 let renderProps = Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: viewApi }, props.extraRenderProps), { text }), dayMeta); 6055 return y(ContentContainer, { elTag: "th", elClasses: classNames, elAttrs: Object.assign({ role: "columnheader", colSpan: props.colSpan, "data-date": !dayMeta.isDisabled ? formatDayString(date) : void 0 }, props.extraDataAttrs), renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContainer) => y("div", { className: "fc-scrollgrid-sync-inner" }, !dayMeta.isDisabled && y(InnerContainer, { elTag: "a", elAttrs: navLinkAttrs, elClasses: [ 6056 "fc-col-header-cell-cushion", 6057 props.isSticky && "fc-sticky" 6058 ] }))); 6059 } 6060} 6061const WEEKDAY_FORMAT = createFormatter({ weekday: "long" }); 6062class TableDowCell extends BaseComponent { 6063 render() { 6064 let { props } = this; 6065 let { dateEnv, theme, viewApi, options } = this.context; 6066 let date = addDays(/* @__PURE__ */ new Date(2592e5), props.dow); 6067 let dateMeta = { 6068 dow: props.dow, 6069 isDisabled: false, 6070 isFuture: false, 6071 isPast: false, 6072 isToday: false, 6073 isOther: false 6074 }; 6075 let text = dateEnv.format(date, props.dayHeaderFormat); 6076 let renderProps = Object.assign(Object.assign(Object.assign(Object.assign({ 6077 // TODO: make this public? 6078 date 6079 }, dateMeta), { view: viewApi }), props.extraRenderProps), { text }); 6080 return y(ContentContainer, { elTag: "th", elClasses: [ 6081 CLASS_NAME, 6082 ...getDayClassNames(dateMeta, theme), 6083 ...props.extraClassNames || [] 6084 ], elAttrs: Object.assign({ role: "columnheader", colSpan: props.colSpan }, props.extraDataAttrs), renderProps, generatorName: "dayHeaderContent", customGenerator: options.dayHeaderContent, defaultGenerator: renderInner$1, classNameGenerator: options.dayHeaderClassNames, didMount: options.dayHeaderDidMount, willUnmount: options.dayHeaderWillUnmount }, (InnerContent) => y( 6085 "div", 6086 { className: "fc-scrollgrid-sync-inner" }, 6087 y(InnerContent, { elTag: "a", elClasses: [ 6088 "fc-col-header-cell-cushion", 6089 props.isSticky && "fc-sticky" 6090 ], elAttrs: { 6091 "aria-label": dateEnv.format(date, WEEKDAY_FORMAT) 6092 } }) 6093 )); 6094 } 6095} 6096class NowTimer extends x$1 { 6097 constructor(props, context) { 6098 super(props, context); 6099 this.initialNowDate = getNow(context.options.now, context.dateEnv); 6100 this.initialNowQueriedMs = (/* @__PURE__ */ new Date()).valueOf(); 6101 this.state = this.computeTiming().currentState; 6102 } 6103 render() { 6104 let { props, state } = this; 6105 return props.children(state.nowDate, state.todayRange); 6106 } 6107 componentDidMount() { 6108 this.setTimeout(); 6109 } 6110 componentDidUpdate(prevProps) { 6111 if (prevProps.unit !== this.props.unit) { 6112 this.clearTimeout(); 6113 this.setTimeout(); 6114 } 6115 } 6116 componentWillUnmount() { 6117 this.clearTimeout(); 6118 } 6119 computeTiming() { 6120 let { props, context } = this; 6121 let unroundedNow = addMs(this.initialNowDate, (/* @__PURE__ */ new Date()).valueOf() - this.initialNowQueriedMs); 6122 let currentUnitStart = context.dateEnv.startOf(unroundedNow, props.unit); 6123 let nextUnitStart = context.dateEnv.add(currentUnitStart, createDuration(1, props.unit)); 6124 let waitMs = nextUnitStart.valueOf() - unroundedNow.valueOf(); 6125 waitMs = Math.min(1e3 * 60 * 60 * 24, waitMs); 6126 return { 6127 currentState: { nowDate: currentUnitStart, todayRange: buildDayRange(currentUnitStart) }, 6128 nextState: { nowDate: nextUnitStart, todayRange: buildDayRange(nextUnitStart) }, 6129 waitMs 6130 }; 6131 } 6132 setTimeout() { 6133 let { nextState, waitMs } = this.computeTiming(); 6134 this.timeoutId = setTimeout(() => { 6135 this.setState(nextState, () => { 6136 this.setTimeout(); 6137 }); 6138 }, waitMs); 6139 } 6140 clearTimeout() { 6141 if (this.timeoutId) { 6142 clearTimeout(this.timeoutId); 6143 } 6144 } 6145} 6146NowTimer.contextType = ViewContextType; 6147function buildDayRange(date) { 6148 let start = startOfDay(date); 6149 let end = addDays(start, 1); 6150 return { start, end }; 6151} 6152class DayHeader extends BaseComponent { 6153 constructor() { 6154 super(...arguments); 6155 this.createDayHeaderFormatter = memoize(createDayHeaderFormatter); 6156 } 6157 render() { 6158 let { context } = this; 6159 let { dates, dateProfile, datesRepDistinctDays, renderIntro } = this.props; 6160 let dayHeaderFormat = this.createDayHeaderFormatter(context.options.dayHeaderFormat, datesRepDistinctDays, dates.length); 6161 return y(NowTimer, { unit: "day" }, (nowDate, todayRange) => y( 6162 "tr", 6163 { role: "row" }, 6164 renderIntro && renderIntro("day"), 6165 dates.map((date) => datesRepDistinctDays ? y(TableDateCell, { key: date.toISOString(), date, dateProfile, todayRange, colCnt: dates.length, dayHeaderFormat }) : y(TableDowCell, { key: date.getUTCDay(), dow: date.getUTCDay(), dayHeaderFormat })) 6166 )); 6167 } 6168} 6169function createDayHeaderFormatter(explicitFormat, datesRepDistinctDays, dateCnt) { 6170 return explicitFormat || computeFallbackHeaderFormat(datesRepDistinctDays, dateCnt); 6171}
vendor: 4,233 bytes, lines 6172-6306
6172class DaySeriesModel { 6173 constructor(range, dateProfileGenerator) { 6174 let date = range.start; 6175 let { end } = range; 6176 let indices = []; 6177 let dates = []; 6178 let dayIndex = -1; 6179 while (date < end) { 6180 if (dateProfileGenerator.isHiddenDay(date)) { 6181 indices.push(dayIndex + 0.5); 6182 } else { 6183 dayIndex += 1; 6184 indices.push(dayIndex); 6185 dates.push(date); 6186 } 6187 date = addDays(date, 1); 6188 } 6189 this.dates = dates; 6190 this.indices = indices; 6191 this.cnt = dates.length; 6192 } 6193 sliceRange(range) { 6194 let firstIndex = this.getDateDayIndex(range.start); 6195 let lastIndex = this.getDateDayIndex(addDays(range.end, -1)); 6196 let clippedFirstIndex = Math.max(0, firstIndex); 6197 let clippedLastIndex = Math.min(this.cnt - 1, lastIndex); 6198 clippedFirstIndex = Math.ceil(clippedFirstIndex); 6199 clippedLastIndex = Math.floor(clippedLastIndex); 6200 if (clippedFirstIndex <= clippedLastIndex) { 6201 return { 6202 firstIndex: clippedFirstIndex, 6203 lastIndex: clippedLastIndex, 6204 isStart: firstIndex === clippedFirstIndex, 6205 isEnd: lastIndex === clippedLastIndex 6206 }; 6207 } 6208 return null; 6209 } 6210 // Given a date, returns its chronolocial cell-index from the first cell of the grid. 6211 // If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets. 6212 // If before the first offset, returns a negative number. 6213 // If after the last offset, returns an offset past the last cell offset. 6214 // Only works for *start* dates of cells. Will not work for exclusive end dates for cells. 6215 getDateDayIndex(date) { 6216 let { indices } = this; 6217 let dayOffset = Math.floor(diffDays(this.dates[0], date)); 6218 if (dayOffset < 0) { 6219 return indices[0] - 1; 6220 } 6221 if (dayOffset >= indices.length) { 6222 return indices[indices.length - 1] + 1; 6223 } 6224 return indices[dayOffset]; 6225 } 6226} 6227class DayTableModel { 6228 constructor(daySeries, breakOnWeeks) { 6229 let { dates } = daySeries; 6230 let daysPerRow; 6231 let firstDay; 6232 let rowCnt; 6233 if (breakOnWeeks) { 6234 firstDay = dates[0].getUTCDay(); 6235 for (daysPerRow = 1; daysPerRow < dates.length; daysPerRow += 1) { 6236 if (dates[daysPerRow].getUTCDay() === firstDay) { 6237 break; 6238 } 6239 } 6240 rowCnt = Math.ceil(dates.length / daysPerRow); 6241 } else { 6242 rowCnt = 1; 6243 daysPerRow = dates.length; 6244 } 6245 this.rowCnt = rowCnt; 6246 this.colCnt = daysPerRow; 6247 this.daySeries = daySeries; 6248 this.cells = this.buildCells(); 6249 this.headerDates = this.buildHeaderDates(); 6250 } 6251 buildCells() { 6252 let rows = []; 6253 for (let row = 0; row < this.rowCnt; row += 1) { 6254 let cells = []; 6255 for (let col = 0; col < this.colCnt; col += 1) { 6256 cells.push(this.buildCell(row, col)); 6257 } 6258 rows.push(cells); 6259 } 6260 return rows; 6261 } 6262 buildCell(row, col) { 6263 let date = this.daySeries.dates[row * this.colCnt + col]; 6264 return { 6265 key: date.toISOString(), 6266 date 6267 }; 6268 } 6269 buildHeaderDates() { 6270 let dates = []; 6271 for (let col = 0; col < this.colCnt; col += 1) { 6272 dates.push(this.cells[0][col].date); 6273 } 6274 return dates; 6275 } 6276 sliceRange(range) { 6277 let { colCnt } = this; 6278 let seriesSeg = this.daySeries.sliceRange(range); 6279 let segs = []; 6280 if (seriesSeg) { 6281 let { firstIndex, lastIndex } = seriesSeg; 6282 let index2 = firstIndex; 6283 while (index2 <= lastIndex) { 6284 let row = Math.floor(index2 / colCnt); 6285 let nextIndex = Math.min((row + 1) * colCnt, lastIndex + 1); 6286 segs.push({ 6287 row, 6288 firstCol: index2 % colCnt, 6289 lastCol: (nextIndex - 1) % colCnt, 6290 isStart: seriesSeg.isStart && index2 === firstIndex, 6291 isEnd: seriesSeg.isEnd && nextIndex - 1 === lastIndex 6292 }); 6293 index2 = nextIndex; 6294 } 6295 } 6296 return segs; 6297 } 6298} 6299class Slicer { 6300 constructor() { 6301 this.sliceBusinessHours = memoize(this._sliceBusinessHours); 6302 this.sliceDateSelection = memoize(this._sliceDateSpan); 6303 this.sliceEventStore = memoize(this._sliceEventStore); 6304 this.sliceEventDrag = memoize(this._sliceInteraction); 6305 this.sliceEventResize = memoize(this._sliceInteraction); 6306 this.forceDayIfListItem = false;
6307 } 6308 sliceProps(props, dateProfile, nextDayThreshold, context, ...extraArgs) { 6309 let { eventUiBases } = props; 6310 let eventSegs = this.sliceEventStore(props.eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs); 6311 return { 6312 dateSelectionSegs: this.sliceDateSelection(props.dateSelection, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs), 6313 businessHourSegs: this.sliceBusinessHours(props.businessHours, dateProfile, nextDayThreshold, context, ...extraArgs), 6314 fgEventSegs: eventSegs.fg, 6315 bgEventSegs: eventSegs.bg, 6316 eventDrag: this.sliceEventDrag(props.eventDrag, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs), 6317 eventResize: this.sliceEventResize(props.eventResize, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs), 6318 eventSelection: props.eventSelection 6319 }; 6320 } 6321 sliceNowDate(date, dateProfile, nextDayThreshold, context, ...extraArgs) { 6322 return this._sliceDateSpan( 6323 { range: { start: date, end: addMs(date, 1) }, allDay: false }, 6324 // add 1 ms, protect against null range 6325 dateProfile, 6326 nextDayThreshold, 6327 {}, 6328 context, 6329 ...extraArgs 6330 ); 6331 } 6332 _sliceBusinessHours(businessHours, dateProfile, nextDayThreshold, context, ...extraArgs) { 6333 if (!businessHours) { 6334 return []; 6335 } 6336 return this._sliceEventStore(expandRecurring(businessHours, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), context), {}, dateProfile, nextDayThreshold, ...extraArgs).bg; 6337 } 6338 _sliceEventStore(eventStore, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) { 6339 if (eventStore) { 6340 let rangeRes = sliceEventStore(eventStore, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 6341 return { 6342 bg: this.sliceEventRanges(rangeRes.bg, extraArgs), 6343 fg: this.sliceEventRanges(rangeRes.fg, extraArgs) 6344 }; 6345 } 6346 return { bg: [], fg: [] }; 6347 } 6348 _sliceInteraction(interaction, eventUiBases, dateProfile, nextDayThreshold, ...extraArgs) { 6349 if (!interaction) { 6350 return null; 6351 } 6352 let rangeRes = sliceEventStore(interaction.mutatedEvents, eventUiBases, computeActiveRange(dateProfile, Boolean(nextDayThreshold)), nextDayThreshold); 6353 return { 6354 segs: this.sliceEventRanges(rangeRes.fg, extraArgs), 6355 affectedInstances: interaction.affectedEvents.instances, 6356 isEvent: interaction.isEvent 6357 }; 6358 } 6359 _sliceDateSpan(dateSpan, dateProfile, nextDayThreshold, eventUiBases, context, ...extraArgs) { 6360 if (!dateSpan) { 6361 return []; 6362 } 6363 let activeRange = computeActiveRange(dateProfile, Boolean(nextDayThreshold)); 6364 let activeDateSpanRange = intersectRanges(dateSpan.range, activeRange); 6365 if (activeDateSpanRange) { 6366 dateSpan = Object.assign(Object.assign({}, dateSpan), { range: activeDateSpanRange }); 6367 let eventRange = fabricateEventRange(dateSpan, eventUiBases, context); 6368 let segs = this.sliceRange(dateSpan.range, ...extraArgs); 6369 for (let seg of segs) { 6370 seg.eventRange = eventRange; 6371 } 6372 return segs; 6373 } 6374 return []; 6375 } 6376 /* 6377 "complete" seg means it has component and eventRange 6378 */ 6379 sliceEventRanges(eventRanges, extraArgs) { 6380 let segs = []; 6381 for (let eventRange of eventRanges) { 6382 segs.push(...this.sliceEventRange(eventRange, extraArgs)); 6383 } 6384 return segs; 6385 } 6386 /* 6387 "complete" seg means it has component and eventRange 6388 */ 6389 sliceEventRange(eventRange, extraArgs) { 6390 let dateRange = eventRange.range; 6391 if (this.forceDayIfListItem && eventRange.ui.display === "list-item") { 6392 dateRange = { 6393 start: dateRange.start, 6394 end: addDays(dateRange.start, 1) 6395 }; 6396 } 6397 let segs = this.sliceRange(dateRange, ...extraArgs); 6398 for (let seg of segs) { 6399 seg.eventRange = eventRange; 6400 seg.isStart = eventRange.isStart && seg.isStart; 6401 seg.isEnd = eventRange.isEnd && seg.isEnd; 6402 } 6403 return segs; 6404 } 6405} 6406function computeActiveRange(dateProfile, isComponentAllDay) { 6407 let range = dateProfile.activeRange; 6408 if (isComponentAllDay) { 6409 return range; 6410 } 6411 return { 6412 start: addMs(range.start, dateProfile.slotMinTime.milliseconds), 6413 end: addMs(range.end, dateProfile.slotMaxTime.milliseconds - 864e5) 6414 // 864e5 = ms in a day 6415 }; 6416} 6417function isInteractionValid(interaction, dateProfile, context) { 6418 let { instances } = interaction.mutatedEvents; 6419 for (let instanceId in instances) { 6420 if (!rangeContainsRange(dateProfile.validRange, instances[instanceId].range)) { 6421 return false;
vendor: 4,387 bytes, lines 6422-6518
6422 } 6423 } 6424 return isNewPropsValid({ eventDrag: interaction }, context); 6425} 6426function isDateSelectionValid(dateSelection, dateProfile, context) { 6427 if (!rangeContainsRange(dateProfile.validRange, dateSelection.range)) { 6428 return false; 6429 } 6430 return isNewPropsValid({ dateSelection }, context); 6431} 6432function isNewPropsValid(newProps, context) { 6433 let calendarState = context.getCurrentData(); 6434 let props = Object.assign({ businessHours: calendarState.businessHours, dateSelection: "", eventStore: calendarState.eventStore, eventUiBases: calendarState.eventUiBases, eventSelection: "", eventDrag: null, eventResize: null }, newProps); 6435 return (context.pluginHooks.isPropsValid || isPropsValid)(props, context); 6436} 6437function isPropsValid(state, context, dateSpanMeta = {}, filterConfig) { 6438 if (state.eventDrag && !isInteractionPropsValid(state, context, dateSpanMeta, filterConfig)) { 6439 return false; 6440 } 6441 if (state.dateSelection && !isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig)) { 6442 return false; 6443 } 6444 return true; 6445} 6446function isInteractionPropsValid(state, context, dateSpanMeta, filterConfig) { 6447 let currentState = context.getCurrentData(); 6448 let interaction = state.eventDrag; 6449 let subjectEventStore = interaction.mutatedEvents; 6450 let subjectDefs = subjectEventStore.defs; 6451 let subjectInstances = subjectEventStore.instances; 6452 let subjectConfigs = compileEventUis(subjectDefs, interaction.isEvent ? state.eventUiBases : { "": currentState.selectionConfig }); 6453 if (filterConfig) { 6454 subjectConfigs = mapHash(subjectConfigs, filterConfig); 6455 } 6456 let otherEventStore = excludeInstances(state.eventStore, interaction.affectedEvents.instances); 6457 let otherDefs = otherEventStore.defs; 6458 let otherInstances = otherEventStore.instances; 6459 let otherConfigs = compileEventUis(otherDefs, state.eventUiBases); 6460 for (let subjectInstanceId in subjectInstances) { 6461 let subjectInstance = subjectInstances[subjectInstanceId]; 6462 let subjectRange = subjectInstance.range; 6463 let subjectConfig = subjectConfigs[subjectInstance.defId]; 6464 let subjectDef = subjectDefs[subjectInstance.defId]; 6465 if (!allConstraintsPass(subjectConfig.constraints, subjectRange, otherEventStore, state.businessHours, context)) { 6466 return false; 6467 } 6468 let { eventOverlap } = context.options; 6469 let eventOverlapFunc = typeof eventOverlap === "function" ? eventOverlap : null; 6470 for (let otherInstanceId in otherInstances) { 6471 let otherInstance = otherInstances[otherInstanceId]; 6472 if (rangesIntersect(subjectRange, otherInstance.range)) { 6473 let otherOverlap = otherConfigs[otherInstance.defId].overlap; 6474 if (otherOverlap === false && interaction.isEvent) { 6475 return false; 6476 } 6477 if (subjectConfig.overlap === false) { 6478 return false; 6479 } 6480 if (eventOverlapFunc && !eventOverlapFunc( 6481 new EventImpl(context, otherDefs[otherInstance.defId], otherInstance), 6482 // still event 6483 new EventImpl(context, subjectDef, subjectInstance) 6484 )) { 6485 return false; 6486 } 6487 } 6488 } 6489 let calendarEventStore = currentState.eventStore; 6490 for (let subjectAllow of subjectConfig.allows) { 6491 let subjectDateSpan = Object.assign(Object.assign({}, dateSpanMeta), { range: subjectInstance.range, allDay: subjectDef.allDay }); 6492 let origDef = calendarEventStore.defs[subjectDef.defId]; 6493 let origInstance = calendarEventStore.instances[subjectInstanceId]; 6494 let eventApi; 6495 if (origDef) { 6496 eventApi = new EventImpl(context, origDef, origInstance); 6497 } else { 6498 eventApi = new EventImpl(context, subjectDef); 6499 } 6500 if (!subjectAllow(buildDateSpanApiWithContext(subjectDateSpan, context), eventApi)) { 6501 return false; 6502 } 6503 } 6504 } 6505 return true; 6506} 6507function isDateSelectionPropsValid(state, context, dateSpanMeta, filterConfig) { 6508 let relevantEventStore = state.eventStore; 6509 let relevantDefs = relevantEventStore.defs; 6510 let relevantInstances = relevantEventStore.instances; 6511 let selection = state.dateSelection; 6512 let selectionRange = selection.range; 6513 let { selectionConfig } = context.getCurrentData(); 6514 if (filterConfig) { 6515 selectionConfig = filterConfig(selectionConfig); 6516 } 6517 if (!allConstraintsPass(selectionConfig.constraints, selectionRange, relevantEventStore, state.businessHours, context)) { 6518 return false;
vendor: 2,511 bytes, lines 6519-6589
6519 } 6520 let { selectOverlap } = context.options; 6521 let selectOverlapFunc = typeof selectOverlap === "function" ? selectOverlap : null; 6522 for (let relevantInstanceId in relevantInstances) { 6523 let relevantInstance = relevantInstances[relevantInstanceId]; 6524 if (rangesIntersect(selectionRange, relevantInstance.range)) { 6525 if (selectionConfig.overlap === false) { 6526 return false; 6527 } 6528 if (selectOverlapFunc && !selectOverlapFunc(new EventImpl(context, relevantDefs[relevantInstance.defId], relevantInstance), null)) { 6529 return false; 6530 } 6531 } 6532 } 6533 for (let selectionAllow of selectionConfig.allows) { 6534 let fullDateSpan = Object.assign(Object.assign({}, dateSpanMeta), selection); 6535 if (!selectionAllow(buildDateSpanApiWithContext(fullDateSpan, context), null)) { 6536 return false; 6537 } 6538 } 6539 return true; 6540} 6541function allConstraintsPass(constraints, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 6542 for (let constraint of constraints) { 6543 if (!anyRangesContainRange(constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context), subjectRange)) { 6544 return false; 6545 } 6546 } 6547 return true; 6548} 6549function constraintToRanges(constraint, subjectRange, otherEventStore, businessHoursUnexpanded, context) { 6550 if (constraint === "businessHours") { 6551 return eventStoreToRanges(expandRecurring(businessHoursUnexpanded, subjectRange, context)); 6552 } 6553 if (typeof constraint === "string") { 6554 return eventStoreToRanges(filterEventStoreDefs(otherEventStore, (eventDef) => eventDef.groupId === constraint)); 6555 } 6556 if (typeof constraint === "object" && constraint) { 6557 return eventStoreToRanges(expandRecurring(constraint, subjectRange, context)); 6558 } 6559 return []; 6560} 6561function eventStoreToRanges(eventStore) { 6562 let { instances } = eventStore; 6563 let ranges = []; 6564 for (let instanceId in instances) { 6565 ranges.push(instances[instanceId].range); 6566 } 6567 return ranges; 6568} 6569function anyRangesContainRange(outerRanges, innerRange) { 6570 for (let outerRange of outerRanges) { 6571 if (rangeContainsRange(outerRange, innerRange)) { 6572 return true; 6573 } 6574 } 6575 return false; 6576} 6577const VISIBLE_HIDDEN_RE = /^(visible|hidden)$/; 6578class Scroller extends BaseComponent { 6579 constructor() { 6580 super(...arguments); 6581 this.handleEl = (el) => { 6582 this.el = el; 6583 setRef(this.props.elRef, el); 6584 }; 6585 } 6586 render() { 6587 let { props } = this; 6588 let { liquid, liquidIsAbsolute } = props; 6589 let isAbsolute = liquid && liquidIsAbsolute;
6590 let className = ["fc-scroller"]; 6591 if (liquid) { 6592 if (liquidIsAbsolute) { 6593 className.push("fc-scroller-liquid-absolute"); 6594 } else { 6595 className.push("fc-scroller-liquid"); 6596 } 6597 } 6598 return y("div", { ref: this.handleEl, className: className.join(" "), style: { 6599 overflowX: props.overflowX, 6600 overflowY: props.overflowY, 6601 left: isAbsolute && -(props.overcomeLeft || 0) || "", 6602 right: isAbsolute && -(props.overcomeRight || 0) || "", 6603 bottom: isAbsolute && -(props.overcomeBottom || 0) || "", 6604 marginLeft: !isAbsolute && -(props.overcomeLeft || 0) || "", 6605 marginRight: !isAbsolute && -(props.overcomeRight || 0) || "", 6606 marginBottom: !isAbsolute && -(props.overcomeBottom || 0) || "", 6607 maxHeight: props.maxHeight || "" 6608 } }, props.children); 6609 } 6610 needsXScrolling() { 6611 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 6612 return false; 6613 } 6614 let { el } = this; 6615 let realClientWidth = this.el.getBoundingClientRect().width - this.getYScrollbarWidth(); 6616 let { children } = el; 6617 for (let i2 = 0; i2 < children.length; i2 += 1) { 6618 let childEl = children[i2]; 6619 if (childEl.getBoundingClientRect().width > realClientWidth) { 6620 return true; 6621 } 6622 } 6623 return false; 6624 } 6625 needsYScrolling() { 6626 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 6627 return false; 6628 } 6629 let { el } = this; 6630 let realClientHeight = this.el.getBoundingClientRect().height - this.getXScrollbarWidth(); 6631 let { children } = el; 6632 for (let i2 = 0; i2 < children.length; i2 += 1) { 6633 let childEl = children[i2]; 6634 if (childEl.getBoundingClientRect().height > realClientHeight) { 6635 return true; 6636 } 6637 } 6638 return false; 6639 } 6640 getXScrollbarWidth() { 6641 if (VISIBLE_HIDDEN_RE.test(this.props.overflowX)) { 6642 return 0; 6643 } 6644 return this.el.offsetHeight - this.el.clientHeight; 6645 } 6646 getYScrollbarWidth() { 6647 if (VISIBLE_HIDDEN_RE.test(this.props.overflowY)) { 6648 return 0; 6649 } 6650 return this.el.offsetWidth - this.el.clientWidth; 6651 } 6652} 6653class RefMap { 6654 constructor(masterCallback) { 6655 this.masterCallback = masterCallback; 6656 this.currentMap = {}; 6657 this.depths = {}; 6658 this.callbackMap = {}; 6659 this.handleValue = (val, key) => { 6660 let { depths, currentMap } = this; 6661 let removed = false; 6662 let added = false; 6663 if (val !== null) { 6664 removed = key in currentMap; 6665 currentMap[key] = val; 6666 depths[key] = (depths[key] || 0) + 1; 6667 added = true; 6668 } else { 6669 depths[key] -= 1; 6670 if (!depths[key]) { 6671 delete currentMap[key]; 6672 delete this.callbackMap[key]; 6673 removed = true; 6674 } 6675 } 6676 if (this.masterCallback) { 6677 if (removed) { 6678 this.masterCallback(null, String(key)); 6679 } 6680 if (added) { 6681 this.masterCallback(val, String(key)); 6682 } 6683 } 6684 }; 6685 } 6686 createRef(key) { 6687 let refCallback = this.callbackMap[key]; 6688 if (!refCallback) { 6689 refCallback = this.callbackMap[key] = (val) => { 6690 this.handleValue(val, String(key)); 6691 }; 6692 } 6693 return refCallback; 6694 } 6695 // TODO: check callers that don't care about order. should use getAll instead 6696 // NOTE: this method has become less valuable now that we are encouraged to map order by some other index 6697 // TODO: provide ONE array-export function, buildArray, which fails on non-numeric indexes. caller can manipulate and "collect" 6698 collect(startIndex, endIndex, step) { 6699 return collectFromHash(this.currentMap, startIndex, endIndex, step); 6700 } 6701 getAll() { 6702 return hashValuesToArray(this.currentMap); 6703 } 6704} 6705function computeShrinkWidth(chunkEls) { 6706 let shrinkCells = findElements(chunkEls, ".fc-scrollgrid-shrink"); 6707 let largestWidth = 0; 6708 for (let shrinkCell of shrinkCells) { 6709 largestWidth = Math.max(largestWidth, computeSmallestCellWidth(shrinkCell)); 6710 } 6711 return Math.ceil(largestWidth); 6712} 6713function getSectionHasLiquidHeight(props, sectionConfig) { 6714 return props.liquid && sectionConfig.liquid; 6715} 6716function getAllowYScrolling(props, sectionConfig) { 6717 return sectionConfig.maxHeight != null || // if its possible for the height to max out, we might need scrollbars 6718 getSectionHasLiquidHeight(props, sectionConfig); 6719} 6720function renderChunkContent(sectionConfig, chunkConfig, arg, isHeader) { 6721 let { expandRows } = arg; 6722 let content = typeof chunkConfig.content === "function" ? chunkConfig.content(arg) : y("table", { 6723 role: "presentation", 6724 className: [ 6725 chunkConfig.tableClassName, 6726 sectionConfig.syncRowHeights ? "fc-scrollgrid-sync-table" : "" 6727 ].join(" "), 6728 style: { 6729 minWidth: arg.tableMinWidth, 6730 width: arg.clientWidth, 6731 height: expandRows ? arg.clientHeight : "" 6732 // css `height` on a <table> serves as a min-height 6733 } 6734 }, arg.tableColGroupNode, y(isHeader ? "thead" : "tbody", { 6735 role: "presentation" 6736 }, typeof chunkConfig.rowContent === "function" ? chunkConfig.rowContent(arg) : chunkConfig.rowContent)); 6737 return content; 6738} 6739function isColPropsEqual(cols0, cols1) { 6740 return isArraysEqual(cols0, cols1, isPropsEqual); 6741} 6742function renderMicroColGroup(cols, shrinkWidth) { 6743 let colNodes = []; 6744 for (let colProps of cols) { 6745 let span = colProps.span || 1; 6746 for (let i2 = 0; i2 < span; i2 += 1) {
6747 colNodes.push(y("col", { style: { 6748 width: colProps.width === "shrink" ? sanitizeShrinkWidth(shrinkWidth) : colProps.width || "", 6749 minWidth: colProps.minWidth || "" 6750 } })); 6751 } 6752 } 6753 return y("colgroup", {}, ...colNodes); 6754} 6755function sanitizeShrinkWidth(shrinkWidth) { 6756 return shrinkWidth == null ? 4 : shrinkWidth; 6757} 6758function hasShrinkWidth(cols) { 6759 for (let col of cols) { 6760 if (col.width === "shrink") { 6761 return true; 6762 } 6763 } 6764 return false; 6765} 6766function getScrollGridClassNames(liquid, context) { 6767 let classNames = [ 6768 "fc-scrollgrid", 6769 context.theme.getClass("table") 6770 ]; 6771 if (liquid) { 6772 classNames.push("fc-scrollgrid-liquid"); 6773 } 6774 return classNames; 6775} 6776function getSectionClassNames(sectionConfig, wholeTableVGrow) { 6777 let classNames = [ 6778 "fc-scrollgrid-section", 6779 `fc-scrollgrid-section-${sectionConfig.type}`, 6780 sectionConfig.className 6781 // used? 6782 ]; 6783 if (wholeTableVGrow && sectionConfig.liquid && sectionConfig.maxHeight == null) { 6784 classNames.push("fc-scrollgrid-section-liquid"); 6785 } 6786 if (sectionConfig.isSticky) { 6787 classNames.push("fc-scrollgrid-section-sticky"); 6788 } 6789 return classNames; 6790}
vendor: 3,041 bytes, lines 6791-6861
6791function renderScrollShim(arg) { 6792 return y("div", { className: "fc-scrollgrid-sticky-shim", style: { 6793 width: arg.clientWidth, 6794 minWidth: arg.tableMinWidth 6795 } }); 6796} 6797function getStickyHeaderDates(options) { 6798 let { stickyHeaderDates } = options; 6799 if (stickyHeaderDates == null || stickyHeaderDates === "auto") { 6800 stickyHeaderDates = options.height === "auto" || options.viewHeight === "auto"; 6801 } 6802 return stickyHeaderDates; 6803} 6804function getStickyFooterScrollbar(options) { 6805 let { stickyFooterScrollbar } = options; 6806 if (stickyFooterScrollbar == null || stickyFooterScrollbar === "auto") { 6807 stickyFooterScrollbar = options.height === "auto" || options.viewHeight === "auto"; 6808 } 6809 return stickyFooterScrollbar; 6810} 6811class SimpleScrollGrid extends BaseComponent { 6812 constructor() { 6813 super(...arguments); 6814 this.processCols = memoize((a2) => a2, isColPropsEqual); 6815 this.renderMicroColGroup = memoize(renderMicroColGroup); 6816 this.scrollerRefs = new RefMap(); 6817 this.scrollerElRefs = new RefMap(this._handleScrollerEl.bind(this)); 6818 this.state = { 6819 shrinkWidth: null, 6820 forceYScrollbars: false, 6821 scrollerClientWidths: {}, 6822 scrollerClientHeights: {} 6823 }; 6824 this.handleSizing = () => { 6825 this.safeSetState(Object.assign({ shrinkWidth: this.computeShrinkWidth() }, this.computeScrollerDims())); 6826 }; 6827 } 6828 render() { 6829 let { props, state, context } = this; 6830 let sectionConfigs = props.sections || []; 6831 let cols = this.processCols(props.cols); 6832 let microColGroupNode = this.renderMicroColGroup(cols, state.shrinkWidth); 6833 let classNames = getScrollGridClassNames(props.liquid, context); 6834 if (props.collapsibleWidth) { 6835 classNames.push("fc-scrollgrid-collapsible"); 6836 } 6837 let configCnt = sectionConfigs.length; 6838 let configI = 0; 6839 let currentConfig; 6840 let headSectionNodes = []; 6841 let bodySectionNodes = []; 6842 let footSectionNodes = []; 6843 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === "header") { 6844 headSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 6845 configI += 1; 6846 } 6847 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === "body") { 6848 bodySectionNodes.push(this.renderSection(currentConfig, microColGroupNode, false)); 6849 configI += 1; 6850 } 6851 while (configI < configCnt && (currentConfig = sectionConfigs[configI]).type === "footer") { 6852 footSectionNodes.push(this.renderSection(currentConfig, microColGroupNode, true)); 6853 configI += 1; 6854 } 6855 let isBuggy = !getCanVGrowWithinCell(); 6856 const roleAttrs = { role: "rowgroup" }; 6857 return y("table", { 6858 role: "grid", 6859 className: classNames.join(" "), 6860 style: { height: props.height } 6861 }, Boolean(!isBuggy && headSectionNodes.length) && y("thead", roleAttrs, ...headSectionNodes), Boolean(!isBuggy && bodySectionNodes.length) && y("tbody", roleAttrs, ...bodySectionNodes), Boolean(!isBuggy && footSectionNodes.length) && y("tfoot", roleAttrs, ...footSectionNodes
6861), isBuggy && y("tbody", roleAttrs, ...headSectionNodes, ...bodySectionNodes, ...footSectionNodes)); 6862 } 6863 renderSection(sectionConfig, microColGroupNode, isHeader) { 6864 if ("outerContent" in sectionConfig) { 6865 return y(_, { key: sectionConfig.key }, sectionConfig.outerContent); 6866 } 6867 return y("tr", { key: sectionConfig.key, role: "presentation", className: getSectionClassNames(sectionConfig, this.props.liquid).join(" ") }, this.renderChunkTd(sectionConfig, microColGroupNode, sectionConfig.chunk, isHeader)); 6868 } 6869 renderChunkTd(sectionConfig, microColGroupNode, chunkConfig, isHeader) { 6870 if ("outerContent" in chunkConfig) { 6871 return chunkConfig.outerContent; 6872 } 6873 let { props } = this; 6874 let { forceYScrollbars, scrollerClientWidths, scrollerClientHeights } = this.state; 6875 let needsYScrolling = getAllowYScrolling(props, sectionConfig); 6876 let isLiquid = getSectionHasLiquidHeight(props, sectionConfig); 6877 let overflowY = !props.liquid ? "visible" : forceYScrollbars ? "scroll" : !needsYScrolling ? "hidden" : "auto"; 6878 let sectionKey = sectionConfig.key; 6879 let content = renderChunkContent(sectionConfig, chunkConfig, { 6880 tableColGroupNode: microColGroupNode, 6881 tableMinWidth: "", 6882 clientWidth: !props.collapsibleWidth && scrollerClientWidths[sectionKey] !== void 0 ? scrollerClientWidths[sectionKey] : null, 6883 clientHeight: scrollerClientHeights[sectionKey] !== void 0 ? scrollerClientHeights[sectionKey] : null, 6884 expandRows: sectionConfig.expandRows, 6885 syncRowHeights: false, 6886 rowSyncHeights: [], 6887 reportRowHeightChange: () => { 6888 } 6889 }, isHeader); 6890 return y(isHeader ? "th" : "td", { 6891 ref: chunkConfig.elRef, 6892 role: "presentation" 6893 }, y( 6894 "div", 6895 { className: `fc-scroller-harness${isLiquid ? " fc-scroller-harness-liquid" : ""}` }, 6896 y(Scroller, { ref: this.scrollerRefs.createRef(sectionKey), elRef: this.scrollerElRefs.createRef(sectionKey), overflowY, overflowX: !props.liquid ? "visible" : "hidden", maxHeight: sectionConfig.maxHeight, liquid: isLiquid, liquidIsAbsolute: true }, content) 6897 )); 6898 } 6899 _handleScrollerEl(scrollerEl, key) { 6900 let section = getSectionByKey(this.props.sections, key); 6901 if (section) { 6902 setRef(section.chunk.scrollerElRef, scrollerEl); 6903 } 6904 } 6905 componentDidMount() { 6906 this.handleSizing(); 6907 this.context.addResizeHandler(this.handleSizing); 6908 } 6909 componentDidUpdate() { 6910 this.handleSizing(); 6911 } 6912 componentWillUnmount() { 6913 this.context.removeResizeHandler(this.handleSizing); 6914 } 6915 computeShrinkWidth() { 6916 return hasShrinkWidth(this.props.cols) ? computeShrinkWidth(this.scrollerElRefs.getAll()) : 0; 6917 } 6918 computeScrollerDims() { 6919 let scrollbarWidth = getScrollbarWidths(); 6920 let { scrollerRefs, scrollerElRefs } = this; 6921 let forceYScrollbars = false; 6922 let scrollerClientWidths = {}; 6923 let scrollerClientHeights = {}; 6924 for (let sectionKey in scrollerRefs.currentMap) { 6925 let scroller = scrollerRefs.currentMap[sectionKey]; 6926 if (scroller && scroller.needsYScrolling()) { 6927 forceYScrollbars = true; 6928 break; 6929 } 6930 } 6931 for (let section of this.props.sections) { 6932 let sectionKey = section.key; 6933 let scrollerEl = scrollerElRefs.currentMap[sectionKey]; 6934 if (scrollerEl) { 6935 let harnessEl = scrollerEl.parentNode; 6936 scrollerClientWidths[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().width - (forceYScrollbars ? scrollbarWidth.y : 0)); 6937 scrollerClientHeights[sectionKey] = Math.floor(harnessEl.getBoundingClientRect().height); 6938 } 6939 } 6940 return { forceYScrollbars, scrollerClientWidths, scrollerClientHeights }; 6941 } 6942} 6943SimpleScrollGrid.addStateEquality({ 6944 scrollerClientWidths: isPropsEqual, 6945 scrollerClientHeights: isPropsEqual 6946}); 6947function getSectionByKey(sections, key) { 6948 for (let section of sections) { 6949 if (section.key === key) { 6950 return section; 6951 } 6952 } 6953 return null; 6954} 6955class EventContainer extends BaseComponent { 6956 constructor() { 6957 super(...arguments); 6958 this.handleEl = (el) => { 6959 this.el = el; 6960 if (el) { 6961 setElSeg(el, this.props.seg); 6962 } 6963 }; 6964 } 6965 render() { 6966 const { props, context } = this; 6967 const { options } = context; 6968 const { seg } = props; 6969 const { eventRange } = seg; 6970 const { ui } = eventRange; 6971 const renderProps = { 6972 event: new EventImpl(context, eventRange.def, eventRange.instance), 6973 view: context.viewApi, 6974 timeText: props.timeText, 6975 textColor: ui.textColor, 6976 backgroundColor: ui.backgroundColor, 6977 borderColor: ui.borderColor, 6978 isDraggable: !props.disableDragging && computeSegDraggable(seg, context), 6979 isStartResizable: !props.disableResizing && computeSegStartResizable(seg, context), 6980 isEndResizable: !props.disableResizing && computeSegEndResizable(seg), 6981 isMirror: Boolean(props.isDragging || props.isResizing || props.isDateSelecting),
6982 isStart: Boolean(seg.isStart), 6983 isEnd: Boolean(seg.isEnd), 6984 isPast: Boolean(props.isPast), 6985 isFuture: Boolean(props.isFuture), 6986 isToday: Boolean(props.isToday), 6987 isSelected: Boolean(props.isSelected), 6988 isDragging: Boolean(props.isDragging), 6989 isResizing: Boolean(props.isResizing) 6990 }; 6991 return y(ContentContainer, Object.assign({}, props, { elRef: this.handleEl, elClasses: [ 6992 ...getEventClassNames(renderProps), 6993 ...seg.eventRange.ui.classNames, 6994 ...props.elClasses || [] 6995 ], renderProps, generatorName: "eventContent", customGenerator: options.eventContent, defaultGenerator: props.defaultGenerator, classNameGenerator: options.eventClassNames, didMount: options.eventDidMount, willUnmount: options.eventWillUnmount })); 6996 } 6997 componentDidUpdate(prevProps) { 6998 if (this.el && this.props.seg !== prevProps.seg) { 6999 setElSeg(this.el, this.props.seg); 7000 } 7001 } 7002} 7003class StandardEvent extends BaseComponent { 7004 render() { 7005 let { props, context } = this; 7006 let { options } = context; 7007 let { seg } = props; 7008 let { ui } = seg.eventRange; 7009 let timeFormat = options.eventTimeFormat || props.defaultTimeFormat; 7010 let timeText = buildSegTimeText(seg, timeFormat, context, props.defaultDisplayEventTime, props.defaultDisplayEventEnd); 7011 return y(EventContainer, Object.assign({}, props, { elTag: "a", elStyle: { 7012 borderColor: ui.borderColor, 7013 backgroundColor: ui.backgroundColor 7014 }, elAttrs: getSegAnchorAttrs(seg, context), defaultGenerator: renderInnerContent$1$1, timeText }), (InnerContent, eventContentArg) => y( 7015 _, 7016 null, 7017 y(InnerContent, { elTag: "div", elClasses: ["fc-event-main"], elStyle: { color: eventContentArg.textColor } }), 7018 Boolean(eventContentArg.isStartResizable) && y("div", { className: "fc-event-resizer fc-event-resizer-start" }), 7019 Boolean(eventContentArg.isEndResizable) && y("div", { className: "fc-event-resizer fc-event-resizer-end" }) 7020 )); 7021 } 7022} 7023function renderInnerContent$1$1(innerProps) { 7024 return y( 7025 "div", 7026 { className: "fc-event-main-frame" }, 7027 innerProps.timeText && y("div", { className: "fc-event-time" }, innerProps.timeText), 7028 y( 7029 "div", 7030 { className: "fc-event-title-container" }, 7031 y("div", { className: "fc-event-title fc-sticky" }, innerProps.event.title || y(_, null, " ")) 7032 ) 7033 ); 7034} 7035const NowIndicatorContainer = (props) => y(ViewContextType.Consumer, null, (context) => { 7036 let { options } = context; 7037 let renderProps = { 7038 isAxis: props.isAxis, 7039 date: context.dateEnv.toDate(props.date), 7040 view: context.viewApi 7041 }; 7042 return y(ContentContainer, Object.assign({}, props, { elTag: props.elTag || "div", renderProps, generatorName: "nowIndicatorContent", customGenerator: options.nowIndicatorContent, classNameGenerator: options.nowIndicatorClassNames, didMount: options.nowIndicatorDidMount, willUnmount: options.nowIndicatorWillUnmount })); 7043}); 7044const DAY_NUM_FORMAT = createFormatter({ day: "numeric" }); 7045class DayCellContainer extends BaseComponent { 7046 constructor() { 7047 super(...arguments); 7048 this.refineRenderProps = memoizeObjArg(refineRenderProps); 7049 } 7050 render() { 7051 let { props, context } = this; 7052 let { options } = context; 7053 let renderProps = this.refineRenderProps({ 7054 date: props.date, 7055 dateProfile: props.dateProfile, 7056 todayRange: props.todayRange, 7057 isMonthStart: props.isMonthStart || false, 7058 showDayNumber: props.showDayNumber, 7059 extraRenderProps: props.extraRenderProps, 7060 viewApi: context.viewApi, 7061 dateEnv: context.dateEnv, 7062 monthStartFormat: options.monthStartFormat 7063 }); 7064 return y(ContentContainer, Object.assign({}, props, { elClasses: [ 7065 ...getDayClassNames(renderProps, context.theme), 7066 ...props.elClasses || [] 7067 ], elAttrs: Object.assign(Object.assign({}, props.elAttrs), renderProps.isDisabled ? {} : { "data-date": formatDayString(props.date) }), renderProps, generatorName: "dayCellContent", customGenerator: options.dayCellContent, defaultGenerator: props.defaultGenerator, classNameGenerator: ( 7068 // don't use custom classNames if disabled 7069 renderProps.isDisabled ? void 0 : options.dayCellClassNames 7070 ), didMount: options.dayCellDidMount, willUnmount: options.dayCellWillUnmount })); 7071 } 7072} 7073function hasCustomDayCellContent(options) { 7074 return Boolean(options.dayCellContent || hasCustomRenderingHandler("dayCellContent", options)); 7075} 7076function refineRenderProps(raw) { 7077 let { date, dateEnv, dateProfile, isMonthStart } = raw;
7078 let dayMeta = getDateMeta(date, raw.todayRange, null, dateProfile); 7079 let dayNumberText = raw.showDayNumber ? dateEnv.format(date, isMonthStart ? raw.monthStartFormat : DAY_NUM_FORMAT) : ""; 7080 return Object.assign(Object.assign(Object.assign({ date: dateEnv.toDate(date), view: raw.viewApi }, dayMeta), { 7081 isMonthStart, 7082 dayNumberText 7083 }), raw.extraRenderProps); 7084} 7085class BgEvent extends BaseComponent { 7086 render() { 7087 let { props } = this; 7088 let { seg } = props; 7089 return y(EventContainer, { elTag: "div", elClasses: ["fc-bg-event"], elStyle: { backgroundColor: seg.eventRange.ui.backgroundColor }, defaultGenerator: renderInnerContent$2, seg, timeText: "", isDragging: false, isResizing: false, isDateSelecting: false, isSelected: false, isPast: props.isPast, isFuture: props.isFuture, isToday: props.isToday, disableDragging: true, disableResizing: true }); 7090 } 7091} 7092function renderInnerContent$2(props) { 7093 let { title } = props.event; 7094 return title && y("div", { className: "fc-event-title" }, props.event.title); 7095} 7096function renderFill(fillType) { 7097 return y("div", { className: `fc-${fillType}` }); 7098} 7099const WeekNumberContainer = (props) => y(ViewContextType.Consumer, null, (context) => { 7100 let { dateEnv, options } = context; 7101 let { date } = props; 7102 let format = options.weekNumberFormat || props.defaultFormat; 7103 let num = dateEnv.computeWeekNumber(date); 7104 let text = dateEnv.format(date, format); 7105 let renderProps = { num, text, date }; 7106 return y( 7107 ContentContainer, 7108 Object.assign({}, props, { renderProps, generatorName: "weekNumberContent", customGenerator: options.weekNumberContent, defaultGenerator: renderInner, classNameGenerator: options.weekNumberClassNames, didMount: options.weekNumberDidMount, willUnmount: options.weekNumberWillUnmount }) 7109 ); 7110}); 7111function renderInner(innerProps) { 7112 return innerProps.text; 7113} 7114const PADDING_FROM_VIEWPORT = 10; 7115class Popover extends BaseComponent { 7116 constructor() { 7117 super(...arguments); 7118 this.state = { 7119 titleId: getUniqueDomId() 7120 }; 7121 this.handleRootEl = (el) => { 7122 this.rootEl = el; 7123 if (this.props.elRef) { 7124 setRef(this.props.elRef, el); 7125 } 7126 }; 7127 this.handleDocumentMouseDown = (ev) => { 7128 const target = getEventTargetViaRoot(ev); 7129 if (!this.rootEl.contains(target)) { 7130 this.handleCloseClick(); 7131 } 7132 }; 7133 this.handleDocumentKeyDown = (ev) => { 7134 if (ev.key === "Escape") { 7135 this.handleCloseClick(); 7136 } 7137 }; 7138 this.handleCloseClick = () => { 7139 let { onClose } = this.props; 7140 if (onClose) { 7141 onClose(); 7142 } 7143 }; 7144 } 7145 render() { 7146 let { theme, options } = this.context; 7147 let { props, state } = this; 7148 let classNames = [ 7149 "fc-popover", 7150 theme.getClass("popover") 7151 ].concat(props.extraClassNames || []); 7152 return j(y( 7153 "div", 7154 Object.assign({}, props.extraAttrs, { id: props.id, className: classNames.join(" "), "aria-labelledby": state.titleId, ref: this.handleRootEl }), 7155 y( 7156 "div", 7157 { className: "fc-popover-header " + theme.getClass("popoverHeader") },
7158 y("span", { className: "fc-popover-title", id: state.titleId }, props.title), 7159 y("span", { className: "fc-popover-close " + theme.getIconClass("close"), title: options.closeHint, onClick: this.handleCloseClick }) 7160 ), 7161 y("div", { className: "fc-popover-body " + theme.getClass("popoverContent") }, props.children) 7162 ), props.parentEl); 7163 } 7164 componentDidMount() { 7165 document.addEventListener("mousedown", this.handleDocumentMouseDown); 7166 document.addEventListener("keydown", this.handleDocumentKeyDown); 7167 this.updateSize(); 7168 } 7169 componentWillUnmount() { 7170 document.removeEventListener("mousedown", this.handleDocumentMouseDown); 7171 document.removeEventListener("keydown", this.handleDocumentKeyDown); 7172 } 7173 updateSize() { 7174 let { isRtl } = this.context; 7175 let { alignmentEl, alignGridTop } = this.props; 7176 let { rootEl } = this; 7177 let alignmentRect = computeClippedClientRect(alignmentEl); 7178 if (alignmentRect) { 7179 let popoverDims = rootEl.getBoundingClientRect(); 7180 let popoverTop = alignGridTop ? elementClosest(alignmentEl, ".fc-scrollgrid").getBoundingClientRect().top : alignmentRect.top; 7181 let popoverLeft = isRtl ? alignmentRect.right - popoverDims.width : alignmentRect.left; 7182 popoverTop = Math.max(popoverTop, PADDING_FROM_VIEWPORT); 7183 popoverLeft = Math.min(popoverLeft, document.documentElement.clientWidth - PADDING_FROM_VIEWPORT - popoverDims.width); 7184 popoverLeft = Math.max(popoverLeft, PADDING_FROM_VIEWPORT); 7185 let origin = rootEl.offsetParent.getBoundingClientRect(); 7186 applyStyle(rootEl, { 7187 top: popoverTop - origin.top, 7188 left: popoverLeft - origin.left 7189 }); 7190 } 7191 } 7192} 7193class MorePopover extends DateComponent { 7194 constructor() { 7195 super(...arguments); 7196 this.handleRootEl = (rootEl) => { 7197 this.rootEl = rootEl; 7198 if (rootEl) { 7199 this.context.registerInteractiveComponent(this, { 7200 el: rootEl, 7201 useEventCenter: false 7202 }); 7203 } else { 7204 this.context.unregisterInteractiveComponent(this); 7205 } 7206 }; 7207 } 7208 render() { 7209 let { options, dateEnv } = this.context; 7210 let { props } = this; 7211 let { startDate, todayRange, dateProfile } = props; 7212 let title = dateEnv.format(startDate, options.dayPopoverFormat); 7213 return y(DayCellContainer, { elRef: this.handleRootEl, date: startDate, dateProfile, todayRange }, (InnerContent, renderProps, elAttrs) => y( 7214 Popover, 7215 { elRef: elAttrs.ref, id: props.id, title, extraClassNames: ["fc-more-popover"].concat(elAttrs.className || []), extraAttrs: elAttrs, parentEl: props.parentEl, alignmentEl: props.alignmentEl, alignGridTop: props.alignGridTop, onClose: props.onClose }, 7216 hasCustomDayCellContent(options) && y(InnerContent, { elTag: "div", elClasses: ["fc-more-popover-misc"] }), 7217 props.children 7218 )); 7219 } 7220 queryHit(positionLeft, positionTop, elWidth, elHeight) { 7221 let { rootEl, props } = this; 7222 if (positionLeft >= 0 && positionLeft < elWidth && positionTop >= 0 && positionTop < elHeight) { 7223 return { 7224 dateProfile: props.dateProfile, 7225 dateSpan: Object.assign({ allDay: !props.forceTimed, range: { 7226 start: props.startDate, 7227 end: props.endDate 7228 } }, props.extraDateSpan), 7229 dayEl: rootEl, 7230 rect: { 7231 left: 0, 7232 top: 0, 7233 right: elWidth, 7234 bottom: elHeight 7235 }, 7236 layer: 1 7237 // important when comparing with hits from other components 7238 }; 7239 } 7240 return null; 7241 } 7242} 7243class MoreLinkContainer extends BaseComponent { 7244 constructor() { 7245 super(...arguments); 7246 this.state = { 7247 isPopoverOpen: false, 7248 popoverId: getUniqueDomId() 7249 }; 7250 this.handleLinkEl = (linkEl) => { 7251 this.linkEl = linkEl; 7252 if (this.props.elRef) { 7253 setRef(this.props.elRef, linkEl); 7254 } 7255 }; 7256 this.handleClick = (ev) => { 7257 let { props, context } = this; 7258 let { moreLinkClick } = context.options; 7259 let date = computeRange(props).start; 7260 function buildPublicSeg(seg) { 7261 let { def, instance, range } = seg.eventRange; 7262 return { 7263 event: new EventImpl(context, def, instance), 7264 start: context.dateEnv.toDate(range.start), 7265 end: context.dateEnv.toDate(range.end), 7266 isStart: seg.isStart, 7267 isEnd: seg.isEnd 7268 }; 7269 } 7270 if (typeof moreLinkClick === "function") { 7271 moreLinkClick = moreLinkClick({ 7272 date, 7273 allDay: Boolean(props.allDayDate), 7274 allSegs: props.allSegs.map(buildPublicSeg), 7275 hiddenSegs: props.hiddenSegs.map(buildPublicSeg), 7276 jsEvent: ev, 7277 view: context.viewApi 7278 }); 7279 } 7280 if (!moreLinkClick || moreLinkClick === "popover") { 7281 this.setState({ isPopoverOpen: true }); 7282 } else if (typeof moreLinkClick === "string") { 7283 context.calendarApi.zoomTo(date, moreLinkClick); 7284 } 7285 }; 7286 this.handlePopoverClose = () => { 7287 this.setState({ isPopoverOpen: false }); 7288 }; 7289 } 7290 render() { 7291 let { props, state } = this; 7292 return y(ViewContextType.Consumer, null, (context) => { 7293 let { viewApi, options, calendarApi } = context; 7294 let { moreLinkText } = options; 7295 let { moreCnt } = props; 7296 let range = computeRange(props); 7297 let text = typeof moreLinkText === "function" ? moreLinkText.call(calendarApi, moreCnt) : `+${more
7297Cnt} ${moreLinkText}`; 7298 let hint = formatWithOrdinals(options.moreLinkHint, [moreCnt], text); 7299 let renderProps = { 7300 num: moreCnt, 7301 shortText: `+${moreCnt}`, 7302 text, 7303 view: viewApi 7304 }; 7305 return y( 7306 _, 7307 null, 7308 Boolean(props.moreCnt) && y(ContentContainer, { elTag: props.elTag || "a", elRef: this.handleLinkEl, elClasses: [ 7309 ...props.elClasses || [], 7310 "fc-more-link" 7311 ], elStyle: props.elStyle, elAttrs: Object.assign(Object.assign(Object.assign({}, props.elAttrs), createAriaClickAttrs(this.handleClick)), { title: hint, "aria-expanded": state.isPopoverOpen, "aria-controls": state.isPopoverOpen ? state.popoverId : "" }), renderProps, generatorName: "moreLinkContent", customGenerator: options.moreLinkContent, defaultGenerator: props.defaultGenerator || renderMoreLinkInner$1, classNameGenerator: options.moreLinkClassNames, didMount: options.moreLinkDidMount, willUnmount: options.moreLinkWillUnmount }, props.children), 7312 state.isPopoverOpen && y(MorePopover, { id: state.popoverId, startDate: range.start, endDate: range.end, dateProfile: props.dateProfile, todayRange: props.todayRange, extraDateSpan: props.extraDateSpan, parentEl: this.parentEl, alignmentEl: props.alignmentElRef ? props.alignmentElRef.current : this.linkEl, alignGridTop: props.alignGridTop, forceTimed: props.forceTimed, onClose: this.handlePopoverClose }, props.popoverContent()) 7313 ); 7314 }); 7315 } 7316 componentDidMount() { 7317 this.updateParentEl(); 7318 } 7319 componentDidUpdate() { 7320 this.updateParentEl(); 7321 } 7322 updateParentEl() { 7323 if (this.linkEl) { 7324 this.parentEl = elementClosest(this.linkEl, ".fc-view-harness"); 7325 } 7326 } 7327} 7328function renderMoreLinkInner$1(props) { 7329 return props.text; 7330} 7331function computeRange(props) { 7332 if (props.allDayDate) { 7333 return { 7334 start: props.allDayDate, 7335 end: addDays(props.allDayDate, 1) 7336 }; 7337 } 7338 let { hiddenSegs } = props; 7339 return { 7340 start: computeEarliestSegStart(hiddenSegs), 7341 end: computeLatestSegEnd(hiddenSegs) 7342 }; 7343} 7344function computeEarliestSegStart(segs) { 7345 return segs.reduce(pickEarliestStart).eventRange.range.start; 7346} 7347function pickEarliestStart(seg0, seg1) { 7348 return seg0.eventRange.range.start < seg1.eventRange.range.start ? seg0 : seg1; 7349} 7350function computeLatestSegEnd(segs) { 7351 return segs.reduce(pickLatestEnd).eventRange.range.end; 7352} 7353function pickLatestEnd(seg0, seg1) { 7354 return seg0.eventRange.range.end > seg1.eventRange.range.end ? seg0 : seg1; 7355} 7356const globalLocales = []; 7357const MINIMAL_RAW_EN_LOCALE = { 7358 code: "en", 7359 week: { 7360 dow: 0, 7361 doy: 4 7362 // 4 days need to be within the year to be considered the first week 7363 }, 7364 direction: "ltr", 7365 buttonText: { 7366 prev: "prev", 7367 next: "next", 7368 prevYear: "prev year", 7369 nextYear: "next year", 7370 year: "year", 7371 today: "today", 7372 month: "month", 7373 week: "week", 7374 day: "day", 7375 list: "list" 7376 }, 7377 weekText: "W", 7378 weekTextLong: "Week", 7379 closeHint: "Close", 7380 timeHint: "Time", 7381 eventHint: "Event", 7382 allDayText: "all-day", 7383 moreLinkText: "more", 7384 noEventsText: "No events to display" 7385}; 7386const RAW_EN_LOCALE = Object.assign(Object.assign({}, MINIMAL_RAW_EN_LOCALE), { 7387 // Includes things we don't want other locales to inherit, 7388 // things that derive from other translatable strings. 7389 buttonHints: { 7390 prev: "Previous $0", 7391 next: "Next $0", 7392 today(buttonText, unit) { 7393 return unit === "day" ? "Today" : `This ${buttonText}`; 7394 } 7395 }, 7396 viewHint: "$0 view", 7397 navLinkHint: "Go to $0", 7398 moreLinkHint(eventCnt) { 7399 return `Show ${eventCnt} more event${eventCnt === 1 ? "" : "s"}`; 7400 } 7401}); 7402function organizeRawLocales(explicitRawLocales) { 7403 let defaultCode = explicitRawLocales.length > 0 ? explicitRawLocales[0].code : "en"; 7404 let allRawLocales = globalLocales.concat(explicitRawLocales); 7405 let rawLocaleMap = { 7406 en: RAW_EN_LOCALE 7407 }; 7408 for (let rawLocale of allRawLocales) { 7409 rawLocaleMap[rawLocale.code] = rawLocale; 7410 } 7411 return { 7412 map: rawLocaleMap, 7413 defaultCode 7414 }; 7415} 7416function buildLocale(inputSingular, available) { 7417 if (typeof inputSingular === "object" && !Array.isArray(inputSingular)) { 7418 return parseLocale(inputSingular.code, [inputSingular.code], inputSingular); 7419 } 7420 return queryLocale(inputSingular, available); 7421} 7422function queryLocale(codeArg, available) { 7423 let codes = [].concat(codeArg || []); 7424 let raw = queryRawLocale(codes, available) || RAW_EN_LOCALE; 7425 return parseLocale(codeArg, codes, raw); 7426} 7427function queryRawLocale(codes, available) { 7428 for (let i2 = 0; i2 < codes.length; i2 += 1) { 7429 let parts = codes[i2].toLocaleLowerCase().split("-"); 7430 for (let j2 = parts.length; j2 > 0; j2 -= 1) { 7431 let simpleId = parts.slice(0, j2).join("-"); 7432 if (available[simpleId]) { 7433 return available[simpleId]; 7434 } 7435 } 7436 } 7437 return null; 7438} 7439function parseLocale(codeArg, codes, raw) { 7440 let merged = mergeProps([MINIMAL_RAW_EN_LOCALE, raw], ["buttonText"]); 7441 delete merged.code;
7442 let { week } = merged; 7443 delete merged.week; 7444 return { 7445 codeArg, 7446 codes, 7447 week, 7448 simpleNumberFormat: new Intl.NumberFormat(codeArg), 7449 options: merged 7450 }; 7451} 7452function createPlugin(input) { 7453 return { 7454 id: guid(), 7455 name: input.name, 7456 premiumReleaseDate: input.premiumReleaseDate ? new Date(input.premiumReleaseDate) : void 0, 7457 deps: input.deps || [], 7458 reducers: input.reducers || [], 7459 isLoadingFuncs: input.isLoadingFuncs || [], 7460 contextInit: [].concat(input.contextInit || []), 7461 eventRefiners: input.eventRefiners || {}, 7462 eventDefMemberAdders: input.eventDefMemberAdders || [], 7463 eventSourceRefiners: input.eventSourceRefiners || {}, 7464 isDraggableTransformers: input.isDraggableTransformers || [], 7465 eventDragMutationMassagers: input.eventDragMutationMassagers || [], 7466 eventDefMutationAppliers: input.eventDefMutationAppliers || [], 7467 dateSelectionTransformers: input.dateSelectionTransformers || [], 7468 datePointTransforms: input.datePointTransforms || [], 7469 dateSpanTransforms: input.dateSpanTransforms || [], 7470 views: input.views || {}, 7471 viewPropsTransformers: input.viewPropsTransformers || [], 7472 isPropsValid: input.isPropsValid || null, 7473 externalDefTransforms: input.externalDefTransforms || [], 7474 viewContainerAppends: input.viewContainerAppends || [], 7475 eventDropTransformers: input.eventDropTransformers || [], 7476 componentInteractions: input.componentInteractions || [], 7477 calendarInteractions: input.calendarInteractions || [], 7478 themeClasses: input.themeClasses || {}, 7479 eventSourceDefs: input.eventSourceDefs || [], 7480 cmdFormatter: input.cmdFormatter, 7481 recurringTypes: input.recurringTypes || [], 7482 namedTimeZonedImpl: input.namedTimeZonedImpl, 7483 initialView: input.initialView || "", 7484 elementDraggingImpl: input.elementDraggingImpl, 7485 optionChangeHandlers: input.optionChangeHandlers || {}, 7486 scrollGridImpl: input.scrollGridImpl || null, 7487 listenerRefiners: input.listenerRefiners || {}, 7488 optionRefiners: input.optionRefiners || {}, 7489 propSetHandlers: input.propSetHandlers || {} 7490 }; 7491} 7492function buildPluginHooks(pluginDefs, globalDefs) { 7493 let currentPluginIds = {}; 7494 let hooks = { 7495 premiumReleaseDate: void 0, 7496 reducers: [], 7497 isLoadingFuncs: [], 7498 contextInit: [], 7499 eventRefiners: {}, 7500 eventDefMemberAdders: [], 7501 eventSourceRefiners: {}, 7502 isDraggableTransformers: [], 7503 eventDragMutationMassagers: [], 7504 eventDefMutationAppliers: [], 7505 dateSelectionTransformers: [], 7506 datePointTransforms: [], 7507 dateSpanTransforms: [], 7508 views: {}, 7509 viewPropsTransformers: [], 7510 isPropsValid: null, 7511 externalDefTransforms: [], 7512 viewContainerAppends: [], 7513 eventDropTransformers: [], 7514 componentInteractions: [], 7515 calendarInteractions: [], 7516 themeClasses: {}, 7517 eventSourceDefs: [], 7518 cmdFormatter: null, 7519 recurringTypes: [], 7520 namedTimeZonedImpl: null, 7521 initialView: "", 7522 elementDraggingImpl: null, 7523 optionChangeHandlers: {}, 7524 scrollGridImpl: null, 7525 listenerRefiners: {}, 7526 optionRefiners: {}, 7527 propSetHandlers: {} 7528 }; 7529 function addDefs(defs) { 7530 for (let def of defs) { 7531 const pluginName = def.name; 7532 const currentId = currentPluginIds[pluginName]; 7533 if (currentId === void 0) { 7534 currentPluginIds[pluginName] = def.id; 7535 addDefs(def.deps); 7536 hooks = combineHooks(hooks, def); 7537 } else if (currentId !== def.id) { 7538 console.warn(`Duplicate plugin '${pluginName}'`); 7539 } 7540 } 7541 } 7542 if (pluginDefs) { 7543 addDefs(pluginDefs); 7544 } 7545 addDefs(globalDefs); 7546 return hooks; 7547} 7548function buildBuildPluginHooks() { 7549 let currentOverrideDefs = []; 7550 let currentGlobalDefs = []; 7551 let currentHooks; 7552 return (overrideDefs, globalDefs) => { 7553 if (!currentHooks || !isArraysEqual(overrideDefs, currentOverrideDefs) || !isArraysEqual(globalDefs, currentGlobalDefs)) { 7554 currentHooks = buildPluginHooks(overrideDefs, globalDefs); 7555 } 7556 currentOverrideDefs = overrideDefs; 7557 currentGlobalDefs = globalDefs; 7558 return currentHooks; 7559 }; 7560} 7561function combineHooks(hooks0, hooks1) { 7562 return { 7563 premiumReleaseDate: compareOptionalDates(hooks0.premiumReleaseDate, hooks1.premiumReleaseDate), 7564 reducers: hooks0.reducers.concat(hooks1.reducers), 7565 isLoadingFuncs: hooks0.isLoadingFuncs.concat(hooks1.isLoadingFuncs), 7566 contextInit: hooks0.contextInit.concat(hooks1.contextInit), 7567 eventRefiners: Object.assign(Object.assign({}, hooks0.eventRefiners), hooks1.eventRefiners), 7568 eventDefMemberAdders: hooks0.eventDefMemberAdders.concat(hooks1.eventDefMemberAdders), 7569 eventSourceRefiners: Object.assign(Object.assign({}, hooks0.eventSourceRefiners), hooks1.eventSourceRefiners), 7570 isDraggableTransformers: hooks0.isDraggableTransformers.concat(hooks1.isDraggableTransformers), 7571 eventDragMutationMassagers: hooks0.eventDragMutationMassagers.concat(hooks1.eventDragMutationMassagers), 7572 eventDefMutationAppliers: hooks0.eventDefMutationAppliers.concat(hooks1.eventDefMutationAppliers), 7573 dateSelectionTransformers: hooks0.dateSelectionTransformers.concat(hooks1.dateSelectionTransformers), 7574 datePointTransforms: hooks0.datePointTransforms.concat(hooks1.datePointTransforms), 7575 dateSpanTransforms: hooks0.dateSpanTransforms.concat(hooks1.dateSpanTransforms), 7576 views: Object.assign(Object.assign({}, hooks0.views), hooks1.views), 7577 viewPropsTransformers: hooks0.viewPropsTransformers.concat(hooks1.viewPropsTransformers), 7578 isPropsValid: hooks1.isPropsValid || hooks0.isPropsValid, 7579 externalDefTransforms: hooks0.externalDefTransforms.concat(hooks1.externalDefTransforms), 7580 viewContainerAppends: hooks0.viewContainerAppends.concat(hooks1.viewContainerAppends), 7581 eventDropTransformers: hooks0.eventDropTransformers.concat(hooks1.eventDropTransformers), 7582 calendarInteractions: hooks0.calendarInteractions.concat(hooks1.calendarInteractions), 7583 componentInteractions: hooks0.componentInteractions.concat(hooks1.componentInteractions),
7584 themeClasses: Object.assign(Object.assign({}, hooks0.themeClasses), hooks1.themeClasses), 7585 eventSourceDefs: hooks0.eventSourceDefs.concat(hooks1.eventSourceDefs), 7586 cmdFormatter: hooks1.cmdFormatter || hooks0.cmdFormatter, 7587 recurringTypes: hooks0.recurringTypes.concat(hooks1.recurringTypes), 7588 namedTimeZonedImpl: hooks1.namedTimeZonedImpl || hooks0.namedTimeZonedImpl, 7589 initialView: hooks0.initialView || hooks1.initialView, 7590 elementDraggingImpl: hooks0.elementDraggingImpl || hooks1.elementDraggingImpl, 7591 optionChangeHandlers: Object.assign(Object.assign({}, hooks0.optionChangeHandlers), hooks1.optionChangeHandlers), 7592 scrollGridImpl: hooks1.scrollGridImpl || hooks0.scrollGridImpl, 7593 listenerRefiners: Object.assign(Object.assign({}, hooks0.listenerRefiners), hooks1.listenerRefiners), 7594 optionRefiners: Object.assign(Object.assign({}, hooks0.optionRefiners), hooks1.optionRefiners), 7595 propSetHandlers: Object.assign(Object.assign({}, hooks0.propSetHandlers), hooks1.propSetHandlers) 7596 }; 7597} 7598function compareOptionalDates(date0, date1) { 7599 if (date0 === void 0) { 7600 return date1; 7601 } 7602 if (date1 === void 0) { 7603 return date0; 7604 } 7605 return new Date(Math.max(date0.valueOf(), date1.valueOf())); 7606} 7607class StandardTheme extends Theme { 7608} 7609StandardTheme.prototype.classes = { 7610 root: "fc-theme-standard", 7611 tableCellShaded: "fc-cell-shaded", 7612 buttonGroup: "fc-button-group", 7613 button: "fc-button fc-button-primary", 7614 buttonActive: "fc-button-active" 7615}; 7616StandardTheme.prototype.baseIconClass = "fc-icon"; 7617StandardTheme.prototype.iconClasses = { 7618 close: "fc-icon-x", 7619 prev: "fc-icon-chevron-left", 7620 next: "fc-icon-chevron-right", 7621 prevYear: "fc-icon-chevrons-left", 7622 nextYear: "fc-icon-chevrons-right" 7623}; 7624StandardTheme.prototype.rtlIconClasses = { 7625 prev: "fc-icon-chevron-right", 7626 next: "fc-icon-chevron-left", 7627 prevYear: "fc-icon-chevrons-right", 7628 nextYear: "fc-icon-chevrons-left" 7629}; 7630StandardTheme.prototype.iconOverrideOption = "buttonIcons"; 7631StandardTheme.prototype.iconOverrideCustomButtonOption = "icon"; 7632StandardTheme.prototype.iconOverridePrefix = "fc-icon-"; 7633function compileViewDefs(defaultConfigs, overrideConfigs) { 7634 let hash = {}; 7635 let viewType; 7636 for (viewType in defaultConfigs) { 7637 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7638 } 7639 for (viewType in overrideConfigs) { 7640 ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7641 } 7642 return hash; 7643} 7644function ensureViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 7645 if (hash[viewType]) { 7646 return hash[viewType]; 7647 } 7648 let viewDef = buildViewDef(viewType, hash, defaultConfigs, overrideConfigs); 7649 if (viewDef) { 7650 hash[viewType] = viewDef; 7651 } 7652 return viewDef; 7653} 7654function buildViewDef(viewType, hash, defaultConfigs, overrideConfigs) { 7655 let defaultConfig = defaultConfigs[viewType]; 7656 let overrideConfig = overrideConfigs[viewType]; 7657 let queryProp = (name) => defaultConfig && defaultConfig[name] !== null ? defaultConfig[name] : overrideConfig && overrideConfig[name] !== null ? overrideConfig[name] : null; 7658 let theComponent = queryProp("component"); 7659 let superType = queryProp("superType"); 7660 let superDef = null; 7661 if (superType) { 7662 if (superType === viewType) { 7663 throw new Error("Can't have a custom view type that references itself"); 7664 } 7665 superDef = ensureViewDef(superType, hash, defaultConfigs, overrideConfigs); 7666 } 7667 if (!theComponent && superDef) { 7668 theComponent = superDef.component; 7669 } 7670 if (!theComponent) { 7671 return null; 7672 } 7673 return { 7674 type: viewType, 7675 component: theComponent, 7676 defaults: Object.assign(Object.assign({}, superDef ? superDef.defaults : {}), defaultConfig ? defaultConfig.rawOptions : {}), 7677 overrides: Object.assign(Object.assign({}, superDef ? superDef.overrides : {}), overrideConfig ? overrideConfig.rawOptions : {}) 7678 }; 7679} 7680function parseViewConfigs(inputs) { 7681 return mapHash(inputs, parseViewConfig); 7682} 7683function parseViewConfig(input) { 7684 let rawOptions = typeof input === "function" ? { component: input } : input; 7685 let { component } = rawOptions; 7686 if (rawOptions.content) { 7687 component = createViewHookComponent(rawOptions); 7688 } else if (component && !(component.prototype instanceof BaseComponent)) { 7689 component = createViewHookComponent(Object.assign(Object.assign({}, rawOptions), { content: component })); 7690 } 7691 return { 7692 superType: rawOptions.type, 7693 component, 7694 rawOptions 7695 // includes type and component too :( 7696 }; 7697} 7698function createViewHookComponent(options) { 7699 return (viewProps) => y(ViewContextType.Consumer, null, (context) => y(ContentContainer, { elTag: "div", elClasses: buildViewClassNames(context.viewSpec), renderProps: Object.assign(Object.assign({}, viewProps), { nextDayThreshold: context.options.nextDayThreshold }), generatorName: void 0, customGenerator: options.content, classNameGenerator: options.classNames, didMount: options.didMount, willUnmount: options.willUnmount })); 7700} 7701function buildViewSpecs(defaultInputs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 7702 let defaultConfigs = parseViewConfigs(defaultInputs); 7703 let overrideConfigs = parseViewConfigs(optionOverrides.views); 7704 let viewDefs = compileViewDefs(defaultConfigs, overrideConfigs); 7705 return mapHash(viewDefs, (viewDef) => buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults)); 7706} 7707function buildViewSpec(viewDef, overrideConfigs, optionOverrides, dynamicOptionOverrides, localeDefaults) { 7708 let durationInput = viewDef.overrides.duration || viewDef.defaults.duration || dynamicOptionOverrides.duration || optionOverrides.duration; 7709 let duration = null; 7710 let durationUnit = ""; 7711 let singleUnit = ""; 7712 let singleUnitOverrides = {}; 7713 if (durationInput) { 7714 duration = createDurationCached(durationInput); 7715 if (duration) { 7716 let denom = greatestDurationDenominator(duration); 7717 durationUnit = denom.unit; 7718 if (denom.value === 1) { 7719 singleUnit = durationUnit; 7720 singleUnitOverrides = overrideConfigs[durationUnit] ? overrideConfigs[durationUnit].rawOptions : {}; 7721 } 7722 } 7723 } 7724 let queryButtonText = (optionsSubset) => { 7725 let buttonTextMap = optionsSubset.buttonText || {}; 7726 let buttonTextKey = viewDef.defaults.buttonTextKey; 7727 if (buttonTextKey != null && buttonTextMap[buttonTextKey] != null) { 7728 return buttonTextMap[buttonTextKey]; 7729 } 7730 if (buttonTextMap[viewDef.type] != null) { 7731 return buttonTextMap[viewDef.type]; 7732 } 7733 if (buttonTextMap[singleUnit] != null) { 7734 return buttonTextMap[singleUnit]; 7735 } 7736 return null; 7737 }; 7738 let queryButtonTitle = (optionsSubset) => { 7739 let buttonHints = optionsSubset.buttonHints || {}; 7740 let buttonKey = viewDef.defaults.buttonTextKey; 7741 if (buttonKey != null && buttonHints[buttonKey] != null) { 7742 return buttonHints[buttonKey]; 7743 } 7744 if (buttonHints[viewDef.type] != null) { 7745 return buttonHints[viewDef.type]; 7746 } 7747 if (buttonHints[singleUnit] != null) { 7748 return buttonHints[singleUnit]; 7749 } 7750 return null; 7751 }; 7752 return { 7753 type: viewDef.type, 7754 component: viewDef.component, 7755 duration, 7756 durationUnit, 7757 singleUnit, 7758 optionDefaults: viewDef.defaults, 7759 optionOverrides: Object.assign(Object.assign({}, singleUnitOverrides), viewDef.overrides), 7760 buttonTextOverride: queryButtonText(dynamicOptionOverrides) || queryButtonText(optionOverrides) || // constructor-specified buttonText lookup hash takes precedence 7761 viewDef.overrides.buttonText, 7762 buttonTextDefault: queryButtonText(localeDefaults) || viewDef.defaults.buttonText || queryButtonText(BASE_OPTION_DEFAULTS) || viewDef.type, 7763 // not DRY 7764 buttonTitleOverride: queryButtonTitle(dynamicOptionOverrides) || queryButtonTitle(optionOverrides) || viewDef.overrides.buttonHint, 7765 buttonTitleDefault: queryButtonTitle(localeDefaults) || viewDef.defaults.buttonHint || queryButtonTitle(BASE_OPTION_DEFAULTS) 7766 // will eventually fall back to buttonText 7767 }; 7768} 7769let durationInputMap = {}; 7770function createDurationCached(durationInput) { 7771 let json = JSON.stringify(durationInput); 7772 let res = durationInputMap[json]; 7773 if (res === void 0) { 7774 res = createDuration(durationInput); 7775 durationInputMap[json] = res; 7776 } 7777 return res; 7778} 7779function reduceViewType(viewType, action) { 7780 switch (action.type) { 7781 case "CHANGE_VIEW_TYPE": 7782 viewType = action.viewType; 7783 } 7784 return viewType; 7785} 7786function reduceDynamicOptionOverrides(dynamicOptionOverrides, action) { 7787 switch (action.type) { 7788 case "SET_OPTION": 7789 return Object.assign(Object.assign({}, dynamicOptionOverrides), { [action.optionName]: action.rawOptionValue }); 7790 default: 7791 return dynamicOptionOverrides; 7792 } 7793} 7794function reduceDateProfile(currentDateProfile, action, currentDate, dateProfileGenerator) { 7795 let dp; 7796 switch (action.type) { 7797 case "CHANGE_VIEW_TYPE": 7798 return dateProfileGenerator.build(action.dateMarker || currentDate); 7799 case "CHANGE_DATE": 7800 return dateProfileGenerator.build(action.dateMarker); 7801 case "PREV": 7802 dp = dateProfileGenerator.buildPrev(currentDateProfile, currentDate); 7803 if (dp.isValid) { 7804 return dp; 7805 } 7806 break; 7807 case "NEXT": 7808 dp = dateProfileGenerator.buildNext(currentDateProfile, currentDate); 7809 if (dp.isValid) { 7810 return dp; 7811 } 7812 break; 7813 } 7814 return currentDateProfile; 7815} 7816function initEventSources(calendarOptions, dateProfile, context) { 7817 let activeRange = dateProfile ? dateProfile.activeRange : null; 7818 return addSources({}, parseInitialSources(calendarOptions, context), activeRange, context); 7819} 7820function reduceEventSources(eventSources, action, dateProfile, context) { 7821 let activeRange = dateProfile ? dateProfile.activeRange : null; 7822 switch (action.type) { 7823 case "ADD_EVENT_SOURCES": 7824 return addSources(eventSources, action.sources, activeRange, context);
vendor: 7,264 bytes, lines 7825-8036
7825 case "REMOVE_EVENT_SOURCE": 7826 return removeSource(eventSources, action.sourceId); 7827 case "PREV": 7828 case "NEXT": 7829 case "CHANGE_DATE": 7830 case "CHANGE_VIEW_TYPE": 7831 if (dateProfile) { 7832 return fetchDirtySources(eventSources, activeRange, context); 7833 } 7834 return eventSources; 7835 case "FETCH_EVENT_SOURCES": 7836 return fetchSourcesByIds(eventSources, action.sourceIds ? ( 7837 // why no type? 7838 arrayToHash(action.sourceIds) 7839 ) : excludeStaticSources(eventSources, context), activeRange, action.isRefetch || false, context); 7840 case "RECEIVE_EVENTS": 7841 case "RECEIVE_EVENT_ERROR": 7842 return receiveResponse(eventSources, action.sourceId, action.fetchId, action.fetchRange); 7843 case "REMOVE_ALL_EVENT_SOURCES": 7844 return {}; 7845 default: 7846 return eventSources; 7847 } 7848} 7849function reduceEventSourcesNewTimeZone(eventSources, dateProfile, context) { 7850 let activeRange = dateProfile ? dateProfile.activeRange : null; 7851 return fetchSourcesByIds(eventSources, excludeStaticSources(eventSources, context), activeRange, true, context); 7852} 7853function computeEventSourcesLoading(eventSources) { 7854 for (let sourceId in eventSources) { 7855 if (eventSources[sourceId].isFetching) { 7856 return true; 7857 } 7858 } 7859 return false; 7860} 7861function addSources(eventSourceHash, sources, fetchRange, context) { 7862 let hash = {}; 7863 for (let source of sources) { 7864 hash[source.sourceId] = source; 7865 } 7866 if (fetchRange) { 7867 hash = fetchDirtySources(hash, fetchRange, context); 7868 } 7869 return Object.assign(Object.assign({}, eventSourceHash), hash); 7870} 7871function removeSource(eventSourceHash, sourceId) { 7872 return filterHash(eventSourceHash, (eventSource) => eventSource.sourceId !== sourceId); 7873} 7874function fetchDirtySources(sourceHash, fetchRange, context) { 7875 return fetchSourcesByIds(sourceHash, filterHash(sourceHash, (eventSource) => isSourceDirty(eventSource, fetchRange, context)), fetchRange, false, context); 7876} 7877function isSourceDirty(eventSource, fetchRange, context) { 7878 if (!doesSourceNeedRange(eventSource, context)) { 7879 return !eventSource.latestFetchId; 7880 } 7881 return !context.options.lazyFetching || !eventSource.fetchRange || eventSource.isFetching || // always cancel outdated in-progress fetches 7882 fetchRange.start < eventSource.fetchRange.start || fetchRange.end > eventSource.fetchRange.end; 7883} 7884function fetchSourcesByIds(prevSources, sourceIdHash, fetchRange, isRefetch, context) { 7885 let nextSources = {}; 7886 for (let sourceId in prevSources) { 7887 let source = prevSources[sourceId]; 7888 if (sourceIdHash[sourceId]) { 7889 nextSources[sourceId] = fetchSource(source, fetchRange, isRefetch, context); 7890 } else { 7891 nextSources[sourceId] = source; 7892 } 7893 } 7894 return nextSources; 7895} 7896function fetchSource(eventSource, fetchRange, isRefetch, context) { 7897 let { options, calendarApi } = context; 7898 let sourceDef = context.pluginHooks.eventSourceDefs[eventSource.sourceDefId]; 7899 let fetchId = guid(); 7900 sourceDef.fetch({ 7901 eventSource, 7902 range: fetchRange, 7903 isRefetch, 7904 context 7905 }, (res) => { 7906 let { rawEvents } = res; 7907 if (options.eventSourceSuccess) { 7908 rawEvents = options.eventSourceSuccess.call(calendarApi, rawEvents, res.response) || rawEvents; 7909 } 7910 if (eventSource.success) { 7911 rawEvents = eventSource.success.call(calendarApi, rawEvents, res.response) || rawEvents; 7912 } 7913 context.dispatch({ 7914 type: "RECEIVE_EVENTS", 7915 sourceId: eventSource.sourceId, 7916 fetchId, 7917 fetchRange, 7918 rawEvents 7919 }); 7920 }, (error) => { 7921 let errorHandled = false; 7922 if (options.eventSourceFailure) { 7923 options.eventSourceFailure.call(calendarApi, error); 7924 errorHandled = true; 7925 } 7926 if (eventSource.failure) { 7927 eventSource.failure(error); 7928 errorHandled = true; 7929 } 7930 if (!errorHandled) { 7931 console.warn(error.message, error); 7932 } 7933 context.dispatch({ 7934 type: "RECEIVE_EVENT_ERROR", 7935 sourceId: eventSource.sourceId, 7936 fetchId, 7937 fetchRange, 7938 error 7939 }); 7940 }); 7941 return Object.assign(Object.assign({}, eventSource), { isFetching: true, latestFetchId: fetchId }); 7942} 7943function receiveResponse(sourceHash, sourceId, fetchId, fetchRange) { 7944 let eventSource = sourceHash[sourceId]; 7945 if (eventSource && // not already removed 7946 fetchId === eventSource.latestFetchId) { 7947 return Object.assign(Object.assign({}, sourceHash), { [sourceId]: Object.assign(Object.assign({}, eventSource), { isFetching: false, fetchRange }) }); 7948 } 7949 return sourceHash; 7950} 7951function excludeStaticSources(eventSources, context) { 7952 return filterHash(eventSources, (eventSource) => doesSourceNeedRange(eventSource, context)); 7953} 7954function parseInitialSources(rawOptions, context) { 7955 let refiners = buildEventSourceRefiners(context); 7956 let rawSources = [].concat(rawOptions.eventSources || []); 7957 let sources = []; 7958 if (rawOptions.initialEvents) { 7959 rawSources.unshift(rawOptions.initialEvents); 7960 } 7961 if (rawOptions.events) { 7962 rawSources.unshift(rawOptions.events); 7963 } 7964 for (let rawSource of rawSources) { 7965 let source = parseEventSource(rawSource, context, refiners); 7966 if (source) { 7967 sources.push(source); 7968 } 7969 } 7970 return sources; 7971} 7972function doesSourceNeedRange(eventSource, context) { 7973 let defs = context.pluginHooks.eventSourceDefs; 7974 return !defs[eventSource.sourceDefId].ignoreRange; 7975} 7976function reduceDateSelection(currentSelection, action) { 7977 switch (action.type) { 7978 case "UNSELECT_DATES": 7979 return null; 7980 case "SELECT_DATES": 7981 return action.selection; 7982 default: 7983 return currentSelection; 7984 } 7985} 7986function reduceSelectedEvent(currentInstanceId, action) { 7987 switch (action.type) { 7988 case "UNSELECT_EVENT": 7989 return ""; 7990 case "SELECT_EVENT": 7991 return action.eventInstanceId; 7992 default: 7993 return currentInstanceId; 7994 } 7995} 7996function reduceEventDrag(currentDrag, action) { 7997 let newDrag; 7998 switch (action.type) { 7999 case "UNSET_EVENT_DRAG": 8000 return null; 8001 case "SET_EVENT_DRAG": 8002 newDrag = action.state; 8003 return { 8004 affectedEvents: newDrag.affectedEvents, 8005 mutatedEvents: newDrag.mutatedEvents, 8006 isEvent: newDrag.isEvent 8007 }; 8008 default: 8009 return currentDrag; 8010 } 8011} 8012function reduceEventResize(currentResize, action) { 8013 let newResize; 8014 switch (action.type) { 8015 case "UNSET_EVENT_RESIZE": 8016 return null; 8017 case "SET_EVENT_RESIZE": 8018 newResize = action.state; 8019 return { 8020 affectedEvents: newResize.affectedEvents, 8021 mutatedEvents: newResize.mutatedEvents, 8022 isEvent: newResize.isEvent 8023 }; 8024 default: 8025 return currentResize; 8026 } 8027} 8028function parseToolbars(calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 8029 let header = calendarOptions.headerToolbar ? parseToolbar(calendarOptions.headerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 8030 let footer = calendarOptions.footerToolbar ? parseToolbar(calendarOptions.footerToolbar, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) : null; 8031 return { header, footer }; 8032} 8033function parseToolbar(sectionStrHash, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 8034 let sectionWidgets = {}; 8035 let viewsWithButtons = []; 8036 let hasTitle = false;
8037 for (let sectionName in sectionStrHash) { 8038 let sectionStr = sectionStrHash[sectionName]; 8039 let sectionRes = parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi); 8040 sectionWidgets[sectionName] = sectionRes.widgets; 8041 viewsWithButtons.push(...sectionRes.viewsWithButtons); 8042 hasTitle = hasTitle || sectionRes.hasTitle; 8043 } 8044 return { sectionWidgets, viewsWithButtons, hasTitle }; 8045} 8046function parseSection(sectionStr, calendarOptions, calendarOptionOverrides, theme, viewSpecs, calendarApi) { 8047 let isRtl = calendarOptions.direction === "rtl"; 8048 let calendarCustomButtons = calendarOptions.customButtons || {}; 8049 let calendarButtonTextOverrides = calendarOptionOverrides.buttonText || {}; 8050 let calendarButtonText = calendarOptions.buttonText || {}; 8051 let calendarButtonHintOverrides = calendarOptionOverrides.buttonHints || {}; 8052 let calendarButtonHints = calendarOptions.buttonHints || {}; 8053 let sectionSubstrs = sectionStr ? sectionStr.split(" ") : []; 8054 let viewsWithButtons = []; 8055 let hasTitle = false; 8056 let widgets = sectionSubstrs.map((buttonGroupStr) => buttonGroupStr.split(",").map((buttonName) => { 8057 if (buttonName === "title") { 8058 hasTitle = true; 8059 return { buttonName }; 8060 } 8061 let customButtonProps; 8062 let viewSpec; 8063 let buttonClick; 8064 let buttonIcon; 8065 let buttonText; 8066 let buttonHint; 8067 if (customButtonProps = calendarCustomButtons[buttonName]) { 8068 buttonClick = (ev) => { 8069 if (customButtonProps.click) { 8070 customButtonProps.click.call(ev.target, ev, ev.target); 8071 } 8072 }; 8073 (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = customButtonProps.text); 8074 buttonHint = customButtonProps.hint || customButtonProps.text; 8075 } else if (viewSpec = viewSpecs[buttonName]) { 8076 viewsWithButtons.push(buttonName); 8077 buttonClick = () => { 8078 calendarApi.changeView(buttonName); 8079 }; 8080 (buttonText = viewSpec.buttonTextOverride) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = viewSpec.buttonTextDefault); 8081 let textFallback = viewSpec.buttonTextOverride || viewSpec.buttonTextDefault; 8082 buttonHint = formatWithOrdinals( 8083 viewSpec.buttonTitleOverride || viewSpec.buttonTitleDefault || calendarOptions.viewHint, 8084 [textFallback, buttonName], 8085 // view-name = buttonName 8086 textFallback 8087 ); 8088 } else if (calendarApi[buttonName]) { 8089 buttonClick = () => { 8090 calendarApi[buttonName](); 8091 }; 8092 (buttonText = calendarButtonTextOverrides[buttonName]) || (buttonIcon = theme.getIconClass(buttonName, isRtl)) || (buttonText = calendarButtonText[buttonName]); 8093 if (buttonName === "prevYear" || buttonName === "nextYear") { 8094 let prevOrNext = buttonName === "prevYear" ? "prev" : "next"; 8095 buttonHint = formatWithOrdinals(calendarButtonHintOverrides[prevOrNext] || calendarButtonHints[prevOrNext], [ 8096 calendarButtonText.year || "year", 8097 "year" 8098 ], calendarButtonText[buttonName]); 8099 } else { 8100 buttonHint = (navUnit) => formatWithOrdinals(calendarButtonHintOverrides[buttonName] || calendarButtonHints[buttonName], [ 8101 calendarButtonText[navUnit] || navUnit, 8102 navUnit 8103 ], calendarButtonText[buttonName]); 8104 } 8105 } 8106 return { buttonName, buttonClick, buttonIcon, buttonText, buttonHint }; 8107 })); 8108 return { widgets, viewsWithButtons, hasTitle }; 8109} 8110class ViewImpl { 8111 constructor(type, getCurrentData, dateEnv) { 8112 this.type = type; 8113 this.getCurrentData = getCurrentData; 8114 this.dateEnv = dateEnv; 8115 } 8116 get calendar() { 8117 return this.getCurrentData().calendarApi; 8118 } 8119 get title() { 8120 return this.getCurrentData().viewTitle; 8121 } 8122 get activeStart() { 8123 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.start); 8124 } 8125 get activeEnd() { 8126 return this.dateEnv.toDate(this.getCurrentData().dateProfile.activeRange.end); 8127 } 8128 get currentStart() { 8129 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.start); 8130 } 8131 get currentEnd() { 8132 return this.dateEnv.toDate(this.getCurrentData().dateProfile.currentRange.end); 8133 } 8134 getOption(name) { 8135 return this.getCurrentData().options[name]; 8136 } 8137} 8138let eventSourceDef$2 = { 8139 ignoreRange: true, 8140 parseMeta(refined) { 8141 if (Array.isArray(refined.events)) { 8142 return refined.events; 8143 } 8144 return null; 8145 }, 8146 fetch(arg, successCallback) { 8147 successCallback({ 8148 rawEvents: arg.eventSource.meta 8149 }); 8150 } 8151}; 8152const arrayEventSourcePlugin = createPlugin({ 8153 name: "array-event-source", 8154 eventSourceDefs: [eventSourceDef$2] 8155}); 8156let eventSourceDef$1 = { 8157 parseMeta(refined) { 8158 if (typeof refined.events === "function") { 8159 return refined.events; 8160 } 8161 return null; 8162 }, 8163 fetch(arg, successCallback, errorCallback) { 8164 const { dateEnv } = arg.context; 8165 const func = arg.eventSource.meta; 8166 unpromisify(func.bind(null, buildRangeApiWithTimeZone(arg.range, dateEnv)), (rawEvents) => successCallback({ rawEvents }), errorCallback); 8167 } 8168}; 8169const funcEventSourcePlugin = createPlugin({ 8170 name: "func-event-source", 8171 eventSourceDefs: [eventSourceDef$1] 8172}); 8173const JSON_FEED_EVENT_SOURCE_REFINERS = { 8174 method: String, 8175 extraParams: identity, 8176 startParam: String, 8177 endParam: String, 8178 timeZoneParam: String 8179}; 8180let eventSourceDef = { 8181 parseMeta(refined) { 8182 if (refined.url && (refined.format === "json" || !refined.format)) { 8183 return { 8184 url: refined.url, 8185 format: "json", 8186 method: (refined.method || "GET").toUpperCase(), 8187 extraParams: refined.extraParams, 8188 startParam: refined.startParam, 8189 endParam: refined.endParam, 8190 timeZoneParam: refined.timeZoneParam 8191 }; 8192 } 8193 return null; 8194 }, 8195 fetch(arg, successCallback, errorCallback) { 8196 const { meta } = arg.eventSource;
8197 const requestParams = buildRequestParams(meta, arg.range, arg.context); 8198 requestJson(meta.method, meta.url, requestParams).then(([rawEvents, response]) => { 8199 successCallback({ rawEvents, response }); 8200 }, errorCallback); 8201 } 8202}; 8203const jsonFeedEventSourcePlugin = createPlugin({ 8204 name: "json-event-source", 8205 eventSourceRefiners: JSON_FEED_EVENT_SOURCE_REFINERS, 8206 eventSourceDefs: [eventSourceDef] 8207}); 8208function buildRequestParams(meta, range, context) { 8209 let { dateEnv, options } = context; 8210 let startParam; 8211 let endParam; 8212 let timeZoneParam; 8213 let customRequestParams; 8214 let params = {}; 8215 startParam = meta.startParam; 8216 if (startParam == null) { 8217 startParam = options.startParam; 8218 } 8219 endParam = meta.endParam; 8220 if (endParam == null) { 8221 endParam = options.endParam; 8222 } 8223 timeZoneParam = meta.timeZoneParam; 8224 if (timeZoneParam == null) { 8225 timeZoneParam = options.timeZoneParam; 8226 } 8227 if (typeof meta.extraParams === "function") { 8228 customRequestParams = meta.extraParams(); 8229 } else { 8230 customRequestParam
8230s = meta.extraParams || {}; 8231 } 8232 Object.assign(params, customRequestParams); 8233 params[startParam] = dateEnv.formatIso(range.start); 8234 params[endParam] = dateEnv.formatIso(range.end); 8235 if (dateEnv.timeZone !== "local") { 8236 params[timeZoneParam] = dateEnv.timeZone; 8237 } 8238 return params; 8239} 8240const SIMPLE_RECURRING_REFINERS = { 8241 daysOfWeek: identity, 8242 startTime: createDuration, 8243 endTime: createDuration, 8244 duration: createDuration, 8245 startRecur: identity, 8246 endRecur: identity 8247}; 8248let recurring = { 8249 parse(refined, dateEnv) { 8250 if (refined.daysOfWeek || refined.startTime || refined.endTime || refined.startRecur || refined.endRecur) { 8251 let recurringData = { 8252 daysOfWeek: refined.daysOfWeek || null, 8253 startTime: refined.startTime || null, 8254 endTime: refined.endTime || null, 8255 startRecur: refined.startRecur ? dateEnv.createMarker(refined.startRecur) : null, 8256 endRecur: refined.endRecur ? dateEnv.createMarker(refined.endRecur) : null 8257 }; 8258 let duration; 8259 if (refined.duration) { 8260 duration = refined.duration; 8261 } 8262 if (!duration && refined.startTime && refined.endTime) { 8263 duration = subtractDurations(refined.endTime, refined.startTime); 8264 } 8265 return { 8266 allDayGuess: Boolean(!refined.startTime && !refined.endTime), 8267 duration, 8268 typeData: recurringData 8269 // doesn't need endTime anymore but oh well 8270 }; 8271 } 8272 return null; 8273 }, 8274 expand(typeData, framingRange, dateEnv) { 8275 let clippedFramingRange = intersectRanges(framingRange, { start: typeData.startRecur, end: typeData.endRecur }); 8276 if (clippedFramingRange) { 8277 return expandRanges(typeData.daysOfWeek, typeData.startTime, clippedFramingRange, dateEnv); 8278 } 8279 return []; 8280 } 8281}; 8282const simpleRecurringEventsPlugin = createPlugin({ 8283 name: "simple-recurring-event", 8284 recurringTypes: [recurring], 8285 eventRefiners: SIMPLE_RECURRING_REFINERS 8286}); 8287function expandRanges(daysOfWeek, startTime, framingRange, dateEnv) { 8288 let dowHash = daysOfWeek ? arrayToHash(daysOfWeek) : null; 8289 let dayMarker = startOfDay(framingRange.start); 8290 let endMarker = framingRange.end; 8291 let instanceStarts = []; 8292 while (dayMarker < endMarker) { 8293 let instanceStart; 8294 if (!dowHash || dowHash[dayMarker.getUTCDay()]) { 8295 if (startTime) { 8296 instanceStart = dateEnv.add(dayMarker, startTime); 8297 } else { 8298 instanceStart = dayMarker; 8299 } 8300 instanceStarts.push(instanceStart); 8301 } 8302 dayMarker = addDays(dayMarker, 1); 8303 } 8304 return instanceStarts; 8305} 8306const changeHandlerPlugin = createPlugin({ 8307 name: "change-handler", 8308 optionChangeHandlers: { 8309 events(events, context) { 8310 handleEventSources([events], context); 8311 }, 8312 eventSources: handleEventSources 8313 } 8314}); 8315function handleEventSources(inputs, context) { 8316 let unfoundSources = hashValuesToArray(context.getCurrentData().eventSources); 8317 if (unfoundSources.length === 1 && inputs.length === 1 && Array.isArray(unfoundSources[0]._raw) && Array.isArray(inputs[0])) { 8318 context.dispatch({ 8319 type: "RESET_RAW_EVENTS", 8320 sourceId: unfoundSources[0].sourceId, 8321 rawEvents: inputs[0] 8322 }); 8323 return; 8324 } 8325 let newInputs = []; 8326 for (let input of inputs) { 8327 let inputFound = false; 8328 for (let i2 = 0; i2 < unfoundSources.length; i2 += 1) { 8329 if (unfoundSources[i2]._raw === input) { 8330 unfoundSources.splice(i2, 1); 8331 inputFound = true; 8332 break; 8333 } 8334 } 8335 if (!inputFound) { 8336 newInputs.push(input); 8337 } 8338 } 8339 for (let unfoundSource of unfoundSources) { 8340 context.dispatch({ 8341 type: "REMOVE_EVENT_SOURCE", 8342 sourceId: unfoundSource.sourceId 8343 }); 8344 } 8345 for (let newInput of newInputs) { 8346 context.calendarApi.addEventSource(newInput); 8347 } 8348} 8349function handleDateProfile(dateProfile, context) { 8350 context.emitter.trigger("datesSet", Object.assign(Object.assign({}, buildRangeApiWithTimeZone(dateProfile.activeRange, context.dateEnv)), { view: context.viewApi })); 8351} 8352function handleEventStore(eventStore, context) { 8353 let { emitter } = context; 8354 if (emitter.hasHandlers("eventsSet")) { 8355 emitter.trigger("eventsSet", buildEventApis(eventStore, context)); 8356 } 8357} 8358const globalPlugins = [ 8359 arrayEventSourcePlugin, 8360 funcEventSourcePlugin, 8361 jsonFeedEventSourcePlugin, 8362 simpleRecurringEventsPlugin, 8363 changeHandlerPlugin, 8364 createPlugin({ 8365 name: "misc", 8366 isLoadingFuncs: [ 8367 (state) => computeEventSourcesLoading(state.eventSources) 8368 ], 8369 propSetHandlers: { 8370 dateProfile: handleDateProfile, 8371 eventStore: handleEventStore 8372 } 8373 }) 8374]; 8375class TaskRunner { 8376 constructor(runTaskOption, drainedOption) { 8377 this.runTaskOption = runTaskOption; 8378 this.drainedOption = drainedOption; 8379 this.queue = []; 8380 this.delayedRunner = new DelayedRunner(this.drain.bind(this)); 8381 } 8382 request(task, delay) { 8383 this.queue.push(task); 8384 this.delayedRunner.request(delay); 8385 } 8386 pause(scope) { 8387 this.delayedRunner.pause(scope); 8388 } 8389 resume(scope, force) { 8390 this.delayedRunner.resume(scope, force); 8391 } 8392 drain() { 8393 let { queue } = this; 8394 while (queue.length) { 8395 let completedTasks = []; 8396 let task; 8397 while (task = queue.shift()) { 8398 this.runTask(task); 8399 completedTasks.push(task); 8400 } 8401 this.drained(completedTasks); 8402 } 8403 } 8404 runTask(task) { 8405 if (this.runTaskOption) { 8406 this.runTaskOption(task); 8407 } 8408 } 8409 drained(completedTasks) { 8410 if (this.drainedOption) { 8411 this.drainedOption(completedTasks); 8412 } 8413 } 8414} 8415function buildTitle(dateProfile, viewOptions, dateEnv) { 8416 let range; 8417 if (/^(year|month)$/.test(dateProfile.currentRangeUnit)) { 8418 range = dateProfile.currentRange; 8419 } else { 8420 range = dateProfile.activeRange; 8421 } 8422 return dateEnv.formatRange(range.start, range.end, createFormatter(viewOptions.titleFormat || buildTitleFormat(dateProfile)), { 8423 isEndExclusive: dateProfile.isRangeAllDay, 8424 defaultSeparator: viewOptions.titleRangeSeparator 8425 }); 8426} 8427function buildTitleFormat(dateProfile) { 8428 let { currentRangeUnit } = dateProfile; 8429 if (currentRangeUnit === "year") { 8430 return { year: "numeric" }; 8431 } 8432 if (currentRangeUnit === "month") { 8433 return { year: "numeric", month: "long" }; 8434 } 8435 let days = diffWholeDays(dateProfile.currentRange.start, dateProfile.currentRange.end); 8436 if (days !== null && days > 1) {
8437 return { year: "numeric", month: "short", day: "numeric" }; 8438 } 8439 return { year: "numeric", month: "long", day: "numeric" }; 8440} 8441class CalendarDataManager { 8442 constructor(props) { 8443 this.computeCurrentViewData = memoize(this._computeCurrentViewData); 8444 this.organizeRawLocales = memoize(organizeRawLocales); 8445 this.buildLocale = memoize(buildLocale); 8446 this.buildPluginHooks = buildBuildPluginHooks(); 8447 this.buildDateEnv = memoize(buildDateEnv$1); 8448 this.buildTheme = memoize(buildTheme); 8449 this.parseToolbars = memoize(parseToolbars); 8450 this.buildViewSpecs = memoize(buildViewSpecs); 8451 this.buildDateProfileGenerator = memoizeObjArg(buildDateProfileGenerator); 8452 this.buildViewApi = memoize(buildViewApi); 8453 this.buildViewUiProps = memoizeObjArg(buildViewUiProps); 8454 this.buildEventUiBySource = memoize(buildEventUiBySource, isPropsEqual); 8455 this.buildEventUiBases = memoize(buildEventUiBases); 8456 this.parseContextBusinessHours = memoizeObjArg(parseContextBusinessHours); 8457 this.buildTitle = memoize(buildTitle); 8458 this.emitter = new Emitter(); 8459 this.actionRunner = new TaskRunner(this._handleAction.bind(this), this.updateData.bind(this)); 8460 this.currentCalendarOptionsInput = {}; 8461 this.currentCalendarOptionsRefined = {}; 8462 this.currentViewOptionsInput = {}; 8463 this.currentViewOptionsRefined = {}; 8464 this.currentCalendarOptionsRefiners = {}; 8465 this.optionsForRefining = []; 8466 this.optionsForHandling = []; 8467 this.getCurrentData = () => this.data; 8468 this.dispatch = (action) => { 8469 this.actionRunner.request(action); 8470 }; 8471 this.props = props; 8472 this.actionRunner.pause(); 8473 let dynamicOptionOverrides = {}; 8474 let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi); 8475 let currentViewType = optionsData.calendarOptions.initialView || optionsData.pluginHooks.initialView; 8476 let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 8477 props.calendarApi.currentDataManager = this; 8478 this.emitter.setThisContext(props.calendarApi); 8479 this.emitter.setOptions(currentViewData.options); 8480 let currentDate = getInitialDate(optionsData.calendarOptions, optionsData.dateEnv); 8481 let dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 8482 if (!rangeContainsMarker(dateProfile.activeRange, currentDate)) { 8483 currentDate = dateProfile.currentRange.start; 8484 } 8485 let calendarContext = { 8486 dateEnv: optionsData.dateEnv, 8487 options: optionsData.calendarOptions, 8488 pluginHooks: optionsData.pluginHooks, 8489 calendarApi: props.calendarApi, 8490 dispatch: this.dispatch, 8491 emitter: this.emitter, 8492 getCurrentData: this.getCurrentData 8493 }; 8494 for (let callback of optionsData.pluginHooks.contextInit) { 8495 callback(calendarContext); 8496 } 8497 let eventSources = initEventSources(optionsData.calendarOptions, dateProfile, calendarContext); 8498 let initialState = { 8499 dynamicOptionOverrides, 8500 currentViewType, 8501 currentDate, 8502 dateProfile, 8503 businessHours: this.parseContextBusinessHours(calendarContext), 8504 eventSources, 8505 eventUiBases: {}, 8506 eventStore: createEmptyEventStore(), 8507 renderableEventStore: createEmptyEventStore(), 8508 dateSelection: null, 8509 eventSelection: "", 8510 eventDrag: null, 8511 eventResize: null, 8512 selectionConfig: this.buildViewUiProps(calendarContext).selectionConfig 8513 }; 8514 let contextAndState = Object.assign(Object.assign({}, calendarContext), initialState); 8515 for (let reducer of optionsData.pluginHooks.reducers) { 8516 Object.assign(initialState, reducer(null, null, contextAndState)); 8517 } 8518 if (computeIsLoading(initialState, calendarContext)) { 8519 this.emitter.trigger("loading", true); 8520 } 8521 this.state = initialState; 8522 this.updateData(); 8523 this.actionRunner.resume(); 8524 } 8525 resetOptions(optionOverrides, changedOptionNames) { 8526 let { props } = this; 8527 if (changedOptionNames === void 0) { 8528 props.optionOverrides = optionOverrides; 8529 } else { 8530 props.optionOverrides = Object.assign(Object.assign({}, props.optionOverrides || {}), optionOverrides); 8531 this.optionsForRefining.push(...changedOptionNames); 8532 } 8533 if (changedOptionNames === void 0 || changedOptionNames.length) { 8534 this.actionRunner.request({ 8535 type: "NOTHING" 8536 }); 8537 } 8538 } 8539 _handleAction(action) { 8540 let { props, state, emitter } = this; 8541 let dynamicOptionOverrides = reduceDynamicOptionOverrides(state.dynamicOptionOverrides, action); 8542 let optionsData = this.computeOptionsData(props.optionOverrides, dynamicOptionOverrides, props.calendarApi);
8543 let currentViewType = reduceViewType(state.currentViewType, action); 8544 let currentViewData = this.computeCurrentViewData(currentViewType, optionsData, props.optionOverrides, dynamicOptionOverrides); 8545 props.calendarApi.currentDataManager = this; 8546 emitter.setThisContext(props.calendarApi); 8547 emitter.setOptions(currentViewData.options); 8548 let calendarContext = { 8549 dateEnv: optionsData.dateEnv, 8550 options: optionsData.calendarOptions, 8551 pluginHooks: optionsData.pluginHooks, 8552 calendarApi: props.calendarApi, 8553 dispatch: this.dispatch, 8554 emitter, 8555 getCurrentData: this.getCurrentData 8556 }; 8557 let { currentDate, dateProfile } = state; 8558 if (this.data && this.data.dateProfileGenerator !== currentViewData.dateProfileGenerator) { 8559 dateProfile = currentViewData.dateProfileGenerator.build(currentDate); 8560 } 8561 currentDate = reduceCurrentDate(currentDate, action); 8562 dateProfile = reduceDateProfile(dateProfile, action, currentDate, currentViewData.dateProfileGenerator); 8563 if (action.type === "PREV" || // TODO: move this logic into DateProfileGenerator 8564 action.type === "NEXT" || // " 8565 !rangeContainsMarker(dateProfile.currentRange, currentDate)) { 8566 currentDate = dateProfile.currentRange.start; 8567 } 8568 let eventSources = reduceEventSources(state.eventSources, action, dateProfile, calendarContext); 8569 let eventStore = reduceEventStore(state.eventStore, action, eventSources, dateProfile, calendarContext); 8570 let isEventsLoading = computeEventSourcesLoading(eventSources); 8571 let renderableEventStore = isEventsLoading && !currentViewData.options.progressiveEventRendering ? state.renderableEventStore || eventStore : ( 8572 // try from previous state 8573 eventStore 8574 ); 8575 let { eventUiSingleBase, selectionConfig } = this.buildViewUiProps(calendarContext); 8576 let eventUiBySource = this.buildEventUiBySource(eventSources); 8577 let eventUiBases = this.buildEventUiBases(renderableEventStore.defs, eventUiSingleBase, eventUiBySource); 8578 let newState = { 8579 dynamicOptionOverrides, 8580 currentViewType, 8581 currentDate, 8582 dateProfile, 8583 eventSources, 8584 eventStore, 8585 renderableEventStore, 8586 selectionConfig, 8587 eventUiBases, 8588 businessHours: this.parseContextBusinessHours(calendarContext), 8589 dateSelection: reduceDateSelection(state.dateSelection, action), 8590 eventSelection: reduceSelectedEvent(state.eventSelection, action), 8591 eventDrag: reduceEventDrag(state.eventDrag, action), 8592 eventResize: reduceEventResize(state.eventResize, action) 8593 }; 8594 let contextAndState = Object.assign(Object.assign({}, calendarContext), newState); 8595 for (let reducer of optionsData.pluginHooks.reducers) { 8596 Object.assign(newState, reducer(state, action, contextAndState)); 8597 } 8598 let wasLoading = computeIsLoading(state, calendarContext); 8599 let isLoading = computeIsLoading(newState, calendarContext); 8600 if (!wasLoading && isLoading) { 8601 emitter.trigger("loading", true); 8602 } else if (wasLoading && !isLoading) { 8603 emitter.trigger("loading", false); 8604 } 8605 this.state = newState; 8606 if (props.onAction) { 8607 props.onAction(action); 8608 } 8609 } 8610 updateData() { 8611 let { props, state } = this; 8612 let oldData = this.data; 8613 let optionsData = this.computeOptionsData(props.optionOverrides, state.dynamicOptionOverrides, props.calendarApi); 8614 let currentViewData = this.computeCurrentViewData(state.currentViewType, optionsData, props.optionOverrides, state.dynamicOptionOverrides); 8615 let data = this.data = Object.assign(Object.assign(Object.assign({ viewTitle: this.buildTitle(state.dateProfile, currentViewData.options, optionsData.dateEnv), calendarApi: props.calendarApi, dispatch: this.dispatch, emitter: this.emitter, getCurrentData: this.getCurrentData }, optionsData), currentViewData), state); 8616 let changeHandlers = optionsData.pluginHooks.optionChangeHandlers; 8617 let oldCalendarOptions = oldData && oldData.calendarOptions; 8618 let newCalendarOptions = optionsData.calendarOptions; 8619 if (oldCalendarOptions && oldCalendarOptions !== newCalendarOptions) { 8620 if (oldCalendarOptions.timeZone !== newCalendarOptions.timeZone) { 8621 state.eventSources = data.eventSources = reduceEventSourcesNe
8621wTimeZone(data.eventSources, state.dateProfile, data); 8622 state.eventStore = data.eventStore = rezoneEventStoreDates(data.eventStore, oldData.dateEnv, data.dateEnv); 8623 state.renderableEventStore = data.renderableEventStore = rezoneEventStoreDates(data.renderableEventStore, oldData.dateEnv, data.dateEnv); 8624 } 8625 for (let optionName in changeHandlers) { 8626 if (this.optionsForHandling.indexOf(optionName) !== -1 || oldCalendarOptions[optionName] !== newCalendarOptions[optionName]) { 8627 changeHandlers[optionName](newCalendarOptions[optionName], data); 8628 } 8629 } 8630 } 8631 this.optionsForHandling = []; 8632 if (props.onData) { 8633 props.onData(data); 8634 } 8635 } 8636 computeOptionsData(optionOverrides, dynamicOptionOverrides, calendarApi) { 8637 if (!this.optionsForRefining.length && optionOverrides === this.stableOptionOverrides && dynamicOptionOverrides === this.stableDynamicOptionOverrides) { 8638 return this.stableCalendarOptionsData; 8639 } 8640 let { refinedOptions, pluginHooks, localeDefaults, availableLocaleData, extra } = this.processRawCalendarOptions(optionOverrides, dynamicOptionOverrides); 8641 warnUnknownOptions(extra); 8642 let dateEnv = this.buildDateEnv(refinedOptions.timeZone, refinedOptions.locale, refinedOptions.weekNumberCalculation, refinedOptions.firstDay, refinedOptions.weekText, pluginHooks, availableLocaleData, refinedOptions.defaultRangeSeparator); 8643 let viewSpecs = this.buildViewSpecs(pluginHooks.views, this.stableOptionOverrides, this.stableDynamicOptionOverrides, localeDefaults); 8644 let theme = this.buildTheme(refinedOptions, pluginHooks); 8645 let toolbarConfig = this.parseToolbars(refinedOptions, this.stableOptionOverrides, theme, viewSpecs, calendarApi); 8646 return this.stableCalendarOptionsData = { 8647 calendarOptions: refinedOptions, 8648 pluginHooks, 8649 dateEnv, 8650 viewSpecs, 8651 theme, 8652 toolbarConfig, 8653 localeDefaults, 8654 availableRawLocales: availableLocaleData.map 8655 }; 8656 } 8657 // always called from behind a memoizer 8658 processRawCalendarOptions(optionOverrides, dynamicOptionOverrides) { 8659 let { locales, locale } = mergeRawOptions([ 8660 BASE_OPTION_DEFAULTS, 8661 optionOverrides, 8662 dynamicOptionOverrides 8663 ]); 8664 let availableLocaleData = this.organizeRawLocales(locales); 8665 let availableRawLocales = availableLocaleData.map; 8666 let localeDefaults = this.buildLocale(locale || availableLocaleData.defaultCode, availableRawLocales).options; 8667 let pluginHooks = this.buildPluginHooks(optionOverrides.plugins || [], globalPlugins); 8668 let refiners = this.currentCalendarOptionsRefiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners); 8669 let extra = {}; 8670 let raw = mergeRawOptions([ 8671 BASE_OPTION_DEFAULTS, 8672 localeDefaults, 8673 optionOverrides, 8674 dynamicOptionOverrides 8675 ]); 8676 let refined = {}; 8677 let currentRaw = this.currentCalendarOptionsInput; 8678 let currentRefined = this.currentCalendarOptionsRefined; 8679 let anyChanges = false; 8680 for (let optionName in raw) { 8681 if (this.optionsForRefining.indexOf(optionName) === -1 && (raw[optionName] === currentRaw[optionName] || COMPLEX_OPTION_COMPARATORS[optionName] && optionName in currentRaw && COMPLEX_OPTION_COMPARATORS[optionName](currentRaw[optionName], raw[optionName]))) { 8682 refined[optionName] = currentRefined[optionName]; 8683 } else if (refiners[optionName]) { 8684 refined[optionName] = refiners[optionName](raw[optionName]); 8685 anyChanges = true; 8686 } else { 8687 extra[optionName] = currentRaw[optionName]; 8688 } 8689 } 8690 if (anyChanges) { 8691 this.currentCalendarOptionsInput = raw; 8692 this.currentCalendarOptionsRefined = refined; 8693 this.stableOptionOverrides = optionOverrides; 8694 this.stableDynamicOptionOverrides = dynamicOptionOverrides; 8695 } 8696 this.optionsForHandling.push(...this.optionsForRefining); 8697 this.optionsForRefining = []; 8698 return { 8699 rawOptions: this.currentCalendarOptionsInput, 8700 refinedOptions: this.currentCalendarOptionsRefined, 8701 pluginHooks, 8702 availableLocaleData, 8703 localeDefaults, 8704 extra 8705 }; 8706 } 8707 _computeCurrentViewData(viewType, optionsData, optionOverrides, dynamicOptionOverrides) { 8708 let viewSpec = optionsData.viewSpecs[viewType]; 8709 if (!viewSpec) { 8710 throw new Error(`viewType "${viewType}" is not available. Please make sure you've loaded all neccessary plugins`); 8711 } 8712 let { refinedOptions, extra } = this.processRawViewOptions(viewSpec, optionsData.pluginHooks, optionsData.localeDefaults, optionOverrides, dynamicOptionOverrides); 8713 warnUnknownOptions(extra); 8714 let dateProfileGenerator = this.buildDateProfileGenerator({ 8715 dateProfileGeneratorClass: viewSpec.optionDefaults.dateProfileGeneratorClass, 8716 duration: viewSpec.duration, 8717 durationUnit: viewSpec.durationUnit, 8718 usesMinMaxTime: viewSpec.optionDefaults.usesMinMaxTime, 8719 dateEnv: optionsData.dateEnv, 8720 calendarApi: this.props.calendarApi, 8721 slotMinTime: refinedOptions.slotMinTime, 8722 slotMaxTime: refinedOptions.slotMaxTime, 8723 showNonCurrentDates: refinedOptions.showNonCurrentDates, 8724 dayCount: refinedOptions.dayCount, 8725 dateAlignment: refinedOptions.dateAlignment, 8726 dateIncrement: refinedOptions.dateIncrement, 8727 hiddenDays: refinedOptions.hiddenDays, 8728 weekends: refinedOptions.weekends, 8729 nowInput: refinedOptions.now, 8730 validRangeInput: refinedOptions.validRange, 8731 visibleRangeInput: refinedOptions.visibleRange, 8732 fixedWeekCount: refinedOptions.fixedWeekCount 8733 }); 8734 let viewApi = this.buildViewApi(viewType, this.getCurrentData, optionsData.dateEnv); 8735 return { viewSpec, options: refinedOptions, dateProfileGenerator, viewApi }; 8736 } 8737 processRawViewOptions(viewSpec, pluginHooks, localeDefaults, optionOverrides, dynamicOptionOverrides) { 8738 let raw = mergeRawOptions([ 8739 BASE_OPTION_DEFAULTS, 8740 viewSpec.optionDefaults, 8741 localeDefaults, 8742 optionOverrides, 8743 viewSpec.optionOverrides, 8744 dynamicOptionOverrides 8745 ]); 8746 let refiners = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, BASE_OPTION_REFINERS), CALENDAR_LISTENER_REFINERS), CALENDAR_OPTION_REFINERS), VIEW_OPTION_REFINERS), pluginHooks.listenerRefiners), pluginHooks.optionRefiners);
8747 let refined = {}; 8748 let currentRaw = this.currentViewOptionsInput; 8749 let currentRefined = this.currentViewOptionsRefined; 8750 let anyChanges = false; 8751 let extra = {}; 8752 for (let optionName in raw) { 8753 if (raw[optionName] === currentRaw[optionName] || COMPLEX_OPTION_COMPARATORS[optionName] && COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], currentRaw[optionName])) { 8754 refined[optionName] = currentRefined[optionName]; 8755 } else { 8756 if (raw[optionName] === this.currentCalendarOptionsInput[optionName] || COMPLEX_OPTION_COMPARATORS[optionName] && COMPLEX_OPTION_COMPARATORS[optionName](raw[optionName], this.currentCalendarOptionsInput[optionName])) { 8757 if (optionName in this.currentCalendarOptionsRefined) { 8758 refined[optionName] = this.currentCalendarOptionsRefined[optionName]; 8759 } 8760 } else if (refiners[optionName]) { 8761 refined[optionName] = refiners[optionName](raw[optionName]); 8762 } else { 8763 extra[optionName] = raw[optionName]; 8764 } 8765 anyChanges = true; 8766 } 8767 } 8768 if (anyChanges) { 8769 this.currentViewOptionsInput = raw; 8770 this.currentViewOptionsRefined = refined; 8771 } 8772 return { 8773 rawOptions: this.currentViewOptionsInput, 8774 refinedOptions: this.currentViewOptionsRefined, 8775 extra 8776 }; 8777 } 8778} 8779function buildDateEnv$1(timeZone, explicitLocale, weekNumberCalculation, firstDay, weekText, pluginHooks, availableLocaleData, defaultSeparator) { 8780 let locale = buildLocale(explicitLocale || availableLocaleData.defaultCode, availableLocaleData.map); 8781 return new DateEnv({ 8782 calendarSystem: "gregory", 8783 timeZone, 8784 namedTimeZoneImpl: pluginHooks.namedTimeZonedImpl, 8785 locale, 8786 weekNumberCalculation, 8787 firstDay, 8788 weekText, 8789 cmdFormatter: pluginHooks.cmdFormatter, 8790 defaultSeparator 8791 }); 8792} 8793function buildTheme(options, pluginHooks) { 8794 let ThemeClass = pluginHooks.themeClasses[options.themeSystem] || StandardTheme; 8795 return new ThemeClass(options); 8796} 8797function buildDateProfileGenerator(props) { 8798 let DateProfileGeneratorClass = props.dateProfileGeneratorClass || DateProfileGenerator; 8799 return new DateProfileGeneratorClass(props); 8800} 8801function buildViewApi(type, getCurrentData, dateEnv) { 8802 return new ViewImpl(type, getCurrentData, dateEnv); 8803} 8804function buildEventUiBySource(eventSources) { 8805 return mapHash(eventSources, (eventSource) => eventSource.ui); 8806} 8807function buildEventUiBases(eventDefs, eventUiSingleBase, eventUiBySource) { 8808 let eventUiBases = { "": eventUiSingleBase }; 8809 for (let defId in eventDefs) { 8810 let def = eventDefs[defId]; 8811 if (def.sourceId && eventUiBySource[def.sourceId]) { 8812 eventUiBases[defId] = eventUiBySource[def.sourceId]; 8813 } 8814 } 8815 return eventUiBases; 8816} 8817function buildViewUiProps(calendarContext) { 8818 let { options } = calendarContext; 8819 return { 8820 eventUiSingleBase: createEventUi({ 8821 display: options.eventDisplay, 8822 editable: options.editable, 8823 startEditable: options.eventStartEditable, 8824 durationEditable: options.eventDurationEditable, 8825 constraint: options.eventConstraint, 8826 overlap: typeof options.eventOverlap === "boolean" ? options.eventOverlap : void 0, 8827 allow: options.eventAllow, 8828 backgroundColor: options.eventBackgroundColor, 8829 borderColor: options.eventBorderColor, 8830 textColor: options.eventTextColor, 8831 color: options.eventColor 8832 // classNames: options.eventClassNames // render hook will handle this 8833 }, calendarContext), 8834 selectionConfig: createEventUi({ 8835 constraint: options.selectConstraint, 8836 overlap: typeof options.selectOverlap === "boolean" ? options.selectOverlap : void 0, 8837 allow: options.selectAllow 8838 }, calendarContext) 8839 }; 8840} 8841function computeIsLoading(state, context) { 8842 for (let isLoadingFunc of context.pluginHooks.isLoadingFuncs) { 8843 if (isLoadingFunc(state)) { 8844 return true; 8845 } 8846 } 8847 return false; 8848} 8849function parseContextBusinessHours(calendarContext) { 8850 return parseBusinessHours(calendarContext.options.businessHours, calendarContext); 8851} 8852function warnUnknownOptions(options, viewName) { 8853 for (let optionName in options) { 8854 console.warn(`Unknown option '${optionName}'`); 8855 } 8856} 8857class ToolbarSection extends BaseComponent { 8858 render() {
8859 let children = this.props.widgetGroups.map((widgetGroup) => this.renderWidgetGroup(widgetGroup)); 8860 return y("div", { className: "fc-toolbar-chunk" }, ...children); 8861 } 8862 renderWidgetGroup(widgetGroup) { 8863 let { props } = this; 8864 let { theme } = this.context; 8865 let children = []; 8866 let isOnlyButtons = true; 8867 for (let widget of widgetGroup) { 8868 let { buttonName, buttonClick, buttonText, buttonIcon, buttonHint } = widget; 8869 if (buttonName === "title") { 8870 isOnlyButtons = false; 8871 children.push(y("h2", { className: "fc-toolbar-title", id: props.titleId }, props.title)); 8872 } else { 8873 let isPressed = buttonName === props.activeButton; 8874 let isDisabled = !props.isTodayEnabled && buttonName === "today" || !props.isPrevEnabled && buttonName === "prev" || !props.isNextEnabled && buttonName === "next"; 8875 let buttonClasses = [`fc-${buttonName}-button`, theme.getClass("button")]; 8876 if (isPressed) { 8877 buttonClasses.push(theme.getClass("buttonActive")); 8878 } 8879 children.push(y("button", { type: "button", title: typeof buttonHint === "function" ? buttonHint(props.navUnit) : buttonHint, disabled: isDisabled, "aria-pressed": isPressed, className: buttonClasses.join(" "), onClick: buttonClick }, buttonText || (buttonIcon ? y("span", { className: buttonIcon, role: "img" }) : ""))); 8880 } 8881 } 8882 if (children.length > 1) { 8883 let groupClassName = isOnlyButtons && theme.getClass("buttonGroup") || ""; 8884 return y("div", { className: groupClassName }, ...children); 8885 } 8886 return children[0]; 8887 } 8888} 8889class Toolbar extends BaseComponent { 8890 render() { 8891 let { model, extraClassName } = this.props; 8892 let forceLtr = false; 8893 let startContent; 8894 let endContent; 8895 let sectionWidgets = model.sectionWidgets; 8896 let centerContent = sectionWidgets.center; 8897 if (sectionWidgets.left) { 8898 forceLtr = true; 8899 startContent = sectionWidgets.left; 8900 } else { 8901 startContent = sectionWidgets.start; 8902 } 8903 if (sectionWidgets.right) { 8904 forceLtr = true; 8905 endContent = sectionWidgets.right; 8906 } else { 8907 endContent = sectionWidgets.end; 8908 } 8909 let classNames = [ 8910 extraClassName || "", 8911 "fc-toolbar", 8912 forceLtr ? "fc-toolbar-ltr" : "" 8913 ]; 8914 return y( 8915 "div", 8916 { className: classNames.join(" ") }, 8917 this.renderSection("start", startContent || []), 8918 this.renderSection("center", centerContent || []), 8919 this.renderSection("end", endContent || []) 8920 ); 8921 } 8922 renderSection(key, widgetGroups) { 8923 let { props } = this; 8924 return y(ToolbarSection, { key, widgetGroups, title: props.title, navUnit: props.navUnit, activeButton: props.activeButton, isTodayEnabled: props.isTodayEnabled, isPrevEnabled: props.isPrevEnabled, isNextEnabled: props.isNextEnabled, titleId: props.titleId }); 8925 } 8926} 8927class ViewHarness extends BaseComponent { 8928 constructor() { 8929 super(...arguments); 8930 this.state = { 8931 availableWidth: null 8932 }; 8933 this.handleEl = (el) => { 8934 this.el = el; 8935 setRef(this.props.elRef, el); 8936 this.updateAvailableWidth(); 8937 }; 8938 this.handleResize = () => { 8939 this.updateAvailableWidth(); 8940 }; 8941 } 8942 render() { 8943 let { props, state } = this; 8944 let { aspectRatio } = props; 8945 let classNames = [ 8946 "fc-view-harness", 8947 aspectRatio || props.liquid || props.height ? "fc-view-harness-active" : "fc-view-harness-passive" 8948 // let the view do the height 8949 ]; 8950 let height = ""; 8951 let paddingBottom = ""; 8952 if (aspectRatio) { 8953 if (state.availableWidth !== null) { 8954 height = state.availableWidth / aspectRatio; 8955 } else { 8956 paddingBottom = `${1 / aspectRatio * 100}%`; 8957 } 8958 } else { 8959 height = props.height || ""; 8960 } 8961 return y("div", { "aria-labelledby": props.labeledById, ref: this.handleEl, className: classNames.join(" "), style: { height, paddingBottom } }, props.children); 8962 } 8963 componentDidMount() { 8964 this.context.addResizeHandler(this.handleResize); 8965 } 8966 componentWillUnmount() { 8967 this.context.removeResizeHandler(this.handleResize); 8968 } 8969 updateAvailableWidth() { 8970 if (this.el && // needed. but why? 8971 this.props.aspectRatio) { 8972 this.setState({ availableWidth: this.el.offsetWidth }); 8973 } 8974 } 8975} 8976class EventClicking extends Interaction { 8977 constructor(settings) { 8978 super(settings); 8979 this.handleSegClick = (ev, segEl) => { 8980 let { component } = this; 8981 let { context } = component; 8982 let seg = getElSeg(segEl); 8983 if (seg && // might be the <div> surrounding the more link 8984 component.isValidSegDownEl(ev.target)) { 8985 let hasUrlContainer = elementClosest(ev.target, ".fc-event-forced-url"); 8986 let url = hasUrlContainer ? hasUrlContainer.querySelector("a[href]").href : ""; 8987 context.emitter.trigger("eventClick", { 8988 el: segEl, 8989 event: new EventImpl(component.context, seg.eventRange.def, seg.eventRange.instance), 8990 jsEvent: ev, 8991 view: context.viewApi 8992 }); 8993 if (url && !ev.defaultPrevented) { 8994 window.location.href = url; 8995 } 8996 } 8997 }; 8998 this.destroy = listenBySelector( 8999 settings.el, 9000 "click", 9001 ".fc-event", 9002 // on both fg and bg events 9003 this.handleSegClick 9004 ); 9005 } 9006} 9007class EventHovering extends Interaction { 9008 constructor(settings) { 9009 super(settings); 9010 this.handleEventElRemove = (el) => { 9011 if (el === this.currentSegEl) { 9012 this.handleSegLeave(null, this.currentSegEl); 9013 } 9014 }; 9015 this.handleSegEnter = (ev, segEl) => { 9016 if (getElSeg(segEl)) { 9017 this.currentSegEl = segEl; 9018 this.triggerEvent("eventMouseEnter", ev, segEl); 9019 } 9020 }; 9021 this.handleSegLeave = (ev, segEl) => { 9022 if (this.currentSegEl) { 9023 this.currentSegEl = null; 9024 this.triggerEvent("eventMouseLeave", ev, segEl); 9025 } 9026 }; 9027 this.removeHoverListeners = listenToHoverBySelector( 9028 settings.el, 9029 ".fc-event", 9030 // on both fg and bg events 9031 this.handleSegEnter, 9032 this.handleSegLeave 9033 ); 9034 } 9035 destroy() { 9036 this.removeHoverListeners(); 9037 } 9038 triggerEvent(publicEvName, ev, segEl) { 9039 let { component } = this; 9040 let { context } = component; 9041 let seg = getElSeg(segEl); 9042 if (!ev || component.isValidSegDownEl(ev.target)) { 9043 context.emitter.trigger(publicEvName, { 9044 el: segEl, 9045 event: new EventImpl(context, seg.eventRange.def, seg.eventRange.instance), 9046 jsEvent: ev, 9047 view: context.viewApi 9048 }); 9049 } 9050 } 9051} 9052class CalendarContent extends PureComponent { 9053 constructor() { 9054 super(...arguments); 9055 this.buildViewContext = memoize(buildViewContext); 9056 this.buildViewPropTransformers = memoize(buildViewPropTransformers); 9057 this.buildToolbarProps = memoize(buildToolbarProps); 9058 this.headerRef = d(); 9059 this.footerRef = d(); 9060 this.interactionsStore = {}; 9061 this.state = { 9062 viewLabelId: getUniqueDomId() 9063 }; 9064 this.registerInteractiveComponent = (component, settingsInput)
9064=> { 9065 let settings = parseInteractionSettings(component, settingsInput); 9066 let DEFAULT_INTERACTIONS = [ 9067 EventClicking, 9068 EventHovering 9069 ]; 9070 let interactionClasses = DEFAULT_INTERACTIONS.concat(this.props.pluginHooks.componentInteractions); 9071 let interactions = interactionClasses.map((TheInteractionClass) => new TheInteractionClass(settings)); 9072 this.interactionsStore[component.uid] = interactions; 9073 interactionSettingsStore[component.uid] = settings; 9074 }; 9075 this.unregisterInteractiveComponent = (component) => { 9076 let listeners = this.interactionsStore[component.uid]; 9077 if (listeners) { 9078 for (let listener of listeners) { 9079 listener.destroy(); 9080 } 9081 delete this.interactionsStore[component.uid]; 9082 } 9083 delete interactionSettingsStore[component.uid]; 9084 }; 9085 this.resizeRunner = new DelayedRunner(() => { 9086 this.props.emitter.trigger("_resize", true); 9087 this.props.emitter.trigger("windowResize", { view: this.props.viewApi }); 9088 }); 9089 this.handleWindowResize = (ev) => { 9090 let { options } = this.props; 9091 if (options.handleWindowResize && ev.target === window) { 9092 this.resizeRunner.request(options.windowResizeDelay); 9093 } 9094 }; 9095 } 9096 /* 9097 renders INSIDE of an outer div 9098 */ 9099 render() { 9100 let { props } = this; 9101 let { toolbarConfig, options } = props; 9102 let toolbarProps = this.buildToolbarProps( 9103 props.viewSpec, 9104 props.dateProfile, 9105 props.dateProfileGenerator, 9106 props.currentDate, 9107 getNow(props.options.now, props.dateEnv), 9108 // TODO: use NowTimer???? 9109 props.viewTitle 9110 ); 9111 let viewVGrow = false; 9112 let viewHeight = ""; 9113 let viewAspectRatio; 9114 if (props.isHeightAuto || props.forPrint) { 9115 viewHeight = ""; 9116 } else if (options.height != null) { 9117 viewVGrow = true; 9118 } else if (options.contentHeight != null) { 9119 viewHeight = options.contentHeight; 9120 } else { 9121 viewAspectRatio = Math.max(options.aspectRatio, 0.5); 9122 } 9123 let viewContext = this.buildViewContext(props.viewSpec, props.viewApi, props.options, props.dateProfileGenerator, props.dateEnv, props.theme, props.pluginHooks, props.dispatch, props.getCurrentData, props.emitter, props.calendarApi, this.registerInteractiveComponent, this.unregisterInteractiveComponent); 9124 let viewLabelId = toolbarConfig.header && toolbarConfig.header.hasTitle ? this.state.viewLabelId : void 0; 9125 return y( 9126 ViewContextType.Provider, 9127 { value: viewContext }, 9128 toolbarConfig.header && y(Toolbar, Object.assign({ ref: this.headerRef, extraClassName: "fc-header-toolbar", model: toolbarConfig.header, titleId: viewLabelId }, toolbarProps)), 9129 y( 9130 ViewHarness, 9131 { liquid: viewVGrow, height: viewHeight, aspectRatio: viewAspectRatio, labeledById: viewLabelId }, 9132 this.renderView(props), 9133 this.buildAppendContent() 9134 ), 9135 toolbarConfig.footer && y(Toolbar, Object.assign({ ref: this.footerRef, extraClassName: "fc-footer-toolbar", model: toolbarConfig.footer, titleId: "" }, toolbarProps)) 9136 ); 9137 } 9138 componentDidMount() { 9139 let { props } = this; 9140 this.calendarInteractions = props.pluginHooks.calendarInteractions.map((CalendarInteractionClass) => new CalendarInteractionClass(props)); 9141 window.addEventListener("resize", this.handleWindowResize); 9142 let { propSetHandlers } = props.pluginHooks; 9143 for (let propName in propSetHandlers) { 9144 propSetHandlers[propName](props[propName], props); 9145 } 9146 } 9147 componentDidUpdate(prevProps) { 9148 let { props } = this; 9149 let { propSetHandlers } = props.pluginHooks; 9150 for (let propName in propSetHandlers) { 9151 if (props[propName] !== prevProps[propName]) { 9152 propSetHandlers[propName](props[propName], props); 9153 } 9154 } 9155 } 9156 componentWillUnmount() { 9157 window.removeEventListener("resize", this.handleWindowResize); 9158 this.resizeRunner.clear(); 9159 for (let interaction of this.calendarInteractions) { 9160 interaction.destroy(); 9161 } 9162 this.props.emitter.trigger("_unmount"); 9163 } 9164 buildAppendContent() { 9165 let { props } = this;
9166 let children = props.pluginHooks.viewContainerAppends.map((buildAppendContent) => buildAppendContent(props)); 9167 return y(_, {}, ...children); 9168 } 9169 renderView(props) { 9170 let { pluginHooks } = props; 9171 let { viewSpec } = props; 9172 let viewProps = { 9173 dateProfile: props.dateProfile, 9174 businessHours: props.businessHours, 9175 eventStore: props.renderableEventStore, 9176 eventUiBases: props.eventUiBases, 9177 dateSelection: props.dateSelection, 9178 eventSelection: props.eventSelection, 9179 eventDrag: props.eventDrag, 9180 eventResize: props.eventResize, 9181 isHeightAuto: props.isHeightAuto, 9182 forPrint: props.forPrint 9183 }; 9184 let transformers = this.buildViewPropTransformers(pluginHooks.viewPropsTransformers); 9185 for (let transformer of transformers) { 9186 Object.assign(viewProps, transformer.transform(viewProps, props)); 9187 } 9188 let ViewComponent = viewSpec.component; 9189 return y(ViewComponent, Object.assign({}, viewProps)); 9190 } 9191} 9192function buildToolbarProps(viewSpec, dateProfile, dateProfileGenerator, currentDate, now, title) { 9193 let todayInfo = dateProfileGenerator.build(now, void 0, false); 9194 let prevInfo = dateProfileGenerator.buildPrev(dateProfile, currentDate, false); 9195 let nextInfo = dateProfileGenerator.buildNext(dateProfile, currentDate, false); 9196 return { 9197 title, 9198 activeButton: viewSpec.type, 9199 navUnit: viewSpec.singleUnit, 9200 isTodayEnabled: todayInfo.isValid && !rangeContainsMarker(dateProfile.currentRange, now), 9201 isPrevEnabled: prevInfo.isValid, 9202 isNextEnabled: nextInfo.isValid 9203 }; 9204} 9205function buildViewPropTransformers(theClasses) { 9206 return theClasses.map((TheClass) => new TheClass()); 9207} 9208class Calendar extends CalendarImpl { 9209 constructor(el, optionOverrides = {}) { 9210 super(); 9211 this.isRendering = false; 9212 this.isRendered = false; 9213 this.currentClassNames = []; 9214 this.customContentRenderId = 0; 9215 this.handleAction = (action) => { 9216 switch (action.type) { 9217 case "SET_EVENT_DRAG": 9218 case "SET_EVENT_RESIZE": 9219 this.renderRunner.tryDrain(); 9220 } 9221 }; 9222 this.handleData = (data) => { 9223 this.currentData = data; 9224 this.renderRunner.request(data.calendarOptions.rerenderDelay); 9225 }; 9226 this.handleRenderRequest = () => { 9227 if (this.isRendering) { 9228 this.isRendered = true; 9229 let { currentData } = this; 9230 flushSync(() => { 9231 D$1(y(CalendarRoot, { options: currentData.calendarOptions, theme: currentData.theme, emitter: currentData.emitter }, (classNames, height, isHeightAuto, forPrint) => { 9232 this.setClassNames(classNames); 9233 this.setHeight(height); 9234 return y( 9235 RenderId.Provider, 9236 { value: this.customContentRenderId }, 9237 y(CalendarContent, Object.assign({ isHeightAuto, forPrint }, currentData)) 9238 ); 9239 }), this.el); 9240 }); 9241 } else if (this.isRendered) { 9242 this.isRendered = false; 9243 D$1(null, this.el); 9244 this.setClassNames([]); 9245 this.setHeight(""); 9246 } 9247 }; 9248 ensureElHasStyles(el); 9249 this.el = el; 9250 this.renderRunner = new DelayedRunner(this.handleRenderRequest); 9251 new CalendarDataManager({ 9252 optionOverrides, 9253 calendarApi: this, 9254 onAction: this.handleAction, 9255 onData: this.handleData 9256 }); 9257 } 9258 render() { 9259 let wasRendering = this.isRendering; 9260 if (!wasRendering) { 9261 this.isRendering = true; 9262 } else { 9263 this.customContentRenderId += 1; 9264 } 9265 this.renderRunner.request(); 9266 if (wasRendering) { 9267 this.updateSize(); 9268 } 9269 } 9270 destroy() { 9271 if (this.isRendering) { 9272 this.isRendering = false; 9273 this.renderRunner.request(); 9274 } 9275 } 9276 updateSize() { 9277 flushSync(() => { 9278 super.updateSize(); 9279 }); 9280 } 9281 batchRendering(func) { 9282 this.renderRunner.pause("batchRendering"); 9283 func(); 9284 this.renderRunner.resume("batchRendering"); 9285 } 9286 pauseRendering() { 9287 this.renderRunner.pause("pauseRendering"); 9288 } 9289 resumeRendering() { 9290 this.renderRunner.resume("pauseRendering", true); 9291 } 9292 resetOptions(optionOverrides, changedOptionNames) { 9293 this.currentDataManager.resetOptions(optionOverrides, changedOptionNames); 9294 } 9295 setClassNames(classNames) { 9296 if (!isArraysEqual(classNames, this.currentClassNames)) { 9297 let { classList } = this.el; 9298 for (let className of this.currentClassNames) { 9299 classList.remove(className); 9300 } 9301 for (let className of classNames) { 9302 classList.add(className); 9303 } 9304 this.currentClassNames = classNames; 9305 } 9306 } 9307 setHeight(height) { 9308 applyStyleProp(this.el, "height", height); 9309 } 9310} 9311class TableView extends DateComponent { 9312 constructor() { 9313 super(...arguments); 9314 this.headerElRef = d(); 9315 } 9316 renderSimpleLayout(headerRowContent, bodyContent) { 9317 let { props, context } = this; 9318 let sections = []; 9319 let stickyHeaderDates = getStickyHeaderDates(context.options); 9320 if (headerRowContent) { 9321 sections.push({ 9322 type: "header", 9323 key: "header", 9324 isSticky: stickyHeaderDates, 9325 chunk: { 9326 elRef: this.headerElRef, 9327 tableClassName: "fc-col-header", 9328 rowContent: headerRowContent 9329 } 9330 }); 9331 } 9332 sections.push({ 9333 type: "body", 9334 key: "body", 9335 liquid: true, 9336 chunk: { content: bodyContent } 9337 }); 9338 return y( 9339 ViewContainer,
9340 { elClasses: ["fc-daygrid"], viewSpec: context.viewSpec }, 9341 y(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [], sections }) 9342 ); 9343 } 9344 renderHScrollLayout(headerRowContent, bodyContent, colCnt, dayMinWidth) { 9345 let ScrollGrid = this.context.pluginHooks.scrollGridImpl; 9346 if (!ScrollGrid) { 9347 throw new Error("No ScrollGrid implementation"); 9348 } 9349 let { props, context } = this; 9350 let stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 9351 let stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 9352 let sections = []; 9353 if (headerRowContent) { 9354 sections.push({ 9355 type: "header", 9356 key: "header", 9357 isSticky: stickyHeaderDates, 9358 chunks: [{ 9359 key: "main", 9360 elRef: this.headerElRef, 9361 tableClassName: "fc-col-header", 9362 rowContent: headerRowContent 9363 }] 9364 }); 9365 } 9366 sections.push({ 9367 type: "body", 9368 key: "body", 9369 liquid: true, 9370 chunks: [{ 9371 key: "main", 9372 content: bodyContent 9373 }] 9374 }); 9375 if (stickyFooterScrollbar) { 9376 sections.push({ 9377 type: "footer", 9378 key: "footer", 9379 isSticky: true, 9380 chunks: [{ 9381 key: "main", 9382 content: renderScrollShim 9383 }] 9384 }); 9385 } 9386 return y( 9387 ViewContainer, 9388 { elClasses: ["fc-daygrid"], viewSpec: context.viewSpec }, 9389 y(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, forPrint: props.forPrint, collapsibleWidth: props.forPrint, colGroups: [{ cols: [{ span: colCnt, minWidth: dayMinWidth }] }], sections }) 9390 ); 9391 } 9392} 9393function splitSegsByRow(segs, rowCnt) { 9394 let byRow = []; 9395 for (let i2 = 0; i2 < rowCnt; i2 += 1) { 9396 byRow[i2] = []; 9397 } 9398 for (let seg of segs) { 9399 byRow[seg.row].push(seg); 9400 } 9401 return byRow; 9402} 9403function splitSegsByFirstCol(segs, colCnt) { 9404 let byCol = []; 9405 for (let i2 = 0; i2 < colCnt; i2 += 1) { 9406 byCol[i2] = []; 9407 } 9408 for (let seg of segs) { 9409 byCol[seg.firstCol].push(seg); 9410 } 9411 return byCol; 9412} 9413function splitInteractionByRow(ui, rowCnt) { 9414 let byRow = []; 9415 if (!ui) { 9416 for (let i2 = 0; i2 < rowCnt; i2 += 1) { 9417 byRow[i2] = null; 9418 } 9419 } else { 9420 for (let i2 = 0; i2 < rowCnt; i2 += 1) { 9421 byRow[i2] = { 9422 affectedInstances: ui.affectedInstances, 9423 isEvent: ui.isEvent, 9424 segs: [] 9425 }; 9426 } 9427 for (let seg of ui.segs) { 9428 byRow[seg.row].segs.push(seg); 9429 } 9430 } 9431 return byRow; 9432} 9433const DEFAULT_TABLE_EVENT_TIME_FORMAT = createFormatter({ 9434 hour: "numeric", 9435 minute: "2-digit", 9436 omitZeroMinute: true, 9437 meridiem: "narrow" 9438}); 9439function hasListItemDisplay(seg) { 9440 let { display } = seg.eventRange.ui;
9441 return display === "list-item" || display === "auto" && !seg.eventRange.def.allDay && seg.firstCol === seg.lastCol && // can't be multi-day 9442 seg.isStart && // " 9443 seg.isEnd; 9444} 9445class TableBlockEvent extends BaseComponent { 9446 render() { 9447 let { props } = this; 9448 return y(StandardEvent, Object.assign({}, props, { elClasses: ["fc-daygrid-event", "fc-daygrid-block-event", "fc-h-event"], defaultTimeFormat: DEFAULT_TABLE_EVENT_TIME_FORMAT, defaultDisplayEventEnd: props.defaultDisplayEventEnd, disableResizing: !props.seg.eventRange.def.allDay })); 9449 } 9450} 9451class TableListItemEvent extends BaseComponent { 9452 render() { 9453 let { props, context } = this; 9454 let { options } = context; 9455 let { seg } = props; 9456 let timeFormat = options.eventTimeFormat || DEFAULT_TABLE_EVENT_TIME_FORMAT; 9457 let timeText = buildSegTimeText(seg, timeFormat, context, true, props.defaultDisplayEventEnd); 9458 return y(EventContainer, Object.assign({}, props, { elTag: "a", elClasses: ["fc-daygrid-event", "fc-daygrid-dot-event"], elAttrs: getSegAnchorAttrs(props.seg, context), defaultGenerator: renderInnerContent$1, timeText, isResizing: false, isDateSelecting: false })); 9459 } 9460} 9461function renderInnerContent$1(renderProps) { 9462 return y( 9463 _, 9464 null, 9465 y("div", { className: "fc-daygrid-event-dot", style: { borderColor: renderProps.borderColor || renderProps.backgroundColor } }), 9466 renderProps.timeText && y("div", { className: "fc-event-time" }, renderProps.timeText), 9467 y("div", { className: "fc-event-title" }, renderProps.event.title || y(_, null, " ")) 9468 ); 9469} 9470class TableCellMoreLink extends BaseComponent { 9471 constructor() { 9472 super(...arguments); 9473 this.compileSegs = memoize(compileSegs); 9474 } 9475 render() { 9476 let { props } = this; 9477 let { allSegs, invisibleSegs } = this.compileSegs(props.singlePlacements); 9478 return y(MoreLinkContainer, { elClasses: ["fc-daygrid-more-link"], dateProfile: props.dateProfile, todayRange: props.todayRange, allDayDate: props.allDayDate, moreCnt: props.moreCnt, allSegs, hiddenSegs: invisibleSegs, alignmentElRef: props.alignmentElRef, alignGridTop: props.alignGridTop, extraDateSpan: props.extraDateSpan, popoverContent: () => { 9479 let isForcedInvisible = (props.eventDrag ? props.eventDrag.affectedInstances : null) || (props.eventResize ? props.eventResize.affectedInstances : null) || {}; 9480 return y(_, null, allSegs.map((seg) => { 9481 let instanceId = seg.eventRange.instance.instanceId; 9482 return y("div", { className: "fc-daygrid-event-harness", key: instanceId, style: { 9483 visibility: isForcedInvisible[instanceId] ? "hidden" : "" 9484 } }, hasListItemDisplay(seg) ? y(TableListItemEvent, Object.assign({ seg, isDragging: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange))) : y(TableBlockEvent, Object.assign({ seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === props.eventSelection, defaultDisplayEventEnd: false }, getSegMeta(seg, props.todayRange)))); 9485 })); 9486 } }); 9487 } 9488} 9489function compileSegs(singlePlacements) { 9490 let allSegs = []; 9491 let invisibleSegs = []; 9492 for (let placement of singlePlacements) { 9493 allSegs.push(placement.seg); 9494 if (!placement.isVisible) { 9495 invisibleSegs.push(placement.seg); 9496 } 9497 } 9498 return { allSegs, invisibleSegs }; 9499} 9500const DEFAULT_WEEK_NUM_FORMAT$1 = createFormatter({ week: "narrow" }); 9501class TableCell extends DateComponent { 9502 constructor() { 9503 super(...arguments); 9504 this.rootElRef = d(); 9505 this.state = { 9506 dayNumberId: getUniqueDomId() 9507 }; 9508 this.handleRootEl = (el) => { 9509 setRef(this.rootElRef, el); 9510 setRef(this.props.elRef, el); 9511 }; 9512 } 9513 render() { 9514 let { context, props, state, rootElRef } = this; 9515 let { options, dateEnv } = context; 9516 let { date, dateProfile } = props; 9517 const isMonthStart = props.showDayNumber && shouldDisplayMonthStart(date, dateProfile.currentRange, dateEnv); 9518 return y(DayCellContainer, { elTag: "td", elRef: this.handleRootEl, elClasses: [
9519 "fc-daygrid-day", 9520 ...props.extraClassNames || [] 9521 ], elAttrs: Object.assign(Object.assign(Object.assign({}, props.extraDataAttrs), props.showDayNumber ? { "aria-labelledby": state.dayNumberId } : {}), { role: "gridcell" }), defaultGenerator: renderTopInner, date, dateProfile, todayRange: props.todayRange, showDayNumber: props.showDayNumber, isMonthStart, extraRenderProps: props.extraRenderProps }, (InnerContent, renderProps) => y( 9522 "div", 9523 { ref: props.innerElRef, className: "fc-daygrid-day-frame fc-scrollgrid-sync-inner", style: { minHeight: props.minHeight } }, 9524 props.showWeekNumber && y(WeekNumberContainer, { elTag: "a", elClasses: ["fc-daygrid-week-number"], elAttrs: buildNavLinkAttrs(context, date, "week"), date, defaultFormat: DEFAULT_WEEK_NUM_FORMAT$1 }), 9525 !renderProps.isDisabled && (props.showDayNumber || hasCustomDayCellContent(options) || props.forceDayTop) ? y( 9526 "div", 9527 { className: "fc-daygrid-day-top" }, 9528 y(InnerContent, { elTag: "a", elClasses: [
9529 "fc-daygrid-day-number", 9530 isMonthStart && "fc-daygrid-month-start" 9531 ], elAttrs: Object.assign(Object.assign({}, buildNavLinkAttrs(context, date)), { id: state.dayNumberId }) }) 9532 ) : props.showDayNumber ? ( 9533 // for creating correct amount of space (see issue #7162) 9534 y( 9535 "div", 9536 { className: "fc-daygrid-day-top", style: { visibility: "hidden" } }, 9537 y("a", { className: "fc-daygrid-day-number" }, " ") 9538 ) 9539 ) : void 0, 9540 y( 9541 "div", 9542 { className: "fc-daygrid-day-events", ref: props.fgContentElRef }, 9543 props.fgContent, 9544 y( 9545 "div", 9546 { className: "fc-daygrid-day-bottom", style: { marginTop: props.moreMarginTop } }, 9547 y(TableCellMoreLink, { allDayDate: date, singlePlacements: props.singlePlacements, moreCnt: props.moreCnt, alignmentElRef: rootElRef, alignGridTop: !props.showDayNumber, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange }) 9548 ) 9549 ), 9550 y("div", { className: "fc-daygrid-day-bg" }, props.bgContent) 9551 )); 9552 } 9553} 9554function renderTopInner(props) { 9555 return props.dayNumberText || y(_, null, " "); 9556} 9557function shouldDisplayMonthStart(date, currentRange, dateEnv) { 9558 const { start: currentStart, end: currentEnd } = currentRange; 9559 const currentEndIncl = addMs(currentEnd, -1); 9560 const currentFirstYear = dateEnv.getYear(currentStart); 9561 const currentFirstMonth = dateEnv.getMonth(currentStart); 9562 const currentLastYear = dateEnv.getYear(currentEndIncl); 9563 const currentLastMonth = dateEnv.getMonth(currentEndIncl); 9564 return !(currentFirstYear === currentLastYear && currentFirstMonth === currentLastMonth) && Boolean( 9565 // first date in current view? 9566 date.valueOf() === currentStart.valueOf() || // a month-start that's within the current range? 9567 dateEnv.getDay(date) === 1 && date.valueOf() < currentEnd.valueOf() 9568 ); 9569} 9570function generateSegKey(seg) { 9571 return seg.eventRange.instance.instanceId + ":" + seg.firstCol; 9572} 9573function generateSegUid(seg) { 9574 return generateSegKey(seg) + ":" + seg.lastCol; 9575} 9576function computeFgSegPlacement(segs, dayMaxEvents, dayMaxEventRows, strictOrder, segHeights, maxContentHeight, cells) { 9577 let hierarchy = new DayGridSegHierarchy((segEntry) => { 9578 let segUid = segs[segEntry.index].eventRange.instance.instanceId + ":" + segEntry.span.start + ":" + (segEntry.span.end - 1); 9579 return segHeights[segUid] || 1; 9580 }); 9581 hierarchy.allowReslicing = true; 9582 hierarchy.strictOrder = strictOrder; 9583 if (dayMaxEvents === true || dayMaxEventRows === true) { 9584 hierarchy.maxCoord = maxContentHeight; 9585 hierarchy.hiddenConsumes = true; 9586 } else if (typeof dayMaxEvents === "number") { 9587 hierarchy.maxStackCnt = dayMaxEvents; 9588 } else if (typeof dayMaxEventRows === "number") { 9589 hierarchy.maxStackCnt = dayMaxEventRows; 9590 hierarchy.hiddenConsumes = true; 9591 } 9592 let segInputs = []; 9593 let unknownHeightSegs = []; 9594 for (let i2 = 0; i2 < segs.length; i2 += 1) { 9595 let seg = segs[i2]; 9596 let segUid = generateSegUid(seg); 9597 let eventHeight = segHeights[segUid]; 9598 if (eventHeight != null) { 9599 segInputs.push({ 9600 index: i2, 9601 span: { 9602 start: seg.firstCol, 9603 end: seg.lastCol + 1 9604 } 9605 }); 9606 } else { 9607 unknownHeightSegs.push(seg); 9608 } 9609 } 9610 let hiddenEntries = hierarchy.addSegs(segInputs); 9611 let segRects = hierarchy.toRects(); 9612 let { singleColPlacements, multiColPlacements, leftoverMargins } = placeRects(segRects, segs, cells); 9613 let moreCnts = []; 9614 let moreMarginTops = []; 9615 for (let seg of unknownHeightSegs) { 9616 multiColPlacements[seg.firstCol].push({ 9617 seg, 9618 isVisible: false, 9619 isAbsolute: true, 9620 absoluteTop: 0, 9621 marginTop: 0 9622 }); 9623 for (let col = seg.firstCol; col <= seg.lastCol; col += 1) { 9624 singleColPlacements[col].push({ 9625 seg: resliceSeg(seg, col, col + 1, cells), 9626 isVisible: false, 9627 isAbsolute: false, 9628 absoluteTop: 0, 9629 marginTop: 0 9630 }); 9631 } 9632 } 9633 for (let col = 0; col < cells.length; col += 1) { 9634 moreCnts.push(0); 9635 } 9636 for (let hiddenEntry of hiddenEntries) { 9637 let seg = segs[hiddenEntry.index]; 9638 let hiddenSpan = hiddenEntry.span; 9639 multiColPlacements[hiddenSpan.start].push({ 9640 seg: resliceSeg(seg, hiddenSpan.start, hiddenSpan.end, cells), 9641 isVisible: false, 9642 isAbsolute: true, 9643 absoluteTop: 0, 9644 marginTop: 0 9645 }); 9646 for (let col = hiddenSpan.start; col < hiddenSpan.end; col += 1) { 9647 moreCnts[col] += 1; 9648 singleColPlacements[col].push({ 9649 seg: resliceSeg(seg, col, col + 1, cells), 9650 isVisible: false, 9651 isAbsolute: false, 9652 absoluteTop: 0, 9653 marginTop: 0 9654 }); 9655 } 9656 } 9657 for (let col = 0; col < cells.length; col += 1) { 9658 moreMarginTops.push(leftoverMargins[col]); 9659 } 9660 return { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops }; 9661} 9662function placeRects(allRects, segs, cells) { 9663 let rectsByEachCol = groupRectsByEachCol(allRects, cells.length); 9664 let singleColPlacements = []; 9665 let multiColPlacements = []; 9666 let leftoverMargins = []; 9667 for (let col = 0; col < cells.length; col += 1) { 9668 let rects = rectsByEachCol[col]; 9669 let singlePlacements = [];
vendor: 8,986 bytes, lines 9670-9886
9670 let currentHeight = 0; 9671 let currentMarginTop = 0; 9672 for (let rect of rects) { 9673 let seg = segs[rect.index]; 9674 singlePlacements.push({ 9675 seg: resliceSeg(seg, col, col + 1, cells), 9676 isVisible: true, 9677 isAbsolute: false, 9678 absoluteTop: rect.levelCoord, 9679 marginTop: rect.levelCoord - currentHeight 9680 }); 9681 currentHeight = rect.levelCoord + rect.thickness; 9682 } 9683 let multiPlacements = []; 9684 currentHeight = 0; 9685 currentMarginTop = 0; 9686 for (let rect of rects) { 9687 let seg = segs[rect.index]; 9688 let isAbsolute = rect.span.end - rect.span.start > 1; 9689 let isFirstCol = rect.span.start === col; 9690 currentMarginTop += rect.levelCoord - currentHeight; 9691 currentHeight = rect.levelCoord + rect.thickness; 9692 if (isAbsolute) { 9693 currentMarginTop += rect.thickness; 9694 if (isFirstCol) { 9695 multiPlacements.push({ 9696 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 9697 isVisible: true, 9698 isAbsolute: true, 9699 absoluteTop: rect.levelCoord, 9700 marginTop: 0 9701 }); 9702 } 9703 } else if (isFirstCol) { 9704 multiPlacements.push({ 9705 seg: resliceSeg(seg, rect.span.start, rect.span.end, cells), 9706 isVisible: true, 9707 isAbsolute: false, 9708 absoluteTop: rect.levelCoord, 9709 marginTop: currentMarginTop 9710 // claim the margin 9711 }); 9712 currentMarginTop = 0; 9713 } 9714 } 9715 singleColPlacements.push(singlePlacements); 9716 multiColPlacements.push(multiPlacements); 9717 leftoverMargins.push(currentMarginTop); 9718 } 9719 return { singleColPlacements, multiColPlacements, leftoverMargins }; 9720} 9721function groupRectsByEachCol(rects, colCnt) { 9722 let rectsByEachCol = []; 9723 for (let col = 0; col < colCnt; col += 1) { 9724 rectsByEachCol.push([]); 9725 } 9726 for (let rect of rects) { 9727 for (let col = rect.span.start; col < rect.span.end; col += 1) { 9728 rectsByEachCol[col].push(rect); 9729 } 9730 } 9731 return rectsByEachCol; 9732} 9733function resliceSeg(seg, spanStart, spanEnd, cells) { 9734 if (seg.firstCol === spanStart && seg.lastCol === spanEnd - 1) { 9735 return seg; 9736 } 9737 let eventRange = seg.eventRange; 9738 let origRange = eventRange.range; 9739 let slicedRange = intersectRanges(origRange, { 9740 start: cells[spanStart].date, 9741 end: addDays(cells[spanEnd - 1].date, 1) 9742 }); 9743 return Object.assign(Object.assign({}, seg), { firstCol: spanStart, lastCol: spanEnd - 1, eventRange: { 9744 def: eventRange.def, 9745 ui: Object.assign(Object.assign({}, eventRange.ui), { durationEditable: false }), 9746 instance: eventRange.instance, 9747 range: slicedRange 9748 }, isStart: seg.isStart && slicedRange.start.valueOf() === origRange.start.valueOf(), isEnd: seg.isEnd && slicedRange.end.valueOf() === origRange.end.valueOf() }); 9749} 9750class DayGridSegHierarchy extends SegHierarchy { 9751 constructor() { 9752 super(...arguments); 9753 this.hiddenConsumes = false; 9754 this.forceHidden = {}; 9755 } 9756 addSegs(segInputs) { 9757 const hiddenSegs = super.addSegs(segInputs); 9758 const { entriesByLevel } = this; 9759 const excludeHidden = (entry) => !this.forceHidden[buildEntryKey(entry)]; 9760 for (let level = 0; level < entriesByLevel.length; level += 1) { 9761 entriesByLevel[level] = entriesByLevel[level].filter(excludeHidden); 9762 } 9763 return hiddenSegs; 9764 } 9765 handleInvalidInsertion(insertion, entry, hiddenEntries) { 9766 const { entriesByLevel, forceHidden } = this; 9767 const { touchingEntry, touchingLevel, touchingLateral } = insertion; 9768 if (this.hiddenConsumes && touchingEntry) { 9769 const touchingEntryId = buildEntryKey(touchingEntry); 9770 if (!forceHidden[touchingEntryId]) { 9771 if (this.allowReslicing) { 9772 const hiddenEntry = Object.assign(Object.assign({}, touchingEntry), { span: intersectSpans(touchingEntry.span, entry.span) }); 9773 const hiddenEntryId = buildEntryKey(hiddenEntry); 9774 forceHidden[hiddenEntryId] = true; 9775 entriesByLevel[touchingLevel][touchingLateral] = hiddenEntry; 9776 hiddenEntries.push(hiddenEntry); 9777 this.splitEntry(touchingEntry, entry, hiddenEntries); 9778 } else { 9779 forceHidden[touchingEntryId] = true; 9780 hiddenEntries.push(touchingEntry); 9781 } 9782 } 9783 } 9784 super.handleInvalidInsertion(insertion, entry, hiddenEntries); 9785 } 9786} 9787class TableRow extends DateComponent { 9788 constructor() { 9789 super(...arguments); 9790 this.cellElRefs = new RefMap(); 9791 this.frameElRefs = new RefMap(); 9792 this.fgElRefs = new RefMap(); 9793 this.segHarnessRefs = new RefMap(); 9794 this.rootElRef = d(); 9795 this.state = { 9796 framePositions: null, 9797 maxContentHeight: null, 9798 segHeights: {} 9799 }; 9800 this.handleResize = (isForced) => { 9801 if (isForced) { 9802 this.updateSizing(true); 9803 } 9804 }; 9805 } 9806 render() { 9807 let { props, state, context } = this; 9808 let { options } = context; 9809 let colCnt = props.cells.length; 9810 let businessHoursByCol = splitSegsByFirstCol(props.businessHourSegs, colCnt); 9811 let bgEventSegsByCol = splitSegsByFirstCol(props.bgEventSegs, colCnt); 9812 let highlightSegsByCol = splitSegsByFirstCol(this.getHighlightSegs(), colCnt); 9813 let mirrorSegsByCol = splitSegsByFirstCol(this.getMirrorSegs(), colCnt); 9814 let { singleColPlacements, multiColPlacements, moreCnts, moreMarginTops } = computeFgSegPlacement(sortEventSegs(props.fgEventSegs, options.eventOrder), props.dayMaxEvents, props.dayMaxEventRows, options.eventOrderStrict, state.segHeights, state.maxContentHeight, props.cells); 9815 let isForcedInvisible = ( 9816 // TODO: messy way to compute this 9817 props.eventDrag && props.eventDrag.affectedInstances || props.eventResize && props.eventResize.affectedInstances || {} 9818 ); 9819 return y( 9820 "tr", 9821 { ref: this.rootElRef, role: "row" }, 9822 props.renderIntro && props.renderIntro(), 9823 props.cells.map((cell, col) => { 9824 let normalFgNodes = this.renderFgSegs(col, props.forPrint ? singleColPlacements[col] : multiColPlacements[col], props.todayRange, isForcedInvisible); 9825 let mirrorFgNodes = this.renderFgSegs(col, buildMirrorPlacements(mirrorSegsByCol[col], multiColPlacements), props.todayRange, {}, Boolean(props.eventDrag), Boolean(props.eventResize), false); 9826 return y(TableCell, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), innerElRef: this.frameElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, showDayNumber: props.showDayNumbers, showWeekNumber: props.showWeekNumbers && col === 0, forceDayTop: props.showWeekNumbers, todayRange: props.todayRange, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, moreCnt: moreCnts[col], moreMarginTop: moreMarginTops[col], singlePlacements: singleColPlacements[col], fgContentElRef: this.fgElRefs.createRef(cell.key), fgContent: ( 9827 // Fragment scopes the keys 9828 y( 9829 _, 9830 null, 9831 y(_, null, normalFgNodes), 9832 y(_, null, mirrorFgNodes) 9833 ) 9834 ), bgContent: ( 9835 // Fragment scopes the keys 9836 y( 9837 _, 9838 null, 9839 this.renderFillSegs(highlightSegsByCol[col], "highlight"), 9840 this.renderFillSegs(businessHoursByCol[col], "non-business"), 9841 this.renderFillSegs(bgEventSegsByCol[col], "bg-event") 9842 ) 9843 ), minHeight: props.cellMinHeight }); 9844 }) 9845 ); 9846 } 9847 componentDidMount() { 9848 this.updateSizing(true); 9849 this.context.addResizeHandler(this.handleResize); 9850 } 9851 componentDidUpdate(prevProps, prevState) { 9852 let currentProps = this.props; 9853 this.updateSizing(!isPropsEqual(prevProps, currentProps)); 9854 } 9855 componentWillUnmount() { 9856 this.context.removeResizeHandler(this.handleResize); 9857 } 9858 getHighlightSegs() { 9859 let { props } = this; 9860 if (props.eventDrag && props.eventDrag.segs.length) { 9861 return props.eventDrag.segs; 9862 } 9863 if (props.eventResize && props.eventResize.segs.length) { 9864 return props.eventResize.segs; 9865 } 9866 return props.dateSelectionSegs; 9867 } 9868 getMirrorSegs() { 9869 let { props } = this; 9870 if (props.eventResize && props.eventResize.segs.length) { 9871 return props.eventResize.segs; 9872 } 9873 return []; 9874 } 9875 renderFgSegs(col, segPlacements, todayRange, isForcedInvisible, isDragging, isResizing, isDateSelecting) { 9876 let { context } = this; 9877 let { eventSelection } = this.props; 9878 let { framePositions } = this.state; 9879 let defaultDisplayEventEnd = this.props.cells.length === 1; 9880 let isMirror = isDragging || isResizing || isDateSelecting; 9881 let nodes = []; 9882 if (framePositions) { 9883 for (let placement of segPlacements) { 9884 let { seg } = placement; 9885 let { instanceId } = seg.eventRange.instance; 9886 let isVisible = placement.isVisible && !isForcedInvisible[instanceId];
9887 let isAbsolute = placement.isAbsolute; 9888 let left = ""; 9889 let right = ""; 9890 if (isAbsolute) { 9891 if (context.isRtl) { 9892 right = 0; 9893 left = framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol]; 9894 } else { 9895 left = 0; 9896 right = framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol]; 9897 } 9898 } 9899 nodes.push(y("div", { className: "fc-daygrid-event-harness" + (isAbsolute ? " fc-daygrid-event-harness-abs" : ""), key: generateSegKey(seg), ref: isMirror ? null : this.segHarnessRefs.createRef(generateSegUid(seg)), style: { 9900 visibility: isVisible ? "" : "hidden", 9901 marginTop: isAbsolute ? "" : placement.marginTop, 9902 top: isAbsolute ? placement.absoluteTop : "", 9903 left, 9904 right 9905 } }, hasListItemDisplay(seg) ? y(TableListItemEvent, Object.assign({ seg, isDragging, isSelected: instanceId === eventSelection, defaultDisplayEventEnd }, getSegMeta(seg, todayRange))) : y(TableBlockEvent, Object.assign({ seg, isDragging, isResizing, isDateSelecting, isSelected: instanceId === eventSelection, defaultDisplayEventEnd }, getSegMeta(seg, todayRange))))); 9906 } 9907 } 9908 return nodes; 9909 } 9910 renderFillSegs(segs, fillType) { 9911 let { isRtl } = this.context; 9912 let { todayRange } = this.props; 9913 let { framePositions } = this.state; 9914 let nodes = []; 9915 if (framePositions) { 9916 for (let seg of segs) { 9917 let leftRightCss = isRtl ? { 9918 right: 0, 9919 left: framePositions.lefts[seg.lastCol] - framePositions.lefts[seg.firstCol] 9920 } : { 9921 left: 0, 9922 right: framePositions.rights[seg.firstCol] - framePositions.rights[seg.lastCol] 9923 }; 9924 nodes.push(y("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-daygrid-bg-harness", style: leftRightCss }, fillType === "bg-event" ? y(BgEvent, Object.assign({ seg }, getSegMeta(seg, todayRange))) : renderFill(fillType))); 9925 } 9926 } 9927 return y(_, {}, ...nodes); 9928 } 9929 updateSizing(isExternalSizingChange) { 9930 let { props, state, frameElRefs } = this; 9931 if (!props.forPrint && props.clientWidth !== null) { 9932 if (isExternalSizingChange) { 9933 let frameEls = props.cells.map((cell) => frameElRefs.currentMap[cell.key]); 9934 if (frameEls.length) { 9935 let originEl = this.rootElRef.current; 9936 let newPositionCache = new PositionCache( 9937 originEl, 9938 frameEls, 9939 true, 9940 // isHorizontal 9941 false 9942 ); 9943 if (!state.framePositions || !state.framePositions.similarTo(newPositionCache)) { 9944 this.setState({ 9945 framePositions: new PositionCache( 9946 originEl, 9947 frameEls, 9948 true, 9949 // isHorizontal 9950 false 9951 ) 9952 }); 9953 } 9954 } 9955 } 9956 const oldSegHeights = this.state.segHeights; 9957 const newSegHeights = this.querySegHeights(); 9958 const limitByContentHeight = props.dayMaxEvents === true || props.dayMaxEventRows === true; 9959 this.safeSetState({ 9960 // HACK to prevent oscillations of events being shown/hidden from max-event-rows 9961 // Essentially, once you compute an element's height, never null-out. 9962 // TODO: always display all events, as visibility:hidden? 9963 segHeights: Object.assign(Object.assign({}, oldSegHeights), newSegHeights), 9964 maxContentHeight: limitByContentHeight ? this.computeMaxContentHeight() : null 9965 }); 9966 } 9967 } 9968 querySegHeights() { 9969 let segElMap = this.segHarnessRefs.currentMap; 9970 let segHeights = {}; 9971 for (let segUid in segElMap) { 9972 let height = Math.round(segElMap[segUid].getBoundingClientRect().height); 9973 segHeights[segUid] = Math.max(segHeights[segUid] || 0, height); 9974 } 9975 return segHeights; 9976 } 9977 computeMaxContentHeight() { 9978 let firstKey = this.props.cells[0].key; 9979 let cellEl = this.cellElRefs.currentMap[firstKey]; 9980 let fcContainerEl = this.fgElRefs.currentMap[firstKey]; 9981 return cellEl.getBoundingClientRect().bottom - fcContainerEl.getBoundingClientRect().top; 9982 } 9983 getCellEls() { 9984 let elMap = this.cellElRefs.currentMap; 9985 return this.props.cells.map((cell) => elMap[cell.key]); 9986 } 9987} 9988TableRow.addStateEquality({ 9989 segHeights: isPropsEqual 9990}); 9991function buildMirrorPlacements(mirrorSegs, colPlacements) { 9992 if (!mirrorSegs.length) { 9993 return []; 9994 } 9995 let topsByInstanceId = buildAbsoluteTopHash(colPlacements); 9996 return mirrorSegs.map((seg) => ({ 9997 seg, 9998 isVisible: true, 9999 isAbsolute: true, 10000 absoluteTop: topsByInstanceId[seg.eventRange.instance.instanceId], 10001 marginTop: 0 10002 })); 10003} 10004function buildAbsoluteTopHash(colPlacements) { 10005 let topsByInstanceId = {}; 10006 for (let placements of colPlacements) { 10007 for (let placement of placements) { 10008 topsByInstanceId[placement.seg.eventRange.instance.instanceId] = placement.absoluteTop; 10009 } 10010 } 10011 return topsByInstanceId; 10012} 10013class TableRows extends DateComponent { 10014 constructor() { 10015 super(...arguments); 10016 this.splitBusinessHourSegs = memoize(splitSegsByRow); 10017 this.splitBgEventSegs = memoize(splitSegsByRow); 10018 this.splitFgEventSegs = memoize(splitSegsByRow); 10019 this.splitDateSelectionSegs = memoize(splitSegsByRow); 10020 this.splitEventDrag = memoize(splitInteractionByRow); 10021 this.splitEventResize = memoize(splitInteractionByRow); 10022 this.rowRefs = new RefMap(); 10023 } 10024 render() { 10025 let { props, context } = this; 10026 let rowCnt = props.cells.length; 10027 let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, rowCnt); 10028 let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, rowCnt); 10029 let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, rowCnt); 10030 let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, rowCnt); 10031 let eventDragByRow = this.splitEventDrag(props.eventDrag, rowCnt); 10032 let eventResizeByRow = this.splitEventResize(props.eventResize, rowCnt);
10033 let cellMinHeight = rowCnt >= 7 && props.clientWidth ? props.clientWidth / context.options.aspectRatio / 6 : null; 10034 return y(NowTimer, { unit: "day" }, (nowDate, todayRange) => y(_, null, props.cells.map((cells, row) => y(TableRow, { 10035 ref: this.rowRefs.createRef(row), 10036 key: cells.length ? cells[0].date.toISOString() : row, 10037 showDayNumbers: rowCnt > 1, 10038 showWeekNumbers: props.showWeekNumbers, 10039 todayRange, 10040 dateProfile: props.dateProfile, 10041 cells, 10042 renderIntro: props.renderRowIntro, 10043 businessHourSegs: businessHourSegsByRow[row], 10044 eventSelection: props.eventSelection, 10045 bgEventSegs: bgEventSegsByRow[row].filter(isSegAllDay), 10046 fgEventSegs: fgEventSegsByRow[row], 10047 dateSelectionSegs: dateSelectionSegsByRow[row], 10048 eventDrag: eventDragByRow[row], 10049 eventResize: eventResizeByRow[row], 10050 dayMaxEvents: props.dayMaxEvents, 10051 dayMaxEventRows: props.dayMaxEventRows, 10052 clientWidth: props.clientWidth, 10053 clientHeight: props.clientHeight, 10054 cellMinHeight, 10055 forPrint: props.forPrint 10056 })))); 10057 } 10058 componentDidMount() { 10059 this.registerInteractiveComponent(); 10060 } 10061 componentDidUpdate() { 10062 this.registerInteractiveComponent(); 10063 } 10064 registerInteractiveComponent() { 10065 if (!this.rootEl) { 10066 const firstCellEl = this.rowRefs.currentMap[0].getCellEls()[0]; 10067 const rootEl = firstCellEl ? firstCellEl.closest(".fc-daygrid-body") : null; 10068 if (rootEl) { 10069 this.rootEl = rootEl; 10070 this.context.registerInteractiveComponent(this, { 10071 el: rootEl, 10072 isHitComboAllowed: this.props.isHitComboAllowed 10073 }); 10074 } 10075 } 10076 } 10077 componentWillUnmount() { 10078 if (this.rootEl) { 10079 this.context.unregisterInteractiveComponent(this); 10080 this.rootEl = null; 10081 } 10082 } 10083 // Hit System 10084 // ---------------------------------------------------------------------------------------------------- 10085 prepareHits() { 10086 this.rowPositions = new PositionCache( 10087 this.rootEl, 10088 this.rowRefs.collect().map((rowObj) => rowObj.getCellEls()[0]), 10089 // first cell el in each row. TODO: not optimal 10090 false, 10091 true 10092 ); 10093 this.colPositions = new PositionCache( 10094 this.rootEl, 10095 this.rowRefs.currentMap[0].getCellEls(), 10096 // cell els in first row 10097 true, 10098 // horizontal 10099 false 10100 ); 10101 } 10102 queryHit(positionLeft, positionTop) { 10103 let { colPositions, rowPositions } = this; 10104 let col = colPositions.leftToIndex(positionLeft); 10105 let row = rowPositions.topToIndex(positionTop); 10106 if (row != null && col != null) { 10107 let cell = this.props.cells[row][col]; 10108 return { 10109 dateProfile: this.props.dateProfile, 10110 dateSpan: Object.assign({ range: this.getCellRange(row, col), allDay: true }, cell.extraDateSpan), 10111 dayEl: this.getCellEl(row, col), 10112 rect: { 10113 left: colPositions.lefts[col], 10114 right: colPositions.rights[col], 10115 top: rowPositions.tops[row], 10116 bottom: rowPositions.bottoms[row] 10117 }, 10118 layer: 0 10119 }; 10120 } 10121 return null; 10122 } 10123 getCellEl(row, col) { 10124 return this.rowRefs.currentMap[row].getCellEls()[col]; 10125 } 10126 getCellRange(row, col) { 10127 let start = this.props.cells[row][col].date; 10128 let end = addDays(start, 1); 10129 return { start, end }; 10130 } 10131} 10132function isSegAllDay(seg) { 10133 return seg.eventRange.def.allDay; 10134} 10135class Table extends DateComponent { 10136 constructor() { 10137 super(...arguments); 10138 this.elRef = d(); 10139 this.needsScrollReset = false; 10140 } 10141 render() { 10142 let { props } = this; 10143 let { dayMaxEventRows, dayMaxEvents, expandRows } = props; 10144 let limitViaBalanced = dayMaxEvents === true || dayMaxEventRows === true; 10145 if (limitViaBalanced && !expandRows) { 10146 limitViaBalanced = false; 10147 dayMaxEventRows = null; 10148 dayMaxEvents = null; 10149 } 10150 let classNames = [
10151 "fc-daygrid-body", 10152 limitViaBalanced ? "fc-daygrid-body-balanced" : "fc-daygrid-body-unbalanced", 10153 expandRows ? "" : "fc-daygrid-body-natural" 10154 // will height of one row depend on the others? 10155 ]; 10156 return y( 10157 "div", 10158 { ref: this.elRef, className: classNames.join(" "), style: { 10159 // these props are important to give this wrapper correct dimensions for interactions 10160 // TODO: if we set it here, can we avoid giving to inner tables? 10161 width: props.clientWidth, 10162 minWidth: props.tableMinWidth 10163 } }, 10164 y( 10165 "table", 10166 { role: "presentation", className: "fc-scrollgrid-sync-table", style: { 10167 width: props.clientWidth, 10168 minWidth: props.tableMinWidth, 10169 height: expandRows ? props.clientHeight : "" 10170 } }, 10171 props.colGroupNode, 10172 y( 10173 "tbody", 10174 { role: "presentation" }, 10175 y(TableRows, { dateProfile: props.dateProfile, cells: props.cells, renderRowIntro: props.renderRowIntro, showWeekNumbers: props.showWeekNumbers, clientWidth: props.clientWidth, clientHeight: props.clientHeight, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bg
10175EventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, dayMaxEvents, dayMaxEventRows, forPrint: props.forPrint, isHitComboAllowed: props.isHitComboAllowed }) 10176 ) 10177 ) 10178 ); 10179 } 10180 componentDidMount() { 10181 this.requestScrollReset(); 10182 } 10183 componentDidUpdate(prevProps) { 10184 if (prevProps.dateProfile !== this.props.dateProfile) { 10185 this.requestScrollReset(); 10186 } else { 10187 this.flushScrollReset(); 10188 } 10189 } 10190 requestScrollReset() { 10191 this.needsScrollReset = true; 10192 this.flushScrollReset(); 10193 } 10194 flushScrollReset() { 10195 if (this.needsScrollReset && this.props.clientWidth) { 10196 const subjectEl = getScrollSubjectEl(this.elRef.current, this.props.dateProfile); 10197 if (subjectEl) { 10198 const originEl = subjectEl.closest(".fc-daygrid-body"); 10199 const scrollEl = originEl.closest(".fc-scroller"); 10200 const scrollTop = subjectEl.getBoundingClientRect().top - originEl.getBoundingClientRect().top; 10201 scrollEl.scrollTop = scrollTop ? scrollTop + 1 : 0; 10202 } 10203 this.needsScrollReset = false; 10204 } 10205 } 10206} 10207function getScrollSubjectEl(containerEl, dateProfile) { 10208 let el; 10209 if (dateProfile.currentRangeUnit.match(/year|month/)) { 10210 el = containerEl.querySelector(`[data-date="${formatIsoMonthStr(dateProfile.currentDate)}-01"]`); 10211 } 10212 if (!el) { 10213 el = containerEl.querySelector(`[data-date="${formatDayString(dateProfile.currentDate)}"]`); 10214 } 10215 return el; 10216} 10217class DayTableSlicer extends Slicer { 10218 constructor() { 10219 super(...arguments); 10220 this.forceDayIfListItem = true; 10221 } 10222 sliceRange(dateRange, dayTableModel) { 10223 return dayTableModel.sliceRange(dateRange); 10224 } 10225} 10226class DayTable extends DateComponent { 10227 constructor() { 10228 super(...arguments); 10229 this.slicer = new DayTableSlicer(); 10230 this.tableRef = d(); 10231 } 10232 render() { 10233 let { props, context } = this; 10234 return y(Table, Object.assign({ ref: this.tableRef }, this.slicer.sliceProps(props, props.dateProfile, props.nextDayThreshold, context, props.dayTableModel), { dateProfile: props.dateProfile, cells: props.dayTableModel.cells, colGroupNode: props.colGroupNode, tableMinWidth: props.tableMinWidth, renderRowIntro: props.renderRowIntro, dayMaxEvents: props.dayMaxEvents, dayMaxEventRows: props.dayMaxEventRows, showWeekNumbers: props.showWeekNumbers, expandRows: props.expandRows, headerAlignElRef: props.headerAlignElRef, clientWidth: props.clientWidth, clientHeight: props.clientHeight, forPrint: props.forPrint })); 10235 } 10236} 10237class DayTableView extends TableView { 10238 constructor() { 10239 super(...arguments); 10240 this.buildDayTableModel = memoize(buildDayTableModel); 10241 this.headerRef = d(); 10242 this.tableRef = d(); 10243 } 10244 render() { 10245 let { options, dateProfileGenerator } = this.context; 10246 let { props } = this; 10247 let dayTableModel = this.buildDayTableModel(props.dateProfile, dateProfileGenerator); 10248 let headerContent = options.dayHeaders && y(DayHeader, { ref: this.headerRef, dateProfile: props.dateProfile, dates: dayTableModel.headerDates, datesRepDistinctDays: dayTableModel.rowCnt === 1 }); 10249 let bodyContent = (contentArg) => y(DayTable, { ref: this.tableRef, dateProfile: props.dateProfile, dayTableModel, businessHours: props.businessHours, dateSelection: props.dateSelection, eventStore: props.eventStore, eventUiBases: props.eventUiBases, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, nextDayThreshold: options.nextDayThreshold, colGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, dayMaxEvents: options.dayMaxEvents, dayMaxEventRows: options.dayMaxEventRows, showWeekNumbers: options.weekNumbers, expandRows: !props.isHeightAuto, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }); 10250 return options.dayMinWidth ? this.renderHScrollLayout(headerContent, bodyContent, dayTableModel.colCnt, options.dayMinWidth) : this.renderSimpleLayout(headerContent, bodyContent); 10251 } 10252} 10253function buildDayTableModel(dateProfile, dateProfileGenerator) {
vendor: 1,387 bytes, lines 10254-10291
10254 let daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 10255 return new DayTableModel(daySeries, /year|month|week/.test(dateProfile.currentRangeUnit)); 10256} 10257class TableDateProfileGenerator extends DateProfileGenerator { 10258 // Computes the date range that will be rendered 10259 buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay) { 10260 let renderRange = super.buildRenderRange(currentRange, currentRangeUnit, isRangeAllDay); 10261 let { props } = this; 10262 return buildDayTableRenderRange({ 10263 currentRange: renderRange, 10264 snapToWeek: /^(year|month)$/.test(currentRangeUnit), 10265 fixedWeekCount: props.fixedWeekCount, 10266 dateEnv: props.dateEnv 10267 }); 10268 } 10269} 10270function buildDayTableRenderRange(props) { 10271 let { dateEnv, currentRange } = props; 10272 let { start, end } = currentRange; 10273 let endOfWeek; 10274 if (props.snapToWeek) { 10275 start = dateEnv.startOfWeek(start); 10276 endOfWeek = dateEnv.startOfWeek(end); 10277 if (endOfWeek.valueOf() !== end.valueOf()) { 10278 end = addWeeks(endOfWeek, 1); 10279 } 10280 } 10281 if (props.fixedWeekCount) { 10282 let lastMonthRenderStart = dateEnv.startOfWeek(dateEnv.startOfMonth(addDays(currentRange.end, -1))); 10283 let rowCnt = Math.ceil( 10284 // could be partial weeks due to hiddenDays 10285 diffWeeks(lastMonthRenderStart, end) 10286 ); 10287 end = addWeeks(end, 6 - rowCnt); 10288 } 10289 return { start, end }; 10290} 10291var css_248z$1 =
vendor: 3,522 bytes, line 10291
10291':root{--fc-daygrid-event-dot-width:8px}.fc-daygrid-day-events:after,.fc-daygrid-day-events:before,.fc-daygrid-day-frame:after,.fc-daygrid-day-frame:before,.fc-daygrid-event-harness:after,.fc-daygrid-event-harness:before{clear:both;content:"";display:table}.fc .fc-daygrid-body{position:relative;z-index:1}.fc .fc-daygrid-day.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-daygrid-day-frame{min-height:100%;position:relative}.fc .fc-daygrid-day-top{display:flex;flex-direction:row-reverse}.fc .fc-day-other .fc-daygrid-day-top{opacity:.3}.fc .fc-daygrid-day-number{padding:4px;position:relative;z-index:4}.fc .fc-daygrid-month-start{font-size:1.1em;font-weight:700}.fc .fc-daygrid-day-events{margin-top:1px}.fc .fc-daygrid-body-balanced .fc-daygrid-day-events{left:0;position:absolute;right:0}.fc .fc-daygrid-body-unbalanced .fc-daygrid-day-events{min-height:2em;position:relative}.fc .fc-daygrid-body-natural .fc-daygrid-day-events{margin-bottom:1em}.fc .fc-daygrid-event-harness{position:relative}.fc .fc-daygrid-event-harness-abs{left:0;position:absolute;right:0;top:0}.fc .fc-daygrid-bg-harness{bottom:0;position:absolute;top:0}.fc .fc-daygrid-day-bg .fc-non-business{z-index:1}.fc .fc-daygrid-day-bg .fc-bg-event{z-index:2}.fc .fc-daygrid-day-bg .fc-highlight{z-index:3}.fc .fc-daygrid-event{margin-top:1px;z-index:6}.fc .fc-daygrid-event.fc-event-mirror{z-index:7}.fc .fc-daygrid-day-bottom{font-size:.85em;margin:0 2px}.fc .fc-daygrid-day-bottom:after,.fc .fc-daygrid-day-bottom:before{clear:both;content:"";display:table}.fc .fc-daygrid-more-link{border-radius:3px;cursor:pointer;line-height:1;margin-top:1px;max-width:100%;overflow:hidden;padding:2px;position:relative;white-space:nowrap;z-index:4}.fc .fc-daygrid-more-link:hover{background-color:rgba(0,0,0,.1)}.fc .fc-daygrid-week-number{background-color:var(--fc-neutral-bg-color);color:var(--fc-neutral-text-color);min-width:1.5em;padding:2px;position:absolute;text-align:center;top:0;z-index:5}.fc .fc-more-popover .fc-popover-body{min-width:220px;padding:10px}.fc-direction-ltr .fc-daygrid-event.fc-event-start,.fc-direction-rtl .fc-daygrid-event.fc-event-end{margin-left:2px}.fc-direction-ltr .fc-daygrid-event.fc-event-end,.fc-direction-rtl .fc-daygrid-event.fc-event-start{margin-right:2px}.fc-direction-ltr .fc-daygrid-more-link{float:left}.fc-direction-ltr .fc-daygrid-week-number{border-radius:0 0 3px 0;left:0}.fc-direction-rtl .fc-daygrid-more-link{float:right}.fc-direction-rtl .fc-daygrid-week-number{border-radius:0 0 0 3px;right:0}.fc-liquid-hack .fc-daygrid-day-frame{position:static}.fc-daygrid-event{border-radius:3px;font-size:var(--fc-small-font-size);position:relative;white-space:nowrap}.fc-daygrid-block-event .fc-event-time{font-weight:700}.fc-daygrid-block-event .fc-event-time,.fc-daygrid-block-event .fc-event-title{padding:1px}.fc-daygrid-dot-event{align-items:center;display:flex;padding:2px 0}.fc-daygrid-dot-event .fc-event-title{flex-grow:1;flex-shrink:1;font-weight:700;min-width:0;overflow:hidden}.fc-daygrid-dot-event.fc-event-mirror,.fc-daygrid-dot-event:hover{background:rgba(0,0,0,.1)}.fc-daygrid-dot-event.fc-event-selected:before{bottom:-10px;top:-10px}.fc-daygrid-event-dot{border:calc(var(--fc-daygrid-event-dot-width)/2) solid var(--fc-event-border-color);border-radius:calc(var(--fc-daygrid-event-dot-width)/2);box-sizing:content-box;height:0;margin:0 4px;width:0}.fc-direction-ltr .fc-daygrid-event .fc-event-time{margin-right:3px}.fc-direction-rtl .fc-daygrid-event .fc-event-time{margin-left:3px}'
10291; 10292injectStyles(css_248z$1); 10293class AllDaySplitter extends Splitter { 10294 getKeyInfo() { 10295 return { 10296 allDay: {}, 10297 timed: {} 10298 }; 10299 } 10300 getKeysForDateSpan(dateSpan) { 10301 if (dateSpan.allDay) { 10302 return ["allDay"]; 10303 } 10304 return ["timed"]; 10305 } 10306 getKeysForEventDef(eventDef) { 10307 if (!eventDef.allDay) { 10308 return ["timed"]; 10309 } 10310 if (hasBgRendering(eventDef)) { 10311 return ["timed", "allDay"]; 10312 } 10313 return ["allDay"]; 10314 } 10315} 10316const DEFAULT_SLAT_LABEL_FORMAT = createFormatter({ 10317 hour: "numeric", 10318 minute: "2-digit", 10319 omitZeroMinute: true, 10320 meridiem: "short" 10321}); 10322function TimeColsAxisCell(props) { 10323 let classNames = [ 10324 "fc-timegrid-slot", 10325 "fc-timegrid-slot-label", 10326 props.isLabeled ? "fc-scrollgrid-shrink" : "fc-timegrid-slot-minor" 10327 ]; 10328 return y(ViewContextType.Consumer, null, (context) => { 10329 if (!props.isLabeled) { 10330 return y("td", { className: classNames.join(" "), "data-time": props.isoTimeStr }); 10331 } 10332 let { dateEnv, options, viewApi } = context; 10333 let labelFormat = ( 10334 // TODO: fully pre-parse 10335 options.slotLabelFormat == null ? DEFAULT_SLAT_LABEL_FORMAT : Array.isArray(options.slotLabelFormat) ? createFormatter(options.slotLabelFormat[0]) : createFormatter(options.slotLabelFormat) 10336 ); 10337 let renderProps = { 10338 level: 0, 10339 time: props.time, 10340 date: dateEnv.toDate(props.date), 10341 view: viewApi, 10342 text: dateEnv.format(props.date, labelFormat) 10343 }; 10344 return y(ContentContainer, { elTag: "td", elClasses: classNames, elAttrs: { 10345 "data-time": props.isoTimeStr 10346 }, renderProps, generatorName: "slotLabelContent", customGenerator: options.slotLabelContent, defaultGenerator: renderInnerContent, classNameGenerator: options.slotLabelClassNames, didMount: options.slotLabelDidMount, willUnmount: options.slotLabelWillUnmount }, (InnerContent) => y( 10347 "div", 10348 { className: "fc-timegrid-slot-label-frame fc-scrollgrid-shrink-frame" }, 10349 y(InnerContent, { elTag: "div", elClasses: [ 10350 "fc-timegrid-slot-label-cushion", 10351 "fc-scrollgrid-shrink-cushion" 10352 ] }) 10353 )); 10354 }); 10355} 10356function renderInnerContent(props) { 10357 return props.text; 10358} 10359class TimeBodyAxis extends BaseComponent { 10360 render() { 10361 return this.props.slatMetas.map((slatMeta) => y( 10362 "tr", 10363 { key: slatMeta.key }, 10364 y(TimeColsAxisCell, Object.assign({}, slatMeta)) 10365 )); 10366 } 10367} 10368const DEFAULT_WEEK_NUM_FORMAT = createFormatter({ week: "short" }); 10369const AUTO_ALL_DAY_MAX_EVENT_ROWS = 5; 10370class TimeColsView extends DateComponent { 10371 constructor() { 10372 super(...arguments); 10373 this.allDaySplitter = new AllDaySplitter(); 10374 this.headerElRef = d(); 10375 this.rootElRef = d(); 10376 this.scrollerElRef = d(); 10377 this.state = { 10378 slatCoords: null 10379 }; 10380 this.handleScrollTopRequest = (scrollTop) => { 10381 let scrollerEl = this.scrollerElRef.current; 10382 if (scrollerEl) { 10383 scrollerEl.scrollTop = scrollTop; 10384 } 10385 }; 10386 this.renderHeadAxis = (rowKey, frameHeight = "") => { 10387 let { options } = this.context; 10388 let { dateProfile } = this.props; 10389 let range = dateProfile.renderRange; 10390 let dayCnt = diffDays(range.start, range.end); 10391 let navLinkAttrs = dayCnt === 1 ? buildNavLinkAttrs(this.context, range.start, "week") : {}; 10392 if (options.weekNumbers && rowKey === "day") { 10393 return y(WeekNumberContainer, { elTag: "th", elClasses: [ 10394 "fc-timegrid-axis", 10395 "fc-scrollgrid-shrink" 10396 ], elAttrs: { 10397 "aria-hidden": true 10398 }, date: range.start, defaultFormat: DEFAULT_WEEK_NUM_FORMAT }, (InnerContent) => y( 10399 "div", 10400 { className: [ 10401 "fc-timegrid-axis-frame", 10402 "fc-scrollgrid-shrink-frame", 10403 "fc-timegrid-axis-frame-liquid" 10404 ].join(" "), style: { height: frameHeight } }, 10405 y(InnerContent, { elTag: "a", elClasses: [ 10406 "fc-timegrid-axis-cushion", 10407 "fc-scrollgrid-shrink-cushion", 10408 "fc-scrollgrid-sync-inner" 10409 ], elAttrs: navLinkAttrs }) 10410 )); 10411 } 10412 return y( 10413 "th", 10414 { "aria-hidden": true, className: "fc-timegrid-axis" }, 10415 y("div", { className: "fc-timegrid-axis-frame", style: { height: frameHeight } }) 10416 ); 10417 }; 10418 this.renderTableRowAxis = (rowHeight) => { 10419 let { options, viewApi } = this.context; 10420 let renderProps = { 10421 text: options.allDayText, 10422 view: viewApi 10423 }; 10424 return ( 10425 // TODO: make reusable hook. used in list view too 10426 y(ContentContainer, { elTag: "td", elClasses: [ 10427 "fc-timegrid-axis", 10428 "fc-scrollgrid-shrink" 10429 ], elAttrs: { 10430 "aria-hidden": true 10431 }, renderProps, generatorName: "allDayContent", customGenerator: options.allDayContent, defaultGenerator: renderAllDayInner, classNameGenerator: options.allDayClassNames, didMount: options.allDayDidMount, willUnmount: options.allDayWillUnmount }, (InnerContent) => y( 10432 "div", 10433 { className: [ 10434 "fc-timegrid-axis-frame", 10435 "fc-scrollgrid-shrink-frame", 10436 rowHeight == null ? " fc-timegrid-axis-frame-liquid" : "" 10437 ].join(" "), style: { height: rowHeight } }, 10438 y(InnerContent, { elTag: "span", elClasses: [ 10439 "fc-timegrid-axis-cushion", 10440 "fc-scrollgrid-shrink-cushion", 10441 "fc-scrollgrid-sync-inner" 10442 ] }) 10443 )) 10444 ); 10445 }; 10446 this.handleSlatCoords = (slatCoords) => { 10447 this.setState({ slatCoords }); 10448 }; 10449 } 10450 // rendering 10451 // ---------------------------------------------------------------------------------------------------- 10452 renderSimpleLayout(headerRowContent, allDayContent, timeContent) { 10453 let { context, props } = this; 10454 let sections = []; 10455 let stickyHeaderDates = getStickyHeaderDates(context.options); 10456 if (headerRowContent) { 10457 sections.push({ 10458 type: "header", 10459 key: "header", 10460 isSticky: stickyHeaderDates, 10461 chunk: { 10462 elRef: this.headerElRef, 10463 tableClassName: "fc-col-header", 10464 rowContent: headerRowContent 10465 } 10466 }); 10467 } 10468 if (allDayContent) { 10469 sections.push({ 10470 type: "body", 10471 key: "all-day", 10472 chunk: { content: allDayContent } 10473 }); 10474 sections.push({ 10475 type: "body", 10476 key: "all-day-divider", 10477 outerContent: ( 10478 // TODO: rename to cellContent so don't need to define <tr>? 10479 y( 10480 "tr", 10481 { role: "presentation", className: "fc-scrollgrid-section" }, 10482 y("td", { className: "fc-timegrid-divider " + context.theme.getClass("tableCellShaded") }) 10483 ) 10484 ) 10485 }); 10486 } 10487 sections.push({ 10488 type: "body", 10489 key: "body", 10490 liquid: true, 10491 expandRows: Boolean(context.options.expandRows), 10492 chunk: { 10493 scrollerElRef: this.scrollerElRef, 10494 content: timeContent 10495 } 10496 }); 10497 return y( 10498 ViewContainer, 10499 { elRef: this.rootElRef, elClasses: ["fc-timegrid"], viewSpec: context.viewSpec }, 10500 y(SimpleScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, collapsibleWidth: props.forPrint, cols: [{ width: "shrink" }], sections }) 10501 ); 10502 } 10503 renderHScrollLayout(headerRowContent, allDayContent, timeContent, colCnt, dayMinWidth, slatMetas, slatCoords) { 10504 let ScrollGrid = this.context.pluginHooks.scrollGridImpl; 10505 if (!ScrollGrid) { 10506 throw new Error("No ScrollGrid implementation"); 10507 } 10508 let { context, props } = this; 10509 let stickyHeaderDates = !props.forPrint && getStickyHeaderDates(context.options); 10510 let stickyFooterScrollbar = !props.forPrint && getStickyFooterScrollbar(context.options); 10511 let sections = []; 10512 if (headerRowContent) { 10513 sections.push({ 10514 type: "header", 10515 key: "header", 10516 isSticky: stickyHeaderDates, 10517 syncRowHeights: true, 10518 chunks: [ 10519 { 10520 key: "axis", 10521 rowContent: (arg) => y("tr", { role: "presentation" }, this.renderHeadAxis("day", arg.rowSyncHeights[0])) 10522 }, 10523 { 10524 key: "cols", 10525 elRef: this.headerElRef, 10526 tableClassName: "fc-col-header", 10527 rowContent: headerRowContent 10528 } 10529 ] 10530 }); 10531 } 10532 if (allDayContent) { 10533 sections.push({ 10534 type: "body", 10535 key: "all-day", 10536 syncRowHeights: true, 10537 chunks: [ 10538 { 10539 key: "axis", 10540 rowContent: (contentArg) => y("tr", { role: "presentation" }, this.renderTableRowAxis(contentArg.rowSyncHeights[0])) 10541 }, 10542 { 10543 key: "cols", 10544 content: allDayContent 10545 } 10546 ] 10547 }); 10548 sections.push({ 10549 key: "all-day-divider", 10550 type: "body", 10551 outerContent: ( 10552 // TODO: rename to cellContent so don't need to define <tr>? 10553 y( 10554 "tr", 10555 { role: "presentation", className: "fc-scrollgrid-section" }, 10556 y("td", { colSpan: 2, className: "fc-timegrid-divider " + context.theme.getClass("tableCellShaded") }) 10557 ) 10558 ) 10559 }); 10560 } 10561 let isNowIndicator = context.options.nowIndicator; 10562 sections.push({ 10563 type: "body", 10564 key: "body", 10565 liquid: true, 10566 expandRows: Boolean(context.options.expandRows), 10567 chunks: [ 10568 { 10569 key: "axis", 10570 content: (arg) => ( 10571 // TODO: make this now-indicator arrow more DRY with TimeColsContent 10572 y( 10573 "div", 10574 { className: "fc-timegrid-axis-chunk" }, 10575 y( 10576 "table", 10577 { "aria-hidden": true, style: { height: arg.expandRows ? arg.clientHeight : "" } }, 10578 arg.tableColGroupNode, 10579 y( 10580 "tbody", 10581 null,
10582 y(TimeBodyAxis, { slatMetas }) 10583 ) 10584 ), 10585 y( 10586 "div", 10587 { className: "fc-timegrid-now-indicator-container" }, 10588 y(NowTimer, { 10589 unit: isNowIndicator ? "minute" : "day" 10590 /* hacky */ 10591 }, (nowDate) => { 10592 let nowIndicatorTop = isNowIndicator && slatCoords && slatCoords.safeComputeTop(nowDate); 10593 if (typeof nowIndicatorTop === "number") { 10594 return y(NowIndicatorContainer, { elClasses: ["fc-timegrid-now-indicator-arrow"], elStyle: { top: nowIndicatorTop }, isAxis: true, date: nowDate }); 10595 } 10596 return null; 10597 }) 10598 ) 10599 ) 10600 ) 10601 }, 10602 { 10603 key: "cols", 10604 scrollerElRef: this.scrollerElRef, 10605 content: timeContent 10606 } 10607 ] 10608 }); 10609 if (stickyFooterScrollbar) { 10610 sections.push({ 10611 key: "footer", 10612 type: "footer", 10613 isSticky: true, 10614 chunks: [ 10615 { 10616 key: "axis", 10617 content: renderScrollShim 10618 }, 10619 { 10620 key: "cols", 10621 content: renderScrollShim 10622 } 10623 ] 10624 }); 10625 } 10626 return y( 10627 ViewContainer, 10628 { elRef: this.rootElRef, elClasses: ["fc-timegrid"], viewSpec: context.viewSpec }, 10629 y(ScrollGrid, { liquid: !props.isHeightAuto && !props.forPrint, forPrint: props.forPrint, collapsibleWidth: false, colGroups: [ 10630 { width: "shrink", cols: [{ width: "shrink" }] }, 10631 { cols: [{ span: colCnt, minWidth: dayMinWidth }] } 10632 ], sections }) 10633 ); 10634 } 10635 /* Dimensions 10636 ------------------------------------------------------------------------------------------------------------------*/ 10637 getAllDayMaxEventProps() { 10638 let { dayMaxEvents, dayMaxEventRows } = this.context.options; 10639 if (dayMaxEvents === true || dayMaxEventRows === true) { 10640 dayMaxEvents = void 0; 10641 dayMaxEventRows = AUTO_ALL_DAY_MAX_EVENT_ROWS; 10642 } 10643 return { dayMaxEvents, dayMaxEventRows }; 10644 } 10645} 10646function renderAllDayInner(renderProps) { 10647 return renderProps.text; 10648} 10649class TimeColsSlatsCoords { 10650 constructor(positions, dateProfile, slotDuration) { 10651 this.positions = positions; 10652 this.dateProfile = dateProfile; 10653 this.slotDuration = slotDuration; 10654 } 10655 safeComputeTop(date) { 10656 let { dateProfile } = this; 10657 if (rangeContainsMarker(dateProfile.currentRange, date)) { 10658 let startOfDayDate = startOfDay(date); 10659 let timeMs = date.valueOf() - startOfDayDate.valueOf(); 10660 if (timeMs >= asRoughMs(dateProfile.slotMinTime) && timeMs < asRoughMs(dateProfile.slotMaxTime)) { 10661 return this.computeTimeTop(createDuration(timeMs)); 10662 } 10663 } 10664 return null; 10665 } 10666 // Computes the top coordinate, relative to the bounds of the grid, of the given date. 10667 // A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight. 10668 computeDateTop(when, startOfDayDate) { 10669 if (!startOfDayDate) { 10670 startOfDayDate = startOfDay(when); 10671 } 10672 return this.computeTimeTop(createDuration(when.valueOf() - startOfDayDate.valueOf())); 10673 } 10674 // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration). 10675 // This is a makeshify way to compute the time-top. Assumes all slatMetas dates are uniform. 10676 // Eventually allow computation with arbirary slat dates. 10677 computeTimeTop(duration) { 10678 let { positions, dateProfile } = this; 10679 let len = positions.els.length; 10680 let slatCoverage = (duration.milliseconds - asRoughMs(dateProfile.slotMinTime)) / asRoughMs(this.slotDuration); 10681 let slatIndex; 10682 let slatRemainder; 10683 slatCoverage = Math.max(0, slatCoverage); 10684 slatCoverage = Math.min(len, slatCoverage); 10685 slatIndex = Math.floor(slatCoverage); 10686 slatIndex = Math.min(slatIndex, len - 1); 10687 slatRemainder = slatCoverage - slatIndex; 10688 return positions.tops[slatIndex] + positions.getHeight(slatIndex) * slatRemainder; 10689 } 10690} 10691class TimeColsSlatsBody extends BaseComponent { 10692 render() { 10693 let { props, context } = this; 10694 let { options } = context; 10695 let { slatElRefs } = props; 10696 return y("tbody", null, props.slatMetas.map((slatMeta, i2) => { 10697 let renderProps = { 10698 time: slatMeta.time, 10699 date: context.dateEnv.toDate(slatMeta.date), 10700 view: context.viewApi 10701 }; 10702 return y( 10703 "tr", 10704 { key: slatMeta.key, ref: slatElRefs.createRef(slatMeta.key) },
10705 props.axis && y(TimeColsAxisCell, Object.assign({}, slatMeta)), 10706 y(ContentContainer, { elTag: "td", elClasses: [ 10707 "fc-timegrid-slot", 10708 "fc-timegrid-slot-lane", 10709 !slatMeta.isLabeled && "fc-timegrid-slot-minor" 10710 ], elAttrs: { 10711 "data-time": slatMeta.isoTimeStr 10712 }, renderProps, generatorName: "slotLaneContent", customGenerator: options.slotLaneContent, classNameGenerator: options.slotLaneClassNames, didMount: options.slotLaneDidMount, willUnmount: options.slotLaneWillUnmount }) 10713 ); 10714 })); 10715 } 10716} 10717class TimeColsSlats extends BaseComponent { 10718 constructor() { 10719 super(...arguments); 10720 this.rootElRef = d(); 10721 this.slatElRefs = new RefMap(); 10722 } 10723 render() { 10724 let { props, context } = this; 10725 return y( 10726 "div", 10727 { ref: this.rootElRef, className: "fc-timegrid-slots" }, 10728 y( 10729 "table", 10730 { "aria-hidden": true, className: context.theme.getClass("table"), style: { 10731 minWidth: props.tableMinWidth, 10732 width: props.clientWidth, 10733 height: props.minHeight 10734 } }, 10735 props.tableColGroupNode, 10736 y(TimeColsSlatsBody, { slatElRefs: this.slatElRefs, axis: props.axis, slatMetas: props.slatMetas }) 10737 ) 10738 ); 10739 } 10740 componentDidMount() { 10741 this.updateSizing(); 10742 } 10743 componentDidUpdate() { 10744 this.updateSizing(); 10745 } 10746 componentWillUnmount() { 10747 if (this.props.onCoords) { 10748 this.props.onCoords(null); 10749 } 10750 } 10751 updateSizing() { 10752 let { context, props } = this; 10753 if (props.onCoords && props.clientWidth !== null) { 10754 let rootEl = this.rootElRef.current; 10755 if (rootEl.offsetHeight) { 10756 props.onCoords(new TimeColsSlatsCoords(new PositionCache(this.rootElRef.current, collectSlatEls(this.slatElRefs.currentMap, props.slatMetas), false, true), this.props.dateProfile, context.options.slotDuration)); 10757 } 10758 } 10759 } 10760} 10761function collectSlatEls(elMap, slatMetas) { 10762 return slatMetas.map((slatMeta) => elMap[slatMeta.key]); 10763} 10764function splitSegsByCol(segs, colCnt) { 10765 let segsByCol = []; 10766 let i2; 10767 for (i2 = 0; i2 < colCnt; i2 += 1) { 10768 segsByCol.push([]); 10769 } 10770 if (segs) { 10771 for (i2 = 0; i2 < segs.length; i2 += 1) { 10772 segsByCol[segs[i2].col].push(segs[i2]); 10773 } 10774 } 10775 return segsByCol; 10776} 10777function splitInteractionByCol(ui, colCnt) { 10778 let byRow = []; 10779 if (!ui) { 10780 for (let i2 = 0; i2 < colCnt; i2 += 1) { 10781 byRow[i2] = null; 10782 } 10783 } else { 10784 for (let i2 = 0; i2 < colCnt; i2 += 1) { 10785 byRow[i2] = { 10786 affectedInstances: ui.affectedInstances, 10787 isEvent: ui.isEvent, 10788 segs: [] 10789 }; 10790 } 10791 for (let seg of ui.segs) { 10792 byRow[seg.col].segs.push(seg); 10793 } 10794 } 10795 return byRow; 10796} 10797class TimeColMoreLink extends BaseComponent { 10798 render() { 10799 let { props } = this; 10800 return y(MoreLinkContainer, { elClasses: ["fc-timegrid-more-link"], elStyle: { 10801 top: props.top, 10802 bottom: props.bottom 10803 }, allDayDate: null, moreCnt: props.hiddenSegs.length, allSegs: props.hiddenSegs, hiddenSegs: props.hiddenSegs, extraDateSpan: props.extraDateSpan, dateProfile: props.dateProfile, todayRange: props.todayRange, popoverContent: () => renderPlainFgSegs(props.hiddenSegs, props), defaultGenerator: renderMoreLinkInner, forceTimed: true }, (InnerContent) => y(InnerContent, { elTag: "div", elClasses: ["fc-timegrid-more-link-inner", "fc-sticky"] })); 10804 } 10805} 10806function renderMoreLinkInner(props) { 10807 return props.shortText; 10808} 10809function buildPositioning(segInputs, strictOrder, maxStackCnt) { 10810 let hierarchy = new SegHierarchy(); 10811 if (strictOrder != null) { 10812 hierarchy.strictOrder = strictOrder; 10813 } 10814 if (maxStackCnt != null) { 10815 hierarchy.maxStackCnt = maxStackCnt; 10816 } 10817 let hiddenEntries = hierarchy.addSegs(segInputs); 10818 let hiddenGroups = groupIntersectingEntries(hiddenEntries); 10819 let web = buildWeb(hierarchy); 10820 web = stretchWeb(web, 1); 10821 let segRects = webToRects(web); 10822 return { segRects, hiddenGroups }; 10823} 10824function buildWeb(hierarchy) { 10825 const { entriesByLevel } = hierarchy; 10826 const buildNode = cacheable((level, lateral) => level + ":" + lateral, (level, lateral) => { 10827 let siblingRange = findNextLevelSegs(hierarchy, level, lateral); 10828 let nextLevelRes = buildNodes(siblingRange, buildNode); 10829 let entry = entriesByLevel[level][lateral]; 10830 return [ 10831 Object.assign(Object.assign({}, entry), { nextLevelNodes: nextLevelRes[0] }), 10832 entry.thickness + nextLevelRes[1] 10833 // the pressure builds 10834 ]; 10835 }); 10836 return buildNodes(entriesByLevel.length ? { level: 0, lateralStart: 0, lateralEnd: entriesByLevel[0].length } : null, buildNode)[0]; 10837} 10838function buildNodes(siblingRange, buildNode) { 10839 if (!siblingRange) { 10840 return [[], 0]; 10841 } 10842 let { level, lateralStart, lateralEnd } = siblingRange; 10843 let lateral = lateralStart; 10844 let pairs = []; 10845 while (lateral < lateralEnd) { 10846 pairs.push(buildNode(level, lateral)); 10847 lateral += 1; 10848 } 10849 pairs.sort(cmpDescPressures); 10850 return [ 10851 pairs.map(extractNode), 10852 pairs[0][1] 10853 // first item's pressure 10854 ]; 10855} 10856function cmpDescPressures(a2, b2) { 10857 return b2[1] - a2[1]; 10858} 10859function extractNode(a2) { 10860 return a2[0]; 10861} 10862function findNextLevelSegs(hierarchy, subjectLevel, subjectLateral) { 10863 let { levelCoords, entriesByLevel } = hierarchy; 10864 let subjectEntry = entriesByLevel[subjectLevel][subjectLateral]; 10865 let afterSubject = levelCoords[subjectLevel] + subjectEntry.thickness; 10866 let levelCnt = levelCoords.length; 10867 let level = subjectLevel; 10868 for (; level < levelCnt && levelCoords[level] < afterSubject;
vendor: 1,688 bytes, lines 10868-10913
10868 level += 1) 10869 ; 10870 for (; level < levelCnt; level += 1) { 10871 let entries = entriesByLevel[level]; 10872 let entry; 10873 let searchIndex = binarySearch(entries, subjectEntry.span.start, getEntrySpanEnd); 10874 let lateralStart = searchIndex[0] + searchIndex[1]; 10875 let lateralEnd = lateralStart; 10876 while ( 10877 // loop through entries that horizontally intersect 10878 (entry = entries[lateralEnd]) && // but not past the whole seg list 10879 entry.span.start < subjectEntry.span.end 10880 ) { 10881 lateralEnd += 1; 10882 } 10883 if (lateralStart < lateralEnd) { 10884 return { level, lateralStart, lateralEnd }; 10885 } 10886 } 10887 return null; 10888} 10889function stretchWeb(topLevelNodes, totalThickness) { 10890 const stretchNode = cacheable((node, startCoord, prevThickness) => buildEntryKey(node), (node, startCoord, prevThickness) => { 10891 let { nextLevelNodes, thickness } = node; 10892 let allThickness = thickness + prevThickness; 10893 let thicknessFraction = thickness / allThickness; 10894 let endCoord; 10895 let newChildren = []; 10896 if (!nextLevelNodes.length) { 10897 endCoord = totalThickness; 10898 } else { 10899 for (let childNode of nextLevelNodes) { 10900 if (endCoord === void 0) { 10901 let res = stretchNode(childNode, startCoord, allThickness); 10902 endCoord = res[0]; 10903 newChildren.push(res[1]); 10904 } else { 10905 let res = stretchNode(childNode, endCoord, 0); 10906 newChildren.push(res[1]); 10907 } 10908 } 10909 } 10910 let newThickness = (endCoord - startCoord) * thicknessFraction; 10911 return [endCoord - newThickness, Object.assign(Object.assign({}, node), { thickness: newThickness, nextLevelNodes: newChildren })]; 10912 }); 10913 return topLevelNodes.map((node) =>
10913 stretchNode(node, 0, 0)[1]); 10914} 10915function webToRects(topLevelNodes) { 10916 let rects = []; 10917 const processNode = cacheable((node, levelCoord, stackDepth) => buildEntryKey(node), (node, levelCoord, stackDepth) => { 10918 let rect = Object.assign(Object.assign({}, node), { 10919 levelCoord, 10920 stackDepth, 10921 stackForward: 0 10922 }); 10923 rects.push(rect); 10924 return rect.stackForward = processNodes(node.nextLevelNodes, levelCoord + node.thickness, stackDepth + 1) + 1; 10925 }); 10926 function processNodes(nodes, levelCoord, stackDepth) { 10927 let stackForward = 0; 10928 for (let node of nodes) { 10929 stackForward = Math.max(processNode(node, levelCoord, stackDepth), stackForward); 10930 } 10931 return stackForward; 10932 } 10933 processNodes(topLevelNodes, 0, 0); 10934 return rects; 10935} 10936function cacheable(keyFunc, workFunc) { 10937 const cache = {}; 10938 return (...args) => { 10939 let key = keyFunc(...args); 10940 return key in cache ? cache[key] : cache[key] = workFunc(...args); 10941 }; 10942} 10943function computeSegVCoords(segs, colDate, slatCoords = null, eventMinHeight = 0) { 10944 let vcoords = []; 10945 if (slatCoords) { 10946 for (let i2 = 0; i2 < segs.length; i2 += 1) { 10947 let seg = segs[i2]; 10948 let spanStart = slatCoords.computeDateTop(seg.start, colDate); 10949 let spanEnd = Math.max( 10950 spanStart + (eventMinHeight || 0), 10951 // :( 10952 slatCoords.computeDateTop(seg.end, colDate) 10953 ); 10954 vcoords.push({ 10955 start: Math.round(spanStart), 10956 end: Math.round(spanEnd) 10957 // 10958 }); 10959 } 10960 } 10961 return vcoords; 10962} 10963function computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack) { 10964 let segInputs = []; 10965 let dumbSegs = []; 10966 for (let i2 = 0; i2 < segs.length; i2 += 1) { 10967 let vcoords = segVCoords[i2]; 10968 if (vcoords) { 10969 segInputs.push({ 10970 index: i2, 10971 thickness: 1, 10972 span: vcoords 10973 }); 10974 } else { 10975 dumbSegs.push(segs[i2]); 10976 } 10977 } 10978 let { segRects, hiddenGroups } = buildPositioning(segInputs, eventOrderStrict, eventMaxStack); 10979 let segPlacements = []; 10980 for (let segRect of segRects) { 10981 segPlacements.push({ 10982 seg: segs[segRect.index], 10983 rect: segRect 10984 }); 10985 } 10986 for (let dumbSeg of dumbSegs) { 10987 segPlacements.push({ seg: dumbSeg, rect: null }); 10988 } 10989 return { segPlacements, hiddenGroups }; 10990} 10991const DEFAULT_TIME_FORMAT = createFormatter({ 10992 hour: "numeric", 10993 minute: "2-digit", 10994 meridiem: false 10995}); 10996class TimeColEvent extends BaseComponent { 10997 render() { 10998 return y(StandardEvent, Object.assign({}, this.props, { elClasses: [ 10999 "fc-timegrid-event", 11000 "fc-v-event", 11001 this.props.isShort && "fc-timegrid-event-short" 11002 ], defaultTimeFormat: DEFAULT_TIME_FORMAT })); 11003 } 11004} 11005class TimeCol extends BaseComponent { 11006 constructor() { 11007 super(...arguments); 11008 this.sortEventSegs = memoize(sortEventSegs); 11009 } 11010 // TODO: memoize event-placement? 11011 render() { 11012 let { props, context } = this; 11013 let { options } = context; 11014 let isSelectMirror = options.selectMirror; 11015 let mirrorSegs = ( 11016 // yuck 11017 props.eventDrag && props.eventDrag.segs || props.eventResize && props.eventResize.segs || isSelectMirror && props.dateSelectionSegs || [] 11018 ); 11019 let interactionAffectedInstances = ( 11020 // TODO: messy way to compute this 11021 props.eventDrag && props.eventDrag.affectedInstances || props.eventResize && props.eventResize.affectedInstances || {} 11022 ); 11023 let sortedFgSegs = this.sortEventSegs(props.fgEventSegs, options.eventOrder); 11024 return y(DayCellContainer, { elTag: "td", elRef: props.elRef, elClasses: [ 11025 "fc-timegrid-col", 11026 ...props.extraClassNames || [] 11027 ], elAttrs: Object.assign({ role: "gridcell" }, props.extraDataAttrs), date: props.date, dateProfile: props.dateProfile, todayRange: props.todayRange, extraRenderProps: props.extraRenderProps }, (InnerContent) => y( 11028 "div", 11029 { className: "fc-timegrid-col-frame" }, 11030 y( 11031 "div", 11032 { className: "fc-timegrid-col-bg" }, 11033 this.renderFillSegs(props.businessHourSegs, "non-business"), 11034 this.renderFillSegs(props.bgEventSegs, "bg-event"), 11035 this.renderFillSegs(props.dateSelectionSegs, "highlight") 11036 ), 11037 y("div", { className: "fc-timegrid-col-events" }, this.renderFgSegs(sortedFgSegs, interactionAffectedInstances, false, false, false)), 11038 y("div", { className: "fc-timegrid-col-events" }, this.renderFgSegs(mirrorSegs, {}, Boolean(props.eventDrag), Boolean(props.eventResize), Boolean(isSelectMirror), "mirror")), 11039 y("div", { className: "fc-timegrid-now-indicator-container" }, this.renderNowIndicator(props.nowIndicatorSegs)), 11040 hasCustomDayCellContent(options) && y(InnerContent, { elTag: "div", elClasses: ["fc-timegrid-col-misc"] }) 11041 )); 11042 } 11043 renderFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey) { 11044 let { props } = this; 11045 if (props.forPrint) { 11046 return renderPlainFgSegs(sortedFgSegs, props); 11047 } 11048 return this.renderPositionedFgSegs(sortedFgSegs, segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey); 11049 } 11050 renderPositionedFgSegs(segs, segIsInvisible, isDragging, isResizing, isDateSelecting, forcedKey) { 11051 let { eventMaxStack, eventShortHeight, eventOrderStrict, eventMinHeight } = this.context.options; 11052 let { date, slatCoords, eventSelection, todayRange, nowDate } = this.props; 11053 let isMirror = isDragging || isResizing || isDateSelecting; 11054 let segVCoords = computeSegVCoords(segs, date, slatCoords, eventMinHeight); 11055 let { segPlacements, hiddenGroups } = computeFgSegPlacements(segs, segVCoords, eventOrderStrict, eventMaxStack); 11056 return y( 11057 _, 11058 null, 11059 this.renderHiddenGroups(hiddenGroups, segs), 11060 segPlacements.map((segPlacement) => { 11061 let { seg, rect } = segPlacement; 11062 let instanceId = seg.eventRange.instance.instanceId; 11063 let isVisible = isMirror || Boolean(!segIsInvisible[instanceId] && rect); 11064 let vStyle = computeSegVStyle(rect && rect.span); 11065 let hStyle = !isMirror && rect ? this.computeSegHStyle(rect) : { left: 0, right: 0 }; 11066 let isInset = Boolean(rect) && rect.stackForward > 0;
11067 let isShort = Boolean(rect) && rect.span.end - rect.span.start < eventShortHeight; 11068 return y( 11069 "div", 11070 { className: "fc-timegrid-event-harness" + (isInset ? " fc-timegrid-event-harness-inset" : ""), key: forcedKey || instanceId, style: Object.assign(Object.assign({ visibility: isVisible ? "" : "hidden" }, vStyle), hStyle) }, 11071 y(TimeColEvent, Object.assign({ seg, isDragging, isResizing, isDateSelecting, isSelected: instanceId === eventSelection, isShort }, getSegMeta(seg, todayRange, nowDate))) 11072 ); 11073 }) 11074 ); 11075 } 11076 // will already have eventMinHeight applied because segInputs already had it 11077 renderHiddenGroups(hiddenGroups, segs) { 11078 let { extraDateSpan, dateProfile, todayRange, nowDate, eventSelection, eventDrag, eventResize } = this.props; 11079 return y(_, null, hiddenGroups.map((hiddenGroup) => { 11080 let positionCss = computeSegVStyle(hiddenGroup.span); 11081 let hiddenSegs = compileSegsFromEntries(hiddenGroup.entries, segs); 11082 return y(TimeColMoreLink, { key: buildIsoString(computeEarliestSegStart(hiddenSegs)), hiddenSegs, top: positionCss.top, bottom: positionCss.bottom, extraDateSpan, dateProfile, todayRange, nowDate, eventSelection, eventDrag, eventResize }); 11083 })); 11084 } 11085 renderFillSegs(segs, fillType) { 11086 let { props, context } = this; 11087 let segVCoords = computeSegVCoords(segs, props.date, props.slatCoords, context.options.eventMinHeight); 11088 let children = segVCoords.map((vcoords, i2) => { 11089 let seg = segs[i2]; 11090 return y("div", { key: buildEventRangeKey(seg.eventRange), className: "fc-timegrid-bg-harness", style: computeSegVStyle(vcoords) }, fillType === "bg-event" ? y(BgEvent, Object.assign({ seg }, getSegMeta(seg, props.todayRange, props.nowDate))) : renderFill(fillType)); 11091 }); 11092 return y(_, null, children); 11093 } 11094 renderNowIndicator(segs) { 11095 let { slatCoords, date } = this.props; 11096 if (!slatCoords) { 11097 return null; 11098 } 11099 return segs.map((seg, i2) => y( 11100 NowIndicatorContainer, 11101 { 11102 // key doesn't matter. will only ever be one 11103 key: i2, 11104 elClasses: ["fc-timegrid-now-indicator-line"], 11105 elStyle: { 11106 top: slatCoords.computeDateTop(seg.start, date) 11107 }, 11108 isAxis: false, 11109 date 11110 } 11111 )); 11112 } 11113 computeSegHStyle(segHCoords) { 11114 let { isRtl, options } = this.context; 11115 let shouldOverlap = options.slotEventOverlap; 11116 let nearCoord = segHCoords.levelCoord; 11117 let farCoord = segHCoords.levelCoord + segHCoords.thickness; 11118 let left; 11119 let right; 11120 if (shouldOverlap) { 11121 farCoord = Math.min(1, nearCoord + (farCoord - nearCoord) * 2); 11122 } 11123 if (isRtl) { 11124 left = 1 - farCoord; 11125 right = nearCoord; 11126 } else { 11127 left = nearCoord; 11128 right = 1 - farCoord; 11129 } 11130 let props = { 11131 zIndex: segHCoords.stackDepth + 1, 11132 left: left * 100 + "%", 11133 right: right * 100 + "%" 11134 }; 11135 if (shouldOverlap && !segHCoords.stackForward) { 11136 props[isRtl ? "marginLeft" : "marginRight"] = 10 * 2; 11137 } 11138 return props; 11139 } 11140} 11141function renderPlainFgSegs(sortedFgSegs, { todayRange, nowDate, eventSelection, eventDrag, eventResize }) { 11142 let hiddenInstances = (eventDrag ? eventDrag.affectedInstances : null) || (eventResize ? eventResize.affectedInstances : null) || {}; 11143 return y(_, null, sortedFgSegs.map((seg) => { 11144 let instanceId = seg.eventRange.instance.instanceId; 11145 return y( 11146 "div", 11147 { key: instanceId, style: { visibility: hiddenInstances[instanceId] ? "hidden" : "" } }, 11148 y(TimeColEvent, Object.assign({ seg, isDragging: false, isResizing: false, isDateSelecting: false, isSelected: instanceId === eventSelection, isShort: false }, getSegMeta(seg, todayRange, nowDate))) 11149 ); 11150 })); 11151} 11152function computeSegVStyle(segVCoords) { 11153 if (!segVCoords) { 11154 return { top: "", bottom: "" }; 11155 } 11156 return { 11157 top: segVCoords.start, 11158 bottom: -segVCoords.end 11159 }; 11160} 11161function compileSegsFromEntries(segEntries, allSegs) { 11162 return segEntries.map((segEntry) => allSegs[segEntry.index]); 11163} 11164class TimeColsContent extends BaseComponent { 11165 constructor() { 11166 super(...arguments); 11167 this.splitFgEventSegs = memoize(splitSegsByCol); 11168 this.splitBgEventSegs = memoize(splitSegsByCol); 11169 this.splitBusinessHourSegs = memoize(splitSegsByCol); 11170 this.splitNowIndicatorSegs = memoize(splitSegsByCol); 11171 this.splitDateSelectionSegs = memoize(splitSegsByCol); 11172 this.splitEventDrag = memoize(splitInteractionByCol); 11173 this.splitEventResize = memoize(splitInteractionByCol); 11174 this.rootElRef = d(); 11175 this.cellElRefs = new RefMap(); 11176 } 11177 render() { 11178 let { props, context } = this; 11179 let nowIndicatorTop = context.options.nowIndicator && props.slatCoords && props.slatCoords.safeComputeTop(props.nowDate);
11180 let colCnt = props.cells.length; 11181 let fgEventSegsByRow = this.splitFgEventSegs(props.fgEventSegs, colCnt); 11182 let bgEventSegsByRow = this.splitBgEventSegs(props.bgEventSegs, colCnt); 11183 let businessHourSegsByRow = this.splitBusinessHourSegs(props.businessHourSegs, colCnt); 11184 let nowIndicatorSegsByRow = this.splitNowIndicatorSegs(props.nowIndicatorSegs, colCnt); 11185 let dateSelectionSegsByRow = this.splitDateSelectionSegs(props.dateSelectionSegs, colCnt); 11186 let eventDragByRow = this.splitEventDrag(props.eventDrag, colCnt); 11187 let eventResizeByRow = this.splitEventResize(props.eventResize, colCnt); 11188 return y( 11189 "div", 11190 { className: "fc-timegrid-cols", ref: this.rootElRef }, 11191 y( 11192 "table", 11193 { role: "presentation", style: { 11194 minWidth: props.tableMinWidth, 11195 width: props.clientWidth 11196 } }, 11197 props.tableColGroupNode, 11198 y( 11199 "tbody", 11200 { role: "presentation" }, 11201 y( 11202 "tr", 11203 { role: "row" }, 11204 props.axis && y( 11205 "td", 11206 { "aria-hidden": true, className: "fc-timegrid-col fc-timegrid-axis" }, 11207 y( 11208 "div", 11209 { className: "fc-timegrid-col-frame" }, 11210 y("div", { className: "fc-timegrid-now-indicator-container" }, typeof nowIndicatorTop === "number" && y(NowIndicatorContainer, { elClasses: ["fc-timegrid-now-indicator-arrow"], elStyle: { top: nowIndicatorTop }, isAxis: true, date: props.nowDate })) 11211 ) 11212 ), 11213 props.cells.map((cell, i2) => y(TimeCol, { key: cell.key, elRef: this.cellElRefs.createRef(cell.key), dateProfile: props.dateProfile, date: cell.date, nowDate: props.nowDate, todayRange: props.todayRange, extraRenderProps: cell.extraRenderProps, extraDataAttrs: cell.extraDataAttrs, extraClassNames: cell.extraClassNames, extraDateSpan: cell.extraDateSpan, fgEventSegs: fgEventSegsByRow[i2], bgEventSegs: bgEventSegsByRow[i2], businessHourSegs: businessHourSegsByRow[i2], nowIndicatorSegs: nowIndicatorSegsByRow[i2], dateSelectionSegs: dateSelectionSegsByRow[i2], eventDrag: eventDragByRow[i2], eventResize: eventResizeByRow[i2], slatCoords: props.slatCoords, eventSelection: props.eventSelection, forPrint: props.forPrint })) 11214 ) 11215 ) 11216 ) 11217 ); 11218 } 11219 componentDidMount() { 11220 this.updateCoords(); 11221 } 11222 componentDidUpdate() { 11223 this.updateCoords(); 11224 } 11225 updateCoords() { 11226 let { props } = this; 11227 if (props.onColCoords && props.clientWidth !== null) { 11228 props.onColCoords(new PositionCache( 11229 this.rootElRef.current, 11230 collectCellEls(this.cellElRefs.currentMap, props.cells), 11231 true, 11232 // horizontal 11233 false 11234 )); 11235 } 11236 } 11237} 11238function collectCellEls(elMap, cells) { 11239 return cells.map((cell) => elMap[cell.key]); 11240} 11241class TimeCols extends DateComponent { 11242 constructor() { 11243 super(...arguments); 11244 this.processSlotOptions = memoize(processSlotOptions); 11245 this.state = { 11246 slatCoords: null 11247 }; 11248 this.handleRootEl = (el) => { 11249 if (el) { 11250 this.context.registerInteractiveComponent(this, { 11251 el, 11252 isHitComboAllowed: this.props.isHitComboAllowed 11253 }); 11254 } else { 11255 this.context.unregisterInteractiveComponent(this); 11256 } 11257 }; 11258 this.handleScrollRequest = (request) => { 11259 let { onScrollTopRequest } = this.props; 11260 let { slatCoords } = this.state; 11261 if (onScrollTopRequest && slatCoords) { 11262 if (request.time) { 11263 let top = slatCoords.computeTimeTop(request.time); 11264 top = Math.ceil(top); 11265 if (top) { 11266 top += 1; 11267 } 11268 onScrollTopRequest(top); 11269 } 11270 return true; 11271 } 11272 return false; 11273 }; 11274 this.handleColCoords = (colCoords) => { 11275 this.colCoords = colCoords; 11276 }; 11277 this.handleSlatCoords = (slatCoords) => { 11278 this.setState({ slatCoords }); 11279 if (this.props.onSlatCoords) { 11280 this.props.onSlatCoords(slatCoords); 11281 } 11282 }; 11283 } 11284 render() { 11285 let { props, state } = this; 11286 return y( 11287 "div", 11288 { className: "fc-timegrid-body", ref: this.handleRootEl, style: { 11289 // these props are important to give this wrapper correct dimensions for interactions 11290 // TODO: if we set it here, can we avoid giving to inner tables? 11291 width: props.clientWidth, 11292 minWidth: props.tableMinWidth 11293 } },
11294 y(TimeColsSlats, { axis: props.axis, dateProfile: props.dateProfile, slatMetas: props.slatMetas, clientWidth: props.clientWidth, minHeight: props.expandRows ? props.clientHeight : "", tableMinWidth: props.tableMinWidth, tableColGroupNode: props.axis ? props.tableColGroupNode : null, onCoords: this.handleSlatCoords }), 11295 y(TimeColsContent, { cells: props.cells, axis: props.axis, dateProfile: props.dateProfile, businessHourSegs: props.businessHourSegs, bgEventSegs: props.bgEventSegs, fgEventSegs: props.fgEventSegs, dateSelectionSegs: props.dateSelectionSegs, eventSelection: props.eventSelection, eventDrag: props.eventDrag, eventResize: props.eventResize, todayRange: props.todayRange, nowDate: props.nowDate, nowIndicatorSegs: props.nowIndicatorSegs, clientWidth: props.clientWidth, tableMinWidth: props.tableMinWidth, tableColGroupNode: props.tableColGroupNode, slatCoords: state.slatCoords, onColCoords: this.handleColCoords, forPrint: props.forPrint }) 11296 ); 11297 } 11298 componentDidMount() { 11299 this.scrollResponder = this.context.createScrollResponder(this.handleScrollRequest); 11300 } 11301 componentDidUpdate(prevProps) { 11302 this.scrollResponder.update(prevProps.dateProfile !== this.props.dateProfile); 11303 } 11304 componentWillUnmount() { 11305 this.scrollResponder.detach(); 11306 } 11307 queryHit(positionLeft, positionTop) { 11308 let { dateEnv, options } = this.context; 11309 let { colCoords } = this; 11310 let { dateProfile } = this.props; 11311 let { slatCoords } = this.state; 11312 let { snapDuration, snapsPerSlot } = this.processSlotOptions(this.props.slotDuration, options.snapDuration); 11313 let colIndex = colCoords.leftToIndex(positionLeft); 11314 let slatIndex = slatCoords.positions.topToIndex(positionTop); 11315 if (colIndex != null && slatIndex != null) { 11316 let cell = this.props.cells[colIndex]; 11317 let slatTop = slatCoords.positions.tops[slatIndex]; 11318 let slatHeight = slatCoords.positions.getHeight(slatIndex); 11319 let partial = (positionTop - slatTop) / slatHeight; 11320 let localSnapIndex = Math.floor(partial * snapsPerSlot); 11321 let snapIndex = slatIndex * snapsPerSlot + localSnapIndex; 11322 let dayDate = this.props.cells[colIndex].date; 11323 let time = addDurations(dateProfile.slotMinTime, multiplyDuration(snapDuration, snapIndex)); 11324 let start = dateEnv.add(dayDate, time); 11325 let end = dateEnv.add(start, snapDuration); 11326 return { 11327 dateProfile, 11328 dateSpan: Object.assign({ range: { start, end }, allDay: false }, cell.extraDateSpan), 11329 dayEl: colCoords.els[colIndex], 11330 rect: { 11331 left: colCoords.lefts[colIndex], 11332 right: colCoords.rights[colIndex], 11333 top: slatTop, 11334 bottom: slatTop + slatHeight 11335 }, 11336 layer: 0 11337 }; 11338 } 11339 return null; 11340 } 11341} 11342function processSlotOptions(slotDuration, snapDurationOverride) { 11343 let snapDuration = snapDurationOverride || slotDuration; 11344 let snapsPerSlot = wholeDivideDurations(slotDuration, snapDuration); 11345 if (snapsPerSlot === null) { 11346 snapDuration = slotDuration; 11347 snapsPerSlot = 1; 11348 } 11349 return { snapDuration, snapsPerSlot }; 11350} 11351class DayTimeColsSlicer extends Slicer { 11352 sliceRange(range, dayRanges) { 11353 let segs = []; 11354 for (let col = 0; col < dayRanges.length; col += 1) { 11355 let segRange = intersectRanges(range, dayRanges[col]); 11356 if (segRange) { 11357 segs.push({ 11358 start: segRange.start, 11359 end: segRange.end, 11360 isStart: segRange.start.valueOf() === range.start.valueOf(), 11361 isEnd: segRange.end.valueOf() === range.end.valueOf(), 11362 col 11363 }); 11364 } 11365 } 11366 return segs; 11367 } 11368} 11369class DayTimeCols extends DateComponent { 11370 constructor() { 11371 super(...arguments); 11372 this.buildDayRanges = memoize(buildDayRanges); 11373 this.slicer = new DayTimeColsSlicer(); 11374 this.timeColsRef = d(); 11375 } 11376 render() { 11377 let { props, context } = this; 11378 let { dateProfile, dayTableModel } = props; 11379 let { nowIndicator, nextDayThreshold } = context.options; 11380 let dayRanges = this.buildDayRanges(dayTableModel, dateProfile, context.dateEnv); 11381 return y(NowTimer, { unit: nowIndicator ? "minute" : "day" }, (nowDate, todayRange) => y(TimeCols, Object.assign({ ref: this.timeColsRef }, this.slicer.sliceProps(props, dateProfile, null, context, dayRanges), { forPrint: props.forPrint, axis: props.axis, dateProfile, slatMetas: props.slatMetas, slotDuration: props.slotDuration, cells: dayTableModel.cells[0], tableColGroupNode: props.tableColGroupNode, tableMinWidth: props.tableMinWidth, clientWidth: props.clientWidth, clientHeight: props.clientHeight, expandRows: props.expandRows, nowDate, nowIndicatorSegs: nowIndicator && this.slicer.sliceNowDate(nowDate, dateProfile, nextDayThreshold, context, dayRanges), todayRange, onScrollTopRequest: props.onScrollTopRequest, onSlatCoords: props.onSlatCoords }))); 11382 } 11383} 11384function buildDayRanges(dayTableModel, dateProfile, dateEnv) { 11385 let ranges = []; 11386 for (let date of dayTableModel.headerDates) { 11387 ranges.push({ 11388 start: dateEnv.add(date, dateProfile.slotMinTime), 11389 end: dateEnv.add(date, dateProfile.slotMaxTime) 11390 }); 11391 } 11392 return ranges; 11393} 11394const STOCK_SUB_DURATIONS = [ 11395 { hours: 1 }, 11396 { minutes: 30 }, 11397 { minutes: 15 }, 11398 { seconds: 30 }, 11399 { seconds: 15 } 11400]; 11401function buildSlatMetas(slotMinTime, slotMaxTime, explicitLabelInterval, slotDuration, dateEnv) { 11402 let dayStart = /* @__PURE__ */ new Date(0); 11403 let slatTime = slotMinTime; 11404 let slatIterator = createDuration(0); 11405 let labelInterval = explicitLabelInterval || computeLabelInterval(slotDuration); 11406 let metas = []; 11407 while (asRoughMs(slatTime) < asRoughMs(slotMaxTime)) { 11408 let date = dateEnv.add(dayStart, slatTime); 11409 let isLabeled = wholeDivideDurations(slatIterator, labelInterval) !== null; 11410 metas.push({ 11411 date, 11412 time: slatTime, 11413 key: date.toISOString(), 11414 isoTimeStr: formatIsoTimeString(date),
11415 isLabeled 11416 }); 11417 slatTime = addDurations(slatTime, slotDuration); 11418 slatIterator = addDurations(slatIterator, slotDuration); 11419 } 11420 return metas; 11421} 11422function computeLabelInterval(slotDuration) { 11423 let i2; 11424 let labelInterval; 11425 let slotsPerLabel; 11426 for (i2 = STOCK_SUB_DURATIONS.length - 1; i2 >= 0; i2 -= 1) { 11427 labelInterval = createDuration(STOCK_SUB_DURATIONS[i2]); 11428 slotsPerLabel = wholeDivideDurations(labelInterval, slotDuration); 11429 if (slotsPerLabel !== null && slotsPerLabel > 1) { 11430 return labelInterval; 11431 } 11432 } 11433 return slotDuration; 11434} 11435class DayTimeColsView extends TimeColsView { 11436 constructor() { 11437 super(...arguments); 11438 this.buildTimeColsModel = memoize(buildTimeColsModel); 11439 this.buildSlatMetas = memoize(buildSlatMetas); 11440 } 11441 render() { 11442 let { options, dateEnv, dateProfileGenerator } = this.context; 11443 let { props } = this; 11444 let { dateProfile } = props; 11445 let dayTableModel = this.buildTimeColsModel(dateProfile, dateProfileGenerator); 11446 let splitProps = this.allDaySplitter.splitProps(props); 11447 let slatMetas = this.buildSlatMetas(dateProfile.slotMinTime, dateProfile.slotMaxTime, options.slotLabelInterval, options.slotDuration, dateEnv); 11448 let { dayMinWidth } = options; 11449 let hasAttachedAxis = !dayMinWidth; 11450 let hasDetachedAxis = dayMinWidth; 11451 let headerContent = options.dayHeaders && y(DayHeader, { dates: dayTableModel.headerDates, dateProfile, datesRepDistinctDays: true, renderIntro: hasAttachedAxis ? this.renderHeadAxis : null }); 11452 let allDayContent = options.allDaySlot !== false && ((contentArg) => y(DayTable, Object.assign({}, splitProps.allDay, { dateProfile, dayTableModel, nextDayThreshold: options.nextDayThreshold, tableMinWidth: contentArg.tableMinWidth, colGroupNode: contentArg.tableColGroupNode, renderRowIntro: hasAttachedAxis ? this.renderTableRowAxis : null, showWeekNumbers: false, expandRows: false, headerAlignElRef: this.headerElRef, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, forPrint: props.forPrint }, this.getAllDayMaxEventProps()))); 11453 let timeGridContent = (contentArg) => y(DayTimeCols, Object.assign({}, splitProps.timed, { dayTableModel, dateProfile, axis: hasAttachedAxis, slotDuration: options.slotDuration, slatMetas, forPrint: props.forPrint, tableColGroupNode: contentArg.tableColGroupNode, tableMinWidth: contentArg.tableMinWidth, clientWidth: contentArg.clientWidth, clientHeight: contentArg.clientHeight, onSlatCoords: this.handleSlatCoords, expandRows: contentArg.expandRows, onScrollTopRequest: this.handleScrollTopRequest })); 11454 return hasDetachedAxis ? this.renderHScrollLayout(headerContent, allDayContent, timeGridContent, dayTableModel.colCnt, dayMinWidth, slatMetas, this.state.slatCoords) : this.renderSimpleLayout(headerContent, allDayContent, timeGridContent); 11455 } 11456}
11457function buildTimeColsModel(dateProfile, dateProfileGenerator) { 11458 let daySeries = new DaySeriesModel(dateProfile.renderRange, dateProfileGenerator); 11459 return new DayTableModel(daySeries, false); 11460} 11461var css_248z = '.fc-v-event{background-color:var(--fc-event-bg-color);border:1px solid var(--fc-event-border-color);display:block}.fc-v-event .fc-event-main{color:var(--fc-event-text-color);height:100%}.fc-v-event .fc-event-main-frame{display:flex;flex-direction:column;height:100%}.fc-v-event .fc-event-time{flex-grow:0;flex-shrink:0;max-height:100%;overflow:hidden}.fc-v-event .fc-event-title-container{flex-grow:1;flex-shrink:1;min-height:0}.fc-v-event .fc-event-title{bottom:0;max-height:100%;overflow:hidden;top:0}.fc-v-event:not(.fc-event-start){border-top-left-radius:0;border-top-right-radius:0;border-top-width:0}.fc-v-event:not(.fc-event-end){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:0}.fc-v-event.fc-event-selected:before{left:-10px;right:-10px}.fc-v-event .fc-event-resizer-start{cursor:n-resize}.fc-v-event .fc-event-resizer-end{cursor:s-resize}.fc-v-event:not(.fc-event-selected) .fc-event-resizer{height:var(--fc-event-resizer-thickness);left:0;right:0}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-start{top:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event:not(.fc-event-selected) .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-thickness)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer{left:50%;margin-left:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-start{top:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc-v-event.fc-event-selected .fc-event-resizer-end{bottom:calc(var(--fc-event-resizer-dot-total-width)/-2)}.fc .fc-timegrid .fc-daygrid-body{z-index:2}.fc .fc-timegrid-divider{padding:0 0 2px}.fc .fc-timegrid-body{min-height:100%;position:relative;z-index:1}.fc .fc-timegrid-axis-chunk{position:relative}.fc .fc-timegrid-axis-chunk>table,.fc .fc-timegrid-slots{position:relative;z-index:1}.fc .fc-timegrid-slot{border-bottom:0;height:1.5em}.fc .fc-timegrid-slot:empty:before{content:"\\00a0"}.fc .fc-timegrid-slot-minor{border-top-style:dotted}.fc .fc-timegrid-slot-label-cushion{display:inline-block;white-space:nowrap}.fc .fc-timegrid-slot-label{vertical-align:middle}.fc .fc-timegrid-axis-cushion,.fc .fc-timegrid-slot-label-cushion{padding:0 4px}.fc .fc-timegrid-axis-frame-liquid{height:100%}.fc .fc-timegrid-axis-frame{align-items:center;display:flex;justify-content:flex-end;overflow:hidden}.fc .fc-timegrid-axis-cushion{flex-shrink:0;max-width:60px}.fc-direction-ltr .fc-timegrid-slot-label-frame{text-align:right}.fc-direction-rtl .fc-timegrid-slot-label-frame{text-align:left}.fc-liquid-hack .fc-timegrid-axis-frame-liquid{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col.fc-day-today{background-color:var(--fc-today-bg-color)}.fc .fc-timegrid-col-frame{min-height:100%;position:relative}.fc-media-screen.fc-liquid-hack .fc-timegrid-col-frame{bottom:0;height:auto;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols{bottom:0;left:0;position:absolute;right:0;top:0}.fc-media-screen .fc-timegrid-cols>table{height:100%}.fc-media-screen .fc-timegrid-col-bg,.fc-media-screen .fc-timegrid-col-events,.fc-media-screen .fc-timegrid-now-indicator-container{left:0;position:absolute;right:0;top:0}.fc .fc-timegrid-col-bg{z-index:2}.fc .fc-timegrid-col-bg .fc-non-business{z-index:1}.fc .fc-timegrid-col-bg .fc-bg-event{z-index:2}.fc .fc-timegrid-col-bg .fc-highlight{z-index:3}.fc .fc-timegrid-bg-harness{left:0;position:absolute;right:0}.fc .fc-timegrid-col-events{z-index:3}.fc .fc-timegrid-now-indicator-container{bottom:0;overflow:hidden}.fc-direction-ltr .fc-timegrid-col-events{margin:0 2.5% 0 2px}.fc-direction-rtl .fc-timegrid-col-events{margin:0 2px 0 2.5%}.fc-timegrid-event-harness{position:absolute}.fc-timegrid-event-harness>.fc-timegrid-event{bottom:0;left:0;position:absolute;right:0;top:0}.fc-timegrid-event-harness-inset .fc-timegrid-event,.fc-timegrid-event.fc-event-mirror,.fc-timegrid-more-link{box-shadow:0 0 0 1px var(--fc-page-bg-color)}.fc-timegrid-event,.fc-timegrid-more-link{border-radius:3px;font-size:var(--fc-small-font-size)}.fc-timegrid-event{margin-bottom:1px}.fc-timegrid-event .fc-event-main{padding:1px 1px 0}.fc-timegrid-event .fc-event-time{font-size:var(--fc-small-font-size);margin-bottom:1px;white-space:nowrap}.fc-timegrid-event-short .fc-event-main-frame{flex-direction:row;overflow:hidden}.fc-timegrid-event-short .fc-event-time:after{content:"\\00a0-\\00a0"}.fc-timegrid-event-short .fc-event-title{font-size:var(--fc-small-font-size)}.fc-timegrid-more-link{background:var(--fc-more-link-bg-color);color:var(--fc-more-link-text-color);cursor:pointer;margin-bottom:1px;position:absolute;z-index:9999}.fc-timegrid-more-link-inner{padding:3px 2px;top:0}.fc-direction-ltr .fc-timegrid-more-link{right:0}.fc-direction-rtl .fc-timegrid-more-link{left:0}.fc .fc-timegrid-now-indicator-arrow,.fc .fc-timegrid-now-indicator-line{pointer-events:none}.fc .fc-timegrid-now-indicator-line{border-color:var(--fc-now-indicator-color);border-style:solid;border-width:1px 0 0;left:0;position:absolute;right:0;z-index:4}.fc .fc-timegrid-now-indicator-arrow{border-color:var(--fc-now-indicator-color);border-style:solid;margin-top:-5px;position:absolute;z-index:4}.fc-direction-ltr .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 0 5px 6px;left:0}.fc-direction-rtl .fc-timegrid-now-indicator-arrow{border-bottom-color:transparent;border-top-color:transparent;border-width:5px 6px 5px 0;right:0}'; 11462injectStyles(css_248z); 11463const OPTION_REFINERS = { 11464 allDaySlot: Boolean 11465}; 11466var index = createPlugin({ 11467 name: "@fullcalendar/timegrid", 11468 initialView: "timeGridWeek", 11469 optionRefiners: OPTION_REFINERS, 11470 views: { 11471 timeGrid: { 11472 component: DayTimeColsView, 11473 usesMinMaxTime: true, 11474 allDaySlot: true, 11475 slotDuration: "00:30:00", 11476 slotEventOverlap: true 11477 // a bad name. confused with overlap/constraint system 11478 }, 11479 timeGridDay: { 11480 type: "timeGrid", 11481 duration: { days: 1 } 11482 }, 11483 timeGridWeek: { 11484 type: "timeGrid", 11485 duration: { weeks: 1 } 11486 } 11487 } 11488}); 11489export { 11490 removeElement as $, 11491 getIsRtlScrollbarOnLeft as A, 11492 BaseComponent as B, 11493 ContentContainer as C, 11494 DateComponent as D, 11495 EventContainer as E, 11496 getAllowYScrolling as F, 11497 getSectionHasLiquidHeight as G, 11498 renderChunkContent as H, 11499 memoizeHashlike as I,
11500 computeShrinkWidth as J, 11501 findElements as K, 11502 getScrollbarWidths as L, 11503 collectFromHash as M, 11504 NowTimer as N, 11505 mapHash as O, 11506 setRef as P, 11507 isArraysEqual as Q, 11508 RefMap as R, 11509 Scroller as S, 11510 isPropsEqual as T, 11511 sanitizeShrinkWidth as U, 11512 ViewContainer as V, 11513 d as W, 11514 renderMicroColGroup as X, 11515 hasShrinkWidth as Y, 11516 compareObjs as Z, 11517 _, 11518 getSegMeta as a, 11519 DayTableSlicer as a$, 11520 translateRect as a0, 11521 computeInnerRect as a1, 11522 applyStyle as a2, 11523 Emitter as a3, 11524 DelayedRunner as a4, 11525 isColPropsEqual as a5, 11526 computeEdges as a6, 11527 getStickyHeaderDates as a7, 11528 getStickyFooterScrollbar as a8, 11529 greatestDurationDenominator as a9, 11530 findDirectChildren as aA, 11531 rangeContainsMarker as aB, 11532 SegHierarchy as aC, 11533 parseFieldSpecs as aD, 11534 refineProps as aE, 11535 guid as aF, 11536 parseBusinessHours as aG, 11537 createEventUi as aH, 11538 EventImpl as aI, 11539 parseClassNames as aJ, 11540 TableDateCell as aK, 11541 TableDowCell as aL, 11542 computeFallbackHeaderFormat as aM, 11543 flexibleCompare as aN, 11544 compareByFieldSpecs as aO, 11545 Splitter as aP, 11546 ViewContextType as aQ, 11547 CalendarImpl as aR, 11548 filterHash as aS, 11549 mergeEventStores as aT, 11550 isPropsValid as aU, 11551 rangesIntersect as aV, 11552 combineEventUis as aW, 11553 rangesEqual as aX, 11554 unpromisify as aY, 11555 requestJson as aZ, 11556 elementClosest as a_, 11557 asCleanDays as aa, 11558 createDuration as ab, 11559 wholeDivideDurations as ac, 11560 asRoughMs as ad, 11561 asRoughSeconds as ae, 11562 asRoughMinutes as af, 11563 diffWholeDays as ag, 11564 isInt as ah, 11565 NowIndicatorContainer as ai, 11566 buildIsoString as aj, 11567 computeEarliestSegStart as ak, 11568 renderScrollShim as al, 11569 padStart as am, 11570 multiplyDuration as an, 11571 groupIntersectingEntries as ao, 11572 BgEvent as ap, 11573 renderFill as aq, 11574 buildEventRangeKey as ar, 11575 Slicer as as, 11576 addMs as at, 11577 StandardEvent as au, 11578 MoreLinkContainer as av, 11579 computeVisibleDayRange as aw, 11580 memoizeObjArg as ax, 11581 getSlotClassNames as ay, 11582 PositionCache as az, 11583 sliceEventStore as b, 11584 Table as b0, 11585 TimeColsView as b1, 11586 buildSlatMetas as b2, 11587 buildTimeColsModel as b3, 11588 buildDayRanges as b4, 11589 DayTimeColsSlicer as b5, 11590 TimeCols as b6, 11591 index as b7, 11592 Calendar as b8, 11593 DayTableView as b9, 11594 diffPoints as bA, 11595 rangeContainsRange as bB, 11596 isDateSpansEqual as bC, 11597 compareNumbers as bD, 11598 ElementScrollController as bE, 11599 WindowScrollController as bF, 11600 getClippingParents as bG, 11601 pointInsideRect as bH, 11602 ScrollController as bI, 11603 TableDateProfileGenerator as ba, 11604 ElementDragging as bb, 11605 preventSelection as bc, 11606 preventContextMenu as bd, 11607 allowSelection as be, 11608 allowContextMenu as bf, 11609 Interaction as bg, 11610 interactionSettingsToStore as bh, 11611 isDateSelectionValid as bi, 11612 enableCursor as bj, 11613 disableCursor as bk, 11614 triggerDateSelect as bl, 11615 getElSeg as bm, 11616 getRelevantEvents as bn, 11617 applyMutationToEventStore as bo, 11618 isInteractionValid as bp, 11619 createEmptyEventStore as bq, 11620 buildEventApis as br, 11621 interactionSettingsStore as bs, 11622 diffDates as bt, 11623 getEventTargetViaRoot as bu, 11624 whenTransitionDone as bv, 11625 computeRect as bw, 11626 constrainPoint as bx, 11627 intersectRects as by, 11628 getRectCenter as bz, 11629 createFormatter as c, 11630 intersectRanges as d, 11631 startOfDay as e, 11632 formatDayString as f, 11633 getUniqueDomId as g, 11634 addDays as h, 11635 injectStyles as i, 11636 getDateMeta as j, 11637 buildNavLinkAttrs as k, 11638 getDayClassNames as l, 11639 memoize as m, 11640 getSegAnchorAttrs as n, 11641 isMultiDayRange as o, 11642 buildSegTimeText as p, 11643 createPlugin as q, 11644 identity as r, 11645 sortEventSegs as s, 11646 isValidDate as t, 11647 config as u, 11648 memoizeArraylike as v, 11649 getScrollGridClassNames as w, 11650 getCanVGrowWithinCell as x, 11651 y, 11652 getSectionClassNames as z 11653};
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.