1(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["vendors~bundle"],{ 2
vendor: 59,976 bytes, lines 3-1412
3/***/ "./node_modules/gsap/CSSPlugin.js": 4/*!****************************************!*\ 5 !*** ./node_modules/gsap/CSSPlugin.js ***! 6 \****************************************/ 7/*! exports provided: CSSPlugin, default, _getBBox, _createElement, checkPrefix */ 8/***/ (function(module, __webpack_exports__, __webpack_require__) { 9 10"use strict"; 11__webpack_require__.r(__webpack_exports__); 12/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CSSPlugin", function() { return CSSPlugin; }); 13/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CSSPlugin; }); 14/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getBBox", function() { return _getBBox; }); 15/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_createElement", function() { return _createElement; }); 16/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "checkPrefix", function() { return _checkPropPrefix; }); 17/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js"); 18/*! 19 * CSSPlugin 3.6.0 20 * https://greensock.com 21 * 22 * Copyright 2008-2021, GreenSock. All rights reserved. 23 * Subject to the terms at https://greensock.com/standard-license or for 24 * Club GreenSock members, the agreement issued with that membership. 25 * @author: Jack Doyle, [email protected] 26*/ 27 28/* eslint-disable */ 29 30 31var _win, 32 _doc, 33 _docElement, 34 _pluginInitted, 35 _tempDiv, 36 _tempDivStyler, 37 _recentSetterPlugin, 38 _windowExists = function _windowExists() { 39 return typeof window !== "undefined"; 40}, 41 _transformProps = {}, 42 _RAD2DEG = 180 / Math.PI, 43 _DEG2RAD = Math.PI / 180, 44 _atan2 = Math.atan2, 45 _bigNum = 1e8, 46 _capsExp = /([A-Z])/g, 47 _horizontalExp = /(?:left|right|width|margin|padding|x)/i, 48 _complexExp = /[\s,\(]\S/, 49 _propertyAliases = { 50 autoAlpha: "opacity,visibility", 51 scale: "scaleX,scaleY", 52 alpha: "opacity" 53}, 54 _renderCSSProp = function _renderCSSProp(ratio, data) { 55 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 56}, 57 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 58 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 59}, 60 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 61 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 62}, 63 //if units change, we need a way to render the original unit/value when the tween goes all the way back to the beginning (ratio:0) 64_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 65 var value = data.s + data.c * ratio; 66 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 67}, 68 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 69 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 70}, 71 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 72 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 73}, 74 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 75 return target.style[property] = value; 76}, 77 _setterCSSProp = function _setterCSSProp(target, property, value) { 78 return target.style.setProperty(property, value); 79}, 80 _setterTransform = function _setterTransform(target, property, value) { 81 return target._gsap[property] = value; 82}, 83 _setterScale = function _setterScale(target, property, value) { 84 return target._gsap.scaleX = target._gsap.scaleY = value; 85}, 86 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 87 var cache = target._gsap; 88 cache.scaleX = cache.scaleY = value; 89 cache.renderTransform(ratio, cache); 90}, 91 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 92 var cache = target._gsap; 93 cache[property] = value; 94 cache.renderTransform(ratio, cache); 95}, 96 _transformProp = "transform", 97 _transformOriginProp = _transformProp + "Origin", 98 _supports3D, 99 _createElement = function _createElement(type, ns) { 100 var e = _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making "style" inaccessible. 101 102 return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). 103}, 104 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 105 var cs = getComputedStyle(target); 106 return cs[property] || cs.getPropertyValue(property.replace(_capsExp, "-$1").toLowerCase()) || cs.getPropertyValue(property) || !skipPrefixFallback && _getComputedProperty(target, _checkPropPrefix(property) || property, 1) || ""; //css variables may not need caps swapped out for dashes and lowercase. 107}, 108 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 109 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 110 var e = element || _tempDiv, 111 s = e.style, 112 i = 5; 113 114 if (property in s && !preferPrefix) { 115 return property; 116 } 117 118 property = property.charAt(0).toUpperCase() + property.substr(1); 119 120 while (i-- && !(_prefixes[i] + property in s)) {} 121 122 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 123}, 124 _initCore = function _initCore() { 125 if (_windowExists() && window.document) { 126 _win = window; 127 _doc = _win.document; 128 _docElement = _doc.documentElement; 129 _tempDiv = _createElement("div") || { 130 style: {} 131 }; 132 _tempDivStyler = _createElement("div"); 133 _transformProp = _checkPropPrefix(_transformProp); 134 _transformOriginProp = _transformProp + "Origin"; 135 _tempDiv.style.cssText = "border-width:0;line-height:0;position:absolute;padding:0"; //make sure to override certain properties that may contaminate measurements, in case the user has overreaching style sheets. 136 137 _supports3D = !!_checkPropPrefix("perspective"); 138 _pluginInitted = 1; 139 } 140}, 141 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 142 //works around issues in some browsers (like Firefox) that don't correctly report getBBox() on SVG elements inside a <defs> element and/or <mask>. We try creating an SVG, adding it to the documentElement and toss the element in there so that it's definitely part of the rendering tree, then grab the bbox and if it works, we actually swap out the original getBBox() method for our own that does these extra steps whenever getBBox is needed. This helps ensure that performance is optimal (only do all these extra steps when absolutely necessary...most elements don't need it). 143 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 144 oldParent = this.parentNode, 145 oldSibling = this.nextSibling, 146 oldCSS = this.style.cssText, 147 bbox; 148 149 _docElement.appendChild(svg); 150 151 svg.appendChild(this); 152 this.style.display = "block"; 153 154 if (swapIfPossible) { 155 try { 156 bbox = this.getBBox(); 157 this._gsapBBox = this.getBBox; //store the original 158 159 this.getBBox = _getBBoxHack; 160 } catch (e) {} 161 } else if (this._gsapBBox) { 162 bbox = this._gsapBBox(); 163 } 164 165 if (oldParent) { 166 if (oldSibling) { 167 oldParent.insertBefore(this, oldSibling); 168 } else { 169 oldParent.appendChild(this); 170 } 171 } 172 173 _docElement.removeChild(svg); 174 175 this.style.cssText = oldCSS; 176 return bbox; 177}, 178 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 179 var i = attributesArray.length; 180 181 while (i--) { 182 if (target.hasAttribute(attributesArray[i])) { 183 return target.getAttribute(attributesArray[i]); 184 } 185 } 186}, 187 _getBBox = function _getBBox(target) { 188 var bounds; 189 190 try { 191 bounds = target.getBBox(); //Firefox throws errors if you try calling getBBox() on an SVG element that's not rendered (like in a <symbol> or <defs>). https://bugzilla.mozilla.org/show_bug.cgi?id=612118 192 } catch (error) { 193 bounds = _getBBoxHack.call(target, true); 194 } 195 196 bounds && (bounds.width || bounds.height) || target.getBBox === _getBBoxHack || (bounds = _getBBoxHack.call(target, true)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes it's at x:0, y:0), thus we need to manually grab the position in that case. 197 198 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 199 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 200 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 201 width: 0, 202 height: 0 203 } : bounds; 204}, 205 _isSVG = function _isSVG(e) { 206 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 207}, 208 //reports if the element is an SVG on which getBBox() actually works 209_removeProperty = function _removeProperty(target, property) { 210 if (property) { 211 var style = target.style; 212 213 if (property in _transformProps && property !== _transformOriginProp) { 214 property = _transformProp; 215 } 216 217 if (style.removeProperty) { 218 if (property.substr(0, 2) === "ms" || property.substr(0, 6) === "webkit") { 219 //Microsoft and some Webkit browsers don't conform to the standard of capitalizing the first prefix character, so we adjust so that when we prefix the caps with a dash, it's correct (otherwise it'd be "ms-transform" instead of "-ms-transform" for IE9, for example) 220 property = "-" + property; 221 } 222 223 style.removeProperty(property.replace(_capsExp, "-$1").toLowerCase()); 224 } else { 225 //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" 226 style.removeAttribute(property); 227 } 228 } 229}, 230 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 231 var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 232 plugin._pt = pt; 233 pt.b = beginning; 234 pt.e = end; 235 236 plugin._props.push(property); 237 238 return pt; 239}, 240 _nonConvertibleUnits = { 241 deg: 1, 242 rad: 1, 243 turn: 1 244}, 245 //takes a single value like 20px and converts it to the unit specified, like "%", returning only the numeric amount. 246_convertToUnit = function _convertToUnit(target, property, value, unit) { 247 var curValue = parseFloat(value) || 0, 248 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 249 // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim() 250 style = _tempDiv.style, 251 horizontal = _horizontalExp.test(property), 252 isRootSVG = target.tagName.toLowerCase() === "svg", 253 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 254 amount = 100, 255 toPixels = unit === "px", 256 toPercent = unit === "%", 257 px, 258 parent, 259 cache, 260 isSVG; 261 262 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 263 return curValue; 264 } 265 266 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 267 isSVG = target.getCTM && _isSVG(target); 268 269 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 270 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 271 return Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(toPercent ? curValue / px * amount : curValue / 100 * px); 272 } 273 274 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 275 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 276 277 if (isSVG) { 278 parent = (target.ownerSVGElement || {}).parentNode; 279 } 280 281 if (!parent || parent === _doc || !parent.appendChild) { 282 parent = _doc.body; 283 } 284 285 cache = parent._gsap; 286 287 if (cache && toPercent && cache.width && horizontal && cache.time === _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_ticker"].time) { 288 return Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(curValue / cache.width * amount); 289 } else { 290 (toPercent || curUnit === "%") && (style.position = _getComputedProperty(target, "position")); 291 parent === target && (style.position = "static"); // like for borderRadius, if it's a % we must have it relative to the target itself but that may not have position: relative or position: absolute in which case it'd go up the chain until it finds its offsetParent (bad). position: static protects against that. 292 293 parent.appendChild(_tempDiv); 294 px = _tempDiv[measureProperty]; 295 parent.removeChild(_tempDiv); 296 style.position = "absolute"; 297 298 if (horizontal && toPercent) { 299 cache = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_getCache"])(parent); 300 cache.time = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_ticker"].time; 301 cache.width = parent[measureProperty]; 302 } 303 } 304 305 return Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 306}, 307 _get = function _get(target, property, unit, uncache) { 308 var value; 309 _pluginInitted || _initCore(); 310 311 if (property in _propertyAliases && property !== "transform") { 312 property = _propertyAliases[property]; 313 314 if (~property.indexOf(",")) { 315 property = property.split(",")[0]; 316 } 317 } 318 319 if (_transformProps[property] && property !== "transform") { 320 value = _parseTransform(target, uncache); 321 value = property !== "transformOrigin" ? value[property] : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 322 } else { 323 value = target.style[property]; 324 325 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 326 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_getProperty"])(target, property) || (property === "opacity" ? 1 : 0); // note: some browsers, like Firefox, don't report borderRadius correctly! Instead, it only reports every corner like borderTopLeftRadius 327 } 328 } 329 330 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 331}, 332 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 333 //note: we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 334 if (!start || start === "none") { 335 // some browsers like Safari actually PREFER the prefixed property and mis-report the unprefixed value like clipPath (BUG). In other words, even though clipPath exists in the style ("clipPath" in target.style) and it's set in the CSS properly (along with -webkit-clip-path), Safari reports clipPath as "none" whereas WebkitClipPath reports accurately like "ellipse(100% 0% at 50% 0%)", so in this case we must SWITCH to using the prefixed property instead. See https://greensock.com/forums/topic/18310-clippath-doesnt-work-on-ios/ 336 var p = _checkPropPrefix(prop, target, 1), 337 s = p && _getComputedProperty(target, p, 1); 338 339 if (s && s !== start) { 340 prop = p; 341 start = s; 342 } else if (prop === "borderColor") { 343 start = _getComputedProperty(target, "borderTopColor"); // Firefox bug: always reports "borderColor" as "", so we must fall back to borderTopColor. See https://greensock.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/ 344 } 345 } 346 347 var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](this._pt, target.style, prop, 0, 1, _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_renderComplexString"]), 348 index = 0, 349 matchIndex = 0, 350 a, 351 result, 352 startValues, 353 startNum, 354 color, 355 startValue, 356 endValue, 357 endNum, 358 chunk, 359 endUnit, 360 startUnit, 361 relative, 362 endValues; 363 pt.b = start; 364 pt.e = end; 365 start += ""; //ensure values are strings 366 367 end += ""; 368 369 if (end === "auto") { 370 target.style[prop] = end; 371 end = _getComputedProperty(target, prop) || end; 372 target.style[prop] = start; 373 } 374 375 a = [start, end]; 376 377 Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_colorStringFilter"])(a); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. If colors are found, it returns true and then we must match where the color shows up order-wise because for things like boxShadow, sometimes the browser provides the computed values with the color FIRST, but the user provides it with the color LAST, so flip them if necessary. Same for drop-shadow(). 378 379 380 start = a[0]; 381 end = a[1]; 382 startValues = start.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_numWithUnitExp"]) || []; 383 endValues = end.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_numWithUnitExp"]) || []; 384 385 if (endValues.length) { 386 while (result = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_numWithUnitExp"].exec(end)) { 387 endValue = result[0]; 388 chunk = end.substring(index, result.index); 389 390 if (color) { 391 color = (color + 1) % 5; 392 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 393 color = 1; 394 } 395 396 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 397 startNum = parseFloat(startValue) || 0; 398 startUnit = startValue.substr((startNum + "").length); 399 relative = endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 400 401 if (relative) { 402 endValue = endValue.substr(2); 403 } 404 405 endNum = parseFloat(endValue); 406 endUnit = endValue.substr((endNum + "").length); 407 index = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_numWithUnitExp"].lastIndex - endUnit.length; 408 409 if (!endUnit) { 410 //if something like "perspective:300" is passed in and we must add a unit to the end 411 endUnit = endUnit || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units[prop] || startUnit; 412 413 if (index === end.length) { 414 end += endUnit; 415 pt.e += endUnit; 416 } 417 } 418 419 if (startUnit !== endUnit) { 420 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 421 } //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method. 422 423 424 pt._pt = { 425 _next: pt._pt, 426 p: chunk || matchIndex === 1 ? chunk : ",", 427 //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 428 s: startNum, 429 c: relative ? relative * endNum : endNum - startNum, 430 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 431 }; 432 } 433 } 434 435 pt.c = index < end.length ? end.substring(index, end.length) : ""; //we use the "c" of the PropTween to store the final part of the string (after the last number) 436 } else { 437 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 438 } 439 440 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_relExp"].test(end) && (pt.e = 0); //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 441 442 this._pt = pt; //start the linked list with this new PropTween. Remember, we call _tweenComplexCSSString.call(pluginInstance...) to ensure that it's scoped properly. We may call it from within another plugin too, thus "this" would refer to the plugin. 443 444 return pt; 445}, 446 _keywordToPercent = { 447 top: "0%", 448 bottom: "100%", 449 left: "0%", 450 right: "100%", 451 center: "50%" 452}, 453 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 454 var split = value.split(" "), 455 x = split[0], 456 y = split[1] || "50%"; 457 458 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 459 //the user provided them in the wrong order, so flip them 460 value = x; 461 x = y; 462 y = value; 463 } 464 465 split[0] = _keywordToPercent[x] || x; 466 split[1] = _keywordToPercent[y] || y; 467 return split.join(" "); 468}, 469 _renderClearProps = function _renderClearProps(ratio, data) { 470 if (data.tween && data.tween._time === data.tween._dur) { 471 var target = data.t, 472 style = target.style, 473 props = data.u, 474 cache = target._gsap, 475 prop, 476 clearTransforms, 477 i; 478 479 if (props === "all" || props === true) { 480 style.cssText = ""; 481 clearTransforms = 1; 482 } else { 483 props = props.split(","); 484 i = props.length; 485 486 while (--i > -1) { 487 prop = props[i]; 488 489 if (_transformProps[prop]) { 490 clearTransforms = 1; 491 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 492 } 493 494 _removeProperty(target, prop); 495 } 496 } 497 498 if (clearTransforms) { 499 _removeProperty(target, _transformProp); 500 501 if (cache) { 502 cache.svg && target.removeAttribute("transform"); 503 504 _parseTransform(target, 1); // force all the cached values back to "normal"/identity, otherwise if there's another tween that's already set to render transforms on this element, it could display the wrong values. 505 506 507 cache.uncache = 1; 508 } 509 } 510 } 511}, 512 // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list. 513_specialProps = { 514 clearProps: function clearProps(plugin, target, property, endValue, tween) { 515 if (tween.data !== "isFromStart") { 516 var pt = plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](plugin._pt, target, property, 0, 0, _renderClearProps); 517 pt.u = endValue; 518 pt.pr = -10; 519 pt.tween = tween; 520 521 plugin._props.push(property); 522 523 return 1; 524 } 525 } 526 /* className feature (about 0.4kb gzipped). 527 , className(plugin, target, property, endValue, tween) { 528 let _renderClassName = (ratio, data) => { 529 data.css.render(ratio, data.css); 530 if (!ratio || ratio === 1) { 531 let inline = data.rmv, 532 target = data.t, 533 p; 534 target.setAttribute("class", ratio ? data.e : data.b); 535 for (p in inline) { 536 _removeProperty(target, p); 537 } 538 } 539 }, 540 _getAllStyles = (target) => { 541 let styles = {}, 542 computed = getComputedStyle(target), 543 p; 544 for (p in computed) { 545 if (isNaN(p) && p !== "cssText" && p !== "length") { 546 styles[p] = computed[p]; 547 } 548 } 549 _setDefaults(styles, _parseTransform(target, 1)); 550 return styles; 551 }, 552 startClassList = target.getAttribute("class"), 553 style = target.style, 554 cssText = style.cssText, 555 cache = target._gsap, 556 classPT = cache.classPT, 557 inlineToRemoveAtEnd = {}, 558 data = {t:target, plugin:plugin, rmv:inlineToRemoveAtEnd, b:startClassList, e:(endValue.charAt(1) !== "=") ? endValue : startClassList.replace(new RegExp("(?:\\s|^)" + endValue.substr(2) + "(?![\\w-])"), "") + ((endValue.charAt(0) === "+") ? " " + endValue.substr(2) : "")}, 559 changingVars = {}, 560 startVars = _getAllStyles(target), 561 transformRelated = /(transform|perspective)/i, 562 endVars, p; 563 if (classPT) { 564 classPT.r(1, classPT.d); 565 _removeLinkedListItem(classPT.d.plugin, classPT, "_pt"); 566 } 567 target.setAttribute("class", data.e); 568 endVars = _getAllStyles(target, true); 569 target.setAttribute("class", startClassList); 570 for (p in endVars) { 571 if (endVars[p] !== startVars[p] && !transformRelated.test(p)) { 572 changingVars[p] = endVars[p]; 573 if (!style[p] && style[p] !== "0") { 574 inlineToRemoveAtEnd[p] = 1; 575 } 576 } 577 } 578 cache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11); 579 if (style.cssText !== cssText) { //only apply if things change. Otherwise, in cases like a background-image that's pulled dynamically, it could cause a refresh. See https://greensock.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/. 580 style.cssText = cssText; //we recorded cssText before we swapped classes and ran _getAllStyles() because in cases when a className tween is overwritten, we remove all the related tweening properties from that class change (otherwise class-specific stuff can't override properties we've directly set on the target's style object due to specificity). 581 } 582 _parseTransform(target, true); //to clear the caching of transforms 583 data.css = new gsap.plugins.css(); 584 data.css.init(target, changingVars, tween); 585 plugin._props.push(...data.css._props); 586 return 1; 587 } 588 */ 589 590}, 591 592/* 593 * -------------------------------------------------------------------------------------- 594 * TRANSFORMS 595 * -------------------------------------------------------------------------------------- 596 */ 597_identity2DMatrix = [1, 0, 0, 1, 0, 0], 598 _rotationalProperties = {}, 599 _isNullTransform = function _isNullTransform(value) { 600 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 601}, 602 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 603 var matrixString = _getComputedProperty(target, _transformProp); 604 605 return _isNullTransform(matrixString) ? _identity2DMatrix : matrixString.substr(7).match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_numExp"]).map(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"]); 606}, 607 _getMatrix = function _getMatrix(target, force2D) { 608 var cache = target._gsap || Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_getCache"])(target), 609 style = target.style, 610 matrix = _getComputedTransformMatrixAsArray(target), 611 parent, 612 nextSibling, 613 temp, 614 addedToDOM; 615 616 if (cache.svg && target.getAttribute("transform")) { 617 temp = target.transform.baseVal.consolidate().matrix; //ensures that even complex values like "translate(50,60) rotate(135,0,0)" are parsed because it mashes it into a matrix. 618 619 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 620 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 621 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 622 //note: if offsetParent is null, that means the element isn't in the normal document flow, like if it has display:none or one of its ancestors has display:none). Firefox returns null for getComputedStyle() if the element is in an iframe that has display:none. https://bugzilla.mozilla.org/show_bug.cgi?id=548397 623 //browsers don't report transforms accurately unless the element is in the DOM and has a display value that's not "none". Firefox and Microsoft browsers have a partial bug where they'll report transforms even if display:none BUT not any percentage-based values like translate(-50%, 8px) will be reported as if it's translate(0, 8px). 624 temp = style.display; 625 style.display = "block"; 626 parent = target.parentNode; 627 628 if (!parent || !target.offsetParent) { 629 // note: in 3.3.0 we switched target.offsetParent to _doc.body.contains(target) to avoid [sometimes unnecessary] MutationObserver calls but that wasn't adequate because there are edge cases where nested position: fixed elements need to get reparented to accurately sense transforms. See https://github.com/greensock/GSAP/issues/388 and https://github.com/greensock/GSAP/issues/375 630 addedToDOM = 1; //flag 631 632 nextSibling = target.nextSibling; 633 634 _docElement.appendChild(target); //we must add it to the DOM in order to get values properly 635 636 } 637 638 matrix = _getComputedTransformMatrixAsArray(target); 639 temp ? style.display = temp : _removeProperty(target, "display"); 640 641 if (addedToDOM) { 642 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 643 } 644 } 645 646 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 647}, 648 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 649 var cache = target._gsap, 650 matrix = matrixArray || _getMatrix(target, true), 651 xOriginOld = cache.xOrigin || 0, 652 yOriginOld = cache.yOrigin || 0, 653 xOffsetOld = cache.xOffset || 0, 654 yOffsetOld = cache.yOffset || 0, 655 a = matrix[0], 656 b = matrix[1], 657 c = matrix[2], 658 d = matrix[3], 659 tx = matrix[4], 660 ty = matrix[5], 661 originSplit = origin.split(" "), 662 xOrigin = parseFloat(originSplit[0]) || 0, 663 yOrigin = parseFloat(originSplit[1]) || 0, 664 bounds, 665 determinant, 666 x, 667 y; 668 669 if (!originIsAbsolute) { 670 bounds = _getBBox(target); 671 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin); 672 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); 673 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 674 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero. 675 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 676 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 677 xOrigin = x; 678 yOrigin = y; 679 } 680 681 if (smooth || smooth !== false && cache.smooth) { 682 tx = xOrigin - xOriginOld; 683 ty = yOrigin - yOriginOld; 684 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 685 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 686 } else { 687 cache.xOffset = cache.yOffset = 0; 688 } 689 690 cache.xOrigin = xOrigin; 691 cache.yOrigin = yOrigin; 692 cache.smooth = !!smooth; 693 cache.origin = origin; 694 cache.originIsAbsolute = !!originIsAbsolute; 695 target.style[_transformOriginProp] = "0px 0px"; //otherwise, if someone sets an origin via CSS, it will likely interfere with the SVG transform attribute ones (because remember, we're baking the origin into the matrix() value). 696 697 if (pluginToAddPropTweensTo) { 698 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 699 700 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 701 702 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 703 704 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 705 } 706 707 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 708}, 709 _parseTransform = function _parseTransform(target, uncache) { 710 var cache = target._gsap || new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["GSCache"](target); 711 712 if ("x" in cache && !uncache && !cache.uncache) { 713 return cache; 714 } 715 716 var style = target.style, 717 invertedScaleX = cache.scaleX < 0, 718 px = "px", 719 deg = "deg", 720 origin = _getComputedProperty(target, _transformOriginProp) || "0", 721 x, 722 y, 723 z, 724 scaleX, 725 scaleY, 726 rotation, 727 rotationX, 728 rotationY, 729 skewX, 730 skewY, 731 perspective, 732 xOrigin, 733 yOrigin, 734 matrix, 735 angle, 736 cos, 737 sin, 738 a, 739 b, 740 c, 741 d, 742 a12, 743 a22, 744 t1, 745 t2, 746 t3, 747 a13, 748 a23, 749 a33, 750 a42, 751 a43, 752 a32; 753 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 754 scaleX = scaleY = 1; 755 cache.svg = !!(target.getCTM && _isSVG(target)); 756 matrix = _getMatrix(target, cache.svg); 757 758 if (cache.svg) { 759 t1 = !cache.uncache && target.getAttribute("data-svg-origin"); 760 761 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 762 } 763 764 xOrigin = cache.xOrigin || 0; 765 yOrigin = cache.yOrigin || 0; 766 767 if (matrix !== _identity2DMatrix) { 768 a = matrix[0]; //a11 769 770 b = matrix[1]; //a21 771 772 c = matrix[2]; //a31 773 774 d = matrix[3]; //a41 775 776 x = a12 = matrix[4]; 777 y = a22 = matrix[5]; //2D matrix 778 779 if (matrix.length === 6) { 780 scaleX = Math.sqrt(a * a + b * b); 781 scaleY = Math.sqrt(d * d + c * c); 782 rotation = a || b ? _atan2(b, a) * _RAD2DEG : 0; //note: if scaleX is 0, we cannot accurately measure rotation. Same for skewX with a scaleY of 0. Therefore, we default to the previously recorded value (or zero if that doesn't exist). 783 784 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 785 skewX && (scaleY *= Math.cos(skewX * _DEG2RAD)); 786 787 if (cache.svg) { 788 x -= xOrigin - (xOrigin * a + yOrigin * c); 789 y -= yOrigin - (xOrigin * b + yOrigin * d); 790 } //3D matrix 791 792 } else { 793 a32 = matrix[6]; 794 a42 = matrix[7]; 795 a13 = matrix[8]; 796 a23 = matrix[9]; 797 a33 = matrix[10]; 798 a43 = matrix[11]; 799 x = matrix[12]; 800 y = matrix[13]; 801 z = matrix[14]; 802 angle = _atan2(a32, a33); 803 rotationX = angle * _RAD2DEG; //rotationX 804 805 if (angle) { 806 cos = Math.cos(-angle); 807 sin = Math.sin(-angle); 808 t1 = a12 * cos + a13 * sin; 809 t2 = a22 * cos + a23 * sin; 810 t3 = a32 * cos + a33 * sin; 811 a13 = a12 * -sin + a13 * cos; 812 a23 = a22 * -sin + a23 * cos; 813 a33 = a32 * -sin + a33 * cos; 814 a43 = a42 * -sin + a43 * cos; 815 a12 = t1; 816 a22 = t2; 817 a32 = t3; 818 } //rotationY 819 820 821 angle = _atan2(-c, a33); 822 rotationY = angle * _RAD2DEG; 823 824 if (angle) { 825 cos = Math.cos(-angle); 826 sin = Math.sin(-angle); 827 t1 = a * cos - a13 * sin; 828 t2 = b * cos - a23 * sin; 829 t3 = c * cos - a33 * sin; 830 a43 = d * sin + a43 * cos; 831 a = t1; 832 b = t2; 833 c = t3; 834 } //rotationZ 835 836 837 angle = _atan2(b, a); 838 rotation = angle * _RAD2DEG; 839 840 if (angle) { 841 cos = Math.cos(angle); 842 sin = Math.sin(angle); 843 t1 = a * cos + b * sin; 844 t2 = a12 * cos + a22 * sin; 845 b = b * cos - a * sin; 846 a22 = a22 * cos - a12 * sin; 847 a = t1; 848 a12 = t2; 849 } 850 851 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 852 //when rotationY is set, it will often be parsed as 180 degrees different than it should be, and rotationX and rotation both being 180 (it looks the same), so we adjust for that here. 853 rotationX = rotation = 0; 854 rotationY = 180 - rotationY; 855 } 856 857 scaleX = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(Math.sqrt(a * a + b * b + c * c)); 858 scaleY = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(Math.sqrt(a22 * a22 + a32 * a32)); 859 angle = _atan2(a12, a22); 860 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 861 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 862 } 863 864 if (cache.svg) { 865 //sense if there are CSS transforms applied on an SVG element in which case we must overwrite them when rendering. The transform attribute is more reliable cross-browser, but we can't just remove the CSS ones because they may be applied in a CSS rule somewhere (not just inline). 866 t1 = target.getAttribute("transform"); 867 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 868 t1 && target.setAttribute("transform", t1); 869 } 870 } 871 872 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 873 if (invertedScaleX) { 874 scaleX *= -1; 875 skewX += rotation <= 0 ? 180 : -180; 876 rotation += rotation <= 0 ? 180 : -180; 877 } else { 878 scaleY *= -1; 879 skewX += skewX <= 0 ? 180 : -180; 880 } 881 } 882 883 cache.x = x - ((cache.xPercent = x && (cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px; 884 cache.y = y - ((cache.yPercent = y && (cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px; 885 cache.z = z + px; 886 cache.scaleX = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(scaleX); 887 cache.scaleY = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(scaleY); 888 cache.rotation = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(rotation) + deg; 889 cache.rotationX = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(rotationX) + deg; 890 cache.rotationY = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(rotationY) + deg; 891 cache.skewX = skewX + deg; 892 cache.skewY = skewY + deg; 893 cache.transformPerspective = perspective + px; 894 895 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || 0) { 896 style[_transformOriginProp] = _firstTwoOnly(origin); 897 } 898 899 cache.xOffset = cache.yOffset = 0; 900 cache.force3D = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].force3D; 901 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 902 cache.uncache = 0; 903 return cache; 904}, 905 _firstTwoOnly = function _firstTwoOnly(value) { 906 return (value = value.split(" "))[0] + " " + value[1]; 907}, 908 //for handling transformOrigin values, stripping out the 3rd dimension 909_addPxTranslate = function _addPxTranslate(target, start, value) { 910 var unit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(start); 911 return Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 912}, 913 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 914 cache.z = "0px"; 915 cache.rotationY = cache.rotationX = "0deg"; 916 cache.force3D = 0; 917 918 _renderCSSTransforms(ratio, cache); 919}, 920 _zeroDeg = "0deg", 921 _zeroPx = "0px", 922 _endParenthesis = ") ", 923 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 924 var _ref = cache || this, 925 xPercent = _ref.xPercent, 926 yPercent = _ref.yPercent, 927 x = _ref.x, 928 y = _ref.y, 929 z = _ref.z, 930 rotation = _ref.rotation, 931 rotationY = _ref.rotationY, 932 rotationX = _ref.rotationX, 933 skewX = _ref.skewX, 934 skewY = _ref.skewY, 935 scaleX = _ref.scaleX, 936 scaleY = _ref.scaleY, 937 transformPerspective = _ref.transformPerspective, 938 force3D = _ref.force3D, 939 target = _ref.target, 940 zOrigin = _ref.zOrigin, 941 transforms = "", 942 use3D = force3D === "auto" && ratio && ratio !== 1 || force3D === true; // Safari has a bug that causes it not to render 3D transform-origin values properly, so we force the z origin to 0, record it in the cache, and then do the math here to offset the translate values accordingly (basically do the 3D transform-origin part manually) 943 944 945 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 946 var angle = parseFloat(rotationY) * _DEG2RAD, 947 a13 = Math.sin(angle), 948 a33 = Math.cos(angle), 949 cos; 950 951 angle = parseFloat(rotationX) * _DEG2RAD; 952 cos = Math.cos(angle); 953 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 954 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 955 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 956 } 957 958 if (transformPerspective !== _zeroPx) { 959 transforms += "perspective(" + transformPerspective + _endParenthesis; 960 } 961 962 if (xPercent || yPercent) { 963 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 964 } 965 966 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 967 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 968 } 969 970 if (rotation !== _zeroDeg) { 971 transforms += "rotate(" + rotation + _endParenthesis; 972 } 973 974 if (rotationY !== _zeroDeg) { 975 transforms += "rotateY(" + rotationY + _endParenthesis; 976 } 977 978 if (rotationX !== _zeroDeg) { 979 transforms += "rotateX(" + rotationX + _endParenthesis; 980 } 981 982 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 983 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 984 } 985 986 if (scaleX !== 1 || scaleY !== 1) { 987 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 988 } 989 990 target.style[_transformProp] = transforms || "translate(0, 0)"; 991}, 992 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 993 var _ref2 = cache || this, 994 xPercent = _ref2.xPercent, 995 yPercent = _ref2.yPercent, 996 x = _ref2.x, 997 y = _ref2.y, 998 rotation = _ref2.rotation, 999 skewX = _ref2.skewX, 1000 skewY = _ref2.skewY, 1001 scaleX = _ref2.scaleX, 1002 scaleY = _ref2.scaleY, 1003 target = _ref2.target, 1004 xOrigin = _ref2.xOrigin, 1005 yOrigin = _ref2.yOrigin, 1006 xOffset = _ref2.xOffset, 1007 yOffset = _ref2.yOffset, 1008 forceCSS = _ref2.forceCSS, 1009 tx = parseFloat(x), 1010 ty = parseFloat(y), 1011 a11, 1012 a21, 1013 a12, 1014 a22, 1015 temp; 1016 1017 rotation = parseFloat(rotation); 1018 skewX = parseFloat(skewX); 1019 skewY = parseFloat(skewY); 1020 1021 if (skewY) { 1022 //for performance reasons, we combine all skewing into the skewX and rotation values. Remember, a skewY of 10 degrees looks the same as a rotation of 10 degrees plus a skewX of 10 degrees. 1023 skewY = parseFloat(skewY); 1024 skewX += skewY; 1025 rotation += skewY; 1026 } 1027 1028 if (rotation || skewX) { 1029 rotation *= _DEG2RAD; 1030 skewX *= _DEG2RAD; 1031 a11 = Math.cos(rotation) * scaleX; 1032 a21 = Math.sin(rotation) * scaleX; 1033 a12 = Math.sin(rotation - skewX) * -scaleY; 1034 a22 = Math.cos(rotation - skewX) * scaleY; 1035 1036 if (skewX) { 1037 skewY *= _DEG2RAD; 1038 temp = Math.tan(skewX - skewY); 1039 temp = Math.sqrt(1 + temp * temp); 1040 a12 *= temp; 1041 a22 *= temp; 1042 1043 if (skewY) { 1044 temp = Math.tan(skewY); 1045 temp = Math.sqrt(1 + temp * temp); 1046 a11 *= temp; 1047 a21 *= temp; 1048 } 1049 } 1050 1051 a11 = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(a11); 1052 a21 = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(a21); 1053 a12 = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(a12); 1054 a22 = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(a22); 1055 } else { 1056 a11 = scaleX; 1057 a22 = scaleY; 1058 a21 = a12 = 0; 1059 } 1060 1061 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 1062 tx = _convertToUnit(target, "x", x, "px"); 1063 ty = _convertToUnit(target, "y", y, "px"); 1064 } 1065 1066 if (xOrigin || yOrigin || xOffset || yOffset) { 1067 tx = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 1068 ty = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 1069 } 1070 1071 if (xPercent || yPercent) { 1072 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it. 1073 temp = target.getBBox(); 1074 tx = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(tx + xPercent / 100 * temp.width); 1075 ty = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_round"])(ty + yPercent / 100 * temp.height); 1076 } 1077 1078 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 1079 target.setAttribute("transform", temp); 1080 forceCSS && (target.style[_transformProp] = temp); //some browsers prioritize CSS transforms over the transform attribute. When we sense that the user has CSS transforms applied, we must overwrite them this way (otherwise some browser simply won't render the transform attribute changes!) 1081}, 1082 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue, relative) { 1083 var cap = 360, 1084 isString = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_isString"])(endValue), 1085 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 1086 change = relative ? endNum * relative : endNum - startNum, 1087 finalValue = startNum + change + "deg", 1088 direction, 1089 pt; 1090 1091 if (isString) { 1092 direction = endValue.split("_")[1]; 1093 1094 if (direction === "short") { 1095 change %= cap; 1096 1097 if (change !== change % (cap / 2)) { 1098 change += change < 0 ? cap : -cap; 1099 } 1100 } 1101 1102 if (direction === "cw" && change < 0) { 1103 change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap; 1104 } else if (direction === "ccw" && change > 0) { 1105 change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap; 1106 } 1107 } 1108 1109 plugin._pt = pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](plugin._pt, target, property, startNum, change, _renderPropWithEnd); 1110 pt.e = finalValue; 1111 pt.u = "deg"; 1112 1113 plugin._props.push(property); 1114 1115 return pt; 1116}, 1117 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 1118 //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)" 1119 var style = _tempDivStyler.style, 1120 startCache = target._gsap, 1121 exclude = "perspective,force3D,transformOrigin,svgOrigin", 1122 endCache, 1123 p, 1124 startValue, 1125 endValue, 1126 startNum, 1127 endNum, 1128 startUnit, 1129 endUnit; 1130 style.cssText = getComputedStyle(target).cssText + ";position:absolute;display:block;"; //%-based translations will fail unless we set the width/height to match the original target (and padding/borders can affect it) 1131 1132 style[_transformProp] = transforms; 1133 1134 _doc.body.appendChild(_tempDivStyler); 1135 1136 endCache = _parseTransform(_tempDivStyler, 1); 1137 1138 for (p in _transformProps) { 1139 startValue = startCache[p]; 1140 endValue = endCache[p]; 1141 1142 if (startValue !== endValue && exclude.indexOf(p) < 0) { 1143 //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case. 1144 startUnit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(startValue); 1145 endUnit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(endValue); 1146 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 1147 endNum = parseFloat(endValue); 1148 plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](plugin._pt, startCache, p, startNum, endNum - startNum, _renderCSSProp); 1149 plugin._pt.u = endUnit || 0; 1150 1151 plugin._props.push(p); 1152 } 1153 } 1154 1155 _doc.body.removeChild(_tempDivStyler); 1156}; // handle splitting apart padding, margin, borderWidth, and borderRadius into their 4 components. Firefox, for example, won't report borderRadius correctly - it will only do borderTopLeftRadius and the other corners. We also want to handle paddingTop, marginLeft, borderRightWidth, etc. 1157 1158 1159Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_forEachName"])("padding,margin,Width,Radius", function (name, index) { 1160 var t = "Top", 1161 r = "Right", 1162 b = "Bottom", 1163 l = "Left", 1164 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 1165 return index < 2 ? name + side : "border" + side + name; 1166 }); 1167 1168 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 1169 var a, vars; 1170 1171 if (arguments.length < 4) { 1172 // getter, passed target, property, and unit (from _get()) 1173 a = props.map(function (prop) { 1174 return _get(plugin, prop, property); 1175 }); 1176 vars = a.join(" "); 1177 return vars.split(a[0]).length === 5 ? a[0] : vars; 1178 } 1179 1180 a = (endValue + "").split(" "); 1181 vars = {}; 1182 props.forEach(function (prop, i) { 1183 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 1184 }); 1185 plugin.init(target, vars, tween); 1186 }; 1187}); 1188 1189var CSSPlugin = { 1190 name: "css", 1191 register: _initCore, 1192 targetTest: function targetTest(target) { 1193 return target.style && target.nodeType; 1194 }, 1195 init: function init(target, vars, tween, index, targets) { 1196 var props = this._props, 1197 style = target.style, 1198 startAt = tween.vars.startAt, 1199 startValue, 1200 endValue, 1201 endNum, 1202 startNum, 1203 type, 1204 specialProp, 1205 p, 1206 startUnit, 1207 endUnit, 1208 relative, 1209 isTransformRelated, 1210 transformPropTween, 1211 cache, 1212 smooth, 1213 hasPriority; 1214 _pluginInitted || _initCore(); 1215 1216 for (p in vars) { 1217 if (p === "autoRound") { 1218 continue; 1219 } 1220 1221 endValue = vars[p]; 1222 1223 if (_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_plugins"][p] && Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_checkPlugin"])(p, vars, tween, index, target, targets)) { 1224 // plugins 1225 continue; 1226 } 1227 1228 type = typeof endValue; 1229 specialProp = _specialProps[p]; 1230 1231 if (type === "function") { 1232 endValue = endValue.call(tween, index, target, targets); 1233 type = typeof endValue; 1234 } 1235 1236 if (type === "string" && ~endValue.indexOf("random(")) { 1237 endValue = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_replaceRandom"])(endValue); 1238 } 1239 1240 if (specialProp) { 1241 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 1242 } else if (p.substr(0, 2) === "--") { 1243 //CSS variable 1244 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 1245 endValue += ""; 1246 startUnit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(startValue); 1247 endUnit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(endValue); 1248 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 1249 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 1250 } else if (type !== "undefined") { 1251 if (startAt && p in startAt) { 1252 // in case someone hard-codes a complex value as the start, like top: "calc(2vh / 2)". Without this, it'd use the computed value (always in px) 1253 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 1254 p in _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units && !Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(startValue) && (startValue += _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units[p]); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work. 1255 1256 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); // can't work with relative values 1257 } else { 1258 startValue = _get(target, p); 1259 } 1260 1261 startNum = parseFloat(startValue); 1262 relative = type === "string" && endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0; 1263 relative && (endValue = endValue.substr(2)); 1264 endNum = parseFloat(endValue); 1265 1266 if (p in _propertyAliases) { 1267 if (p === "autoAlpha") { 1268 //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened. 1269 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 1270 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) 1271 startNum = 0; 1272 } 1273 1274 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 1275 } 1276 1277 if (p !== "scale" && p !== "transform") { 1278 p = _propertyAliases[p]; 1279 ~p.indexOf(",") && (p = p.split(",")[0]); 1280 } 1281 } 1282 1283 isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED --- 1284 1285 if (isTransformRelated) { 1286 if (!transformPropTween) { 1287 cache = target._gsap; 1288 cache.renderTransform && !vars.parseTransform || _parseTransform(target, vars.parseTransform); // if, for example, gsap.set(... {transform:"translateX(50vw)"}), the _get() call doesn't parse the transform, thus cache.renderTransform won't be set yet so force the parsing of the transform here. 1289 1290 smooth = vars.smoothOrigin !== false && cache.smooth; 1291 transformPropTween = this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](this._pt, style, _transformProp, 0, 1, cache.renderTransform, cache, 0, -1); //the first time through, create the rendering PropTween so that it runs LAST (in the linked list, we keep adding to the beginning) 1292 1293 transformPropTween.dep = 1; //flag it as dependent so that if things get killed/overwritten and this is the only PropTween left, we can safely kill the whole tween. 1294 } 1295 1296 if (p === "scale") { 1297 this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](this._pt, cache, "scaleY", cache.scaleY, relative ? relative * endNum : endNum - cache.scaleY); 1298 props.push("scaleY", p); 1299 p += "X"; 1300 } else if (p === "transformOrigin") { 1301 endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages. 1302 1303 if (cache.svg) { 1304 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 1305 } else { 1306 endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately! 1307 1308 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 1309 1310 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 1311 } 1312 1313 continue; 1314 } else if (p === "svgOrigin") { 1315 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 1316 1317 continue; 1318 } else if (p in _rotationalProperties) { 1319 _addRotationalPropTween(this, cache, p, startNum, endValue, relative); 1320 1321 continue; 1322 } else if (p === "smoothOrigin") { 1323 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 1324 1325 continue; 1326 } else if (p === "force3D") { 1327 cache[p] = endValue; 1328 continue; 1329 } else if (p === "transform") { 1330 _addRawTransformPTs(this, endValue, target); 1331 1332 continue; 1333 } 1334 } else if (!(p in style)) { 1335 p = _checkPropPrefix(p) || p; 1336 } 1337 1338 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 1339 startUnit = (startValue + "").substr((startNum + "").length); 1340 endNum || (endNum = 0); // protect against NaN 1341 1342 endUnit = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"])(endValue) || (p in _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units ? _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units[p] : startUnit); 1343 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 1344 this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["PropTween"](this._pt, isTransformRelated ? cache : style, p, startNum, relative ? relative * endNum : endNum - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp); 1345 this._pt.u = endUnit || 0; 1346 1347 if (startUnit !== endUnit) { 1348 //when the tween goes all the way back to the beginning, we need to revert it to the OLD/ORIGINAL value (with those units). We record that as a "b" (beginning) property and point to a render method that handles that. (performance optimization) 1349 this._pt.b = startValue; 1350 this._pt.r = _renderCSSPropWithBeginning; 1351 } 1352 } else if (!(p in style)) { 1353 if (p in target) { 1354 //maybe it's not a style - it could be a property added directly to an element in which case we'll try to animate that. 1355 this.add(target, p, target[p], endValue, index, targets); 1356 } else { 1357 Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_missingPlugin"])(p, endValue); 1358 1359 continue; 1360 } 1361 } else { 1362 _tweenComplexCSSString.call(this, target, p, startValue, endValue); 1363 } 1364 1365 props.push(p); 1366 } 1367 } 1368 1369 hasPriority && Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_sortPropTweensByPriority"])(this); 1370 }, 1371 get: _get, 1372 aliases: _propertyAliases, 1373 getSetter: function getSetter(target, property, plugin) { 1374 //returns a setter function that accepts target, property, value and applies it accordingly. Remember, properties like "x" aren't as simple as target.style.property = value because they've got to be applied to a proxy object and then merged into a transform string in a renderer. 1375 var p = _propertyAliases[property]; 1376 p && p.indexOf(",") < 0 && (property = p); 1377 return property in _transformProps && property !== _transformOriginProp && (target._gsap.x || _get(target, "x")) ? plugin && _recentSetterPlugin === plugin ? property === "scale" ? _setterScale : _setterTransform : (_recentSetterPlugin = plugin || {}) && (property === "scale" ? _setterScaleWithRender : _setterTransformWithRender) : target.style && !Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_isUndefined"])(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_getSetter"])(target, property); 1378 }, 1379 core: { 1380 _removeProperty: _removeProperty, 1381 _getMatrix: _getMatrix 1382 } 1383}; 1384_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["gsap"].utils.checkPrefix = _checkPropPrefix; 1385 1386(function (positionAndScale, rotation, others, aliases) { 1387 var all = Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_forEachName"])(positionAndScale + "," + rotation + "," + others, function (name) { 1388 _transformProps[name] = 1; 1389 }); 1390 1391 Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_forEachName"])(rotation, function (name) { 1392 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units[name] = "deg"; 1393 _rotationalProperties[name] = 1; 1394 }); 1395 1396 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 1397 1398 Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_forEachName"])(aliases, function (name) { 1399 var split = name.split(":"); 1400 _propertyAliases[split[1]] = all[split[0]]; 1401 }); 1402})("x,y,z,scale,scaleX,scaleY,xPercent,yPercent", "rotation,rotationX,rotationY,skewX,skewY", "transform,transformOrigin,svgOrigin,force3D,smoothOrigin,transformPerspective", "0:translateX,1:translateY,2:translateZ,8:rotate,8:rotationZ,8:rotateZ,9:rotateX,10:rotateY"); 1403 1404Object(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_forEachName"])("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 1405 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["_config"].units[name] = "px"; 1406}); 1407 1408_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["gsap"].registerPlugin(CSSPlugin); 1409 1410 1411/***/ }), 1412
vendor: 4,148 bytes, lines 1413-1560
1413/***/ "./node_modules/gsap/CSSRulePlugin.js": 1414/*!********************************************!*\ 1415 !*** ./node_modules/gsap/CSSRulePlugin.js ***! 1416 \********************************************/ 1417/*! exports provided: CSSRulePlugin, default */ 1418/***/ (function(module, __webpack_exports__, __webpack_require__) { 1419 1420"use strict"; 1421__webpack_require__.r(__webpack_exports__); 1422/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CSSRulePlugin", function() { return CSSRulePlugin; }); 1423/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CSSRulePlugin; }); 1424/*! 1425 * CSSRulePlugin 3.6.0 1426 * https://greensock.com 1427 * 1428 * @license Copyright 2008-2021, GreenSock. All rights reserved. 1429 * Subject to the terms at https://greensock.com/standard-license or for 1430 * Club GreenSock members, the agreement issued with that membership. 1431 * @author: Jack Doyle, [email protected] 1432*/ 1433 1434/* eslint-disable */ 1435var gsap, 1436 _coreInitted, 1437 _win, 1438 _doc, 1439 CSSPlugin, 1440 _windowExists = function _windowExists() { 1441 return typeof window !== "undefined"; 1442}, 1443 _getGSAP = function _getGSAP() { 1444 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 1445}, 1446 _checkRegister = function _checkRegister() { 1447 if (!_coreInitted) { 1448 _initCore(); 1449 1450 if (!CSSPlugin) { 1451 console.warn("Please gsap.registerPlugin(CSSPlugin, CSSRulePlugin)"); 1452 } 1453 } 1454 1455 return _coreInitted; 1456}, 1457 _initCore = function _initCore(core) { 1458 gsap = core || _getGSAP(); 1459 1460 if (_windowExists()) { 1461 _win = window; 1462 _doc = document; 1463 } 1464 1465 if (gsap) { 1466 CSSPlugin = gsap.plugins.css; 1467 1468 if (CSSPlugin) { 1469 _coreInitted = 1; 1470 } 1471 } 1472}; 1473 1474var CSSRulePlugin = { 1475 version: "3.6.0", 1476 name: "cssRule", 1477 init: function init(target, value, tween, index, targets) { 1478 if (!_checkRegister() || typeof target.cssText === "undefined") { 1479 return false; 1480 } 1481 1482 var div = target._gsProxy = target._gsProxy || _doc.createElement("div"); 1483 1484 this.ss = target; 1485 this.style = div.style; 1486 div.style.cssText = target.cssText; 1487 CSSPlugin.prototype.init.call(this, div, value, tween, index, targets); //we just offload all the work to the regular CSSPlugin and then copy the cssText back over to the rule in the render() method. This allows us to have all of the updates to CSSPlugin automatically flow through to CSSRulePlugin instead of having to maintain both 1488 }, 1489 render: function render(ratio, data) { 1490 var pt = data._pt, 1491 style = data.style, 1492 ss = data.ss, 1493 i; 1494 1495 while (pt) { 1496 pt.r(ratio, pt.d); 1497 pt = pt._next; 1498 } 1499 1500 i = style.length; 1501 1502 while (--i > -1) { 1503 ss[style[i]] = style[style[i]]; 1504 } 1505 }, 1506 getRule: function getRule(selector) { 1507 _checkRegister(); 1508 1509 var ruleProp = _doc.all ? "rules" : "cssRules", 1510 styleSheets = _doc.styleSheets, 1511 i = styleSheets.length, 1512 pseudo = selector.charAt(0) === ":", 1513 j, 1514 curSS, 1515 cs, 1516 a; 1517 selector = (pseudo ? "" : ",") + selector.split("::").join(":").toLowerCase() + ","; //note: old versions of IE report tag name selectors as upper case, so we just change everything to lowercase. 1518 1519 if (pseudo) { 1520 a = []; 1521 } 1522 1523 while (i--) { 1524 //Firefox may throw insecure operation errors when css is loaded from other domains, so try/catch. 1525 try { 1526 curSS = styleSheets[i][ruleProp]; 1527 1528 if (!curSS) { 1529 continue; 1530 } 1531 1532 j = curSS.length; 1533 } catch (e) { 1534 console.warn(e); 1535 continue; 1536 } 1537 1538 while (--j > -1) { 1539 cs = curSS[j]; 1540 1541 if (cs.selectorText && ("," + cs.selectorText.split("::").join(":").toLowerCase() + ",").indexOf(selector) !== -1) { 1542 //note: IE adds an extra ":" to pseudo selectors, so .myClass:after becomes .myClass::after, so we need to strip the extra one out. 1543 if (pseudo) { 1544 a.push(cs.style); 1545 } else { 1546 return cs.style; 1547 } 1548 } 1549 } 1550 } 1551 1552 return a; 1553 }, 1554 register: _initCore 1555}; 1556_getGSAP() && gsap.registerPlugin(CSSRulePlugin); 1557 1558 1559/***/ }), 1560
vendor: 5,044 bytes, lines 1561-1740
1561/***/ "./node_modules/gsap/CustomBounce.js": 1562/*!*******************************************!*\ 1563 !*** ./node_modules/gsap/CustomBounce.js ***! 1564 \*******************************************/ 1565/*! exports provided: CustomBounce, default */ 1566/***/ (function(module, __webpack_exports__, __webpack_require__) { 1567 1568"use strict"; 1569__webpack_require__.r(__webpack_exports__); 1570/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomBounce", function() { return CustomBounce; }); 1571/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomBounce; }); 1572/*! 1573 * CustomBounce 3.6.0 1574 * https://greensock.com 1575 * 1576 * @license Copyright 2008-2021, GreenSock. All rights reserved. 1577 * Subject to the terms at https://greensock.com/standard-license or for 1578 * Club GreenSock members, the agreement issued with that membership. 1579 * @author: Jack Doyle, [email protected] 1580*/ 1581 1582/* eslint-disable */ 1583var gsap, 1584 _coreInitted, 1585 createCustomEase, 1586 _getGSAP = function _getGSAP() { 1587 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 1588}, 1589 _initCore = function _initCore(required) { 1590 gsap = _getGSAP(); 1591 createCustomEase = gsap && gsap.parseEase("_CE"); 1592 1593 if (createCustomEase) { 1594 _coreInitted = 1; 1595 1596 gsap.parseEase("bounce").config = function (vars) { 1597 return typeof vars === "object" ? _create("", vars) : _create("bounce(" + vars + ")", { 1598 strength: +vars 1599 }); 1600 }; 1601 } else { 1602 required && console.warn("Please gsap.registerPlugin(CustomEase, CustomBounce)"); 1603 } 1604}, 1605 _normalizeX = function _normalizeX(a) { 1606 //scales all the x values in an array [x, y, x, y...] AND rounds them to the closest hundredth (decimal) 1607 var l = a.length, 1608 s = 1 / a[l - 2], 1609 rnd = 1000, 1610 i; 1611 1612 for (i = 2; i < l; i += 2) { 1613 a[i] = ~~(a[i] * s * rnd) / rnd; 1614 } 1615 1616 a[l - 2] = 1; //in case there are any rounding errors. x should always end at 1. 1617}, 1618 _bonusValidated = 1, 1619 //<name>CustomBounce</name> 1620_create = function _create(id, vars) { 1621 if (!_coreInitted) { 1622 _initCore(1); 1623 } 1624 1625 vars = vars || {}; 1626 1627 if (_bonusValidated) { 1628 var max = 0.999, 1629 decay = Math.min(max, vars.strength || 0.7), 1630 // Math.min(0.999, 1 - 0.3 / (vars.strength || 1)), 1631 decayX = decay, 1632 gap = (vars.squash || 0) / 100, 1633 originalGap = gap, 1634 slope = 1 / 0.03, 1635 w = 0.2, 1636 h = 1, 1637 prevX = 0.1, 1638 path = [0, 0, 0.07, 0, 0.1, 1, 0.1, 1], 1639 squashPath = [0, 0, 0, 0, 0.1, 0, 0.1, 0], 1640 cp1, 1641 cp2, 1642 x, 1643 y, 1644 i, 1645 nextX, 1646 squishMagnitude; 1647 1648 for (i = 0; i < 200; i++) { 1649 w *= decayX * ((decayX + 1) / 2); 1650 h *= decay * decay; 1651 nextX = prevX + w; 1652 x = prevX + w * 0.49; 1653 y = 1 - h; 1654 cp1 = prevX + h / slope; 1655 cp2 = x + (x - cp1) * 0.8; 1656 1657 if (gap) { 1658 prevX += gap; 1659 cp1 += gap; 1660 x += gap; 1661 cp2 += gap; 1662 nextX += gap; 1663 squishMagnitude = gap / originalGap; 1664 squashPath.push(prevX - gap, 0, prevX - gap, squishMagnitude, prevX - gap / 2, squishMagnitude, //center peak anchor 1665 prevX, squishMagnitude, prevX, 0, prevX, 0, //base anchor 1666 prevX, squishMagnitude * -0.6, prevX + (nextX - prevX) / 6, 0, nextX, 0); 1667 path.push(prevX - gap, 1, prevX, 1, prevX, 1); 1668 gap *= decay * decay; 1669 } 1670 1671 path.push(prevX, 1, cp1, y, x, y, cp2, y, nextX, 1, nextX, 1); 1672 decay *= 0.95; 1673 slope = h / (nextX - cp2); 1674 prevX = nextX; 1675 1676 if (y > max) { 1677 break; 1678 } 1679 } 1680 1681 if (vars.endAtStart && vars.endAtStart !== "false") { 1682 x = -0.1; 1683 path.unshift(x, 1, x, 1, -0.07, 0); 1684 1685 if (originalGap) { 1686 gap = originalGap * 2.5; //make the initial anticipation squash longer (more realistic) 1687 1688 x -= gap; 1689 path.unshift(x, 1, x, 1, x, 1); 1690 squashPath.splice(0, 6); 1691 squashPath.unshift(x, 0, x, 0, x, 1, x + gap / 2, 1, x + gap, 1, x + gap, 0, x + gap, 0, x + gap, -0.6, x + gap + 0.033, 0); 1692 1693 for (i = 0; i < squashPath.length; i += 2) { 1694 squashPath[i] -= x; 1695 } 1696 } 1697 1698 for (i = 0; i < path.length; i += 2) { 1699 path[i] -= x; 1700 path[i + 1] = 1 - path[i + 1]; 1701 } 1702 } 1703 1704 if (gap) { 1705 _normalizeX(squashPath); 1706 1707 squashPath[2] = "C" + squashPath[2]; 1708 createCustomEase(vars.squashID || id + "-squash", "M" + squashPath.join(",")); 1709 } 1710 1711 _normalizeX(path); 1712 1713 path[2] = "C" + path[2]; 1714 return createCustomEase(id, "M" + path.join(",")); 1715 } 1716}; 1717 1718var CustomBounce = /*#__PURE__*/function () { 1719 function CustomBounce(id, vars) { 1720 this.ease = _create(id, vars); 1721 } 1722 1723 CustomBounce.create = function create(id, vars) { 1724 return _create(id, vars); 1725 }; 1726 1727 CustomBounce.register = function register(core) { 1728 gsap = core; 1729 1730 _initCore(); 1731 }; 1732 1733 return CustomBounce; 1734}(); 1735_getGSAP() && gsap.registerPlugin(CustomBounce); 1736CustomBounce.version = "3.6.0"; 1737 1738 1739/***/ }), 1740
vendor: 12,037 bytes, lines 1741-2126
1741/***/ "./node_modules/gsap/CustomEase.js": 1742/*!*****************************************!*\ 1743 !*** ./node_modules/gsap/CustomEase.js ***! 1744 \*****************************************/ 1745/*! exports provided: CustomEase, default */ 1746/***/ (function(module, __webpack_exports__, __webpack_require__) { 1747 1748"use strict"; 1749__webpack_require__.r(__webpack_exports__); 1750/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomEase", function() { return CustomEase; }); 1751/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomEase; }); 1752/* harmony import */ var _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/paths.js */ "./node_modules/gsap/utils/paths.js"); 1753/*! 1754 * CustomEase 3.6.0 1755 * https://greensock.com 1756 * 1757 * @license Copyright 2008-2021, GreenSock. All rights reserved. 1758 * Subject to the terms at https://greensock.com/standard-license or for 1759 * Club GreenSock members, the agreement issued with that membership. 1760 * @author: Jack Doyle, [email protected] 1761*/ 1762 1763/* eslint-disable */ 1764 1765 1766var gsap, 1767 _coreInitted, 1768 _getGSAP = function _getGSAP() { 1769 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 1770}, 1771 _initCore = function _initCore() { 1772 gsap = _getGSAP(); 1773 1774 if (gsap) { 1775 gsap.registerEase("_CE", CustomEase.create); 1776 _coreInitted = 1; 1777 } else { 1778 console.warn("Please gsap.registerPlugin(CustomEase)"); 1779 } 1780}, 1781 _bigNum = 1e20, 1782 _round = function _round(value) { 1783 return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000; 1784}, 1785 _bonusValidated = 1, 1786 //<name>CustomEase</name> 1787_numExp = /[-+=\.]*\d+[\.e\-\+]*\d*[e\-\+]*\d*/gi, 1788 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 1789_needsParsingExp = /[cLlsSaAhHvVtTqQ]/g, 1790 _findMinimum = function _findMinimum(values) { 1791 var l = values.length, 1792 min = _bigNum, 1793 i; 1794 1795 for (i = 1; i < l; i += 6) { 1796 +values[i] < min && (min = +values[i]); 1797 } 1798 1799 return min; 1800}, 1801 //takes all the points and translates/scales them so that the x starts at 0 and ends at 1. 1802_normalize = function _normalize(values, height, originY) { 1803 if (!originY && originY !== 0) { 1804 originY = Math.max(+values[values.length - 1], +values[1]); 1805 } 1806 1807 var tx = +values[0] * -1, 1808 ty = -originY, 1809 l = values.length, 1810 sx = 1 / (+values[l - 2] + tx), 1811 sy = -height || (Math.abs(+values[l - 1] - +values[1]) < 0.01 * (+values[l - 2] - +values[0]) ? _findMinimum(values) + ty : +values[l - 1] + ty), 1812 i; 1813 1814 if (sy) { 1815 //typically y ends at 1 (so that the end values are reached) 1816 sy = 1 / sy; 1817 } else { 1818 //in case the ease returns to its beginning value, scale everything proportionally 1819 sy = -sx; 1820 } 1821 1822 for (i = 0; i < l; i += 2) { 1823 values[i] = (+values[i] + tx) * sx; 1824 values[i + 1] = (+values[i + 1] + ty) * sy; 1825 } 1826}, 1827 //note that this function returns point objects like {x, y} rather than working with segments which are arrays with alternating x, y values as in the similar function in paths.js 1828_bezierToPoints = function _bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) { 1829 var x12 = (x1 + x2) / 2, 1830 y12 = (y1 + y2) / 2, 1831 x23 = (x2 + x3) / 2, 1832 y23 = (y2 + y3) / 2, 1833 x34 = (x3 + x4) / 2, 1834 y34 = (y3 + y4) / 2, 1835 x123 = (x12 + x23) / 2, 1836 y123 = (y12 + y23) / 2, 1837 x234 = (x23 + x34) / 2, 1838 y234 = (y23 + y34) / 2, 1839 x1234 = (x123 + x234) / 2, 1840 y1234 = (y123 + y234) / 2, 1841 dx = x4 - x1, 1842 dy = y4 - y1, 1843 d2 = Math.abs((x2 - x4) * dy - (y2 - y4) * dx), 1844 d3 = Math.abs((x3 - x4) * dy - (y3 - y4) * dx), 1845 length; 1846 1847 if (!points) { 1848 points = [{ 1849 x: x1, 1850 y: y1 1851 }, { 1852 x: x4, 1853 y: y4 1854 }]; 1855 index = 1; 1856 } 1857 1858 points.splice(index || points.length - 1, 0, { 1859 x: x1234, 1860 y: y1234 1861 }); 1862 1863 if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) { 1864 length = points.length; 1865 1866 _bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index); 1867 1868 _bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 1 + (points.length - length)); 1869 } 1870 1871 return points; 1872}; 1873 1874var CustomEase = /*#__PURE__*/function () { 1875 function CustomEase(id, data, config) { 1876 _coreInitted || _initCore(); 1877 this.id = id; 1878 _bonusValidated && this.setData(data, config); 1879 } 1880 1881 var _proto = CustomEase.prototype; 1882 1883 _proto.setData = function setData(data, config) { 1884 config = config || {}; 1885 data = data || "0,0,1,1"; 1886 var values = data.match(_numExp), 1887 closest = 1, 1888 points = [], 1889 lookup = [], 1890 precision = config.precision || 1, 1891 fast = precision <= 1, 1892 l, 1893 a1, 1894 a2, 1895 i, 1896 inc, 1897 j, 1898 point, 1899 prevPoint, 1900 p; 1901 this.data = data; 1902 1903 if (_needsParsingExp.test(data) || ~data.indexOf("M") && data.indexOf("C") < 0) { 1904 values = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(data)[0]; 1905 } 1906 1907 l = values.length; 1908 1909 if (l === 4) { 1910 values.unshift(0, 0); 1911 values.push(1, 1); 1912 l = 8; 1913 } else if ((l - 2) % 6) { 1914 throw "Invalid CustomEase"; 1915 } 1916 1917 if (+values[0] !== 0 || +values[l - 2] !== 1) { 1918 _normalize(values, config.height, config.originY); 1919 } 1920 1921 this.segment = values; 1922 1923 for (i = 2; i < l; i += 6) { 1924 a1 = { 1925 x: +values[i - 2], 1926 y: +values[i - 1] 1927 }; 1928 a2 = { 1929 x: +values[i + 4], 1930 y: +values[i + 5] 1931 }; 1932 points.push(a1, a2); 1933 1934 _bezierToPoints(a1.x, a1.y, +values[i], +values[i + 1], +values[i + 2], +values[i + 3], a2.x, a2.y, 1 / (precision * 200000), points, points.length - 1); 1935 } 1936 1937 l = points.length; 1938 1939 for (i = 0; i < l; i++) { 1940 point = points[i]; 1941 prevPoint = points[i - 1] || point; 1942 1943 if ((point.x > prevPoint.x || prevPoint.y !== point.y && prevPoint.x === point.x || point === prevPoint) && point.x <= 1) { 1944 //if a point goes BACKWARD in time or is a duplicate, just drop it. Also it shouldn't go past 1 on the x axis, as could happen in a string like "M0,0 C0,0 0.12,0.68 0.18,0.788 0.195,0.845 0.308,1 0.32,1 0.403,1.005 0.398,1 0.5,1 0.602,1 0.816,1.005 0.9,1 0.91,1 0.948,0.69 0.962,0.615 1.003,0.376 1,0 1,0". 1945 prevPoint.cx = point.x - prevPoint.x; //change in x between this point and the next point (performance optimization) 1946 1947 prevPoint.cy = point.y - prevPoint.y; 1948 prevPoint.n = point; 1949 prevPoint.nx = point.x; //next point's x value (performance optimization, making lookups faster in getRatio()). Remember, the lookup will always land on a spot where it's either this point or the very next one (never beyond that) 1950 1951 if (fast && i > 1 && Math.abs(prevPoint.cy / prevPoint.cx - points[i - 2].cy / points[i - 2].cx) > 2) { 1952 //if there's a sudden change in direction, prioritize accuracy over speed. Like a bounce ease - you don't want to risk the sampling chunks landing on each side of the bounce anchor and having it clipped off. 1953 fast = 0; 1954 } 1955 1956 if (prevPoint.cx < closest) { 1957 if (!prevPoint.cx) { 1958 prevPoint.cx = 0.001; //avoids math problems in getRatio() (dividing by zero) 1959 1960 if (i === l - 1) { 1961 //in case the final segment goes vertical RIGHT at the end, make sure we end at the end. 1962 prevPoint.x -= 0.001; 1963 closest = Math.min(closest, 0.001); 1964 fast = 0; 1965 } 1966 } else { 1967 closest = prevPoint.cx; 1968 } 1969 } 1970 } else { 1971 points.splice(i--, 1); 1972 l--; 1973 } 1974 } 1975 1976 l = 1 / closest + 1 | 0; 1977 inc = 1 / l; 1978 j = 0; 1979 point = points[0]; 1980 1981 if (fast) { 1982 for (i = 0; i < l; i++) { 1983 //for fastest lookups, we just sample along the path at equal x (time) distance. Uses more memory and is slightly less accurate for anchors that don't land on the sampling points, but for the vast majority of eases it's excellent (and fast). 1984 p = i * inc; 1985 1986 if (point.nx < p) { 1987 point = points[++j]; 1988 } 1989 1990 a1 = point.y + (p - point.x) / point.cx * point.cy; 1991 lookup[i] = { 1992 x: p, 1993 cx: inc, 1994 y: a1, 1995 cy: 0, 1996 nx: 9 1997 }; 1998 1999 if (i) { 2000 lookup[i - 1].cy = a1 - lookup[i - 1].y; 2001 } 2002 } 2003 2004 lookup[l - 1].cy = points[points.length - 1].y - a1; 2005 } else { 2006 //this option is more accurate, ensuring that EVERY anchor is hit perfectly. Clipping across a bounce, for example, would never happen. 2007 for (i = 0; i < l; i++) { 2008 //build a lookup table based on the smallest distance so that we can instantly find the appropriate point (well, it'll either be that point or the very next one). We'll look up based on the linear progress. So it's it's 0.5 and the lookup table has 100 elements, it'd be like lookup[Math.floor(0.5 * 100)] 2009 if (point.nx < i * inc) { 2010 point = points[++j]; 2011 } 2012 2013 lookup[i] = point; 2014 } 2015 2016 if (j < points.length - 1) { 2017 lookup[i - 1] = points[points.length - 2]; 2018 } 2019 } //this._calcEnd = (points[points.length-1].y !== 1 || points[0].y !== 0); //ensures that we don't run into floating point errors. As long as we're starting at 0 and ending at 1, tell GSAP to skip the final calculation and use 0/1 as the factor. 2020 2021 2022 this.ease = function (p) { 2023 var point = lookup[p * l | 0] || lookup[l - 1]; 2024 2025 if (point.nx < p) { 2026 point = point.n; 2027 } 2028 2029 return point.y + (p - point.x) / point.cx * point.cy; 2030 }; 2031 2032 this.ease.custom = this; 2033 this.id && gsap.registerEase(this.id, this.ease); 2034 return this; 2035 }; 2036 2037 _proto.getSVGData = function getSVGData(config) { 2038 return CustomEase.getSVGData(this, config); 2039 }; 2040 2041 CustomEase.create = function create(id, data, config) { 2042 return new CustomEase(id, data, config).ease; 2043 }; 2044 2045 CustomEase.register = function register(core) { 2046 gsap = core; 2047 2048 _initCore(); 2049 }; 2050 2051 CustomEase.get = function get(id) { 2052 return gsap.parseEase(id); 2053 }; 2054 2055 CustomEase.getSVGData = function getSVGData(ease, config) { 2056 config = config || {}; 2057 var width = config.width || 100, 2058 height = config.height || 100, 2059 x = config.x || 0, 2060 y = (config.y || 0) + height, 2061 e = gsap.utils.toArray(config.path)[0], 2062 a, 2063 slope, 2064 i, 2065 inc, 2066 tx, 2067 ty, 2068 precision, 2069 threshold, 2070 prevX, 2071 prevY; 2072 2073 if (config.invert) { 2074 height = -height; 2075 y = 0; 2076 } 2077 2078 if (typeof ease === "string") { 2079 ease = gsap.parseEase(ease); 2080 } 2081 2082 if (ease.custom) { 2083 ease = ease.custom; 2084 } 2085 2086 if (ease instanceof CustomEase) { 2087 a = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])([ease.segment], width, 0, 0, -height, x, y)); 2088 } else { 2089 a = [x, y]; 2090 precision = Math.max(5, (config.precision || 1) * 200); 2091 inc = 1 / precision; 2092 precision += 2; 2093 threshold = 5 / precision; 2094 prevX = _round(x + inc * width); 2095 prevY = _round(y + ease(inc) * -height); 2096 slope = (prevY - y) / (prevX - x); 2097 2098 for (i = 2; i < precision; i++) { 2099 tx = _round(x + i * inc * width); 2100 ty = _round(y + ease(i * inc) * -height); 2101 2102 if (Math.abs((ty - prevY) / (tx - prevX) - slope) > threshold || i === precision - 1) { 2103 //only add points when the slope changes beyond the threshold 2104 a.push(prevX, prevY); 2105 slope = (ty - prevY) / (tx - prevX); 2106 } 2107 2108 prevX = tx; 2109 prevY = ty; 2110 } 2111 2112 a = "M" + a.join(","); 2113 } 2114 2115 e && e.setAttribute("d", a); 2116 return a; 2117 }; 2118 2119 return CustomEase; 2120}(); 2121_getGSAP() && gsap.registerPlugin(CustomEase); 2122CustomEase.version = "3.6.0"; 2123 2124 2125/***/ }), 2126
vendor: 5,239 bytes, lines 2127-2302
2127/***/ "./node_modules/gsap/CustomWiggle.js": 2128/*!*******************************************!*\ 2129 !*** ./node_modules/gsap/CustomWiggle.js ***! 2130 \*******************************************/ 2131/*! exports provided: CustomWiggle, default */ 2132/***/ (function(module, __webpack_exports__, __webpack_require__) { 2133 2134"use strict"; 2135__webpack_require__.r(__webpack_exports__); 2136/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CustomWiggle", function() { return CustomWiggle; }); 2137/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return CustomWiggle; }); 2138/*! 2139 * CustomWiggle 3.6.0 2140 * https://greensock.com 2141 * 2142 * @license Copyright 2008-2021, GreenSock. All rights reserved. 2143 * Subject to the terms at https://greensock.com/standard-license or for 2144 * Club GreenSock members, the agreement issued with that membership. 2145 * @author: Jack Doyle, [email protected] 2146*/ 2147 2148/* eslint-disable */ 2149var gsap, 2150 _coreInitted, 2151 createCustomEase, 2152 _getGSAP = function _getGSAP() { 2153 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 2154}, 2155 _eases = { 2156 easeOut: "M0,1,C0.7,1,0.6,0,1,0", 2157 easeInOut: "M0,0,C0.1,0,0.24,1,0.444,1,0.644,1,0.6,0,1,0", 2158 anticipate: "M0,0,C0,0.222,0.024,0.386,0,0.4,0.18,0.455,0.65,0.646,0.7,0.67,0.9,0.76,1,0.846,1,1", 2159 uniform: "M0,0,C0,0.95,0,1,0,1,0,1,1,1,1,1,1,1,1,0,1,0" 2160}, 2161 _linearEase = function _linearEase(p) { 2162 return p; 2163}, 2164 _initCore = function _initCore(required) { 2165 if (!_coreInitted) { 2166 gsap = _getGSAP(); 2167 createCustomEase = gsap && gsap.parseEase("_CE"); 2168 2169 if (createCustomEase) { 2170 for (var p in _eases) { 2171 _eases[p] = createCustomEase("", _eases[p]); 2172 } 2173 2174 _coreInitted = 1; 2175 2176 _create("wiggle").config = function (vars) { 2177 return typeof vars === "object" ? _create("", vars) : _create("wiggle(" + vars + ")", { 2178 wiggles: +vars 2179 }); 2180 }; 2181 } else { 2182 required && console.warn("Please gsap.registerPlugin(CustomEase, CustomWiggle)"); 2183 } 2184 } 2185}, 2186 _parseEase = function _parseEase(ease, invertNonCustomEases) { 2187 if (typeof ease !== "function") { 2188 ease = gsap.parseEase(ease) || createCustomEase("", ease); 2189 } 2190 2191 return ease.custom || !invertNonCustomEases ? ease : function (p) { 2192 return 1 - ease(p); 2193 }; 2194}, 2195 _bonusValidated = 1, 2196 //<name>CustomWiggle</name> 2197_create = function _create(id, vars) { 2198 if (!_coreInitted) { 2199 _initCore(1); 2200 } 2201 2202 vars = vars || {}; 2203 var wiggles = (vars.wiggles || 10) | 0, 2204 inc = 1 / wiggles, 2205 x = inc / 2, 2206 anticipate = vars.type === "anticipate", 2207 yEase = _eases[vars.type] || _eases.easeOut, 2208 xEase = _linearEase, 2209 rnd = 1000, 2210 nextX, 2211 nextY, 2212 angle, 2213 handleX, 2214 handleY, 2215 easedX, 2216 y, 2217 path, 2218 i; 2219 2220 if (_bonusValidated) { 2221 if (anticipate) { 2222 //the anticipate ease is actually applied on the x-axis (timing) and uses easeOut for amplitude. 2223 xEase = yEase; 2224 yEase = _eases.easeOut; 2225 } 2226 2227 if (vars.timingEase) { 2228 xEase = _parseEase(vars.timingEase); 2229 } 2230 2231 if (vars.amplitudeEase) { 2232 yEase = _parseEase(vars.amplitudeEase, true); 2233 } 2234 2235 easedX = xEase(x); 2236 y = anticipate ? -yEase(x) : yEase(x); 2237 path = [0, 0, easedX / 4, 0, easedX / 2, y, easedX, y]; 2238 2239 if (vars.type === "random") { 2240 //if we just select random values on the y-axis and plug them into the "normal" algorithm, since the control points are always straight horizontal, it creates a bit of a slowdown at each anchor which just didn't seem as desirable, so we switched to an algorithm that bends the control points to be more in line with their context. 2241 path.length = 4; 2242 nextX = xEase(inc); 2243 nextY = Math.random() * 2 - 1; 2244 2245 for (i = 2; i < wiggles; i++) { 2246 x = nextX; 2247 y = nextY; 2248 nextX = xEase(inc * i); 2249 nextY = Math.random() * 2 - 1; 2250 angle = Math.atan2(nextY - path[path.length - 3], nextX - path[path.length - 4]); 2251 handleX = Math.cos(angle) * inc; 2252 handleY = Math.sin(angle) * inc; 2253 path.push(x - handleX, y - handleY, x, y, x + handleX, y + handleY); 2254 } 2255 2256 path.push(nextX, 0, 1, 0); 2257 } else { 2258 for (i = 1; i < wiggles; i++) { 2259 path.push(xEase(x + inc / 2), y); 2260 x += inc; 2261 y = (y > 0 ? -1 : 1) * yEase(i * inc); 2262 easedX = xEase(x); 2263 path.push(xEase(x - inc / 2), y, easedX, y); 2264 } 2265 2266 path.push(xEase(x + inc / 4), y, xEase(x + inc / 4), 0, 1, 0); 2267 } 2268 2269 i = path.length; 2270 2271 while (--i > -1) { 2272 path[i] = ~~(path[i] * rnd) / rnd; //round values to avoid odd strings for super tiny values 2273 } 2274 2275 path[2] = "C" + path[2]; 2276 return createCustomEase(id, "M" + path.join(",")); 2277 } 2278}; 2279 2280var CustomWiggle = /*#__PURE__*/function () { 2281 function CustomWiggle(id, vars) { 2282 this.ease = _create(id, vars); 2283 } 2284 2285 CustomWiggle.create = function create(id, vars) { 2286 return _create(id, vars); 2287 }; 2288 2289 CustomWiggle.register = function register(core) { 2290 gsap = core; 2291 2292 _initCore(); 2293 }; 2294 2295 return CustomWiggle; 2296}(); 2297_getGSAP() && gsap.registerPlugin(CustomWiggle); 2298CustomWiggle.version = "3.6.0"; 2299 2300 2301/***/ }), 2302
vendor: 99,626 bytes, lines 2303-4972
2303/***/ "./node_modules/gsap/Draggable.js": 2304/*!****************************************!*\ 2305 !*** ./node_modules/gsap/Draggable.js ***! 2306 \****************************************/ 2307/*! exports provided: Draggable, default */ 2308/***/ (function(module, __webpack_exports__, __webpack_require__) { 2309 2310"use strict"; 2311__webpack_require__.r(__webpack_exports__); 2312/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Draggable", function() { return Draggable; }); 2313/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Draggable; }); 2314/* harmony import */ var _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/matrix.js */ "./node_modules/gsap/utils/matrix.js"); 2315function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 2316 2317function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } 2318 2319/*! 2320 * Draggable 3.6.0 2321 * https://greensock.com 2322 * 2323 * @license Copyright 2008-2021, GreenSock. All rights reserved. 2324 * Subject to the terms at https://greensock.com/standard-license or for 2325 * Club GreenSock members, the agreement issued with that membership. 2326 * @author: Jack Doyle, [email protected] 2327 */ 2328 2329/* eslint-disable */ 2330 2331 2332var gsap, 2333 _win, 2334 _doc, 2335 _docElement, 2336 _body, 2337 _tempDiv, 2338 _placeholderDiv, 2339 _coreInitted, 2340 _checkPrefix, 2341 _toArray, 2342 _supportsPassive, 2343 _isTouchDevice, 2344 _touchEventLookup, 2345 _dragCount, 2346 _isMultiTouching, 2347 _isAndroid, 2348 InertiaPlugin, 2349 _defaultCursor, 2350 _supportsPointer, 2351 _windowExists = function _windowExists() { 2352 return typeof window !== "undefined"; 2353}, 2354 _getGSAP = function _getGSAP() { 2355 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 2356}, 2357 _isFunction = function _isFunction(value) { 2358 return typeof value === "function"; 2359}, 2360 _isObject = function _isObject(value) { 2361 return typeof value === "object"; 2362}, 2363 _isUndefined = function _isUndefined(value) { 2364 return typeof value === "undefined"; 2365}, 2366 _emptyFunc = function _emptyFunc() { 2367 return false; 2368}, 2369 _transformProp = "transform", 2370 _transformOriginProp = "transformOrigin", 2371 _round = function _round(value) { 2372 return Math.round(value * 10000) / 10000; 2373}, 2374 _isArray = Array.isArray, 2375 _createElement = function _createElement(type, ns) { 2376 var e = _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making "style" inaccessible. 2377 2378 return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). 2379}, 2380 _RAD2DEG = 180 / Math.PI, 2381 _bigNum = 1e20, 2382 _identityMatrix = new _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["Matrix2D"](), 2383 _getTime = Date.now || function () { 2384 return new Date().getTime(); 2385}, 2386 _renderQueue = [], 2387 _lookup = {}, 2388 //when a Draggable is created, the target gets a unique _gsDragID property that allows gets associated with the Draggable instance for quick lookups in Draggable.get(). This avoids circular references that could cause gc problems. 2389_lookupCount = 0, 2390 _clickableTagExp = /^(?:a|input|textarea|button|select)$/i, 2391 _lastDragTime = 0, 2392 _temp1 = {}, 2393 // a simple object we reuse and populate (usually x/y properties) to conserve memory and improve performance. 2394_windowProxy = {}, 2395 //memory/performance optimization - we reuse this object during autoScroll to store window-related bounds/offsets. 2396_copy = function _copy(obj, factor) { 2397 var copy = {}, 2398 p; 2399 2400 for (p in obj) { 2401 copy[p] = factor ? obj[p] * factor : obj[p]; 2402 } 2403 2404 return copy; 2405}, 2406 _extend = function _extend(obj, defaults) { 2407 for (var p in defaults) { 2408 if (!(p in obj)) { 2409 obj[p] = defaults[p]; 2410 } 2411 } 2412 2413 return obj; 2414}, 2415 _setTouchActionForAllDescendants = function _setTouchActionForAllDescendants(elements, value) { 2416 var i = elements.length, 2417 children; 2418 2419 while (i--) { 2420 value ? elements[i].style.touchAction = value : elements[i].style.removeProperty("touch-action"); 2421 children = elements[i].children; 2422 children && children.length && _setTouchActionForAllDescendants(children, value); 2423 } 2424}, 2425 _renderQueueTick = function _renderQueueTick() { 2426 return _renderQueue.forEach(function (func) { 2427 return func(); 2428 }); 2429}, 2430 _addToRenderQueue = function _addToRenderQueue(func) { 2431 _renderQueue.push(func); 2432 2433 if (_renderQueue.length === 1) { 2434 gsap.ticker.add(_renderQueueTick); 2435 } 2436}, 2437 _renderQueueTimeout = function _renderQueueTimeout() { 2438 return !_renderQueue.length && gsap.ticker.remove(_renderQueueTick); 2439}, 2440 _removeFromRenderQueue = function _removeFromRenderQueue(func) { 2441 var i = _renderQueue.length; 2442 2443 while (i--) { 2444 if (_renderQueue[i] === func) { 2445 _renderQueue.splice(i, 1); 2446 } 2447 } 2448 2449 gsap.to(_renderQueueTimeout, { 2450 overwrite: true, 2451 delay: 15, 2452 duration: 0, 2453 onComplete: _renderQueueTimeout, 2454 data: "_draggable" 2455 }); //remove the "tick" listener only after the render queue is empty for 15 seconds (to improve performance). Adding/removing it constantly for every click/touch wouldn't deliver optimal speed, and we also don't want the ticker to keep calling the render method when things are idle for long periods of time (we want to improve battery life on mobile devices). 2456}, 2457 _setDefaults = function _setDefaults(obj, defaults) { 2458 for (var p in defaults) { 2459 if (!(p in obj)) { 2460 obj[p] = defaults[p]; 2461 } 2462 } 2463 2464 return obj; 2465}, 2466 _addListener = function _addListener(element, type, func, capture) { 2467 if (element.addEventListener) { 2468 var touchType = _touchEventLookup[type]; 2469 capture = capture || (_supportsPassive ? { 2470 passive: false 2471 } : null); 2472 element.addEventListener(touchType || type, func, capture); 2473 touchType && type !== touchType && element.addEventListener(type, func, capture); //some browsers actually support both, so must we. But pointer events cover all. 2474 } 2475}, 2476 _removeListener = function _removeListener(element, type, func) { 2477 if (element.removeEventListener) { 2478 var touchType = _touchEventLookup[type]; 2479 element.removeEventListener(touchType || type, func); 2480 touchType && type !== touchType && element.removeEventListener(type, func); 2481 } 2482}, 2483 _preventDefault = function _preventDefault(event) { 2484 event.preventDefault && event.preventDefault(); 2485 event.preventManipulation && event.preventManipulation(); //for some Microsoft browsers 2486}, 2487 _hasTouchID = function _hasTouchID(list, ID) { 2488 var i = list.length; 2489 2490 while (i--) { 2491 if (list[i].identifier === ID) { 2492 return true; 2493 } 2494 } 2495}, 2496 _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(event) { 2497 _isMultiTouching = event.touches && _dragCount < event.touches.length; 2498 2499 _removeListener(event.target, "touchend", _onMultiTouchDocumentEnd); 2500}, 2501 _onMultiTouchDocument = function _onMultiTouchDocument(event) { 2502 _isMultiTouching = event.touches && _dragCount < event.touches.length; 2503 2504 _addListener(event.target, "touchend", _onMultiTouchDocumentEnd); 2505}, 2506 _getDocScrollTop = function _getDocScrollTop(doc) { 2507 return _win.pageYOffset || doc.scrollTop || doc.documentElement.scrollTop || doc.body.scrollTop || 0; 2508}, 2509 _getDocScrollLeft = function _getDocScrollLeft(doc) { 2510 return _win.pageXOffset || doc.scrollLeft || doc.documentElement.scrollLeft || doc.body.scrollLeft || 0; 2511}, 2512 _addScrollListener = function _addScrollListener(e, callback) { 2513 _addListener(e, "scroll", callback); 2514 2515 if (!_isRoot(e.parentNode)) { 2516 _addScrollListener(e.parentNode, callback); 2517 } 2518}, 2519 _removeScrollListener = function _removeScrollListener(e, callback) { 2520 _removeListener(e, "scroll", callback); 2521 2522 if (!_isRoot(e.parentNode)) { 2523 _removeScrollListener(e.parentNode, callback); 2524 } 2525}, 2526 _isRoot = function _isRoot(e) { 2527 return !!(!e || e === _docElement || e.nodeType === 9 || e === _doc.body || e === _win || !e.nodeType || !e.parentNode); 2528}, 2529 _getMaxScroll = function _getMaxScroll(element, axis) { 2530 var dim = axis === "x" ? "Width" : "Height", 2531 scroll = "scroll" + dim, 2532 client = "client" + dim; 2533 return Math.max(0, _isRoot(element) ? Math.max(_docElement[scroll], _body[scroll]) - (_win["inner" + dim] || _docElement[client] || _body[client]) : element[scroll] - element[client]); 2534}, 2535 _recordMaxScrolls = function _recordMaxScrolls(e, skipCurrent) { 2536 //records _gsMaxScrollX and _gsMaxScrollY properties for the element and all ancestors up the chain so that we can cap it, otherwise dragging beyond the edges with autoScroll on can endlessly scroll. 2537 var x = _getMaxScroll(e, "x"), 2538 y = _getMaxScroll(e, "y"); 2539 2540 if (_isRoot(e)) { 2541 e = _windowProxy; 2542 } else { 2543 _recordMaxScrolls(e.parentNode, skipCurrent); 2544 } 2545 2546 e._gsMaxScrollX = x; 2547 e._gsMaxScrollY = y; 2548 2549 if (!skipCurrent) { 2550 e._gsScrollX = e.scrollLeft || 0; 2551 e._gsScrollY = e.scrollTop || 0; 2552 } 2553}, 2554 _setStyle = function _setStyle(element, property, value) { 2555 var style = element.style; 2556 2557 if (!style) { 2558 return; 2559 } 2560 2561 if (_isUndefined(style[property])) { 2562 property = _checkPrefix(property, element) || property; 2563 } 2564 2565 if (value == null) { 2566 style.removeProperty && style.removeProperty(property.replace(/([A-Z])/g, "-$1").toLowerCase()); 2567 } else { 2568 style[property] = value; 2569 } 2570}, 2571 _getComputedStyle = function _getComputedStyle(element) { 2572 return _win.getComputedStyle(element instanceof Element ? element : element.host || (element.parentNode || {}).host || element); 2573}, 2574 //the "host" stuff helps to accommodate ShadowDom objects. 2575_tempRect = {}, 2576 //reuse to reduce garbage collection tasks 2577_parseRect = function _parseRect(e) { 2578 //accepts a DOM element, a mouse event, or a rectangle object and returns the corresponding rectangle with left, right, width, height, top, and bottom properties 2579 if (e === _win) { 2580 _tempRect.left = _tempRect.top = 0; 2581 _tempRect.width = _tempRect.right = _docElement.clientWidth || e.innerWidth || _body.clientWidth || 0; 2582 _tempRect.height = _tempRect.bottom = (e.innerHeight || 0) - 20 < _docElement.clientHeight ? _docElement.clientHeight : e.innerHeight || _body.clientHeight || 0; 2583 return _tempRect; 2584 } 2585 2586 var doc = e.ownerDocument || _doc, 2587 r = !_isUndefined(e.pageX) ? { 2588 left: e.pageX - _getDocScrollLeft(doc), 2589 top: e.pageY - _getDocScrollTop(doc), 2590 right: e.pageX - _getDocScrollLeft(doc) + 1, 2591 bottom: e.pageY - _getDocScrollTop(doc) + 1 2592 } : !e.nodeType && !_isUndefined(e.left) && !_isUndefined(e.top) ? e : _toArray(e)[0].getBoundingClientRect(); 2593 2594 if (_isUndefined(r.right) && !_isUndefined(r.width)) { 2595 r.right = r.left + r.width; 2596 r.bottom = r.top + r.height; 2597 } else if (_isUndefined(r.width)) { 2598 //some browsers don't include width and height properties. We can't just set them directly on r because some browsers throw errors, so create a new generic object. 2599 r = { 2600 width: r.right - r.left, 2601 height: r.bottom - r.top, 2602 right: r.right, 2603 left: r.left, 2604 bottom: r.bottom, 2605 top: r.top 2606 }; 2607 } 2608 2609 return r; 2610}, 2611 _dispatchEvent = function _dispatchEvent(target, type, callbackName) { 2612 var vars = target.vars, 2613 callback = vars[callbackName], 2614 listeners = target._listeners[type], 2615 result; 2616 2617 if (_isFunction(callback)) { 2618 result = callback.apply(vars.callbackScope || target, vars[callbackName + "Params"] || [target.pointerEvent]); 2619 } 2620 2621 if (listeners && target.dispatchEvent(type) === false) { 2622 result = false; 2623 } 2624 2625 return result; 2626}, 2627 _getBounds = function _getBounds(target, context) { 2628 //accepts any of the following: a DOM element, jQuery object, selector text, or an object defining bounds as {top, left, width, height} or {minX, maxX, minY, maxY}. Returns an object with left, top, width, and height properties. 2629 var e = _toArray(target)[0], 2630 top, 2631 left, 2632 offset; 2633 2634 if (!e.nodeType && e !== _win) { 2635 if (!_isUndefined(target.left)) { 2636 offset = { 2637 x: 0, 2638 y: 0 2639 }; //_getOffsetTransformOrigin(context); //the bounds should be relative to the origin 2640 2641 return { 2642 left: target.left - offset.x, 2643 top: target.top - offset.y, 2644 width: target.width, 2645 height: target.height 2646 }; 2647 } 2648 2649 left = target.min || target.minX || target.minRotation || 0; 2650 top = target.min || target.minY || 0; 2651 return { 2652 left: left, 2653 top: top, 2654 width: (target.max || target.maxX || target.maxRotation || 0) - left, 2655 height: (target.max || target.maxY || 0) - top 2656 }; 2657 } 2658 2659 return _getElementBounds(e, context); 2660}, 2661 _point1 = {}, 2662 //we reuse to minimize garbage collection tasks. 2663_getElementBounds = function _getElementBounds(element, context) { 2664 context = _toArray(context)[0]; 2665 var isSVG = element.getBBox && element.ownerSVGElement, 2666 doc = element.ownerDocument || _doc, 2667 left, 2668 right, 2669 top, 2670 bottom, 2671 matrix, 2672 p1, 2673 p2, 2674 p3, 2675 p4, 2676 bbox, 2677 width, 2678 height, 2679 cs, 2680 contextParent; 2681 2682 if (element === _win) { 2683 top = _getDocScrollTop(doc); 2684 left = _getDocScrollLeft(doc); 2685 right = left + (doc.documentElement.clientWidth || element.innerWidth || doc.body.clientWidth || 0); 2686 bottom = top + ((element.innerHeight || 0) - 20 < doc.documentElement.clientHeight ? doc.documentElement.clientHeight : element.innerHeight || doc.body.clientHeight || 0); //some browsers (like Firefox) ignore absolutely positioned elements, and collapse the height of the documentElement, so it could be 8px, for example, if you have just an absolutely positioned div. In that case, we use the innerHeight to resolve this. 2687 } else if (context === _win || _isUndefined(context)) { 2688 return element.getBoundingClientRect(); 2689 } else { 2690 left = top = 0; 2691 2692 if (isSVG) { 2693 bbox = element.getBBox(); 2694 width = bbox.width; 2695 height = bbox.height; 2696 } else { 2697 if (element.viewBox && (bbox = element.viewBox.baseVal)) { 2698 left = bbox.x || 0; 2699 top = bbox.y || 0; 2700 width = bbox.width; 2701 height = bbox.height; 2702 } 2703 2704 if (!width) { 2705 cs = _getComputedStyle(element); 2706 bbox = cs.boxSizing === "border-box"; 2707 width = (parseFloat(cs.width) || element.clientWidth || 0) + (bbox ? 0 : parseFloat(cs.borderLeftWidth) + parseFloat(cs.borderRightWidth)); 2708 height = (parseFloat(cs.height) || element.clientHeight || 0) + (bbox ? 0 : parseFloat(cs.borderTopWidth) + parseFloat(cs.borderBottomWidth)); 2709 } 2710 } 2711 2712 right = width; 2713 bottom = height; 2714 } 2715 2716 if (element === context) { 2717 return { 2718 left: left, 2719 top: top, 2720 width: right - left, 2721 height: bottom - top 2722 }; 2723 } 2724 2725 matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(context, true).multiply(Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(element)); 2726 p1 = matrix.apply({ 2727 x: left, 2728 y: top 2729 }); 2730 p2 = matrix.apply({ 2731 x: right, 2732 y: top 2733 }); 2734 p3 = matrix.apply({ 2735 x: right, 2736 y: bottom 2737 }); 2738 p4 = matrix.apply({ 2739 x: left, 2740 y: bottom 2741 }); 2742 left = Math.min(p1.x, p2.x, p3.x, p4.x); 2743 top = Math.min(p1.y, p2.y, p3.y, p4.y); 2744 contextParent = context.parentNode || {}; 2745 return { 2746 left: left + (contextParent.scrollLeft || 0), 2747 top: top + (contextParent.scrollTop || 0), 2748 width: Math.max(p1.x, p2.x, p3.x, p4.x) - left, 2749 height: Math.max(p1.y, p2.y, p3.y, p4.y) - top 2750 }; 2751}, 2752 _parseInertia = function _parseInertia(draggable, snap, max, min, factor, forceZeroVelocity) { 2753 var vars = {}, 2754 a, 2755 i, 2756 l; 2757 2758 if (snap) { 2759 if (factor !== 1 && snap instanceof Array) { 2760 //some data must be altered to make sense, like if the user passes in an array of rotational values in degrees, we must convert it to radians. Or for scrollLeft and scrollTop, we invert the values. 2761 vars.end = a = []; 2762 l = snap.length; 2763 2764 if (_isObject(snap[0])) { 2765 //if the array is populated with objects, like points ({x:100, y:200}), make copies before multiplying by the factor, otherwise we'll mess up the originals and the user may reuse it elsewhere. 2766 for (i = 0; i < l; i++) { 2767 a[i] = _copy(snap[i], factor); 2768 } 2769 } else { 2770 for (i = 0; i < l; i++) { 2771 a[i] = snap[i] * factor; 2772 } 2773 } 2774 2775 max += 1.1; //allow 1.1 pixels of wiggle room when snapping in order to work around some browser inconsistencies in the way bounds are reported which can make them roughly a pixel off. For example, if "snap:[-$('#menu').width(), 0]" was defined and #menu had a wrapper that was used as the bounds, some browsers would be one pixel off, making the minimum -752 for example when snap was [-753,0], thus instead of snapping to -753, it would snap to 0 since -753 was below the minimum. 2776 2777 min -= 1.1; 2778 } else if (_isFunction(snap)) { 2779 vars.end = function (value) { 2780 var result = snap.call(draggable, value), 2781 copy, 2782 p; 2783 2784 if (factor !== 1) { 2785 if (_isObject(result)) { 2786 copy = {}; 2787 2788 for (p in result) { 2789 copy[p] = result[p] * factor; 2790 } 2791 2792 result = copy; 2793 } else { 2794 result *= factor; 2795 } 2796 } 2797 2798 return result; //we need to ensure that we can scope the function call to the Draggable instance itself so that users can access important values like maxX, minX, maxY, minY, x, and y from within that function. 2799 }; 2800 } else { 2801 vars.end = snap; 2802 } 2803 } 2804 2805 if (max || max === 0) { 2806 vars.max = max; 2807 } 2808 2809 if (min || min === 0) { 2810 vars.min = min; 2811 } 2812 2813 if (forceZeroVelocity) { 2814 vars.velocity = 0; 2815 } 2816 2817 return vars; 2818}, 2819 _isClickable = function _isClickable(element) { 2820 //sometimes it's convenient to mark an element as clickable by adding a data-clickable="true" attribute (in which case we won't preventDefault() the mouse/touch event). This method checks if the element is an <a>, <input>, or <button> or has an onclick or has the data-clickable or contentEditable attribute set to true (or any of its parent elements). 2821 var data; 2822 return !element || !element.getAttribute || element === _body ? false : (data = element.getAttribute("data-clickable")) === "true" || data !== "false" && (element.onclick || _clickableTagExp.test(element.nodeName + "") || element.getAttribute("contentEditable") === "true") ? true : _isClickable(element.parentNode); 2823}, 2824 _setSelectable = function _setSelectable(elements, selectable) { 2825 var i = elements.length, 2826 e; 2827 2828 while (i--) { 2829 e = elements[i]; 2830 e.ondragstart = e.onselectstart = selectable ? null : _emptyFunc; 2831 gsap.set(e, { 2832 lazy: true, 2833 userSelect: selectable ? "text" : "none" 2834 }); 2835 } 2836}, 2837 _isFixed = function _isFixed(element) { 2838 if (_getComputedStyle(element).position === "fixed") { 2839 return true; 2840 } 2841 2842 element = element.parentNode; 2843 2844 if (element && element.nodeType === 1) { 2845 // avoid document fragments which will throw an error. 2846 return _isFixed(element); 2847 } 2848}, 2849 _supports3D, 2850 _addPaddingBR, 2851 //The ScrollProxy class wraps an element's contents into another div (we call it "content") that we either add padding when necessary or apply a translate3d() transform in order to overscroll (scroll past the boundaries). This allows us to simply set the scrollTop/scrollLeft (or top/left for easier reverse-axis orientation, which is what we do in Draggable) and it'll do all the work for us. For example, if we tried setting scrollTop to -100 on a normal DOM element, it wouldn't work - it'd look the same as setting it to 0, but if we set scrollTop of a ScrollProxy to -100, it'll give the correct appearance by either setting paddingTop of the wrapper to 100 or applying a 100-pixel translateY. 2852ScrollProxy = function ScrollProxy(element, vars) { 2853 element = gsap.utils.toArray(element)[0]; 2854 vars = vars || {}; 2855 var content = document.createElement("div"), 2856 style = content.style, 2857 node = element.firstChild, 2858 offsetTop = 0, 2859 offsetLeft = 0, 2860 prevTop = element.scrollTop, 2861 prevLeft = element.scrollLeft, 2862 scrollWidth = element.scrollWidth, 2863 scrollHeight = element.scrollHeight, 2864 extraPadRight = 0, 2865 maxLeft = 0, 2866 maxTop = 0, 2867 elementWidth, 2868 elementHeight, 2869 contentHeight, 2870 nextNode, 2871 transformStart, 2872 transformEnd; 2873 2874 if (_supports3D && vars.force3D !== false) { 2875 transformStart = "translate3d("; 2876 transformEnd = "px,0px)"; 2877 } else if (_transformProp) { 2878 transformStart = "translate("; 2879 transformEnd = "px)"; 2880 } 2881 2882 this.scrollTop = function (value, force) { 2883 if (!arguments.length) { 2884 return -this.top(); 2885 } 2886 2887 this.top(-value, force); 2888 }; 2889 2890 this.scrollLeft = function (value, force) { 2891 if (!arguments.length) { 2892 return -this.left(); 2893 } 2894 2895 this.left(-value, force); 2896 }; 2897 2898 this.left = function (value, force) { 2899 if (!arguments.length) { 2900 return -(element.scrollLeft + offsetLeft); 2901 } 2902 2903 var dif = element.scrollLeft - prevLeft, 2904 oldOffset = offsetLeft; 2905 2906 if ((dif > 2 || dif < -2) && !force) { 2907 //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy. 2908 prevLeft = element.scrollLeft; 2909 gsap.killTweensOf(this, { 2910 left: 1, 2911 scrollLeft: 1 2912 }); 2913 this.left(-prevLeft); 2914 2915 if (vars.onKill) { 2916 vars.onKill(); 2917 } 2918 2919 return; 2920 } 2921 2922 value = -value; //invert because scrolling works in the opposite direction 2923 2924 if (value < 0) { 2925 offsetLeft = value - 0.5 | 0; 2926 value = 0; 2927 } else if (value > maxLeft) { 2928 offsetLeft = value - maxLeft | 0; 2929 value = maxLeft; 2930 } else { 2931 offsetLeft = 0; 2932 } 2933 2934 if (offsetLeft || oldOffset) { 2935 if (!this._skip) { 2936 style[_transformProp] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd; 2937 } 2938 2939 if (offsetLeft + extraPadRight >= 0) { 2940 style.paddingRight = offsetLeft + extraPadRight + "px"; 2941 } 2942 } 2943 2944 element.scrollLeft = value | 0; 2945 prevLeft = element.scrollLeft; //don't merge this with the line above because some browsers adjust the scrollLeft after it's set, so in order to be 100% accurate in tracking it, we need to ask the browser to report it. 2946 }; 2947 2948 this.top = function (value, force) { 2949 if (!arguments.length) { 2950 return -(element.scrollTop + offsetTop); 2951 } 2952 2953 var dif = element.scrollTop - prevTop, 2954 oldOffset = offsetTop; 2955 2956 if ((dif > 2 || dif < -2) && !force) { 2957 //if the user interacts with the scrollbar (or something else scrolls it, like the mouse wheel), we should kill any tweens of the ScrollProxy. 2958 prevTop = element.scrollTop; 2959 gsap.killTweensOf(this, { 2960 top: 1, 2961 scrollTop: 1 2962 }); 2963 this.top(-prevTop); 2964 2965 if (vars.onKill) { 2966 vars.onKill(); 2967 } 2968 2969 return; 2970 } 2971 2972 value = -value; //invert because scrolling works in the opposite direction 2973 2974 if (value < 0) { 2975 offsetTop = value - 0.5 | 0; 2976 value = 0; 2977 } else if (value > maxTop) { 2978 offsetTop = value - maxTop | 0; 2979 value = maxTop; 2980 } else { 2981 offsetTop = 0; 2982 } 2983 2984 if (offsetTop || oldOffset) { 2985 if (!this._skip) { 2986 style[_transformProp] = transformStart + -offsetLeft + "px," + -offsetTop + transformEnd; 2987 } 2988 } 2989 2990 element.scrollTop = value | 0; 2991 prevTop = element.scrollTop; 2992 }; 2993 2994 this.maxScrollTop = function () { 2995 return maxTop; 2996 }; 2997 2998 this.maxScrollLeft = function () { 2999 return maxLeft; 3000 }; 3001 3002 this.disable = function () { 3003 node = content.firstChild; 3004 3005 while (node) { 3006 nextNode = node.nextSibling; 3007 element.appendChild(node); 3008 node = nextNode; 3009 } 3010 3011 if (element === content.parentNode) { 3012 //in case disable() is called when it's already disabled. 3013 element.removeChild(content); 3014 } 3015 }; 3016 3017 this.enable = function () { 3018 node = element.firstChild; 3019 3020 if (node === content) { 3021 return; 3022 } 3023 3024 while (node) { 3025 nextNode = node.nextSibling; 3026 content.appendChild(node); 3027 node = nextNode; 3028 } 3029 3030 element.appendChild(content); 3031 this.calibrate(); 3032 }; 3033 3034 this.calibrate = function (force) { 3035 var widthMatches = element.clientWidth === elementWidth, 3036 cs, 3037 x, 3038 y; 3039 prevTop = element.scrollTop; 3040 prevLeft = element.scrollLeft; 3041 3042 if (widthMatches && element.clientHeight === elementHeight && content.offsetHeight === contentHeight && scrollWidth === element.scrollWidth && scrollHeight === element.scrollHeight && !force) { 3043 return; //no need to recalculate things if the width and height haven't changed. 3044 } 3045 3046 if (offsetTop || offsetLeft) { 3047 x = this.left(); 3048 y = this.top(); 3049 this.left(-element.scrollLeft); 3050 this.top(-element.scrollTop); 3051 } 3052 3053 cs = _getComputedStyle(element); //first, we need to remove any width constraints to see how the content naturally flows so that we can see if it's wider than the containing element. If so, we've got to record the amount of overage so that we can apply that as padding in order for browsers to correctly handle things. Then we switch back to a width of 100% (without that, some browsers don't flow the content correctly) 3054 3055 if (!widthMatches || force) { 3056 style.display = "block"; 3057 style.width = "auto"; 3058 style.paddingRight = "0px"; 3059 extraPadRight = Math.max(0, element.scrollWidth - element.clientWidth); //if the content is wider than the container, we need to add the paddingLeft and paddingRight in order for things to behave correctly. 3060 3061 if (extraPadRight) { 3062 extraPadRight += parseFloat(cs.paddingLeft) + (_addPaddingBR ? parseFloat(cs.paddingRight) : 0); 3063 } 3064 } 3065 3066 style.display = "inline-block"; 3067 style.position = "relative"; 3068 style.overflow = "visible"; 3069 style.verticalAlign = "top"; 3070 style.boxSizing = "content-box"; 3071 style.width = "100%"; 3072 style.paddingRight = extraPadRight + "px"; //some browsers neglect to factor in the bottom padding when calculating the scrollHeight, so we need to add that padding to the content when that happens. Allow a 2px margin for error 3073 3074 if (_addPaddingBR) { 3075 style.paddingBottom = cs.paddingBottom; 3076 } 3077 3078 elementWidth = element.clientWidth; 3079 elementHeight = element.clientHeight; 3080 scrollWidth = element.scrollWidth; 3081 scrollHeight = element.scrollHeight; 3082 maxLeft = element.scrollWidth - elementWidth; 3083 maxTop = element.scrollHeight - elementHeight; 3084 contentHeight = content.offsetHeight; 3085 style.display = "block"; 3086 3087 if (x || y) { 3088 this.left(x); 3089 this.top(y); 3090 } 3091 }; 3092 3093 this.content = content; 3094 this.element = element; 3095 this._skip = false; 3096 this.enable(); 3097}, 3098 _initCore = function _initCore(required) { 3099 if (_windowExists() && document.body) { 3100 var nav = window && window.navigator; 3101 _win = window; 3102 _doc = document; 3103 _docElement = _doc.documentElement; 3104 _body = _doc.body; 3105 _tempDiv = _createElement("div"); 3106 _supportsPointer = !!window.PointerEvent; 3107 _placeholderDiv = _createElement("div"); 3108 _placeholderDiv.style.cssText = "visibility:hidden;height:1px;top:-1px;pointer-events:none;position:relative;clear:both;cursor:grab"; 3109 _defaultCursor = _placeholderDiv.style.cursor === "grab" ? "grab" : "move"; 3110 _isAndroid = nav && nav.userAgent.toLowerCase().indexOf("android") !== -1; //Android handles touch events in an odd way and it's virtually impossible to "feature test" so we resort to UA sniffing 3111 3112 _isTouchDevice = "ontouchstart" in _docElement && "orientation" in _win || nav && (nav.MaxTouchPoints > 0 || nav.msMaxTouchPoints > 0); 3113 3114 _addPaddingBR = function () { 3115 //this function is in charge of analyzing browser behavior related to padding. It sets the _addPaddingBR to true if the browser doesn't normally factor in the bottom or right padding on the element inside the scrolling area, and it sets _addPaddingLeft to true if it's a browser that requires the extra offset (offsetLeft) to be added to the paddingRight (like Opera). 3116 var div = _createElement("div"), 3117 child = _createElement("div"), 3118 childStyle = child.style, 3119 parent = _body, 3120 val; 3121 3122 childStyle.display = "inline-block"; 3123 childStyle.position = "relative"; 3124 div.style.cssText = child.innerHTML = "width:90px;height:40px;padding:10px;overflow:auto;visibility:hidden"; 3125 div.appendChild(child); 3126 parent.appendChild(div); 3127 val = child.offsetHeight + 18 > div.scrollHeight; //div.scrollHeight should be child.offsetHeight + 20 because of the 10px of padding on each side, but some browsers ignore one side. We allow a 2px margin of error. 3128 3129 parent.removeChild(div); 3130 return val; 3131 }(); 3132 3133 _touchEventLookup = function (types) { 3134 //we create an object that makes it easy to translate touch event types into their "pointer" counterparts if we're in a browser that uses those instead. Like IE10 uses "MSPointerDown" instead of "touchstart", for example. 3135 var standard = types.split(","), 3136 converted = ("onpointerdown" in _tempDiv ? "pointerdown,pointermove,pointerup,pointercancel" : "onmspointerdown" in _tempDiv ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","), 3137 obj = {}, 3138 i = 4; 3139 3140 while (--i > -1) { 3141 obj[standard[i]] = converted[i]; 3142 obj[converted[i]] = standard[i]; 3143 } //to avoid problems in iOS 9, test to see if the browser supports the "passive" option on addEventListener(). 3144 3145 3146 try { 3147 _docElement.addEventListener("test", null, Object.defineProperty({}, "passive", { 3148 get: function get() { 3149 _supportsPassive = 1; 3150 } 3151 })); 3152 } catch (e) {} 3153 3154 return obj; 3155 }("touchstart,touchmove,touchend,touchcancel"); 3156 3157 _addListener(_doc, "touchcancel", _emptyFunc); //some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. Very strange indeed. 3158 3159 3160 _addListener(_win, "touchmove", _emptyFunc); //works around Safari bugs that still allow the page to scroll even when we preventDefault() on the touchmove event. 3161 3162 3163 _body && _body.addEventListener("touchstart", _emptyFunc); //works around Safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 3164 3165 _addListener(_doc, "contextmenu", function () { 3166 for (var p in _lookup) { 3167 if (_lookup[p].isPressed) { 3168 _lookup[p].endDrag(); 3169 } 3170 } 3171 }); 3172 3173 gsap = _coreInitted = _getGSAP(); 3174 } 3175 3176 if (gsap) { 3177 InertiaPlugin = gsap.plugins.inertia; 3178 _checkPrefix = gsap.utils.checkPrefix; 3179 _transformProp = _checkPrefix(_transformProp); 3180 _transformOriginProp = _checkPrefix(_transformOriginProp); 3181 _toArray = gsap.utils.toArray; 3182 _supports3D = !!_checkPrefix("perspective"); 3183 } else if (required) { 3184 console.warn("Please gsap.registerPlugin(Draggable)"); 3185 } 3186}; 3187 3188var EventDispatcher = /*#__PURE__*/function () { 3189 function EventDispatcher(target) { 3190 this._listeners = {}; 3191 this.target = target || this; 3192 } 3193 3194 var _proto = EventDispatcher.prototype; 3195 3196 _proto.addEventListener = function addEventListener(type, callback) { 3197 var list = this._listeners[type] || (this._listeners[type] = []); 3198 3199 if (!~list.indexOf(callback)) { 3200 list.push(callback); 3201 } 3202 }; 3203 3204 _proto.removeEventListener = function removeEventListener(type, callback) { 3205 var list = this._listeners[type], 3206 i = list && list.indexOf(callback) || -1; 3207 i > -1 && list.splice(i, 1); 3208 }; 3209 3210 _proto.dispatchEvent = function dispatchEvent(type) { 3211 var _this = this; 3212 3213 var result; 3214 (this._listeners[type] || []).forEach(function (callback) { 3215 return callback.call(_this, { 3216 type: type, 3217 target: _this.target 3218 }) === false && (result = false); 3219 }); 3220 return result; //if any of the callbacks return false, pass that along. 3221 }; 3222 3223 return EventDispatcher; 3224}(); 3225 3226var Draggable = /*#__PURE__*/function (_EventDispatcher) { 3227 _inheritsLoose(Draggable, _EventDispatcher); 3228 3229 function Draggable(target, vars) { 3230 var _this2; 3231 3232 _this2 = _EventDispatcher.call(this) || this; 3233 3234 if (!gsap) { 3235 _initCore(1); 3236 } 3237 3238 target = _toArray(target)[0]; //in case the target is a selector object or selector text 3239 3240 if (!InertiaPlugin) { 3241 InertiaPlugin = gsap.plugins.inertia; 3242 } 3243 3244 _this2.vars = vars = _copy(vars || {}); 3245 _this2.target = target; 3246 _this2.x = _this2.y = _this2.rotation = 0; 3247 _this2.dragResistance = parseFloat(vars.dragResistance) || 0; 3248 _this2.edgeResistance = isNaN(vars.edgeResistance) ? 1 : parseFloat(vars.edgeResistance) || 0; 3249 _this2.lockAxis = vars.lockAxis; 3250 _this2.autoScroll = vars.autoScroll || 0; 3251 _this2.lockedAxis = null; 3252 _this2.allowEventDefault = !!vars.allowEventDefault; 3253 gsap.getProperty(target, "x"); // to ensure that transforms are instantiated. 3254 3255 var type = (vars.type || "x,y").toLowerCase(), 3256 xyMode = ~type.indexOf("x") || ~type.indexOf("y"), 3257 rotationMode = type.indexOf("rotation") !== -1, 3258 xProp = rotationMode ? "rotation" : xyMode ? "x" : "left", 3259 yProp = xyMode ? "y" : "top", 3260 allowX = !!(~type.indexOf("x") || ~type.indexOf("left") || type === "scroll"), 3261 allowY = !!(~type.indexOf("y") || ~type.indexOf("top") || type === "scroll"), 3262 minimumMovement = vars.minimumMovement || 2, 3263 self = _assertThisInitialized(_this2), 3264 triggers = _toArray(vars.trigger || vars.handle || target), 3265 killProps = {}, 3266 dragEndTime = 0, 3267 checkAutoScrollBounds = false, 3268 autoScrollMarginTop = vars.autoScrollMarginTop || 40, 3269 autoScrollMarginRight = vars.autoScrollMarginRight || 40, 3270 autoScrollMarginBottom = vars.autoScrollMarginBottom || 40, 3271 autoScrollMarginLeft = vars.autoScrollMarginLeft || 40, 3272 isClickable = vars.clickableTest || _isClickable, 3273 clickTime = 0, 3274 gsCache = target._gsap || gsap.core.getCache(target), 3275 isFixed = _isFixed(target), 3276 getPropAsNum = function getPropAsNum(property, unit) { 3277 return parseFloat(gsCache.get(target, property, unit)); 3278 }, 3279 ownerDoc = target.ownerDocument || _doc, 3280 enabled, 3281 scrollProxy, 3282 startPointerX, 3283 startPointerY, 3284 startElementX, 3285 startElementY, 3286 hasBounds, 3287 hasDragCallback, 3288 hasMoveCallback, 3289 maxX, 3290 minX, 3291 maxY, 3292 minY, 3293 touch, 3294 touchID, 3295 rotationOrigin, 3296 dirty, 3297 old, 3298 snapX, 3299 snapY, 3300 snapXY, 3301 isClicking, 3302 touchEventTarget, 3303 matrix, 3304 interrupted, 3305 allowNativeTouchScrolling, 3306 touchDragAxis, 3307 isDispatching, 3308 clickDispatch, 3309 trustedClickDispatch, 3310 isPreventingDefault, 3311 onContextMenu = function onContextMenu(e) { 3312 //used to prevent long-touch from triggering a context menu. 3313 // (self.isPressed && e.which < 2) && self.endDrag() // previously ended drag when context menu was triggered, but instead we should just stop propagation and prevent the default event behavior. 3314 _preventDefault(e); 3315 3316 e.stopImmediatePropagation && e.stopImmediatePropagation(); 3317 return false; 3318 }, 3319 //this method gets called on every tick of TweenLite.ticker which allows us to synchronize the renders to the core engine (which is typically synchronized with the display refresh via requestAnimationFrame). This is an optimization - it's better than applying the values inside the "mousemove" or "touchmove" event handler which may get called many times inbetween refreshes. 3320 render = function render(suppressEvents) { 3321 if (self.autoScroll && self.isDragging && (checkAutoScrollBounds || dirty)) { 3322 var e = target, 3323 autoScrollFactor = self.autoScroll * 15, 3324 //multiplying by 15 just gives us a better "feel" speed-wise. 3325 parent, 3326 isRoot, 3327 rect, 3328 pointerX, 3329 pointerY, 3330 changeX, 3331 changeY, 3332 gap; 3333 checkAutoScrollBounds = false; 3334 _windowProxy.scrollTop = _win.pageYOffset != null ? _win.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop; 3335 _windowProxy.scrollLeft = _win.pageXOffset != null ? _win.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft; 3336 pointerX = self.pointerX - _windowProxy.scrollLeft; 3337 pointerY = self.pointerY - _windowProxy.scrollTop; 3338 3339 while (e && !isRoot) { 3340 //walk up the chain and sense wherever the pointer is within 40px of an edge that's scrollable. 3341 isRoot = _isRoot(e.parentNode); 3342 parent = isRoot ? _windowProxy : e.parentNode; 3343 rect = isRoot ? { 3344 bottom: Math.max(_docElement.clientHeight, _win.innerHeight || 0), 3345 right: Math.max(_docElement.clientWidth, _win.innerWidth || 0), 3346 left: 0, 3347 top: 0 3348 } : parent.getBoundingClientRect(); 3349 changeX = changeY = 0; 3350 3351 if (allowY) { 3352 gap = parent._gsMaxScrollY - parent.scrollTop; 3353 3354 if (gap < 0) { 3355 changeY = gap; 3356 } else if (pointerY > rect.bottom - autoScrollMarginBottom && gap) { 3357 checkAutoScrollBounds = true; 3358 changeY = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.bottom - pointerY) / autoScrollMarginBottom) | 0); 3359 } else if (pointerY < rect.top + autoScrollMarginTop && parent.scrollTop) { 3360 checkAutoScrollBounds = true; 3361 changeY = -Math.min(parent.scrollTop, autoScrollFactor * (1 - Math.max(0, pointerY - rect.top) / autoScrollMarginTop) | 0); 3362 } 3363 3364 if (changeY) { 3365 parent.scrollTop += changeY; 3366 } 3367 } 3368 3369 if (allowX) { 3370 gap = parent._gsMaxScrollX - parent.scrollLeft; 3371 3372 if (gap < 0) { 3373 changeX = gap; 3374 } else if (pointerX > rect.right - autoScrollMarginRight && gap) { 3375 checkAutoScrollBounds = true; 3376 changeX = Math.min(gap, autoScrollFactor * (1 - Math.max(0, rect.right - pointerX) / autoScrollMarginRight) | 0); 3377 } else if (pointerX < rect.left + autoScrollMarginLeft && parent.scrollLeft) { 3378 checkAutoScrollBounds = true; 3379 changeX = -Math.min(parent.scrollLeft, autoScrollFactor * (1 - Math.max(0, pointerX - rect.left) / autoScrollMarginLeft) | 0); 3380 } 3381 3382 if (changeX) { 3383 parent.scrollLeft += changeX; 3384 } 3385 } 3386 3387 if (isRoot && (changeX || changeY)) { 3388 _win.scrollTo(parent.scrollLeft, parent.scrollTop); 3389 3390 setPointerPosition(self.pointerX + changeX, self.pointerY + changeY); 3391 } 3392 3393 e = parent; 3394 } 3395 } 3396 3397 if (dirty) { 3398 var x = self.x, 3399 y = self.y; 3400 3401 if (rotationMode) { 3402 self.deltaX = x - parseFloat(gsCache.rotation); 3403 self.rotation = x; 3404 gsCache.rotation = x + "deg"; 3405 gsCache.renderTransform(1, gsCache); 3406 } else { 3407 if (scrollProxy) { 3408 if (allowY) { 3409 self.deltaY = y - scrollProxy.top(); 3410 scrollProxy.top(y); 3411 } 3412 3413 if (allowX) { 3414 self.deltaX = x - scrollProxy.left(); 3415 scrollProxy.left(x); 3416 } 3417 } else if (xyMode) { 3418 if (allowY) { 3419 self.deltaY = y - parseFloat(gsCache.y); 3420 gsCache.y = y + "px"; 3421 } 3422 3423 if (allowX) { 3424 self.deltaX = x - parseFloat(gsCache.x); 3425 gsCache.x = x + "px"; 3426 } 3427 3428 gsCache.renderTransform(1, gsCache); 3429 } else { 3430 if (allowY) { 3431 self.deltaY = y - parseFloat(target.style.top || 0); 3432 target.style.top = y + "px"; 3433 } 3434 3435 if (allowX) { 3436 self.deltaY = x - parseFloat(target.style.left || 0); 3437 target.style.left = x + "px"; 3438 } 3439 } 3440 } 3441 3442 if (hasDragCallback && !suppressEvents && !isDispatching) { 3443 isDispatching = true; //in case onDrag has an update() call (avoid endless loop) 3444 3445 if (_dispatchEvent(self, "drag", "onDrag") === false) { 3446 if (allowX) { 3447 self.x -= self.deltaX; 3448 } 3449 3450 if (allowY) { 3451 self.y -= self.deltaY; 3452 } 3453 3454 render(true); 3455 } 3456 3457 isDispatching = false; 3458 } 3459 } 3460 3461 dirty = false; 3462 }, 3463 //copies the x/y from the element (whether that be transforms, top/left, or ScrollProxy's top/left) to the Draggable's x and y (and rotation if necessary) properties so that they reflect reality and it also (optionally) applies any snapping necessary. This is used by the InertiaPlugin tween in an onUpdate to ensure things are synced and snapped. 3464 syncXY = function syncXY(skipOnUpdate, skipSnap) { 3465 var x = self.x, 3466 y = self.y, 3467 snappedValue, 3468 cs; 3469 3470 if (!target._gsap) { 3471 //just in case the _gsap cache got wiped, like if the user called clearProps on the transform or something (very rare). 3472 gsCache = gsap.core.getCache(target); 3473 } 3474 3475 gsCache.uncache && gsap.getProperty(target, "x"); // trigger a re-cache 3476 3477 if (xyMode) { 3478 self.x = parseFloat(gsCache.x); 3479 self.y = parseFloat(gsCache.y); 3480 } else if (rotationMode) { 3481 self.x = self.rotation = parseFloat(gsCache.rotation); 3482 } else if (scrollProxy) { 3483 self.y = scrollProxy.top(); 3484 self.x = scrollProxy.left(); 3485 } else { 3486 self.y = parseInt(target.style.top || (cs = _getComputedStyle(target)) && cs.top, 10) || 0; 3487 self.x = parseInt(target.style.left || (cs || {}).left, 10) || 0; 3488 } 3489 3490 if ((snapX || snapY || snapXY) && !skipSnap && (self.isDragging || self.isThrowing)) { 3491 if (snapXY) { 3492 _temp1.x = self.x; 3493 _temp1.y = self.y; 3494 snappedValue = snapXY(_temp1); 3495 3496 if (snappedValue.x !== self.x) { 3497 self.x = snappedValue.x; 3498 dirty = true; 3499 } 3500 3501 if (snappedValue.y !== self.y) { 3502 self.y = snappedValue.y; 3503 dirty = true; 3504 } 3505 } 3506 3507 if (snapX) { 3508 snappedValue = snapX(self.x); 3509 3510 if (snappedValue !== self.x) { 3511 self.x = snappedValue; 3512 3513 if (rotationMode) { 3514 self.rotation = snappedValue; 3515 } 3516 3517 dirty = true; 3518 } 3519 } 3520 3521 if (snapY) { 3522 snappedValue = snapY(self.y); 3523 3524 if (snappedValue !== self.y) { 3525 self.y = snappedValue; 3526 } 3527 3528 dirty = true; 3529 } 3530 } 3531 3532 dirty && render(true); 3533 3534 if (!skipOnUpdate) { 3535 self.deltaX = self.x - x; 3536 self.deltaY = self.y - y; 3537 3538 _dispatchEvent(self, "throwupdate", "onThrowUpdate"); 3539 } 3540 }, 3541 buildSnapFunc = function buildSnapFunc(snap, min, max, factor) { 3542 if (min == null) { 3543 min = -_bigNum; 3544 } 3545 3546 if (max == null) { 3547 max = _bigNum; 3548 } 3549 3550 if (_isFunction(snap)) { 3551 return function (n) { 3552 var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance; //if we're tweening, disable the edgeTolerance because it's already factored into the tweening values (we don't want to apply it multiple times) 3553 3554 return snap.call(self, n > max ? max + (n - max) * edgeTolerance : n < min ? min + (n - min) * edgeTolerance : n) * factor; 3555 }; 3556 } 3557 3558 if (_isArray(snap)) { 3559 return function (n) { 3560 var i = snap.length, 3561 closest = 0, 3562 absDif = _bigNum, 3563 val, 3564 dif; 3565 3566 while (--i > -1) { 3567 val = snap[i]; 3568 dif = val - n; 3569 3570 if (dif < 0) { 3571 dif = -dif; 3572 } 3573 3574 if (dif < absDif && val >= min && val <= max) { 3575 closest = i; 3576 absDif = dif; 3577 } 3578 } 3579 3580 return snap[closest]; 3581 }; 3582 } 3583 3584 return isNaN(snap) ? function (n) { 3585 return n; 3586 } : function () { 3587 return snap * factor; 3588 }; 3589 }, 3590 buildPointSnapFunc = function buildPointSnapFunc(snap, minX, maxX, minY, maxY, radius, factor) { 3591 radius = radius && radius < _bigNum ? radius * radius : _bigNum; //so we don't have to Math.sqrt() in the functions. Performance optimization. 3592 3593 if (_isFunction(snap)) { 3594 return function (point) { 3595 var edgeTolerance = !self.isPressed ? 1 : 1 - self.edgeResistance, 3596 x = point.x, 3597 y = point.y, 3598 result, 3599 dx, 3600 dy; //if we're tweening, disable the edgeTolerance because it's already factored into the tweening values (we don't want to apply it multiple times) 3601 3602 point.x = x = x > maxX ? maxX + (x - maxX) * edgeTolerance : x < minX ? minX + (x - minX) * edgeTolerance : x; 3603 point.y = y = y > maxY ? maxY + (y - maxY) * edgeTolerance : y < minY ? minY + (y - minY) * edgeTolerance : y; 3604 result = snap.call(self, point); 3605 3606 if (result !== point) { 3607 point.x = result.x; 3608 point.y = result.y; 3609 } 3610 3611 if (factor !== 1) { 3612 point.x *= factor; 3613 point.y *= factor; 3614 } 3615 3616 if (radius < _bigNum) { 3617 dx = point.x - x; 3618 dy = point.y - y; 3619 3620 if (dx * dx + dy * dy > radius) { 3621 point.x = x; 3622 point.y = y; 3623 } 3624 } 3625 3626 return point; 3627 }; 3628 } 3629 3630 if (_isArray(snap)) { 3631 return function (p) { 3632 var i = snap.length, 3633 closest = 0, 3634 minDist = _bigNum, 3635 x, 3636 y, 3637 point, 3638 dist; 3639 3640 while (--i > -1) { 3641 point = snap[i]; 3642 x = point.x - p.x; 3643 y = point.y - p.y; 3644 dist = x * x + y * y; 3645 3646 if (dist < minDist) { 3647 closest = i; 3648 minDist = dist; 3649 } 3650 } 3651 3652 return minDist <= radius ? snap[closest] : p; 3653 }; 3654 } 3655 3656 return function (n) { 3657 return n; 3658 }; 3659 }, 3660 calculateBounds = function calculateBounds() { 3661 var bounds, targetBounds, snap, snapIsRaw; 3662 hasBounds = false; 3663 3664 if (scrollProxy) { 3665 scrollProxy.calibrate(); 3666 self.minX = minX = -scrollProxy.maxScrollLeft(); 3667 self.minY = minY = -scrollProxy.maxScrollTop(); 3668 self.maxX = maxX = self.maxY = maxY = 0; 3669 hasBounds = true; 3670 } else if (!!vars.bounds) { 3671 bounds = _getBounds(vars.bounds, target.parentNode); //could be a selector/jQuery object or a DOM element or a generic object like {top:0, left:100, width:1000, height:800} or {minX:100, maxX:1100, minY:0, maxY:800} 3672 3673 if (rotationMode) { 3674 self.minX = minX = bounds.left; 3675 self.maxX = maxX = bounds.left + bounds.width; 3676 self.minY = minY = self.maxY = maxY = 0; 3677 } else if (!_isUndefined(vars.bounds.maxX) || !_isUndefined(vars.bounds.maxY)) { 3678 bounds = vars.bounds; 3679 self.minX = minX = bounds.minX; 3680 self.minY = minY = bounds.minY; 3681 self.maxX = maxX = bounds.maxX; 3682 self.maxY = maxY = bounds.maxY; 3683 } else { 3684 targetBounds = _getBounds(target, target.parentNode); 3685 self.minX = minX = Math.round(getPropAsNum(xProp, "px") + bounds.left - targetBounds.left - 0.5); 3686 self.minY = minY = Math.round(getPropAsNum(yProp, "px") + bounds.top - targetBounds.top - 0.5); 3687 self.maxX = maxX = Math.round(minX + (bounds.width - targetBounds.width)); 3688 self.maxY = maxY = Math.round(minY + (bounds.height - targetBounds.height)); 3689 } 3690 3691 if (minX > maxX) { 3692 self.minX = maxX; 3693 self.maxX = maxX = minX; 3694 minX = self.minX; 3695 } 3696 3697 if (minY > maxY) { 3698 self.minY = maxY; 3699 self.maxY = maxY = minY; 3700 minY = self.minY; 3701 } 3702 3703 if (rotationMode) { 3704 self.minRotation = minX; 3705 self.maxRotation = maxX; 3706 } 3707 3708 hasBounds = true; 3709 } 3710 3711 if (vars.liveSnap) { 3712 snap = vars.liveSnap === true ? vars.snap || {} : vars.liveSnap; 3713 snapIsRaw = _isArray(snap) || _isFunction(snap); 3714 3715 if (rotationMode) { 3716 snapX = buildSnapFunc(snapIsRaw ? snap : snap.rotation, minX, maxX, 1); 3717 snapY = null; 3718 } else { 3719 if (snap.points) { 3720 snapXY = buildPointSnapFunc(snapIsRaw ? snap : snap.points, minX, maxX, minY, maxY, snap.radius, scrollProxy ? -1 : 1); 3721 } else { 3722 if (allowX) { 3723 snapX = buildSnapFunc(snapIsRaw ? snap : snap.x || snap.left || snap.scrollLeft, minX, maxX, scrollProxy ? -1 : 1); 3724 } 3725 3726 if (allowY) { 3727 snapY = buildSnapFunc(snapIsRaw ? snap : snap.y || snap.top || snap.scrollTop, minY, maxY, scrollProxy ? -1 : 1); 3728 } 3729 } 3730 } 3731 } 3732 }, 3733 onThrowComplete = function onThrowComplete() { 3734 self.isThrowing = false; 3735 3736 _dispatchEvent(self, "throwcomplete", "onThrowComplete"); 3737 }, 3738 onThrowInterrupt = function onThrowInterrupt() { 3739 self.isThrowing = false; 3740 }, 3741 animate = function animate(inertia, forceZeroVelocity) { 3742 var snap, snapIsRaw, tween, overshootTolerance; 3743 3744 if (inertia && InertiaPlugin) { 3745 if (inertia === true) { 3746 snap = vars.snap || vars.liveSnap || {}; 3747 snapIsRaw = _isArray(snap) || _isFunction(snap); 3748 inertia = { 3749 resistance: (vars.throwResistance || vars.resistance || 1000) / (rotationMode ? 10 : 1) 3750 }; 3751 3752 if (rotationMode) { 3753 inertia.rotation = _parseInertia(self, snapIsRaw ? snap : snap.rotation, maxX, minX, 1, forceZeroVelocity); 3754 } else { 3755 if (allowX) { 3756 inertia[xProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.x || snap.left, maxX, minX, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "x"); 3757 } 3758 3759 if (allowY) { 3760 inertia[yProp] = _parseInertia(self, snapIsRaw ? snap : snap.points || snap.y || snap.top, maxY, minY, scrollProxy ? -1 : 1, forceZeroVelocity || self.lockedAxis === "y"); 3761 } 3762 3763 if (snap.points || _isArray(snap) && _isObject(snap[0])) { 3764 inertia.linkedProps = xProp + "," + yProp; 3765 inertia.radius = snap.radius; //note: we also disable liveSnapping while throwing if there's a "radius" defined, otherwise it looks weird to have the item thrown past a snapping point but live-snapping mid-tween. We do this by altering the onUpdateParams so that "skipSnap" parameter is true for syncXY. 3766 } 3767 } 3768 } 3769 3770 self.isThrowing = true; 3771 overshootTolerance = !isNaN(vars.overshootTolerance) ? vars.overshootTolerance : vars.edgeResistance === 1 ? 0 : 1 - self.edgeResistance + 0.2; 3772 3773 if (!inertia.duration) { 3774 inertia.duration = { 3775 max: Math.max(vars.minDuration || 0, "maxDuration" in vars ? vars.maxDuration : 2), 3776 min: !isNaN(vars.minDuration) ? vars.minDuration : overshootTolerance === 0 || _isObject(inertia) && inertia.resistance > 1000 ? 0 : 0.5, 3777 overshoot: overshootTolerance 3778 }; 3779 } 3780 3781 self.tween = tween = gsap.to(scrollProxy || target, { 3782 inertia: inertia, 3783 data: "_draggable", 3784 onComplete: onThrowComplete, 3785 onInterrupt: onThrowInterrupt, 3786 onUpdate: vars.fastMode ? _dispatchEvent : syncXY, 3787 onUpdateParams: vars.fastMode ? [self, "onthrowupdate", "onThrowUpdate"] : snap && snap.radius ? [false, true] : [] 3788 }); 3789 3790 if (!vars.fastMode) { 3791 if (scrollProxy) { 3792 scrollProxy._skip = true; // Microsoft browsers have a bug that causes them to briefly render the position incorrectly (it flashes to the end state when we seek() the tween even though we jump right back to the current position, and this only seems to happen when we're affecting both top and left), so we set a _suspendTransforms flag to prevent it from actually applying the values in the ScrollProxy. 3793 } 3794 3795 tween.render(1e9, true, true); // force to the end. Remember, the duration will likely change upon initting because that's when InertiaPlugin calculates it. 3796 3797 syncXY(true, true); 3798 self.endX = self.x; 3799 self.endY = self.y; 3800 3801 if (rotationMode) { 3802 self.endRotation = self.x; 3803 } 3804 3805 tween.play(0); 3806 syncXY(true, true); 3807 3808 if (scrollProxy) { 3809 scrollProxy._skip = false; //Microsoft browsers have a bug that causes them to briefly render the position incorrectly (it flashes to the end state when we seek() the tween even though we jump right back to the current position, and this only seems to happen when we're affecting both top and left), so we set a _suspendTransforms flag to prevent it from actually applying the values in the ScrollProxy. 3810 } 3811 } 3812 } else if (hasBounds) { 3813 self.applyBounds(); 3814 } 3815 }, 3816 updateMatrix = function updateMatrix(shiftStart) { 3817 var start = matrix, 3818 p; 3819 matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(target.parentNode, true); 3820 3821 if (shiftStart && self.isPressed && !matrix.equals(start || new _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["Matrix2D"]())) { 3822 //if the matrix changes WHILE the element is pressed, we must adjust the startPointerX and startPointerY accordingly, so we invert the original matrix and figure out where the pointerX and pointerY were in the global space, then apply the new matrix to get the updated coordinates. 3823 p = start.inverse().apply({ 3824 x: startPointerX, 3825 y: startPointerY 3826 }); 3827 matrix.apply(p, p); 3828 startPointerX = p.x; 3829 startPointerY = p.y; 3830 } 3831 3832 if (matrix.equals(_identityMatrix)) { 3833 //if there are no transforms, we can optimize performance by not factoring in the matrix 3834 matrix = null; 3835 } 3836 }, 3837 recordStartPositions = function recordStartPositions() { 3838 var edgeTolerance = 1 - self.edgeResistance, 3839 offsetX = isFixed ? _getDocScrollLeft(ownerDoc) : 0, 3840 offsetY = isFixed ? _getDocScrollTop(ownerDoc) : 0, 3841 parsedOrigin, 3842 x, 3843 y; 3844 updateMatrix(false); 3845 _point1.x = self.pointerX - offsetX; 3846 _point1.y = self.pointerY - offsetY; 3847 matrix && matrix.apply(_point1, _point1); 3848 startPointerX = _point1.x; //translate to local coordinate system 3849 3850 startPointerY = _point1.y; 3851 3852 if (dirty) { 3853 setPointerPosition(self.pointerX, self.pointerY); 3854 render(true); 3855 } 3856 3857 if (scrollProxy) { 3858 calculateBounds(); 3859 startElementY = scrollProxy.top(); 3860 startElementX = scrollProxy.left(); 3861 } else { 3862 //if the element is in the process of tweening, don't force snapping to occur because it could make it jump. Imagine the user throwing, then before it's done, clicking on the element in its inbetween state. 3863 if (isTweening()) { 3864 syncXY(true, true); 3865 calculateBounds(); 3866 } else { 3867 self.applyBounds(); 3868 } 3869 3870 if (rotationMode) { 3871 parsedOrigin = target.ownerSVGElement ? [gsCache.xOrigin - target.getBBox().x, gsCache.yOrigin - target.getBBox().y] : (_getComputedStyle(target)[_transformOriginProp] || "0 0").split(" "); 3872 rotationOrigin = self.rotationOrigin = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(target).apply({ 3873 x: parseFloat(parsedOrigin[0]) || 0, 3874 y: parseFloat(parsedOrigin[1]) || 0 3875 }); 3876 syncXY(true, true); 3877 x = self.pointerX - rotationOrigin.x - offsetX; 3878 y = rotationOrigin.y - self.pointerY + offsetY; 3879 startElementX = self.x; //starting rotation (x always refers to rotation in type:"rotation", measured in degrees) 3880 3881 startElementY = self.y = Math.atan2(y, x) * _RAD2DEG; 3882 } else { 3883 //parent = !isFixed && target.parentNode; 3884 //startScrollTop = parent ? parent.scrollTop || 0 : 0; 3885 //startScrollLeft = parent ? parent.scrollLeft || 0 : 0; 3886 startElementY = getPropAsNum(yProp, "px"); //record the starting top and left values so that we can just add the mouse's movement to them later. 3887 3888 startElementX = getPropAsNum(xProp, "px"); 3889 } 3890 } 3891 3892 if (hasBounds && edgeTolerance) { 3893 if (startElementX > maxX) { 3894 startElementX = maxX + (startElementX - maxX) / edgeTolerance; 3895 } else if (startElementX < minX) { 3896 startElementX = minX - (minX - startElementX) / edgeTolerance; 3897 } 3898 3899 if (!rotationMode) { 3900 if (startElementY > maxY) { 3901 startElementY = maxY + (startElementY - maxY) / edgeTolerance; 3902 } else if (startElementY < minY) { 3903 startElementY = minY - (minY - startElementY) / edgeTolerance; 3904 } 3905 } 3906 } 3907 3908 self.startX = startElementX; 3909 self.startY = startElementY; 3910 }, 3911 isTweening = function isTweening() { 3912 return self.tween && self.tween.isActive(); 3913 }, 3914 removePlaceholder = function removePlaceholder() { 3915 if (_placeholderDiv.parentNode && !isTweening() && !self.isDragging) { 3916 //_placeholderDiv just props open auto-scrolling containers so they don't collapse as the user drags left/up. We remove it after dragging (and throwing, if necessary) finishes. 3917 _placeholderDiv.parentNode.removeChild(_placeholderDiv); 3918 } 3919 }, 3920 //called when the mouse is pressed (or touch starts) 3921 onPress = function onPress(e, force) { 3922 var i; 3923 3924 if (!enabled || self.isPressed || !e || (e.type === "mousedown" || e.type === "pointerdown") && !force && _getTime() - clickTime < 30 && _touchEventLookup[self.pointerEvent.type]) { 3925 //when we DON'T preventDefault() in order to accommodate touch-scrolling and the user just taps, many browsers also fire a mousedown/mouseup sequence AFTER the touchstart/touchend sequence, thus it'd result in two quick "click" events being dispatched. This line senses that condition and halts it on the subsequent mousedown. 3926 isPreventingDefault && e && enabled && _preventDefault(e); // in some browsers, we must listen for multiple event types like touchstart, pointerdown, mousedown. The first time this function is called, we record whether or not we _preventDefault() so that on duplicate calls, we can do the same if necessary. 3927 3928 return; 3929 } 3930 3931 interrupted = isTweening(); 3932 self.pointerEvent = e; 3933 3934 if (_touchEventLookup[e.type]) { 3935 //note: on iOS, BOTH touchmove and mousemove are dispatched, but the mousemove has pageY and pageX of 0 which would mess up the calculations and needlessly hurt performance. 3936 touchEventTarget = ~e.type.indexOf("touch") ? e.currentTarget || e.target : ownerDoc; //pointer-based touches (for Microsoft browsers) don't remain locked to the original target like other browsers, so we must use the document instead. The event type would be "MSPointerDown" or "pointerdown". 3937 3938 _addListener(touchEventTarget, "touchend", onRelease); 3939 3940 _addListener(touchEventTarget, "touchmove", onMove); 3941 3942 _addListener(touchEventTarget, "touchcancel", onRelease); 3943 3944 _addListener(ownerDoc, "touchstart", _onMultiTouchDocument); 3945 } else { 3946 touchEventTarget = null; 3947 3948 _addListener(ownerDoc, "mousemove", onMove); //attach these to the document instead of the box itself so that if the user's mouse moves too quickly (and off of the box), things still work. 3949 3950 } 3951 3952 touchDragAxis = null; 3953 3954 if (!_supportsPointer || !touchEventTarget) { 3955 _addListener(ownerDoc, "mouseup", onRelease); 3956 3957 e && e.target && _addListener(e.target, "mouseup", onRelease); //we also have to listen directly on the element because some browsers don't bubble up the event to the _doc on elements with contentEditable="true" 3958 } 3959 3960 isClicking = isClickable.call(self, e.target) && vars.dragClickables === false && !force; 3961 3962 if (isClicking) { 3963 _addListener(e.target, "change", onRelease); //in some browsers, when you mousedown on a <select> element, no mouseup gets dispatched! So we listen for a "change" event instead. 3964 3965 3966 _dispatchEvent(self, "pressInit", "onPressInit"); 3967 3968 _dispatchEvent(self, "press", "onPress"); 3969 3970 _setSelectable(triggers, true); //accommodates things like inputs and elements with contentEditable="true" (otherwise user couldn't drag to select text) 3971 3972 3973 isPreventingDefault = false; 3974 return; 3975 } 3976 3977 allowNativeTouchScrolling = !touchEventTarget || allowX === allowY || self.vars.allowNativeTouchScrolling === false || self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2) ? false : allowX ? "y" : "x"; //note: in Chrome, right-clicking (for a context menu) fires onPress and it doesn't have the event.which set properly, so we must look for event.ctrlKey. If the user wants to allow context menus we should of course sense it here and not allow native touch scrolling. 3978 3979 isPreventingDefault = !allowNativeTouchScrolling && !self.allowEventDefault; 3980 3981 if (isPreventingDefault) { 3982 _preventDefault(e); 3983 3984 _addListener(_win, "touchforcechange", _preventDefault); //works around safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 3985 3986 } 3987 3988 if (e.changedTouches) { 3989 //touch events store the data slightly differently 3990 e = touch = e.changedTouches[0]; 3991 touchID = e.identifier; 3992 } else if (e.pointerId) { 3993 touchID = e.pointerId; //for some Microsoft browsers 3994 } else { 3995 touch = touchID = null; 3996 } 3997 3998 _dragCount++; 3999 4000 _addToRenderQueue(render); //causes the Draggable to render on each "tick" of TweenLite.ticker (performance optimization - updating values in a mousemove can cause them to happen too frequently, like multiple times between frame redraws which is wasteful, and it also prevents values from updating properly in IE8) 4001 4002 4003 startPointerY = self.pointerY = e.pageY; //record the starting x and y so that we can calculate the movement from the original in _onMouseMove 4004 4005 startPointerX = self.pointerX = e.pageX; 4006 4007 _dispatchEvent(self, "pressInit", "onPressInit"); 4008 4009 if (allowNativeTouchScrolling || self.autoScroll) { 4010 _recordMaxScrolls(target.parentNode); 4011 } 4012 4013 if (target.parentNode && self.autoScroll && !scrollProxy && !rotationMode && target.parentNode._gsMaxScrollX && !_placeholderDiv.parentNode && !target.getBBox) { 4014 //add a placeholder div to prevent the parent container from collapsing when the user drags the element left. 4015 _placeholderDiv.style.width = target.parentNode.scrollWidth + "px"; 4016 target.parentNode.appendChild(_placeholderDiv); 4017 } 4018 4019 recordStartPositions(); 4020 self.tween && self.tween.kill(); 4021 self.isThrowing = false; 4022 gsap.killTweensOf(scrollProxy || target, killProps, true); //in case the user tries to drag it before the last tween is done. 4023 4024 scrollProxy && gsap.killTweensOf(target, { 4025 scrollTo: 1 4026 }, true); //just in case the original target's scroll position is being tweened somewhere else. 4027 4028 self.tween = self.lockedAxis = null; 4029 4030 if (vars.zIndexBoost || !rotationMode && !scrollProxy && vars.zIndexBoost !== false) { 4031 target.style.zIndex = Draggable.zIndex++; 4032 } 4033 4034 self.isPressed = true; 4035 hasDragCallback = !!(vars.onDrag || self._listeners.drag); 4036 hasMoveCallback = !!(vars.onMove || self._listeners.move); 4037 4038 if (!rotationMode && (vars.cursor !== false || vars.activeCursor)) { 4039 i = triggers.length; 4040 4041 while (--i > -1) { 4042 gsap.set(triggers[i], { 4043 cursor: vars.activeCursor || vars.cursor || (_defaultCursor === "grab" ? "grabbing" : _defaultCursor) 4044 }); 4045 } 4046 } 4047 4048 _dispatchEvent(self, "press", "onPress"); 4049 }, 4050 //called every time the mouse/touch moves 4051 onMove = function onMove(e) { 4052 var originalEvent = e, 4053 touches, 4054 pointerX, 4055 pointerY, 4056 i, 4057 dx, 4058 dy; 4059 4060 if (!enabled || _isMultiTouching || !self.isPressed || !e) { 4061 isPreventingDefault && e && enabled && _preventDefault(e); // in some browsers, we must listen for multiple event types like touchmove, pointermove, mousemove. The first time this function is called, we record whether or not we _preventDefault() so that on duplicate calls, we can do the same if necessary. 4062 4063 return; 4064 } 4065 4066 self.pointerEvent = e; 4067 touches = e.changedTouches; 4068 4069 if (touches) { 4070 //touch events store the data slightly differently 4071 e = touches[0]; 4072 4073 if (e !== touch && e.identifier !== touchID) { 4074 //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) 4075 i = touches.length; 4076 4077 while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {} // Some Android devices dispatch a touchstart AND pointerdown initially, and then only pointermove thus the touchID may not match because it was grabbed from the touchstart event whereas the pointer event is the one that the browser dispatches for move, so if the event target matches this Draggable's target, let it through. 4078 4079 4080 if (i < 0) { 4081 return; 4082 } 4083 } 4084 } else if (e.pointerId && touchID && e.pointerId !== touchID) { 4085 //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch) 4086 return; 4087 } 4088 4089 if (touchEventTarget && allowNativeTouchScrolling && !touchDragAxis) { 4090 //Android browsers force us to decide on the first "touchmove" event if we should allow the default (scrolling) behavior or preventDefault(). Otherwise, a "touchcancel" will be fired and then no "touchmove" or "touchend" will fire during the scrolling (no good). 4091 _point1.x = e.pageX; 4092 _point1.y = e.pageY; 4093 matrix && matrix.apply(_point1, _point1); 4094 pointerX = _point1.x; 4095 pointerY = _point1.y; 4096 dx = Math.abs(pointerX - startPointerX); 4097 dy = Math.abs(pointerY - startPointerY); 4098 4099 if (dx !== dy && (dx > minimumMovement || dy > minimumMovement) || _isAndroid && allowNativeTouchScrolling === touchDragAxis) { 4100 touchDragAxis = dx > dy && allowX ? "x" : "y"; 4101 4102 if (allowNativeTouchScrolling && touchDragAxis !== allowNativeTouchScrolling) { 4103 _addListener(_win, "touchforcechange", _preventDefault); // prevents native touch scrolling from taking over if the user started dragging in the other direction in iOS Safari 4104 4105 } 4106 4107 if (self.vars.lockAxisOnTouchScroll !== false && allowX && allowY) { 4108 self.lockedAxis = touchDragAxis === "x" ? "y" : "x"; 4109 _isFunction(self.vars.onLockAxis) && self.vars.onLockAxis.call(self, originalEvent); 4110 } 4111 4112 if (_isAndroid && allowNativeTouchScrolling === touchDragAxis) { 4113 onRelease(originalEvent); 4114 return; 4115 } 4116 } 4117 } 4118 4119 if (!self.allowEventDefault && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling !== touchDragAxis) && originalEvent.cancelable !== false) { 4120 _preventDefault(originalEvent); 4121 4122 isPreventingDefault = true; 4123 } else if (isPreventingDefault) { 4124 isPreventingDefault = false; 4125 } 4126 4127 if (self.autoScroll) { 4128 checkAutoScrollBounds = true; 4129 } 4130 4131 setPointerPosition(e.pageX, e.pageY, hasMoveCallback); 4132 }, 4133 setPointerPosition = function setPointerPosition(pointerX, pointerY, invokeOnMove) { 4134 var dragTolerance = 1 - self.dragResistance, 4135 edgeTolerance = 1 - self.edgeResistance, 4136 prevPointerX = self.pointerX, 4137 prevPointerY = self.pointerY, 4138 prevStartElementY = startElementY, 4139 prevX = self.x, 4140 prevY = self.y, 4141 prevEndX = self.endX, 4142 prevEndY = self.endY, 4143 prevEndRotation = self.endRotation, 4144 prevDirty = dirty, 4145 xChange, 4146 yChange, 4147 x, 4148 y, 4149 dif, 4150 temp; 4151 self.pointerX = pointerX; 4152 self.pointerY = pointerY; 4153 4154 if (isFixed) { 4155 pointerX -= _getDocScrollLeft(ownerDoc); 4156 pointerY -= _getDocScrollTop(ownerDoc); 4157 } 4158 4159 if (rotationMode) { 4160 y = Math.atan2(rotationOrigin.y - pointerY, pointerX - rotationOrigin.x) * _RAD2DEG; 4161 dif = self.y - y; 4162 4163 if (dif > 180) { 4164 startElementY -= 360; 4165 self.y = y; 4166 } else if (dif < -180) { 4167 startElementY += 360; 4168 self.y = y; 4169 } 4170 4171 if (self.x !== startElementX || Math.abs(startElementY - y) > minimumMovement) { 4172 self.y = y; 4173 x = startElementX + (startElementY - y) * dragTolerance; 4174 } else { 4175 x = startElementX; 4176 } 4177 } else { 4178 if (matrix) { 4179 temp = pointerX * matrix.a + pointerY * matrix.c + matrix.e; 4180 pointerY = pointerX * matrix.b + pointerY * matrix.d + matrix.f; 4181 pointerX = temp; 4182 } 4183 4184 yChange = pointerY - startPointerY; 4185 xChange = pointerX - startPointerX; 4186 4187 if (yChange < minimumMovement && yChange > -minimumMovement) { 4188 yChange = 0; 4189 } 4190 4191 if (xChange < minimumMovement && xChange > -minimumMovement) { 4192 xChange = 0; 4193 } 4194 4195 if ((self.lockAxis || self.lockedAxis) && (xChange || yChange)) { 4196 temp = self.lockedAxis; 4197 4198 if (!temp) { 4199 self.lockedAxis = temp = allowX && Math.abs(xChange) > Math.abs(yChange) ? "y" : allowY ? "x" : null; 4200 4201 if (temp && _isFunction(self.vars.onLockAxis)) { 4202 self.vars.onLockAxis.call(self, self.pointerEvent); 4203 } 4204 } 4205 4206 if (temp === "y") { 4207 yChange = 0; 4208 } else if (temp === "x") { 4209 xChange = 0; 4210 } 4211 } 4212 4213 x = _round(startElementX + xChange * dragTolerance); 4214 y = _round(startElementY + yChange * dragTolerance); 4215 } 4216 4217 if ((snapX || snapY || snapXY) && (self.x !== x || self.y !== y && !rotationMode)) { 4218 if (snapXY) { 4219 _temp1.x = x; 4220 _temp1.y = y; 4221 temp = snapXY(_temp1); 4222 x = _round(temp.x); 4223 y = _round(temp.y); 4224 } 4225 4226 if (snapX) { 4227 x = _round(snapX(x)); 4228 } 4229 4230 if (snapY) { 4231 y = _round(snapY(y)); 4232 } 4233 } else if (hasBounds) { 4234 if (x > maxX) { 4235 x = maxX + Math.round((x - maxX) * edgeTolerance); 4236 } else if (x < minX) { 4237 x = minX + Math.round((x - minX) * edgeTolerance); 4238 } 4239 4240 if (!rotationMode) { 4241 if (y > maxY) { 4242 y = Math.round(maxY + (y - maxY) * edgeTolerance); 4243 } else if (y < minY) { 4244 y = Math.round(minY + (y - minY) * edgeTolerance); 4245 } 4246 } 4247 } 4248 4249 if (self.x !== x || self.y !== y && !rotationMode) { 4250 if (rotationMode) { 4251 self.endRotation = self.x = self.endX = x; 4252 dirty = true; 4253 } else { 4254 if (allowY) { 4255 self.y = self.endY = y; 4256 dirty = true; //a flag that indicates we need to render the target next time the TweenLite.ticker dispatches a "tick" event (typically on a requestAnimationFrame) - this is a performance optimization (we shouldn't render on every move because sometimes many move events can get dispatched between screen refreshes, and that'd be wasteful to render every time) 4257 } 4258 4259 if (allowX) { 4260 self.x = self.endX = x; 4261 dirty = true; 4262 } 4263 } 4264 4265 if (!invokeOnMove || _dispatchEvent(self, "move", "onMove") !== false) { 4266 if (!self.isDragging && self.isPressed) { 4267 self.isDragging = true; 4268 4269 _dispatchEvent(self, "dragstart", "onDragStart"); 4270 } 4271 } else { 4272 //revert because the onMove returned false! 4273 self.pointerX = prevPointerX; 4274 self.pointerY = prevPointerY; 4275 startElementY = prevStartElementY; 4276 self.x = prevX; 4277 self.y = prevY; 4278 self.endX = prevEndX; 4279 self.endY = prevEndY; 4280 self.endRotation = prevEndRotation; 4281 dirty = prevDirty; 4282 } 4283 } 4284 }, 4285 //called when the mouse/touch is released 4286 onRelease = function onRelease(e, force) { 4287 if (!enabled || !self.isPressed || e && touchID != null && !force && (e.pointerId && e.pointerId !== touchID && e.target !== target || e.changedTouches && !_hasTouchID(e.changedTouches, touchID))) { 4288 //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch) 4289 isPreventingDefault && e && enabled && _preventDefault(e); // in some browsers, we must listen for multiple event types like touchend, pointerup, mouseup. The first time this function is called, we record whether or not we _preventDefault() so that on duplicate calls, we can do the same if necessary. 4290 4291 return; 4292 } 4293 4294 self.isPressed = false; 4295 var originalEvent = e, 4296 wasDragging = self.isDragging, 4297 isContextMenuRelease = self.vars.allowContextMenu && e && (e.ctrlKey || e.which > 2), 4298 placeholderDelayedCall = gsap.delayedCall(0.001, removePlaceholder), 4299 touches, 4300 i, 4301 syntheticEvent, 4302 eventTarget, 4303 syntheticClick; 4304 4305 if (touchEventTarget) { 4306 _removeListener(touchEventTarget, "touchend", onRelease); 4307 4308 _removeListener(touchEventTarget, "touchmove", onMove); 4309 4310 _removeListener(touchEventTarget, "touchcancel", onRelease); 4311 4312 _removeListener(ownerDoc, "touchstart", _onMultiTouchDocument); 4313 } else { 4314 _removeListener(ownerDoc, "mousemove", onMove); 4315 } 4316 4317 _removeListener(_win, "touchforcechange", _preventDefault); 4318 4319 if (!_supportsPointer || !touchEventTarget) { 4320 _removeListener(ownerDoc, "mouseup", onRelease); 4321 4322 e && e.target && _removeListener(e.target, "mouseup", onRelease); 4323 } 4324 4325 dirty = false; 4326 4327 if (isClicking && !isContextMenuRelease) { 4328 if (e) { 4329 _removeListener(e.target, "change", onRelease); 4330 4331 self.pointerEvent = originalEvent; 4332 } 4333 4334 _setSelectable(triggers, false); 4335 4336 _dispatchEvent(self, "release", "onRelease"); 4337 4338 _dispatchEvent(self, "click", "onClick"); 4339 4340 isClicking = false; 4341 return; 4342 } 4343 4344 _removeFromRenderQueue(render); 4345 4346 if (!rotationMode) { 4347 i = triggers.length; 4348 4349 while (--i > -1) { 4350 _setStyle(triggers[i], "cursor", vars.cursor || (vars.cursor !== false ? _defaultCursor : null)); 4351 } 4352 } 4353 4354 if (wasDragging) { 4355 dragEndTime = _lastDragTime = _getTime(); 4356 self.isDragging = false; 4357 } 4358 4359 _dragCount--; 4360 4361 if (e) { 4362 touches = e.changedTouches; 4363 4364 if (touches) { 4365 //touch events store the data slightly differently 4366 e = touches[0]; 4367 4368 if (e !== touch && e.identifier !== touchID) { 4369 //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) 4370 i = touches.length; 4371 4372 while (--i > -1 && (e = touches[i]).identifier !== touchID && e.target !== target) {} 4373 4374 if (i < 0) { 4375 return; 4376 } 4377 } 4378 } 4379 4380 self.pointerEvent = originalEvent; 4381 self.pointerX = e.pageX; 4382 self.pointerY = e.pageY; 4383 } 4384 4385 if (isContextMenuRelease && originalEvent) { 4386 _preventDefault(originalEvent); 4387 4388 isPreventingDefault = true; 4389 4390 _dispatchEvent(self, "release", "onRelease"); 4391 } else if (originalEvent && !wasDragging) { 4392 isPreventingDefault = false; 4393 4394 if (interrupted && (vars.snap || vars.bounds)) { 4395 //otherwise, if the user clicks on the object while it's animating to a snapped position, and then releases without moving 3 pixels, it will just stay there (it should animate/snap) 4396 animate(vars.inertia || vars.throwProps); 4397 } 4398 4399 _dispatchEvent(self, "release", "onRelease"); 4400 4401 if ((!_isAndroid || originalEvent.type !== "touchmove") && originalEvent.type.indexOf("cancel") === -1) { 4402 //to accommodate native scrolling on Android devices, we have to immediately call onRelease() on the first touchmove event, but that shouldn't trigger a "click". 4403 _dispatchEvent(self, "click", "onClick"); 4404 4405 if (_getTime() - clickTime < 300) { 4406 _dispatchEvent(self, "doubleclick", "onDoubleClick"); 4407 } 4408 4409 eventTarget = originalEvent.target || target; //old IE uses srcElement 4410 4411 clickTime = _getTime(); 4412 4413 syntheticClick = function syntheticClick() { 4414 // some browsers (like Firefox) won't trust script-generated clicks, so if the user tries to click on a video to play it, for example, it simply won't work. Since a regular "click" event will most likely be generated anyway (one that has its isTrusted flag set to true), we must slightly delay our script-generated click so that the "real"/trusted one is prioritized. Remember, when there are duplicate events in quick succession, we suppress all but the first one. Some browsers don't even trigger the "real" one at all, so our synthetic one is a safety valve that ensures that no matter what, a click event does get dispatched. 4415 if (clickTime !== clickDispatch && self.enabled() && !self.isPressed && !originalEvent.defaultPrevented) { 4416 if (eventTarget.click) { 4417 //some browsers (like mobile Safari) don't properly trigger the click event 4418 eventTarget.click(); 4419 } else if (ownerDoc.createEvent) { 4420 syntheticEvent = ownerDoc.createEvent("MouseEvents"); 4421 syntheticEvent.initMouseEvent("click", true, true, _win, 1, self.pointerEvent.screenX, self.pointerEvent.screenY, self.pointerX, self.pointerY, false, false, false, false, 0, null); 4422 eventTarget.dispatchEvent(syntheticEvent); 4423 } 4424 } 4425 }; 4426 4427 if (!_isAndroid && !originalEvent.defaultPrevented) { 4428 //iOS Safari requires the synthetic click to happen immediately or else it simply won't work, but Android doesn't play nice. 4429 gsap.delayedCall(0.05, syntheticClick); //in addition to the iOS bug workaround, there's a Firefox issue with clicking on things like a video to play, so we must fake a click event in a slightly delayed fashion. Previously, we listened for the "click" event with "capture" false which solved the video-click-to-play issue, but it would allow the "click" event to be dispatched twice like if you were using a jQuery.click() because that was handled in the capture phase, thus we had to switch to the capture phase to avoid the double-dispatching, but do the delayed synthetic click. Don't fire it too fast (like 0.00001) because we want to give the native event a chance to fire first as it's "trusted". 4430 } 4431 } 4432 } else { 4433 animate(vars.inertia || vars.throwProps); //will skip if inertia/throwProps isn't defined or IntertiaPlugin isn't loaded. 4434 4435 if (!self.allowEventDefault && originalEvent && (vars.dragClickables !== false || !isClickable.call(self, originalEvent.target)) && wasDragging && (!allowNativeTouchScrolling || touchDragAxis && allowNativeTouchScrolling === touchDragAxis) && originalEvent.cancelable !== false) { 4436 isPreventingDefault = true; 4437 4438 _preventDefault(originalEvent); 4439 } else { 4440 isPreventingDefault = false; 4441 } 4442 4443 _dispatchEvent(self, "release", "onRelease"); 4444 } 4445 4446 isTweening() && placeholderDelayedCall.duration(self.tween.duration()); //sync the timing so that the placeholder DIV gets 4447 4448 wasDragging && _dispatchEvent(self, "dragend", "onDragEnd"); 4449 return true; 4450 }, 4451 updateScroll = function updateScroll(e) { 4452 if (e && self.isDragging && !scrollProxy) { 4453 var parent = e.target || target.parentNode, 4454 deltaX = parent.scrollLeft - parent._gsScrollX, 4455 deltaY = parent.scrollTop - parent._gsScrollY; 4456 4457 if (deltaX || deltaY) { 4458 if (matrix) { 4459 startPointerX -= deltaX * matrix.a + deltaY * matrix.c; 4460 startPointerY -= deltaY * matrix.d + deltaX * matrix.b; 4461 } else { 4462 startPointerX -= deltaX; 4463 startPointerY -= deltaY; 4464 } 4465 4466 parent._gsScrollX += deltaX; 4467 parent._gsScrollY += deltaY; 4468 setPointerPosition(self.pointerX, self.pointerY); 4469 } 4470 } 4471 }, 4472 onClick = function onClick(e) { 4473 //this was a huge pain in the neck to align all the various browsers and their behaviors. Chrome, Firefox, Safari, Opera, Android, and Microsoft Edge all handle events differently! Some will only trigger native behavior (like checkbox toggling) from trusted events. Others don't even support isTrusted, but require 2 events to flow through before triggering native behavior. Edge treats everything as trusted but also mandates that 2 flow through to trigger the correct native behavior. 4474 var time = _getTime(), 4475 recentlyClicked = time - clickTime < 40, 4476 recentlyDragged = time - dragEndTime < 40, 4477 alreadyDispatched = recentlyClicked && clickDispatch === clickTime, 4478 defaultPrevented = self.pointerEvent && self.pointerEvent.defaultPrevented, 4479 alreadyDispatchedTrusted = recentlyClicked && trustedClickDispatch === clickTime, 4480 trusted = e.isTrusted || e.isTrusted == null && recentlyClicked && alreadyDispatched; //note: Safari doesn't support isTrusted, and it won't properly execute native behavior (like toggling checkboxes) on the first synthetic "click" event - we must wait for the 2nd and treat it as trusted (but stop propagation at that point). Confusing, I know. Don't you love cross-browser compatibility challenges? 4481 4482 4483 if ((alreadyDispatched || recentlyDragged && self.vars.suppressClickOnDrag !== false) && e.stopImmediatePropagation) { 4484 e.stopImmediatePropagation(); 4485 } 4486 4487 if (recentlyClicked && !(self.pointerEvent && self.pointerEvent.defaultPrevented) && (!alreadyDispatched || trusted && !alreadyDispatchedTrusted)) { 4488 //let the first click pass through unhindered. Let the next one only if it's trusted, then no more (stop quick-succession ones) 4489 if (trusted && alreadyDispatched) { 4490 trustedClickDispatch = clickTime; 4491 } 4492 4493 clickDispatch = clickTime; 4494 return; 4495 } 4496 4497 if (self.isPressed || recentlyDragged || recentlyClicked) { 4498 if (!trusted || !e.detail || !recentlyClicked || defaultPrevented) { 4499 _preventDefault(e); 4500 } 4501 } 4502 4503 if (!recentlyClicked && !recentlyDragged) { 4504 // for script-triggered event dispatches, like element.click() 4505 e && e.target && (self.pointerEvent = e); 4506 4507 _dispatchEvent(self, "click", "onClick"); 4508 } 4509 }, 4510 localizePoint = function localizePoint(p) { 4511 return matrix ? { 4512 x: p.x * matrix.a + p.y * matrix.c + matrix.e, 4513 y: p.x * matrix.b + p.y * matrix.d + matrix.f 4514 } : { 4515 x: p.x, 4516 y: p.y 4517 }; 4518 }; 4519 4520 old = Draggable.get(target); 4521 old && old.kill(); // avoids duplicates (an element can only be controlled by one Draggable) 4522 //give the user access to start/stop dragging... 4523 4524 _this2.startDrag = function (event, align) { 4525 var r1, r2, p1, p2; 4526 onPress(event || self.pointerEvent, true); //if the pointer isn't on top of the element, adjust things accordingly 4527 4528 if (align && !self.hitTest(event || self.pointerEvent)) { 4529 r1 = _parseRect(event || self.pointerEvent); 4530 r2 = _parseRect(target); 4531 p1 = localizePoint({ 4532 x: r1.left + r1.width / 2, 4533 y: r1.top + r1.height / 2 4534 }); 4535 p2 = localizePoint({ 4536 x: r2.left + r2.width / 2, 4537 y: r2.top + r2.height / 2 4538 }); 4539 startPointerX -= p1.x - p2.x; 4540 startPointerY -= p1.y - p2.y; 4541 } 4542 4543 if (!self.isDragging) { 4544 self.isDragging = true; 4545 4546 _dispatchEvent(self, "dragstart", "onDragStart"); 4547 } 4548 }; 4549 4550 _this2.drag = onMove; 4551 4552 _this2.endDrag = function (e) { 4553 return onRelease(e || self.pointerEvent, true); 4554 }; 4555 4556 _this2.timeSinceDrag = function () { 4557 return self.isDragging ? 0 : (_getTime() - dragEndTime) / 1000; 4558 }; 4559 4560 _this2.timeSinceClick = function () { 4561 return (_getTime() - clickTime) / 1000; 4562 }; 4563 4564 _this2.hitTest = function (target, threshold) { 4565 return Draggable.hitTest(self.target, target, threshold); 4566 }; 4567 4568 _this2.getDirection = function (from, diagonalThreshold) { 4569 //from can be "start" (default), "velocity", or an element 4570 var mode = from === "velocity" && InertiaPlugin ? from : _isObject(from) && !rotationMode ? "element" : "start", 4571 xChange, 4572 yChange, 4573 ratio, 4574 direction, 4575 r1, 4576 r2; 4577 4578 if (mode === "element") { 4579 r1 = _parseRect(self.target); 4580 r2 = _parseRect(from); 4581 } 4582 4583 xChange = mode === "start" ? self.x - startElementX : mode === "velocity" ? InertiaPlugin.getVelocity(target, xProp) : r1.left + r1.width / 2 - (r2.left + r2.width / 2); 4584 4585 if (rotationMode) { 4586 return xChange < 0 ? "counter-clockwise" : "clockwise"; 4587 } else { 4588 diagonalThreshold = diagonalThreshold || 2; 4589 yChange = mode === "start" ? self.y - startElementY : mode === "velocity" ? InertiaPlugin.getVelocity(target, yProp) : r1.top + r1.height / 2 - (r2.top + r2.height / 2); 4590 ratio = Math.abs(xChange / yChange); 4591 direction = ratio < 1 / diagonalThreshold ? "" : xChange < 0 ? "left" : "right"; 4592 4593 if (ratio < diagonalThreshold) { 4594 if (direction !== "") { 4595 direction += "-"; 4596 } 4597 4598 direction += yChange < 0 ? "up" : "down"; 4599 } 4600 } 4601 4602 return direction; 4603 }; 4604 4605 _this2.applyBounds = function (newBounds, sticky) { 4606 var x, y, forceZeroVelocity, e, parent, isRoot; 4607 4608 if (newBounds && vars.bounds !== newBounds) { 4609 vars.bounds = newBounds; 4610 return self.update(true, sticky); 4611 } 4612 4613 syncXY(true); 4614 calculateBounds(); 4615 4616 if (hasBounds && !isTweening()) { 4617 x = self.x; 4618 y = self.y; 4619 4620 if (x > maxX) { 4621 x = maxX; 4622 } else if (x < minX) { 4623 x = minX; 4624 } 4625 4626 if (y > maxY) { 4627 y = maxY; 4628 } else if (y < minY) { 4629 y = minY; 4630 } 4631 4632 if (self.x !== x || self.y !== y) { 4633 forceZeroVelocity = true; 4634 self.x = self.endX = x; 4635 4636 if (rotationMode) { 4637 self.endRotation = x; 4638 } else { 4639 self.y = self.endY = y; 4640 } 4641 4642 dirty = true; 4643 render(true); 4644 4645 if (self.autoScroll && !self.isDragging) { 4646 _recordMaxScrolls(target.parentNode); 4647 4648 e = target; 4649 _windowProxy.scrollTop = _win.pageYOffset != null ? _win.pageYOffset : ownerDoc.documentElement.scrollTop != null ? ownerDoc.documentElement.scrollTop : ownerDoc.body.scrollTop; 4650 _windowProxy.scrollLeft = _win.pageXOffset != null ? _win.pageXOffset : ownerDoc.documentElement.scrollLeft != null ? ownerDoc.documentElement.scrollLeft : ownerDoc.body.scrollLeft; 4651 4652 while (e && !isRoot) { 4653 //walk up the chain and sense wherever the scrollTop/scrollLeft exceeds the maximum. 4654 isRoot = _isRoot(e.parentNode); 4655 parent = isRoot ? _windowProxy : e.parentNode; 4656 4657 if (allowY && parent.scrollTop > parent._gsMaxScrollY) { 4658 parent.scrollTop = parent._gsMaxScrollY; 4659 } 4660 4661 if (allowX && parent.scrollLeft > parent._gsMaxScrollX) { 4662 parent.scrollLeft = parent._gsMaxScrollX; 4663 } 4664 4665 e = parent; 4666 } 4667 } 4668 } 4669 4670 if (self.isThrowing && (forceZeroVelocity || self.endX > maxX || self.endX < minX || self.endY > maxY || self.endY < minY)) { 4671 animate(vars.inertia || vars.throwProps, forceZeroVelocity); 4672 } 4673 } 4674 4675 return self; 4676 }; 4677 4678 _this2.update = function (applyBounds, sticky, ignoreExternalChanges) { 4679 var x = self.x, 4680 y = self.y; 4681 updateMatrix(!sticky); 4682 4683 if (applyBounds) { 4684 self.applyBounds(); 4685 } else { 4686 dirty && ignoreExternalChanges && render(true); 4687 syncXY(true); 4688 } 4689 4690 if (sticky) { 4691 setPointerPosition(self.pointerX, self.pointerY); 4692 dirty && render(true); 4693 } 4694 4695 if (self.isPressed && !sticky && (allowX && Math.abs(x - self.x) > 0.01 || allowY && Math.abs(y - self.y) > 0.01 && !rotationMode)) { 4696 recordStartPositions(); 4697 } 4698 4699 if (self.autoScroll) { 4700 _recordMaxScrolls(target.parentNode, self.isDragging); 4701 4702 checkAutoScrollBounds = self.isDragging; 4703 render(true); //in case reparenting occurred. 4704 4705 _removeScrollListener(target, updateScroll); 4706 4707 _addScrollListener(target, updateScroll); 4708 } 4709 4710 return self; 4711 }; 4712 4713 _this2.enable = function (type) { 4714 var setVars = { 4715 lazy: true 4716 }, 4717 id, 4718 i, 4719 trigger; 4720 4721 if (!rotationMode && vars.cursor !== false) { 4722 setVars.cursor = vars.cursor || _defaultCursor; 4723 } 4724 4725 if (gsap.utils.checkPrefix("touchCallout")) { 4726 setVars.touchCallout = "none"; 4727 } 4728 4729 if (type !== "soft") { 4730 _setTouchActionForAllDescendants(triggers, allowX === allowY ? "none" : vars.allowNativeTouchScrolling && target.scrollHeight === target.clientHeight === (target.scrollWidth === target.clientHeight) || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x"); // Some browsers like Internet Explorer will fire a pointercancel event when the user attempts to drag when touchAction is "manipulate" because it's perceived as a pan. If the element has scrollable content in only one direction, we should use pan-x or pan-y accordingly so that the pointercancel doesn't prevent dragging. 4731 4732 4733 i = triggers.length; 4734 4735 while (--i > -1) { 4736 trigger = triggers[i]; 4737 _supportsPointer || _addListener(trigger, "mousedown", onPress); 4738 4739 _addListener(trigger, "touchstart", onPress); 4740 4741 _addListener(trigger, "click", onClick, true); //note: used to pass true for capture but it prevented click-to-play-video functionality in Firefox. 4742 4743 4744 gsap.set(trigger, setVars); 4745 4746 if (trigger.getBBox && trigger.ownerSVGElement) { 4747 // a bug in chrome doesn't respect touch-action on SVG elements - it only works if we set it on the parent SVG. 4748 gsap.set(trigger.ownerSVGElement, { 4749 touchAction: allowX === allowY ? "none" : vars.allowNativeTouchScrolling || vars.allowEventDefault ? "manipulation" : allowX ? "pan-y" : "pan-x" 4750 }); 4751 } 4752 4753 vars.allowContextMenu || _addListener(trigger, "contextmenu", onContextMenu); 4754 } 4755 4756 _setSelectable(triggers, false); 4757 } 4758 4759 _addScrollListener(target, updateScroll); 4760 4761 enabled = true; 4762 4763 if (InertiaPlugin && type !== "soft") { 4764 InertiaPlugin.track(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left"); 4765 } 4766 4767 target._gsDragID = id = "d" + _lookupCount++; 4768 _lookup[id] = self; 4769 4770 if (scrollProxy) { 4771 scrollProxy.enable(); 4772 scrollProxy.element._gsDragID = id; 4773 } 4774 4775 (vars.bounds || rotationMode) && recordStartPositions(); 4776 vars.bounds && self.applyBounds(); 4777 return self; 4778 }; 4779 4780 _this2.disable = function (type) { 4781 var dragging = self.isDragging, 4782 i, 4783 trigger; 4784 4785 if (!rotationMode) { 4786 i = triggers.length; 4787 4788 while (--i > -1) { 4789 _setStyle(triggers[i], "cursor", null); 4790 } 4791 } 4792 4793 if (type !== "soft") { 4794 _setTouchActionForAllDescendants(triggers, null); 4795 4796 i = triggers.length; 4797 4798 while (--i > -1) { 4799 trigger = triggers[i]; 4800 4801 _setStyle(trigger, "touchCallout", null); 4802 4803 _removeListener(trigger, "mousedown", onPress); 4804 4805 _removeListener(trigger, "touchstart", onPress); 4806 4807 _removeListener(trigger, "click", onClick); 4808 4809 _removeListener(trigger, "contextmenu", onContextMenu); 4810 } 4811 4812 _setSelectable(triggers, true); 4813 4814 if (touchEventTarget) { 4815 _removeListener(touchEventTarget, "touchcancel", onRelease); 4816 4817 _removeListener(touchEventTarget, "touchend", onRelease); 4818 4819 _removeListener(touchEventTarget, "touchmove", onMove); 4820 } 4821 4822 _removeListener(ownerDoc, "mouseup", onRelease); 4823 4824 _removeListener(ownerDoc, "mousemove", onMove); 4825 } 4826 4827 _removeScrollListener(target, updateScroll); 4828 4829 enabled = false; 4830 InertiaPlugin && type !== "soft" && InertiaPlugin.untrack(scrollProxy || target, xyMode ? "x,y" : rotationMode ? "rotation" : "top,left"); 4831 scrollProxy && scrollProxy.disable(); 4832 4833 _removeFromRenderQueue(render); 4834 4835 self.isDragging = self.isPressed = isClicking = false; 4836 dragging && _dispatchEvent(self, "dragend", "onDragEnd"); 4837 return self; 4838 }; 4839 4840 _this2.enabled = function (value, type) { 4841 return arguments.length ? value ? self.enable(type) : self.disable(type) : enabled; 4842 }; 4843 4844 _this2.kill = function () { 4845 self.isThrowing = false; 4846 self.tween && self.tween.kill(); 4847 self.disable(); 4848 gsap.set(triggers, { 4849 clearProps: "userSelect" 4850 }); 4851 delete _lookup[target._gsDragID]; 4852 return self; 4853 }; 4854 4855 if (~type.indexOf("scroll")) { 4856 scrollProxy = _this2.scrollProxy = new ScrollProxy(target, _extend({ 4857 onKill: function onKill() { 4858 //ScrollProxy's onKill() gets called if/when the ScrollProxy senses that the user interacted with the scroll position manually (like using the scrollbar). IE9 doesn't fire the "mouseup" properly when users drag the scrollbar of an element, so this works around that issue. 4859 self.isPressed && onRelease(null); 4860 } 4861 }, vars)); //a bug in many Android devices' stock browser causes scrollTop to get forced back to 0 after it is altered via JS, so we set overflow to "hidden" on mobile/touch devices (they hide the scroll bar anyway). That works around the bug. (This bug is discussed at https://code.google.com/p/android/issues/detail?id=19625) 4862 4863 target.style.overflowY = allowY && !_isTouchDevice ? "auto" : "hidden"; 4864 target.style.overflowX = allowX && !_isTouchDevice ? "auto" : "hidden"; 4865 target = scrollProxy.content; 4866 } 4867 4868 if (rotationMode) { 4869 killProps.rotation = 1; 4870 } else { 4871 if (allowX) { 4872 killProps[xProp] = 1; 4873 } 4874 4875 if (allowY) { 4876 killProps[yProp] = 1; 4877 } 4878 } 4879 4880 gsCache.force3D = "force3D" in vars ? vars.force3D : true; //otherwise, normal dragging would be in 2D and then as soon as it's released and there's an inertia tween, it'd jump to 3D which can create an initial jump due to the work the browser must to do layerize it. 4881 4882 _this2.enable(); 4883 4884 return _this2; 4885 } 4886 4887 Draggable.register = function register(core) { 4888 gsap = core; 4889 4890 _initCore(); 4891 }; 4892 4893 Draggable.create = function create(targets, vars) { 4894 _coreInitted || _initCore(true); 4895 return _toArray(targets).map(function (target) { 4896 return new Draggable(target, vars); 4897 }); 4898 }; 4899 4900 Draggable.get = function get(target) { 4901 return _lookup[(_toArray(target)[0] || {})._gsDragID]; 4902 }; 4903 4904 Draggable.timeSinceDrag = function timeSinceDrag() { 4905 return (_getTime() - _lastDragTime) / 1000; 4906 }; 4907 4908 Draggable.hitTest = function hitTest(obj1, obj2, threshold) { 4909 if (obj1 === obj2) { 4910 return false; 4911 } 4912 4913 var r1 = _parseRect(obj1), 4914 r2 = _parseRect(obj2), 4915 top = r1.top, 4916 left = r1.left, 4917 right = r1.right, 4918 bottom = r1.bottom, 4919 width = r1.width, 4920 height = r1.height, 4921 isOutside = r2.left > right || r2.right < left || r2.top > bottom || r2.bottom < top, 4922 overlap, 4923 area, 4924 isRatio; 4925 4926 if (isOutside || !threshold) { 4927 return !isOutside; 4928 } 4929 4930 isRatio = (threshold + "").indexOf("%") !== -1; 4931 threshold = parseFloat(threshold) || 0; 4932 overlap = { 4933 left: Math.max(left, r2.left), 4934 top: Math.max(top, r2.top) 4935 }; 4936 overlap.width = Math.min(right, r2.right) - overlap.left; 4937 overlap.height = Math.min(bottom, r2.bottom) - overlap.top; 4938 4939 if (overlap.width < 0 || overlap.height < 0) { 4940 return false; 4941 } 4942 4943 if (isRatio) { 4944 threshold *= 0.01; 4945 area = overlap.width * overlap.height; 4946 return area >= width * height * threshold || area >= r2.width * r2.height * threshold; 4947 } 4948 4949 return overlap.width > threshold && overlap.height > threshold; 4950 }; 4951 4952 return Draggable; 4953}(EventDispatcher); 4954 4955_setDefaults(Draggable.prototype, { 4956 pointerX: 0, 4957 pointerY: 0, 4958 startX: 0, 4959 startY: 0, 4960 deltaX: 0, 4961 deltaY: 0, 4962 isDragging: false, 4963 isPressed: false 4964}); 4965 4966Draggable.zIndex = 1000; 4967Draggable.version = "3.6.0"; 4968_getGSAP() && gsap.registerPlugin(Draggable); 4969 4970 4971/***/ }), 4972
vendor: 10,725 bytes, lines 4973-5284
4973/***/ "./node_modules/gsap/DrawSVGPlugin.js": 4974/*!********************************************!*\ 4975 !*** ./node_modules/gsap/DrawSVGPlugin.js ***! 4976 \********************************************/ 4977/*! exports provided: DrawSVGPlugin, default */ 4978/***/ (function(module, __webpack_exports__, __webpack_require__) { 4979 4980"use strict"; 4981__webpack_require__.r(__webpack_exports__); 4982/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DrawSVGPlugin", function() { return DrawSVGPlugin; }); 4983/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return DrawSVGPlugin; }); 4984/*! 4985 * DrawSVGPlugin 3.6.0 4986 * https://greensock.com 4987 * 4988 * @license Copyright 2008-2021, GreenSock. All rights reserved. 4989 * Subject to the terms at https://greensock.com/standard-license or for 4990 * Club GreenSock members, the agreement issued with that membership. 4991 * @author: Jack Doyle, [email protected] 4992*/ 4993 4994/* eslint-disable */ 4995var gsap, 4996 _toArray, 4997 _doc, 4998 _win, 4999 _isEdge, 5000 _coreInitted, 5001 _windowExists = function _windowExists() { 5002 return typeof window !== "undefined"; 5003}, 5004 _getGSAP = function _getGSAP() { 5005 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 5006}, 5007 _numExp = /[-+=\.]*\d+[\.e\-\+]*\d*[e\-\+]*\d*/gi, 5008 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 5009_types = { 5010 rect: ["width", "height"], 5011 circle: ["r", "r"], 5012 ellipse: ["rx", "ry"], 5013 line: ["x2", "y2"] 5014}, 5015 _round = function _round(value) { 5016 return Math.round(value * 10000) / 10000; 5017}, 5018 _parseNum = function _parseNum(value) { 5019 return parseFloat(value) || 0; 5020}, 5021 _parseSingleVal = function _parseSingleVal(value, length) { 5022 var num = _parseNum(value); 5023 5024 return ~value.indexOf("%") ? num / 100 * length : num; 5025}, 5026 _getAttributeAsNumber = function _getAttributeAsNumber(target, attr) { 5027 return _parseNum(target.getAttribute(attr)); 5028}, 5029 _sqrt = Math.sqrt, 5030 _getDistance = function _getDistance(x1, y1, x2, y2, scaleX, scaleY) { 5031 return _sqrt(Math.pow((_parseNum(x2) - _parseNum(x1)) * scaleX, 2) + Math.pow((_parseNum(y2) - _parseNum(y1)) * scaleY, 2)); 5032}, 5033 _warn = function _warn(message) { 5034 return console.warn(message); 5035}, 5036 _hasNonScalingStroke = function _hasNonScalingStroke(target) { 5037 return target.getAttribute("vector-effect") === "non-scaling-stroke"; 5038}, 5039 _bonusValidated = 1, 5040 //<name>DrawSVGPlugin</name> 5041//accepts values like "100%" or "20% 80%" or "20 50" and parses it into an absolute start and end position on the line/stroke based on its length. Returns an an array with the start and end values, like [0, 243] 5042_parse = function _parse(value, length, defaultStart) { 5043 var i = value.indexOf(" "), 5044 s, 5045 e; 5046 5047 if (i < 0) { 5048 s = defaultStart !== undefined ? defaultStart + "" : value; 5049 e = value; 5050 } else { 5051 s = value.substr(0, i); 5052 e = value.substr(i + 1); 5053 } 5054 5055 s = _parseSingleVal(s, length); 5056 e = _parseSingleVal(e, length); 5057 return s > e ? [e, s] : [s, e]; 5058}, 5059 _getLength = function _getLength(target) { 5060 target = _toArray(target)[0]; 5061 5062 if (!target) { 5063 return 0; 5064 } 5065 5066 var type = target.tagName.toLowerCase(), 5067 style = target.style, 5068 scaleX = 1, 5069 scaleY = 1, 5070 length, 5071 bbox, 5072 points, 5073 prevPoint, 5074 i, 5075 rx, 5076 ry; 5077 5078 if (_hasNonScalingStroke(target)) { 5079 //non-scaling-stroke basically scales the shape and then strokes it at the screen-level (after transforms), thus we need to adjust the length accordingly. 5080 scaleY = target.getScreenCTM(); 5081 scaleX = _sqrt(scaleY.a * scaleY.a + scaleY.b * scaleY.b); 5082 scaleY = _sqrt(scaleY.d * scaleY.d + scaleY.c * scaleY.c); 5083 } 5084 5085 try { 5086 //IE bug: calling <path>.getTotalLength() locks the repaint area of the stroke to whatever its current dimensions are on that frame/tick. To work around that, we must call getBBox() to force IE to recalculate things. 5087 bbox = target.getBBox(); //solely for fixing bug in IE - we don't actually use the bbox. 5088 } catch (e) { 5089 //firefox has a bug that throws an error if the element isn't visible. 5090 _warn("Some browsers won't measure invisible elements (like display:none or masks inside defs)."); 5091 } 5092 5093 var _ref = bbox || { 5094 x: 0, 5095 y: 0, 5096 width: 0, 5097 height: 0 5098 }, 5099 x = _ref.x, 5100 y = _ref.y, 5101 width = _ref.width, 5102 height = _ref.height; 5103 5104 if ((!bbox || !width && !height) && _types[type]) { 5105 //if the element isn't visible, try to discern width/height using its attributes. 5106 width = _getAttributeAsNumber(target, _types[type][0]); 5107 height = _getAttributeAsNumber(target, _types[type][1]); 5108 5109 if (type !== "rect" && type !== "line") { 5110 //double the radius for circles and ellipses 5111 width *= 2; 5112 height *= 2; 5113 } 5114 5115 if (type === "line") { 5116 x = _getAttributeAsNumber(target, "x1"); 5117 y = _getAttributeAsNumber(target, "y1"); 5118 width = Math.abs(width - x); 5119 height = Math.abs(height - y); 5120 } 5121 } 5122 5123 if (type === "path") { 5124 prevPoint = style.strokeDasharray; 5125 style.strokeDasharray = "none"; 5126 length = target.getTotalLength() || 0; 5127 scaleX !== scaleY && _warn("Warning: <path> length cannot be measured when vector-effect is non-scaling-stroke and the element isn't proportionally scaled."); 5128 length *= (scaleX + scaleY) / 2; 5129 style.strokeDasharray = prevPoint; 5130 } else if (type === "rect") { 5131 length = width * 2 * scaleX + height * 2 * scaleY; 5132 } else if (type === "line") { 5133 length = _getDistance(x, y, x + width, y + height, scaleX, scaleY); 5134 } else if (type === "polyline" || type === "polygon") { 5135 points = target.getAttribute("points").match(_numExp) || []; 5136 type === "polygon" && points.push(points[0], points[1]); 5137 length = 0; 5138 5139 for (i = 2; i < points.length; i += 2) { 5140 length += _getDistance(points[i - 2], points[i - 1], points[i], points[i + 1], scaleX, scaleY) || 0; 5141 } 5142 } else if (type === "circle" || type === "ellipse") { 5143 rx = width / 2 * scaleX; 5144 ry = height / 2 * scaleY; 5145 length = Math.PI * (3 * (rx + ry) - _sqrt((3 * rx + ry) * (rx + 3 * ry))); 5146 } 5147 5148 return length || 0; 5149}, 5150 _getPosition = function _getPosition(target, length) { 5151 target = _toArray(target)[0]; 5152 5153 if (!target) { 5154 return [0, 0]; 5155 } 5156 5157 length || (length = _getLength(target) + 1); 5158 5159 var cs = _win.getComputedStyle(target), 5160 dash = cs.strokeDasharray || "", 5161 offset = _parseNum(cs.strokeDashoffset), 5162 i = dash.indexOf(","); 5163 5164 i < 0 && (i = dash.indexOf(" ")); 5165 dash = i < 0 ? length : _parseNum(dash.substr(0, i)); 5166 dash > length && (dash = length); 5167 return [-offset || 0, dash - offset || 0]; 5168}, 5169 _initCore = function _initCore() { 5170 if (_windowExists()) { 5171 _doc = document; 5172 _win = window; 5173 _coreInitted = gsap = _getGSAP(); 5174 _toArray = gsap.utils.toArray; 5175 _isEdge = ((_win.navigator || {}).userAgent || "").indexOf("Edge") !== -1; //Microsoft Edge has a bug that causes it not to redraw the path correctly if the stroke-linecap is anything other than "butt" (like "round") and it doesn't match the stroke-linejoin. A way to trigger it is to change the stroke-miterlimit, so we'll only do that if/when we have to (to maximize performance) 5176 } 5177}; 5178 5179var DrawSVGPlugin = { 5180 version: "3.6.0", 5181 name: "drawSVG", 5182 register: function register(core) { 5183 gsap = core; 5184 5185 _initCore(); 5186 }, 5187 init: function init(target, value, tween, index, targets) { 5188 if (!target.getBBox) { 5189 return false; 5190 } 5191 5192 _coreInitted || _initCore(); 5193 5194 var length = _getLength(target), 5195 start, 5196 end, 5197 cs; 5198 5199 this._style = target.style; 5200 this._target = target; 5201 5202 if (value + "" === "true") { 5203 value = "0 100%"; 5204 } else if (!value) { 5205 value = "0 0"; 5206 } else if ((value + "").indexOf(" ") === -1) { 5207 value = "0 " + value; 5208 } 5209 5210 start = _getPosition(target, length); 5211 end = _parse(value, length, start[0]); 5212 this._length = _round(length); 5213 this._dash = _round(start[1] - start[0]); //some browsers render artifacts if dash is 0, so we use a very small number in that case. 5214 5215 this._offset = _round(-start[0]); 5216 this._dashPT = this.add(this, "_dash", this._dash, _round(end[1] - end[0])); 5217 this._offsetPT = this.add(this, "_offset", this._offset, _round(-end[0])); 5218 5219 if (_isEdge) { 5220 //to work around a bug in Microsoft Edge, animate the stroke-miterlimit by 0.0001 just to trigger the repaint (unnecessary if it's "round" and stroke-linejoin is also "round"). Imperceptible, relatively high-performance, and effective. Another option was to set the "d" <path> attribute to its current value on every tick, but that seems like it'd be much less performant. 5221 cs = _win.getComputedStyle(target); 5222 5223 if (cs.strokeLinecap !== cs.strokeLinejoin) { 5224 end = _parseNum(cs.strokeMiterlimit); 5225 this.add(target.style, "strokeMiterlimit", end, end + 0.01); 5226 } 5227 } 5228 5229 this._live = _hasNonScalingStroke(target) || ~(value + "").indexOf("live"); 5230 5231 this._props.push("drawSVG"); 5232 5233 return _bonusValidated; 5234 }, 5235 render: function render(ratio, data) { 5236 var pt = data._pt, 5237 style = data._style, 5238 length, 5239 lengthRatio, 5240 dash, 5241 offset; 5242 5243 if (pt) { 5244 //when the element has vector-effect="non-scaling-stroke" and the SVG is resized (like on a window resize), it actually changes the length of the stroke! So we must sense that and make the proper adjustments. 5245 if (data._live) { 5246 length = _getLength(data._target); 5247 5248 if (length !== data._length) { 5249 lengthRatio = length / data._length; 5250 data._length = length; 5251 data._offsetPT.s *= lengthRatio; 5252 data._offsetPT.c *= lengthRatio; 5253 5254 if (data._dashPT) { 5255 data._dashPT.s *= lengthRatio; 5256 data._dashPT.c *= lengthRatio; 5257 } else { 5258 data._dash *= lengthRatio; 5259 } 5260 } 5261 } 5262 5263 while (pt) { 5264 pt.r(ratio, pt.d); 5265 pt = pt._next; 5266 } 5267 5268 dash = data._dash || ratio && ratio !== 1 && 0.0001 || 0; // only let it be zero if it's at the start or end of the tween. 5269 5270 length = data._length - dash + 0.1; 5271 offset = data._offset; 5272 dash && offset && dash + Math.abs(offset % data._length) > data._length - 0.2 && (offset += offset < 0 ? 0.1 : -0.1) && (length += 0.1); 5273 style.strokeDashoffset = dash ? offset : offset + 0.001; 5274 style.strokeDasharray = length < 0.2 ? "none" : dash ? dash + "px," + length + "px" : "0px, 999999px"; 5275 } 5276 }, 5277 getLength: _getLength, 5278 getPosition: _getPosition 5279}; 5280_getGSAP() && gsap.registerPlugin(DrawSVGPlugin); 5281 5282 5283/***/ }), 5284
vendor: 6,272 bytes, lines 5285-5513
5285/***/ "./node_modules/gsap/EasePack.js": 5286/*!***************************************!*\ 5287 !*** ./node_modules/gsap/EasePack.js ***! 5288 \***************************************/ 5289/*! exports provided: SlowMo, ExpoScaleEase, RoughEase, EasePack, default */ 5290/***/ (function(module, __webpack_exports__, __webpack_require__) { 5291 5292"use strict"; 5293__webpack_require__.r(__webpack_exports__); 5294/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SlowMo", function() { return SlowMo; }); 5295/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ExpoScaleEase", function() { return ExpoScaleEase; }); 5296/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "RoughEase", function() { return RoughEase; }); 5297/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EasePack", function() { return EasePack; }); 5298/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return EasePack; }); 5299/*! 5300 * EasePack 3.6.0 5301 * https://greensock.com 5302 * 5303 * @license Copyright 2008-2021, GreenSock. All rights reserved. 5304 * Subject to the terms at https://greensock.com/standard-license or for 5305 * Club GreenSock members, the agreement issued with that membership. 5306 * @author: Jack Doyle, [email protected] 5307*/ 5308 5309/* eslint-disable */ 5310var gsap, 5311 _coreInitted, 5312 _registerEase, 5313 _getGSAP = function _getGSAP() { 5314 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 5315}, 5316 _boolean = function _boolean(value, defaultValue) { 5317 return !!(typeof value === "undefined" ? defaultValue : value && !~(value + "").indexOf("false")); 5318}, 5319 _initCore = function _initCore(core) { 5320 gsap = core || _getGSAP(); 5321 5322 if (gsap) { 5323 _registerEase = gsap.registerEase; //add weighted ease capabilities to standard eases so users can do "power2.inOut(0.8)" for example to push everything toward the "out", or (-0.8) to push it toward the "in" (0 is neutral) 5324 5325 var eases = gsap.parseEase(), 5326 createConfig = function createConfig(ease) { 5327 return function (ratio) { 5328 var y = 0.5 + ratio / 2; 5329 5330 ease.config = function (p) { 5331 return ease(2 * (1 - p) * p * y + p * p); 5332 }; 5333 }; 5334 }, 5335 p; 5336 5337 for (p in eases) { 5338 if (!eases[p].config) { 5339 createConfig(eases[p]); 5340 } 5341 } 5342 5343 _registerEase("slow", SlowMo); 5344 5345 _registerEase("expoScale", ExpoScaleEase); 5346 5347 _registerEase("rough", RoughEase); 5348 5349 for (p in EasePack) { 5350 p !== "version" && gsap.core.globals(p, EasePack[p]); 5351 } 5352 5353 _coreInitted = 1; 5354 } 5355}, 5356 _createSlowMo = function _createSlowMo(linearRatio, power, yoyoMode) { 5357 linearRatio = Math.min(1, linearRatio || 0.7); 5358 5359 var pow = linearRatio < 1 ? power || power === 0 ? power : 0.7 : 0, 5360 p1 = (1 - linearRatio) / 2, 5361 p3 = p1 + linearRatio, 5362 calcEnd = _boolean(yoyoMode); 5363 5364 return function (p) { 5365 var r = p + (0.5 - p) * pow; 5366 return p < p1 ? calcEnd ? 1 - (p = 1 - p / p1) * p : r - (p = 1 - p / p1) * p * p * p * r : p > p3 ? calcEnd ? p === 1 ? 0 : 1 - (p = (p - p3) / p1) * p : r + (p - r) * (p = (p - p3) / p1) * p * p * p : calcEnd ? 1 : r; 5367 }; 5368}, 5369 _createExpoScale = function _createExpoScale(start, end, ease) { 5370 var p1 = Math.log(end / start), 5371 p2 = end - start; 5372 ease && (ease = gsap.parseEase(ease)); 5373 return function (p) { 5374 return (start * Math.exp(p1 * (ease ? ease(p) : p)) - start) / p2; 5375 }; 5376}, 5377 EasePoint = function EasePoint(time, value, next) { 5378 this.t = time; 5379 this.v = value; 5380 5381 if (next) { 5382 this.next = next; 5383 next.prev = this; 5384 this.c = next.v - value; 5385 this.gap = next.t - time; 5386 } 5387}, 5388 _createRoughEase = function _createRoughEase(vars) { 5389 if (typeof vars !== "object") { 5390 //users may pass in via a string, like "rough(30)" 5391 vars = { 5392 points: +vars || 20 5393 }; 5394 } 5395 5396 var taper = vars.taper || "none", 5397 a = [], 5398 cnt = 0, 5399 points = (+vars.points || 20) | 0, 5400 i = points, 5401 randomize = _boolean(vars.randomize, true), 5402 clamp = _boolean(vars.clamp), 5403 template = gsap ? gsap.parseEase(vars.template) : 0, 5404 strength = (+vars.strength || 1) * 0.4, 5405 x, 5406 y, 5407 bump, 5408 invX, 5409 obj, 5410 pnt, 5411 recent; 5412 5413 while (--i > -1) { 5414 x = randomize ? Math.random() : 1 / points * i; 5415 y = template ? template(x) : x; 5416 5417 if (taper === "none") { 5418 bump = strength; 5419 } else if (taper === "out") { 5420 invX = 1 - x; 5421 bump = invX * invX * strength; 5422 } else if (taper === "in") { 5423 bump = x * x * strength; 5424 } else if (x < 0.5) { 5425 //"both" (start) 5426 invX = x * 2; 5427 bump = invX * invX * 0.5 * strength; 5428 } else { 5429 //"both" (end) 5430 invX = (1 - x) * 2; 5431 bump = invX * invX * 0.5 * strength; 5432 } 5433 5434 if (randomize) { 5435 y += Math.random() * bump - bump * 0.5; 5436 } else if (i % 2) { 5437 y += bump * 0.5; 5438 } else { 5439 y -= bump * 0.5; 5440 } 5441 5442 if (clamp) { 5443 if (y > 1) { 5444 y = 1; 5445 } else if (y < 0) { 5446 y = 0; 5447 } 5448 } 5449 5450 a[cnt++] = { 5451 x: x, 5452 y: y 5453 }; 5454 } 5455 5456 a.sort(function (a, b) { 5457 return a.x - b.x; 5458 }); 5459 pnt = new EasePoint(1, 1, null); 5460 i = points; 5461 5462 while (i--) { 5463 obj = a[i]; 5464 pnt = new EasePoint(obj.x, obj.y, pnt); 5465 } 5466 5467 recent = new EasePoint(0, 0, pnt.t ? pnt : pnt.next); 5468 return function (p) { 5469 var pnt = recent; 5470 5471 if (p > pnt.t) { 5472 while (pnt.next && p >= pnt.t) { 5473 pnt = pnt.next; 5474 } 5475 5476 pnt = pnt.prev; 5477 } else { 5478 while (pnt.prev && p <= pnt.t) { 5479 pnt = pnt.prev; 5480 } 5481 } 5482 5483 recent = pnt; 5484 return pnt.v + (p - pnt.t) / pnt.gap * pnt.c; 5485 }; 5486}; 5487 5488var SlowMo = _createSlowMo(0.7); 5489SlowMo.ease = SlowMo; //for backward compatibility 5490 5491SlowMo.config = _createSlowMo; 5492var ExpoScaleEase = _createExpoScale(1, 2); 5493ExpoScaleEase.config = _createExpoScale; 5494var RoughEase = _createRoughEase(); 5495RoughEase.ease = RoughEase; //for backward compatibility 5496 5497RoughEase.config = _createRoughEase; 5498var EasePack = { 5499 SlowMo: SlowMo, 5500 RoughEase: RoughEase, 5501 ExpoScaleEase: ExpoScaleEase 5502}; 5503 5504for (var p in EasePack) { 5505 EasePack[p].register = _initCore; 5506 EasePack[p].version = "3.6.0"; 5507} 5508 5509_getGSAP() && gsap.registerPlugin(SlowMo); 5510 5511 5512/***/ }), 5513
vendor: 9,333 bytes, lines 5514-5868
5514/***/ "./node_modules/gsap/EaselPlugin.js": 5515/*!******************************************!*\ 5516 !*** ./node_modules/gsap/EaselPlugin.js ***! 5517 \******************************************/ 5518/*! exports provided: EaselPlugin, default */ 5519/***/ (function(module, __webpack_exports__, __webpack_require__) { 5520 5521"use strict"; 5522__webpack_require__.r(__webpack_exports__); 5523/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "EaselPlugin", function() { return EaselPlugin; }); 5524/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return EaselPlugin; }); 5525/*! 5526 * EaselPlugin 3.6.0 5527 * https://greensock.com 5528 * 5529 * @license Copyright 2008-2021, GreenSock. All rights reserved. 5530 * Subject to the terms at https://greensock.com/standard-license or for 5531 * Club GreenSock members, the agreement issued with that membership. 5532 * @author: Jack Doyle, [email protected] 5533*/ 5534 5535/* eslint-disable */ 5536var gsap, 5537 _coreInitted, 5538 _win, 5539 _createJS, 5540 _ColorFilter, 5541 _ColorMatrixFilter, 5542 _colorProps = "redMultiplier,greenMultiplier,blueMultiplier,alphaMultiplier,redOffset,greenOffset,blueOffset,alphaOffset".split(","), 5543 _windowExists = function _windowExists() { 5544 return typeof window !== "undefined"; 5545}, 5546 _getGSAP = function _getGSAP() { 5547 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 5548}, 5549 _getCreateJS = function _getCreateJS() { 5550 return _createJS || _win && _win.createjs || _win || {}; 5551}, 5552 _warn = function _warn(message) { 5553 return console.warn(message); 5554}, 5555 _cache = function _cache(target) { 5556 var b = target.getBounds && target.getBounds(); 5557 5558 if (!b) { 5559 b = target.nominalBounds || { 5560 x: 0, 5561 y: 0, 5562 width: 100, 5563 height: 100 5564 }; 5565 target.setBounds && target.setBounds(b.x, b.y, b.width, b.height); 5566 } 5567 5568 target.cache && target.cache(b.x, b.y, b.width, b.height); 5569 5570 _warn("EaselPlugin: for filters to display in EaselJS, you must call the object's cache() method first. GSAP attempted to use the target's getBounds() for the cache but that may not be completely accurate. " + target); 5571}, 5572 _parseColorFilter = function _parseColorFilter(target, v, plugin) { 5573 if (!_ColorFilter) { 5574 _ColorFilter = _getCreateJS().ColorFilter; 5575 5576 if (!_ColorFilter) { 5577 _warn("EaselPlugin error: The EaselJS ColorFilter JavaScript file wasn't loaded."); 5578 } 5579 } 5580 5581 var filters = target.filters || [], 5582 i = filters.length, 5583 c, 5584 s, 5585 e, 5586 a, 5587 p, 5588 pt; 5589 5590 while (i--) { 5591 if (filters[i] instanceof _ColorFilter) { 5592 s = filters[i]; 5593 break; 5594 } 5595 } 5596 5597 if (!s) { 5598 s = new _ColorFilter(); 5599 filters.push(s); 5600 target.filters = filters; 5601 } 5602 5603 e = s.clone(); 5604 5605 if (v.tint != null) { 5606 c = gsap.utils.splitColor(v.tint); 5607 a = v.tintAmount != null ? +v.tintAmount : 1; 5608 e.redOffset = +c[0] * a; 5609 e.greenOffset = +c[1] * a; 5610 e.blueOffset = +c[2] * a; 5611 e.redMultiplier = e.greenMultiplier = e.blueMultiplier = 1 - a; 5612 } else { 5613 for (p in v) { 5614 if (p !== "exposure") if (p !== "brightness") { 5615 e[p] = +v[p]; 5616 } 5617 } 5618 } 5619 5620 if (v.exposure != null) { 5621 e.redOffset = e.greenOffset = e.blueOffset = 255 * (+v.exposure - 1); 5622 e.redMultiplier = e.greenMultiplier = e.blueMultiplier = 1; 5623 } else if (v.brightness != null) { 5624 a = +v.brightness - 1; 5625 e.redOffset = e.greenOffset = e.blueOffset = a > 0 ? a * 255 : 0; 5626 e.redMultiplier = e.greenMultiplier = e.blueMultiplier = 1 - Math.abs(a); 5627 } 5628 5629 i = 8; 5630 5631 while (i--) { 5632 p = _colorProps[i]; 5633 5634 if (s[p] !== e[p]) { 5635 pt = plugin.add(s, p, s[p], e[p]); 5636 5637 if (pt) { 5638 pt.op = "easel_colorFilter"; 5639 } 5640 } 5641 } 5642 5643 plugin._props.push("easel_colorFilter"); 5644 5645 if (!target.cacheID) { 5646 _cache(target); 5647 } 5648}, 5649 _idMatrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], 5650 _lumR = 0.212671, 5651 _lumG = 0.715160, 5652 _lumB = 0.072169, 5653 _applyMatrix = function _applyMatrix(m, m2) { 5654 if (!(m instanceof Array) || !(m2 instanceof Array)) { 5655 return m2; 5656 } 5657 5658 var temp = [], 5659 i = 0, 5660 z = 0, 5661 y, 5662 x; 5663 5664 for (y = 0; y < 4; y++) { 5665 for (x = 0; x < 5; x++) { 5666 z = x === 4 ? m[i + 4] : 0; 5667 temp[i + x] = m[i] * m2[x] + m[i + 1] * m2[x + 5] + m[i + 2] * m2[x + 10] + m[i + 3] * m2[x + 15] + z; 5668 } 5669 5670 i += 5; 5671 } 5672 5673 return temp; 5674}, 5675 _setSaturation = function _setSaturation(m, n) { 5676 if (isNaN(n)) { 5677 return m; 5678 } 5679 5680 var inv = 1 - n, 5681 r = inv * _lumR, 5682 g = inv * _lumG, 5683 b = inv * _lumB; 5684 return _applyMatrix([r + n, g, b, 0, 0, r, g + n, b, 0, 0, r, g, b + n, 0, 0, 0, 0, 0, 1, 0], m); 5685}, 5686 _colorize = function _colorize(m, color, amount) { 5687 if (isNaN(amount)) { 5688 amount = 1; 5689 } 5690 5691 var c = gsap.utils.splitColor(color), 5692 r = c[0] / 255, 5693 g = c[1] / 255, 5694 b = c[2] / 255, 5695 inv = 1 - amount; 5696 return _applyMatrix([inv + amount * r * _lumR, amount * r * _lumG, amount * r * _lumB, 0, 0, amount * g * _lumR, inv + amount * g * _lumG, amount * g * _lumB, 0, 0, amount * b * _lumR, amount * b * _lumG, inv + amount * b * _lumB, 0, 0, 0, 0, 0, 1, 0], m); 5697}, 5698 _setHue = function _setHue(m, n) { 5699 if (isNaN(n)) { 5700 return m; 5701 } 5702 5703 n *= Math.PI / 180; 5704 var c = Math.cos(n), 5705 s = Math.sin(n); 5706 return _applyMatrix([_lumR + c * (1 - _lumR) + s * -_lumR, _lumG + c * -_lumG + s * -_lumG, _lumB + c * -_lumB + s * (1 - _lumB), 0, 0, _lumR + c * -_lumR + s * 0.143, _lumG + c * (1 - _lumG) + s * 0.14, _lumB + c * -_lumB + s * -0.283, 0, 0, _lumR + c * -_lumR + s * -(1 - _lumR), _lumG + c * -_lumG + s * _lumG, _lumB + c * (1 - _lumB) + s * _lumB, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1], m); 5707}, 5708 _setContrast = function _setContrast(m, n) { 5709 if (isNaN(n)) { 5710 return m; 5711 } 5712 5713 n += 0.01; 5714 return _applyMatrix([n, 0, 0, 0, 128 * (1 - n), 0, n, 0, 0, 128 * (1 - n), 0, 0, n, 0, 128 * (1 - n), 0, 0, 0, 1, 0], m); 5715}, 5716 _parseColorMatrixFilter = function _parseColorMatrixFilter(target, v, plugin) { 5717 if (!_ColorMatrixFilter) { 5718 _ColorMatrixFilter = _getCreateJS().ColorMatrixFilter; 5719 5720 if (!_ColorMatrixFilter) { 5721 _warn("EaselPlugin: The EaselJS ColorMatrixFilter JavaScript file wasn't loaded."); 5722 } 5723 } 5724 5725 var filters = target.filters || [], 5726 i = filters.length, 5727 matrix, 5728 startMatrix, 5729 s, 5730 pg; 5731 5732 while (--i > -1) { 5733 if (filters[i] instanceof _ColorMatrixFilter) { 5734 s = filters[i]; 5735 break; 5736 } 5737 } 5738 5739 if (!s) { 5740 s = new _ColorMatrixFilter(_idMatrix.slice()); 5741 filters.push(s); 5742 target.filters = filters; 5743 } 5744 5745 startMatrix = s.matrix; 5746 matrix = _idMatrix.slice(); 5747 5748 if (v.colorize != null) { 5749 matrix = _colorize(matrix, v.colorize, Number(v.colorizeAmount)); 5750 } 5751 5752 if (v.contrast != null) { 5753 matrix = _setContrast(matrix, Number(v.contrast)); 5754 } 5755 5756 if (v.hue != null) { 5757 matrix = _setHue(matrix, Number(v.hue)); 5758 } 5759 5760 if (v.saturation != null) { 5761 matrix = _setSaturation(matrix, Number(v.saturation)); 5762 } 5763 5764 i = matrix.length; 5765 5766 while (--i > -1) { 5767 if (matrix[i] !== startMatrix[i]) { 5768 pg = plugin.add(startMatrix, i, startMatrix[i], matrix[i]); 5769 5770 if (pg) { 5771 pg.op = "easel_colorMatrixFilter"; 5772 } 5773 } 5774 } 5775 5776 plugin._props.push("easel_colorMatrixFilter"); 5777 5778 if (!target.cacheID) { 5779 _cache(); 5780 } 5781 5782 plugin._matrix = startMatrix; 5783}, 5784 _initCore = function _initCore(core) { 5785 gsap = core || _getGSAP(); 5786 5787 if (_windowExists()) { 5788 _win = window; 5789 } 5790 5791 if (gsap) { 5792 _coreInitted = 1; 5793 } 5794}; 5795 5796var EaselPlugin = { 5797 version: "3.6.0", 5798 name: "easel", 5799 init: function init(target, value, tween, index, targets) { 5800 if (!_coreInitted) { 5801 _initCore(); 5802 5803 if (!gsap) { 5804 _warn("Please gsap.registerPlugin(EaselPlugin)"); 5805 } 5806 } 5807 5808 this.target = target; 5809 var p, pt, tint, colorMatrix, end, labels, i; 5810 5811 for (p in value) { 5812 end = value[p]; 5813 5814 if (p === "colorFilter" || p === "tint" || p === "tintAmount" || p === "exposure" || p === "brightness") { 5815 if (!tint) { 5816 _parseColorFilter(target, value.colorFilter || value, this); 5817 5818 tint = true; 5819 } 5820 } else if (p === "saturation" || p === "contrast" || p === "hue" || p === "colorize" || p === "colorizeAmount") { 5821 if (!colorMatrix) { 5822 _parseColorMatrixFilter(target, value.colorMatrixFilter || value, this); 5823 5824 colorMatrix = true; 5825 } 5826 } else if (p === "frame") { 5827 if (typeof end === "string" && end.charAt(1) !== "=" && (labels = target.labels)) { 5828 for (i = 0; i < labels.length; i++) { 5829 if (labels[i].label === end) { 5830 end = labels[i].position; 5831 } 5832 } 5833 } 5834 5835 pt = this.add(target, "gotoAndStop", target.currentFrame, end, index, targets, Math.round); 5836 5837 if (pt) { 5838 pt.op = p; 5839 } 5840 } else if (target[p] != null) { 5841 this.add(target, p, "get", end); 5842 } 5843 } 5844 }, 5845 render: function render(ratio, data) { 5846 var pt = data._pt; 5847 5848 while (pt) { 5849 pt.r(ratio, pt.d); 5850 pt = pt._next; 5851 } 5852 5853 if (data.target.cacheID) { 5854 data.target.updateCache(); 5855 } 5856 }, 5857 register: _initCore 5858}; 5859 5860EaselPlugin.registerCreateJS = function (createjs) { 5861 _createJS = createjs; 5862}; 5863 5864_getGSAP() && gsap.registerPlugin(EaselPlugin); 5865 5866 5867/***/ }), 5868
vendor: 30,993 bytes, lines 5869-6819
5869/***/ "./node_modules/gsap/Flip.js": 5870/*!***********************************!*\ 5871 !*** ./node_modules/gsap/Flip.js ***! 5872 \***********************************/ 5873/*! exports provided: Flip, default */ 5874/***/ (function(module, __webpack_exports__, __webpack_require__) { 5875 5876"use strict"; 5877__webpack_require__.r(__webpack_exports__); 5878/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Flip", function() { return Flip; }); 5879/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Flip; }); 5880/* harmony import */ var _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/matrix.js */ "./node_modules/gsap/utils/matrix.js"); 5881/*! 5882 * EasePack 3.6.0 5883 * https://greensock.com 5884 * 5885 * @license Copyright 2008-2021, GreenSock. All rights reserved. 5886 * Subject to the terms at https://greensock.com/standard-license or for 5887 * Club GreenSock members, the agreement issued with that membership. 5888 * @author: Jack Doyle, [email protected] 5889*/ 5890 5891/* eslint-disable */ 5892 5893 5894var _id = 1, 5895 _toArray, 5896 gsap, 5897 _RAD2DEG = 180 / Math.PI, 5898 _DEG2RAD = Math.PI / 180, 5899 _emptyObj = {}, 5900 _dashedNameLookup = {}, 5901 _memoizedRemoveProps = {}, 5902 _callbacks = "onStart,onUpdate,onComplete,onReverseComplete,onInterrupt".split(","), 5903 _removeProps = "transform,transformOrigin,width,height,position,top,left,opacity,zIndex".split(","), 5904 _getEl = function _getEl(target) { 5905 return _toArray(target)[0] || console.warn("Element not found:", target); 5906}, 5907 _round = function _round(value) { 5908 return Math.round(value * 10000) / 10000 || 0; 5909}, 5910 _toggleClass = function _toggleClass(targets, className, action) { 5911 return targets.forEach(function (el) { 5912 return el.classList[action](className); 5913 }); 5914}, 5915 _reserved = { 5916 zIndex: 1, 5917 clear: 1, 5918 simple: 1, 5919 spin: 1, 5920 clearProps: 1, 5921 targets: 1, 5922 toggleClass: 1, 5923 onComplete: 1, 5924 onUpdate: 1, 5925 onInterrupt: 1, 5926 onStart: 1, 5927 delay: 1, 5928 repeat: 1, 5929 repeatDelay: 1, 5930 yoyo: 1, 5931 scale: 1, 5932 fade: 1, 5933 absolute: 1, 5934 props: 1, 5935 onEnter: 1, 5936 onLeave: 1, 5937 custom: 1, 5938 paused: 1, 5939 nested: 1 5940}, 5941 _fitReserved = { 5942 zIndex: 1, 5943 simple: 1, 5944 clearProps: 1, 5945 scale: 1, 5946 absolute: 1, 5947 fitChild: 1, 5948 getVars: 1, 5949 props: 1 5950}, 5951 _camelToDashed = function _camelToDashed(p) { 5952 return p.replace(/([A-Z])/g, "-$1").toLowerCase(); 5953}, 5954 _listToArray = function _listToArray(list) { 5955 return typeof list === "string" ? list.split(" ").join("").split(",") : list; 5956}, 5957 // removes extra spaces contaminating the names, returns an Array. 5958_closestTenth, 5959 _bonusValidated = 1, 5960 //<name>Flip</name> 5961_copy = function _copy(obj, exclude) { 5962 var result = {}, 5963 p; 5964 5965 for (p in obj) { 5966 exclude[p] || (result[p] = obj[p]); 5967 } 5968 5969 return result; 5970}, 5971 _memoizedProps = {}, 5972 _memoizeProps = function _memoizeProps(props) { 5973 var p = _memoizedProps[props] = _listToArray(props); 5974 5975 _memoizedRemoveProps[props] = p.concat(_removeProps); 5976 return p; 5977}, 5978 _getInverseGlobalMatrix = function _getInverseGlobalMatrix(el) { 5979 // integrates caching for improved performance 5980 var cache = el._gsap || gsap.core.getCache(el); 5981 5982 if (cache.gmCache === gsap.ticker.frame) { 5983 return cache.gMatrix; 5984 } 5985 5986 cache.gmCache = gsap.ticker.frame; 5987 return cache.gMatrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(el, true, false, true); 5988}, 5989 _getDOMDepth = function _getDOMDepth(el, invert, level) { 5990 if (level === void 0) { 5991 level = 0; 5992 } 5993 5994 // In invert is true, the sibling depth is increments of 1, and parent/nesting depth is increments of 1000. This lets us order elements in an Array to reflect document flow. 5995 var parent = el.parentNode, 5996 inc = 1000 * Math.pow(10, level) * (invert ? -1 : 1), 5997 l = invert ? -inc * 900 : 0; 5998 5999 while (el) { 6000 l += inc; 6001 el = el.previousSibling; 6002 } 6003 6004 return parent ? l + _getDOMDepth(parent, invert, level + 1) : l; 6005}, 6006 _orderByDOMDepth = function _orderByDOMDepth(comps, invert, isElStates) { 6007 comps.forEach(function (comp) { 6008 return comp.d = _getDOMDepth(isElStates ? comp.element : comp.t, invert); 6009 }); 6010 comps.sort(function (c1, c2) { 6011 return c1.d - c2.d; 6012 }); 6013 return comps; 6014}, 6015 _recordInlineStyles = function _recordInlineStyles(elState, props) { 6016 // records the current inline CSS properties into an Array in alternating name/value pairs that's stored in a "css" property on the state object so that we can revert later. 6017 var style = elState.element.style, 6018 a = elState.css = elState.css || [], 6019 i = props.length, 6020 p, 6021 v; 6022 6023 while (i--) { 6024 p = props[i]; 6025 v = style[p] || style.getPropertyValue(p); 6026 a.push(v ? p : _dashedNameLookup[p] || (_dashedNameLookup[p] = _camelToDashed(p)), v); 6027 } 6028 6029 return style; 6030}, 6031 _applyInlineStyles = function _applyInlineStyles(state) { 6032 var css = state.css, 6033 style = state.element.style, 6034 i = 0; 6035 state.cache.uncache = 1; 6036 6037 for (; i < css.length; i += 2) { 6038 css[i + 1] ? style[css[i]] = css[i + 1] : style.removeProperty(css[i]); 6039 } 6040}, 6041 _setFinalStates = function _setFinalStates(comps, onlyTransforms) { 6042 var i = comps.length, 6043 comp; 6044 6045 while (i--) { 6046 comp = comps[i]; 6047 comp.a.cache.uncache = 1; 6048 } 6049 6050 onlyTransforms || comps.finalStates.forEach(_applyInlineStyles); 6051}, 6052 _makeAbsolute = function _makeAbsolute(elState, fallbackNode) { 6053 var element = elState.element, 6054 width = elState.width, 6055 height = elState.height, 6056 uncache = elState.uncache, 6057 getProp = elState.getProp, 6058 style = element.style, 6059 result, 6060 displayIsNone; 6061 typeof fallbackNode !== "object" && (fallbackNode = elState); 6062 6063 if (getProp("position") !== "absolute") { 6064 displayIsNone = getProp("display") === "none"; 6065 6066 if (!elState.isVisible || displayIsNone) { 6067 displayIsNone && (_recordInlineStyles(elState, ["display"]).display = fallbackNode.display); 6068 elState.matrix = fallbackNode.matrix; 6069 elState.width = width = elState.width || fallbackNode.width; 6070 elState.height = height = elState.height || fallbackNode.height; 6071 } 6072 6073 style.position = "absolute"; 6074 style.width = width + "px"; 6075 style.height = height + "px"; 6076 style.top || (style.top = "0px"); 6077 style.left || (style.left = "0px"); 6078 6079 if (uncache) { 6080 result = new ElementState(element); 6081 } else { 6082 // better performance 6083 result = _copy(elState, _emptyObj); 6084 6085 if (elState.simple) { 6086 var bounds = element.getBoundingClientRect(); 6087 result.matrix = new _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["Matrix2D"](1, 0, 0, 1, bounds.left + Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollLeft"])(), bounds.top + Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollTop"])()); 6088 } else { 6089 result.matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(element, false, false, true); 6090 } 6091 } 6092 6093 result = _fit(result, elState, true); 6094 elState.x = parseFloat(result.x); 6095 elState.y = parseFloat(result.y); 6096 } 6097 6098 return element; 6099}, 6100 _findElStateInState = function _findElStateInState(state, other) { 6101 return other && state.idLookup[_parseElementState(other).id] || state.elementStates[0]; 6102}, 6103 _parseElementState = function _parseElementState(elOrNode, props, simple, other) { 6104 return elOrNode instanceof ElementState ? elOrNode : elOrNode instanceof FlipState ? _findElStateInState(elOrNode, other) : new ElementState(typeof elOrNode === "string" ? _getEl(elOrNode) || console.warn(elOrNode + " not found") : elOrNode, props, simple); 6105}, 6106 _recordProps = function _recordProps(elState, props) { 6107 var getProp = gsap.getProperty(elState.element, null, "native"), 6108 obj = elState.props = {}, 6109 i = props.length; 6110 6111 while (i--) { 6112 obj[props[i]] = (getProp(props[i]) + "").trim(); 6113 } 6114 6115 obj.zIndex && (obj.zIndex = parseFloat(obj.zIndex) || 0); 6116 return elState; 6117}, 6118 _applyProps = function _applyProps(element, props) { 6119 var style = element.style || element, 6120 // could pass in a vars object. 6121 p; 6122 6123 for (p in props) { 6124 style[p] = props[p]; 6125 } 6126}, 6127 _getID = function _getID(el) { 6128 var id = el.getAttribute("data-flip-id"); 6129 id || el.setAttribute("data-flip-id", id = "auto-" + _id++); 6130 return id; 6131}, 6132 _elementsFromElementStates = function _elementsFromElementStates(elStates) { 6133 return elStates.map(function (elState) { 6134 return elState.element; 6135 }); 6136}, 6137 _handleCallback = function _handleCallback(callback, elStates, tl) { 6138 return callback && elStates.length && tl.add(callback(_elementsFromElementStates(elStates), tl, new FlipState(elStates, 0, true)), 0); 6139}, 6140 _fit = function _fit(fromState, toState, scale, applyProps, fitChild, vars) { 6141 var element = fromState.element, 6142 cache = fromState.cache, 6143 parent = fromState.parent, 6144 x = fromState.x, 6145 y = fromState.y, 6146 width = toState.width, 6147 height = toState.height, 6148 scaleX = toState.scaleX, 6149 scaleY = toState.scaleY, 6150 rotation = toState.rotation, 6151 cssText = vars && element.style.cssText, 6152 dimensionState = fromState, 6153 _toState$matrix = toState.matrix, 6154 e = _toState$matrix.e, 6155 f = _toState$matrix.f, 6156 deep = fromState.width !== width || fromState.height !== height || fromState.scaleX !== scaleX || fromState.scaleY !== scaleY || fromState.rotation !== rotation, 6157 simple = !deep && fromState.simple && toState.simple && !fitChild, 6158 skewX, 6159 fromPoint, 6160 toPoint, 6161 getProp, 6162 parentMatrix, 6163 matrix; 6164 6165 if (simple) { 6166 scaleX = scaleY = 1; 6167 rotation = skewX = 0; 6168 } else { 6169 parentMatrix = _getInverseGlobalMatrix(parent); 6170 matrix = parentMatrix.clone().multiply(toState.matrix); 6171 rotation = _round(Math.atan2(matrix.b, matrix.a) * _RAD2DEG); 6172 skewX = _round(Math.atan2(matrix.c, matrix.d) * _RAD2DEG + rotation) % 360; // in very rare cases, minor rounding might end up with 360 which should be 0. 6173 6174 scaleX = Math.sqrt(Math.pow(matrix.a, 2) + Math.pow(matrix.b, 2)); 6175 scaleY = Math.sqrt(Math.pow(matrix.c, 2) + Math.pow(matrix.d, 2)) * Math.cos(skewX * _DEG2RAD); 6176 6177 if (fitChild) { 6178 getProp = gsap.getProperty(fitChild); 6179 dimensionState = { 6180 scaleX: getProp("scaleX"), 6181 scaleY: getProp("scaleY"), 6182 width: Math.ceil(parseFloat(getProp("width", "px"))), 6183 height: parseFloat(getProp("height", "px")) 6184 }; 6185 } 6186 6187 cache.rotation = rotation + "deg"; 6188 cache.skewX = skewX + "deg"; 6189 } 6190 6191 if (scale) { 6192 scaleX *= width / dimensionState.width; 6193 scaleY *= height / dimensionState.height; 6194 cache.scaleX = scaleX; 6195 cache.scaleY = scaleY; 6196 } else { 6197 width *= scaleX / dimensionState.scaleX; 6198 height *= scaleY / dimensionState.scaleY; 6199 element.style.width = width + "px"; 6200 element.style.height = height + "px"; 6201 } 6202 6203 if (fromState.position === "fixed") { 6204 e -= Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollLeft"])(); 6205 f -= Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollTop"])(); 6206 } 6207 6208 if (toState.position === "fixed") { 6209 e += Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollLeft"])(); 6210 f += Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollTop"])(); 6211 } 6212 6213 applyProps && _applyProps(element, toState.props); 6214 6215 if (simple) { 6216 x += e - fromState.matrix.e; 6217 y += f - fromState.matrix.f; 6218 } else if (deep || parent !== toState.parent) { 6219 cache.renderTransform(1, cache); 6220 matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(fitChild || element, false, false, true); 6221 fromPoint = parentMatrix.apply({ 6222 x: matrix.e, 6223 y: matrix.f 6224 }); 6225 toPoint = parentMatrix.apply({ 6226 x: e, 6227 y: f 6228 }); 6229 x += _round(toPoint.x - fromPoint.x); 6230 y += _round(toPoint.y - fromPoint.y); 6231 } else { 6232 // use a faster/cheaper algorithm if we're just moving x/y 6233 parentMatrix.e = parentMatrix.f = 0; 6234 toPoint = parentMatrix.apply({ 6235 x: e - fromState.matrix.e, 6236 y: f - fromState.matrix.f 6237 }); 6238 x += _round(toPoint.x); 6239 y += _round(toPoint.y); 6240 } 6241 6242 if (vars && !(vars instanceof ElementState)) { 6243 // revert 6244 element.style.cssText = cssText; 6245 cache.uncache = 1; 6246 } else { 6247 // or apply the transform immediately 6248 cache.x = x + "px"; 6249 cache.y = y + "px"; 6250 cache.renderTransform(1, cache); 6251 } 6252 6253 if (vars) { 6254 vars.x = x; 6255 vars.y = y; 6256 vars.rotation = rotation; 6257 vars.skewX = skewX; 6258 6259 if (scale) { 6260 vars.scaleX = scaleX; 6261 vars.scaleY = scaleY; 6262 } else { 6263 vars.width = width; 6264 vars.height = height; 6265 } 6266 } 6267 6268 return vars || cache; 6269}, 6270 _parseState = function _parseState(targetsOrState, vars) { 6271 return targetsOrState instanceof FlipState ? targetsOrState : new FlipState(targetsOrState, vars); 6272}, 6273 _getChangingElState = function _getChangingElState(toState, fromState, id) { 6274 var to1 = toState.idLookup[id], 6275 to2 = toState.alt[id]; 6276 return to2.isVisible && (!(fromState.getElementState(to2.element) || to2).isVisible || !to1.isVisible) ? to2 : to1; 6277}, 6278 _fromTo = function _fromTo(fromState, toState, vars, relative) { 6279 // relative is -1 if "from()", and 1 if "to()" 6280 if (!_bonusValidated) { 6281 return; 6282 } 6283 6284 fromState instanceof FlipState && toState instanceof FlipState || console.warn("Not a valid state object."); 6285 vars = vars || {}; 6286 6287 var _vars = vars, 6288 clearProps = _vars.clearProps, 6289 onEnter = _vars.onEnter, 6290 onLeave = _vars.onLeave, 6291 absolute = _vars.absolute, 6292 custom = _vars.custom, 6293 delay = _vars.delay, 6294 paused = _vars.paused, 6295 repeat = _vars.repeat, 6296 repeatDelay = _vars.repeatDelay, 6297 yoyo = _vars.yoyo, 6298 toggleClass = _vars.toggleClass, 6299 nested = _vars.nested, 6300 _zIndex = _vars.zIndex, 6301 scale = _vars.scale, 6302 fade = _vars.fade, 6303 stagger = _vars.stagger, 6304 spin = _vars.spin, 6305 props = ("props" in vars ? vars : fromState).props, 6306 tweenVars = _copy(vars, _reserved), 6307 animation = gsap.timeline({ 6308 delay: delay, 6309 paused: paused, 6310 repeat: repeat, 6311 repeatDelay: repeatDelay, 6312 yoyo: yoyo 6313 }), 6314 remainingProps = tweenVars, 6315 entering = [], 6316 leaving = [], 6317 comps = [], 6318 swapOutTargets = [], 6319 spinNum = spin === true ? 1 : spin || 0, 6320 spinFunc = typeof spin === "function" ? spin : function () { 6321 return spinNum; 6322 }, 6323 interrupted = fromState.interrupted || toState.interrupted, 6324 addFunc = animation[relative !== 1 ? "to" : "from"], 6325 v, 6326 p, 6327 endTime, 6328 i, 6329 el, 6330 comp, 6331 state, 6332 targets, 6333 finalStates, 6334 fromNode, 6335 toNode; 6336 6337 relative || (toState = new FlipState(toState.targets, props).fit(toState, scale)); 6338 6339 for (p in toState.idLookup) { 6340 toNode = !toState.alt[p] ? toState.idLookup[p] : _getChangingElState(toState, fromState, p); 6341 el = toNode.element; 6342 fromNode = fromState.idLookup[p]; 6343 fromState.alt[p] && el === fromNode.element && (fromNode = fromState.alt[p]); 6344 6345 if (fromNode) { 6346 comp = { 6347 t: el, 6348 b: fromNode, 6349 a: toNode, 6350 sd: fromNode.element === el ? 0 : toNode.isVisible ? 1 : -1 6351 }; 6352 comps.push(comp); 6353 6354 if (comp.sd) { 6355 if (comp.sd < 0) { 6356 comp.b = toNode; 6357 comp.a = fromNode; 6358 } //comp.fb = fromState.getElementState(el) || comp.b; // fallback? Might need to be something other than the before state, like making sure we use the values from the same element. 6359 6360 6361 fade && comps.push(comp.swap = { 6362 t: fromNode.element, 6363 b: comp.b, 6364 a: comp.a, 6365 sd: comp.sd * -1, 6366 swap: comp 6367 }); 6368 } 6369 6370 el._flip = fromNode.element._flip = animation; 6371 } else if (toNode.isVisible) { 6372 comps.push({ 6373 t: el, 6374 b: _copy(toNode, { 6375 isVisible: 1 6376 }), 6377 a: toNode, 6378 sd: 0 6379 }); // to include it in the "entering" Array and do absolute positioning if necessary 6380 6381 el._flip = animation; 6382 } 6383 } 6384 6385 props && (_memoizedProps[props] || _memoizeProps(props)).forEach(function (p) { 6386 return tweenVars[p] = function (i) { 6387 return comps[i].a.props[p]; 6388 }; 6389 }); 6390 comps.finalStates = finalStates = []; 6391 absolute && _orderByDOMDepth(comps, true).forEach(function (c) { 6392 return (c.a.isVisible || c.b.isVisible) && _makeAbsolute(c.sd < 0 ? c.b : c.a, c.b); 6393 }); // when making absolute, we must go in a very particular order so that document flow changes don't affect things. Don't make it visible if both the before and after states are invisible! There's no point, and it could make things appear visible during the flip that shouldn't be. 6394 6395 _orderByDOMDepth(comps); // TODO: cache the matrix, especially for parent because it'll probably get reused quite a bit, but lock it to a particular cycle(?). 6396 6397 6398 for (i = 0; i < comps.length; i++) { 6399 comp = comps[i]; 6400 el = comp.t; 6401 nested && !(comp.sd < 0) && (comp.a.matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(el, false, false, true)); // moving a parent affects the position of children 6402 6403 if (comp.sd || comp.b.isVisible && comp.a.isVisible) { 6404 if (comp.sd < 0) { 6405 // swapping OUT (swap direction of -1 is out) 6406 state = new ElementState(el, props, fromState.simple); 6407 6408 _fit(state, comp.a, scale, 0, 0, state); 6409 6410 state.matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(el, false, false, true); 6411 state.css = comp.b.css; 6412 comp.a = state; 6413 fade && (el.style.opacity = interrupted ? comp.b.opacity : comp.a.opacity); 6414 stagger && swapOutTargets.push(el); 6415 } else if (comp.sd > 0 && fade) { 6416 // swapping IN (swap direction of 1 is in) 6417 el.style.opacity = interrupted ? comp.a.opacity - comp.b.opacity : "0"; 6418 } 6419 6420 _fit(comp.a, comp.b, scale, props); 6421 } else { 6422 // either entering or leaving (one side is invisible) 6423 if (!comp.b.isVisible) { 6424 // entering 6425 comp.a.isVisible && entering.push(comp.a); 6426 comps.splice(i--, 1); 6427 } else if (!comp.a.isVisible) { 6428 // leaving 6429 comp.b.css = comp.a.css; 6430 leaving.push(comp.b); 6431 comps.splice(i--, 1); 6432 absolute && nested && _fit(comp.a, comp.b, scale, props); 6433 } 6434 } 6435 6436 finalStates.push(comp.a); 6437 } 6438 6439 if (scale) { 6440 tweenVars.scaleX = function (i) { 6441 return comps[i].a.scaleX; 6442 }; 6443 6444 tweenVars.scaleY = function (i) { 6445 return comps[i].a.scaleY; 6446 }; 6447 } else { 6448 tweenVars.width = function (i) { 6449 return comps[i].a.width; 6450 }; 6451 6452 tweenVars.height = function (i) { 6453 return comps[i].a.height; 6454 }; 6455 6456 tweenVars.autoRound = vars.autoRound || false; 6457 } 6458 6459 tweenVars.x = function (i) { 6460 return comps[i].a.x; 6461 }; 6462 6463 tweenVars.y = function (i) { 6464 return comps[i].a.y; 6465 }; 6466 6467 tweenVars.rotation = function (i) { 6468 return comps[i].a.rotation + (spin ? spinFunc(i, targets[i], targets) * 360 : 0); 6469 }; 6470 6471 tweenVars.skewX = function (i) { 6472 return comps[i].a.skewX; 6473 }; 6474 6475 (_zIndex || _zIndex === 0) && (tweenVars.modifiers = { 6476 zIndex: function zIndex() { 6477 return _zIndex; 6478 } 6479 }) && (tweenVars.zIndex = 0); 6480 targets = comps.map(function (c) { 6481 return c.t; 6482 }); 6483 fade && (tweenVars.opacity = function (i) { 6484 return comps[i].sd < 0 ? 0 : comps[i].sd > 0 ? comps[i].a.opacity : "+=0"; 6485 }); 6486 6487 if (swapOutTargets.length) { 6488 stagger = gsap.utils.distribute(stagger); 6489 var dummyArray = targets.slice(swapOutTargets.length); 6490 6491 tweenVars.stagger = function (i, el) { 6492 return stagger(~swapOutTargets.indexOf(el) ? targets.indexOf(comps[i].swap.t) : i, el, dummyArray); 6493 }; 6494 } // // for testing... 6495 // gsap.delayedCall(vars.data ? 50 : 1, function() { 6496 // animation.eventCallback("onComplete", () => _setFinalStates(comps, !clearProps)); 6497 // addFunc.call(animation, targets, tweenVars, 0).play(); 6498 // }); 6499 // return; 6500 6501 6502 _callbacks.forEach(function (name) { 6503 return vars[name] && animation.eventCallback(name, vars[name], vars[name + "Params"]); 6504 }); // apply callbacks to the timeline, not tweens (because "custom" timing can make multiple tweens) 6505 6506 6507 if (custom && targets.length) { 6508 // bust out the custom properties as their own tweens so they can use different eases, durations, etc. 6509 remainingProps = _copy(tweenVars, _reserved); 6510 6511 if ("scale" in custom) { 6512 custom.scaleX = custom.scaleY = custom.scale; 6513 delete custom.scale; 6514 } 6515 6516 for (p in custom) { 6517 v = _copy(custom[p], _fitReserved); 6518 v[p] = tweenVars[p]; 6519 !("duration" in v) && "duration" in tweenVars && (v.duration = tweenVars.duration); 6520 v.stagger = tweenVars.stagger; 6521 addFunc.call(animation, targets, v, 0); 6522 delete remainingProps[p]; 6523 } 6524 } 6525 6526 if (targets.length || leaving.length || entering.length) { 6527 toggleClass && animation.add(function () { 6528 return _toggleClass(targets, toggleClass, animation._zTime < 0 ? "remove" : "add"); 6529 }, 0) && !paused && _toggleClass(targets, toggleClass, "add"); 6530 targets.length && addFunc.call(animation, targets, remainingProps, 0); 6531 } 6532 6533 _handleCallback(onEnter, entering, animation); 6534 6535 _handleCallback(onLeave, leaving, animation); 6536 6537 endTime = animation.duration(); 6538 animation.call(function () { 6539 var forward = animation.time() >= endTime; 6540 forward && _setFinalStates(comps, !clearProps); 6541 toggleClass && _toggleClass(targets, toggleClass, forward ? "remove" : "add"); 6542 }); 6543 return animation; 6544}, 6545 _createLookup = function _createLookup(state) { 6546 var lookup = state.idLookup = {}, 6547 alt = state.alt = {}, 6548 elStates = state.elementStates, 6549 i = elStates.length, 6550 elState; 6551 6552 while (i--) { 6553 elState = elStates[i]; 6554 lookup[elState.id] ? alt[elState.id] = elState : lookup[elState.id] = elState; 6555 } 6556}; 6557 6558var FlipState = /*#__PURE__*/function () { 6559 function FlipState(targets, vars, targetsAreElementStates) { 6560 this.props = vars && vars.props; 6561 this.simple = !!(vars && vars.simple); 6562 6563 if (targetsAreElementStates) { 6564 this.targets = _elementsFromElementStates(targets); 6565 this.elementStates = targets; 6566 6567 _createLookup(this); 6568 } else { 6569 this.targets = _toArray(targets); 6570 this.update(!vars || vars.clear !== false); 6571 } 6572 } 6573 6574 var _proto = FlipState.prototype; 6575 6576 _proto.update = function update(clear) { 6577 var _this = this; 6578 6579 this.elementStates = this.targets.map(function (el) { 6580 return new ElementState(el, _this.props, _this.simple); 6581 }); 6582 6583 _createLookup(this); 6584 6585 this.killFlips(clear); 6586 this.recordInlineStyles(); 6587 return this; 6588 }; 6589 6590 _proto.fit = function fit(state, scale, nested) { 6591 var elStatesInOrder = _orderByDOMDepth(this.elementStates.slice(0), false, true), 6592 toElStates = (state || this).idLookup, 6593 i = 0, 6594 fromNode, 6595 toNode; 6596 6597 for (; i < elStatesInOrder.length; i++) { 6598 fromNode = elStatesInOrder[i]; 6599 nested && (fromNode.matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(fromNode.element, false, false, true)); // moving a parent affects the position of children 6600 6601 toNode = toElStates[fromNode.id]; 6602 toNode && _fit(fromNode, toNode, scale, true, 0, fromNode); 6603 fromNode.matrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(fromNode.element, false, false, true); 6604 } 6605 6606 return this; 6607 }; 6608 6609 _proto.getProperty = function getProperty(element, property) { 6610 var es = this.getElementState(element) || _emptyObj; 6611 6612 return property in es ? es[property] : (es.props || _emptyObj)[property]; 6613 }; 6614 6615 _proto.recordInlineStyles = function recordInlineStyles() { 6616 var props = _memoizedRemoveProps[this.props] || _removeProps, 6617 i = this.elementStates.length; 6618 6619 while (i--) { 6620 _recordInlineStyles(this.elementStates[i], props); 6621 } 6622 }; 6623 6624 _proto.killFlips = function killFlips(clear) { 6625 var found; 6626 this.targets.forEach(function (tl) { 6627 tl = tl._flip; 6628 6629 if (tl && tl.progress() < 1 && !tl.paused()) { 6630 found = 1; 6631 tl.vars.onInterrupt && tl.vars.onInterrupt.apply(tl, tl.vars.onInterruptParams || []); 6632 clear && tl.progress(1); 6633 tl.kill(); // we should also kill it in case it was added to a parent timeline. 6634 } 6635 }); 6636 6637 if (found && clear) { 6638 // if we found an in-progress Flip animation, we must record all the values in their current state at that point BUT we should update the isVisible value AFTER pushing that flip to completion so that elements that are entering or leaving will populate those Arrays properly. 6639 this.elementStates.forEach(function (es) { 6640 var b = es.element.getBoundingClientRect(); 6641 es.isVisible = b.width || b.height || b.top || b.left; 6642 es.uncache = 1; 6643 }); 6644 } 6645 6646 this.interrupted = !!found; 6647 }; 6648 6649 _proto.getElementState = function getElementState(element) { 6650 return this.elementStates[this.targets.indexOf(_getEl(element))]; 6651 }; 6652 6653 _proto.makeAbsolute = function makeAbsolute() { 6654 return _orderByDOMDepth(this.elementStates.slice(0), true, true).map(_makeAbsolute); 6655 }; 6656 6657 return FlipState; 6658}(); 6659 6660var ElementState = /*#__PURE__*/function () { 6661 function ElementState(element, props, simple) { 6662 this.element = element; 6663 this.update(props, simple); 6664 } 6665 6666 var _proto2 = ElementState.prototype; 6667 6668 _proto2.update = function update(props, simple) { 6669 var element = this.element, 6670 getProp = gsap.getProperty(element), 6671 cache = gsap.core.getCache(element), 6672 bounds = element.getBoundingClientRect(), 6673 m = simple ? new _utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["Matrix2D"](1, 0, 0, 1, bounds.left + Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollLeft"])(), bounds.top + Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_getDocScrollTop"])()) : Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(element, false, false, true); 6674 this.getProp = getProp; 6675 this.element = element; 6676 this.id = _getID(element); 6677 this.matrix = m; 6678 this.cache = cache; 6679 this.bounds = bounds; 6680 this.isVisible = !!(bounds.width || bounds.height || bounds.left || bounds.top); 6681 this.display = getProp("display"); 6682 this.position = getProp("position"); 6683 this.parent = element.parentNode; 6684 this.x = getProp("x"); 6685 this.y = getProp("y"); 6686 this.scaleX = cache.scaleX; 6687 this.scaleY = cache.scaleY; 6688 this.rotation = getProp("rotation"); 6689 this.skewX = getProp("skewX"); 6690 this.opacity = getProp("opacity"); 6691 this.width = _closestTenth(parseFloat(getProp("width", "px")) + 0.04); // round up to the closest 0.25 so that text doesn't wrap. 6692 6693 this.height = parseFloat(getProp("height", "px")); 6694 props && _recordProps(this, _memoizedProps[props] || _memoizeProps(props)); 6695 this.simple = simple || _round(m.a) === 1 && !_round(m.b) && !_round(m.c) && _round(m.d) === 1; // allows us to speed through some other tasks if it's not scale/rotated 6696 6697 this.uncache = 0; 6698 }; 6699 6700 return ElementState; 6701}(); 6702 6703var Flip = /*#__PURE__*/function () { 6704 function Flip() {} 6705 6706 Flip.getState = function getState(targets, vars) { 6707 return _parseState(targets, typeof vars === "string" ? { 6708 props: vars 6709 } : vars); 6710 }; 6711 6712 Flip.from = function from(state, vars) { 6713 vars = vars || {}; 6714 "clearProps" in vars || (vars.clearProps = true); 6715 return _fromTo(state, _parseState(vars.targets || state.targets, { 6716 props: vars.props || state.props, 6717 simple: vars.simple, 6718 clear: !!vars.clear 6719 }), vars, -1); 6720 }; 6721 6722 Flip.to = function to(state, vars) { 6723 return _fromTo(state, _parseState(vars.targets || state.targets, { 6724 props: vars.props || state.props, 6725 simple: vars.simple, 6726 clear: !!vars.clear 6727 }), vars, 1); 6728 }; 6729 6730 Flip.fromTo = function fromTo(fromState, toState, vars) { 6731 return _fromTo(fromState, toState, vars); 6732 }; 6733 6734 Flip.fit = function fit(fromEl, toEl, vars) { 6735 if (!_bonusValidated) { 6736 return; 6737 } 6738 6739 var v = vars ? _copy(vars, _fitReserved) : {}, 6740 _ref = vars || v, 6741 absolute = _ref.absolute, 6742 scale = _ref.scale, 6743 getVars = _ref.getVars, 6744 props = _ref.props, 6745 runBackwards = _ref.runBackwards, 6746 onComplete = _ref.onComplete, 6747 simple = _ref.simple, 6748 fitChild = vars && vars.fitChild && _getEl(vars.fitChild), 6749 before = _parseElementState(toEl, props, simple, fromEl), 6750 after = _parseElementState(fromEl, 0, simple, before), 6751 inlineProps = props ? _memoizedRemoveProps[props] : _removeProps; 6752 6753 props && _applyProps(v, before.props); 6754 6755 if (runBackwards) { 6756 _recordInlineStyles(after, inlineProps); 6757 6758 "immediateRender" in v || (v.immediateRender = true); 6759 6760 v.onComplete = function () { 6761 _applyInlineStyles(after); 6762 6763 onComplete && onComplete.apply(this, arguments); 6764 }; 6765 } 6766 6767 absolute && _makeAbsolute(after, before); 6768 v = _fit(after, before, scale || fitChild, props, fitChild, v.duration || getVars ? v : 0); 6769 return getVars ? v : v.duration ? gsap.to(after.element, v) : null; 6770 }; 6771 6772 Flip.makeAbsolute = function makeAbsolute(targetsOrStates, vars) { 6773 return (targetsOrStates instanceof FlipState ? targetsOrStates : new FlipState(targetsOrStates, vars)).makeAbsolute(); 6774 }; 6775 6776 Flip.isFlipping = function isFlipping(target) { 6777 var f = Flip.getByTarget(target); 6778 return !!f && f.isActive(); 6779 }; 6780 6781 Flip.getByTarget = function getByTarget(target) { 6782 return (_getEl(target) || _emptyObj)._flip; 6783 }; 6784 6785 Flip.getElementState = function getElementState(target, props) { 6786 return new ElementState(_getEl(target), props); 6787 }; 6788 6789 Flip.convertCoordinates = function convertCoordinates(fromElement, toElement, point) { 6790 var m = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(toElement, true, true).multiply(Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["getGlobalMatrix"])(fromElement)); 6791 return point ? m.apply(point) : m; 6792 }; 6793 6794 Flip.register = function register(core) { 6795 gsap = core; 6796 6797 Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_0__["_setDoc"])(document.body); 6798 6799 _toArray = gsap.utils.toArray; 6800 _closestTenth = gsap.utils.snap(0.1); 6801 }; 6802 6803 return Flip; 6804}(); // function whenImagesLoad(el, func) { 6805// let pending = [], 6806// onLoad = e => { 6807// pending.splice(pending.indexOf(e.target), 1); 6808// e.target.removeEventListener("load", onLoad); 6809// pending.length || func(); 6810// }; 6811// gsap.utils.toArray(el.tagName.toLowerCase() === "img" ? el : el.querySelectorAll("img")).forEach(img => img.complete || img.addEventListener("load", onLoad) || pending.push(img)); 6812// pending.length || func(); 6813// } 6814 6815typeof window !== "undefined" && window.gsap && window.gsap.registerPlugin(Flip); 6816 6817 6818/***/ }), 6819
vendor: 75,711 bytes, lines 6820-8389
6820/***/ "./node_modules/gsap/GSDevTools.js": 6821/*!*****************************************!*\ 6822 !*** ./node_modules/gsap/GSDevTools.js ***! 6823 \*****************************************/ 6824/*! exports provided: GSDevTools, default */ 6825/***/ (function(module, __webpack_exports__, __webpack_require__) { 6826 6827"use strict"; 6828__webpack_require__.r(__webpack_exports__); 6829/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GSDevTools", function() { return GSDevTools; }); 6830/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return GSDevTools; }); 6831/* harmony import */ var _Draggable_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Draggable.js */ "./node_modules/gsap/Draggable.js"); 6832/*! 6833 * GSDevTools 3.6.0 6834 * https://greensock.com 6835 * 6836 * @license Copyright 2008-2021, GreenSock. All rights reserved. 6837 * Subject to the terms at https://greensock.com/standard-license or for 6838 * Club GreenSock members, the agreement issued with that membership. 6839 * @author: Jack Doyle, [email protected] 6840*/ 6841 6842/* eslint-disable */ 6843 6844 6845var gsap, 6846 _coreInitted, 6847 _doc, 6848 _docEl, 6849 _win, 6850 _recordedRoot, 6851 Animation, 6852 _rootTween, 6853 _rootInstance, 6854 _rootIsDirty, 6855 _keyboardInstance, 6856 _globalTimeline, 6857 _independentRoot, 6858 _delayedCall, 6859 _recording = true, 6860 _startupPhase = true, 6861 //for the first 2 seconds, we don't record any zero-duration tweens because they're typically just setup stuff and/or the "from" or "startAt" tweens. In version 1.20.3 we started flagging those with data:"isStart"|"isFromStart" but this logic helps GSDevTools work with older versions too. 6862_globalStartTime = 0, 6863 _windowExists = function _windowExists() { 6864 return typeof window !== "undefined"; 6865}, 6866 _getGSAP = function _getGSAP() { 6867 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 6868}, 6869 _isString = function _isString(value) { 6870 return typeof value === "string"; 6871}, 6872 _isFunction = function _isFunction(value) { 6873 return typeof value === "function"; 6874}, 6875 _isObject = function _isObject(value) { 6876 return typeof value === "object"; 6877}, 6878 _isUndefined = function _isUndefined(value) { 6879 return typeof value === "undefined"; 6880}, 6881 _bonusValidated = 1, 6882 //<name>GSDevTools</name> 6883_svgNS = "http://www.w3.org/2000/svg", 6884 _domNS = "http://www.w3.org/1999/xhtml", 6885 _idSeed = 0, 6886 //we assign an ID to each GSDevTools instance so that we can segregate the sessionStorage data accordingly. 6887_lookup = {}, 6888 _supportsStorage = function () { 6889 try { 6890 sessionStorage.setItem("gsTest", "1"); 6891 sessionStorage.removeItem("gsTest"); 6892 return true; 6893 } catch (e) { 6894 return false; 6895 } 6896}(), 6897 _parseAnimation = function _parseAnimation(animationOrId) { 6898 return animationOrId instanceof Animation ? animationOrId : animationOrId ? gsap.getById(animationOrId) : null; 6899}, 6900 _createElement = function _createElement(type, container, cssText) { 6901 var element = _doc.createElementNS ? _doc.createElementNS(type === "svg" ? _svgNS : _domNS, type) : _doc.createElement(type); 6902 6903 if (container) { 6904 if (_isString(container)) { 6905 container = _doc.querySelector(container); 6906 } 6907 6908 container.appendChild(element); 6909 } 6910 6911 if (type === "svg") { 6912 element.setAttribute("xmlns", _svgNS); 6913 element.setAttribute("xmlns:xlink", _domNS); 6914 } 6915 6916 cssText && (element.style.cssText = cssText); 6917 return element; 6918}, 6919 _clearSelection = function _clearSelection() { 6920 if (_doc.selection) { 6921 _doc.selection.empty(); 6922 } else if (_win.getSelection) { 6923 _win.getSelection().removeAllRanges(); 6924 } 6925}, 6926 _getChildrenOf = function _getChildrenOf(timeline, includeTimelines) { 6927 var a = [], 6928 cnt = 0, 6929 Tween = gsap.core.Tween, 6930 tween = timeline._first; 6931 6932 while (tween) { 6933 if (tween instanceof Tween) { 6934 if (tween.vars.id) { 6935 a[cnt++] = tween; 6936 } 6937 } else { 6938 if (includeTimelines && tween.vars.id) { 6939 a[cnt++] = tween; 6940 } 6941 6942 a = a.concat(_getChildrenOf(tween, includeTimelines)); 6943 cnt = a.length; 6944 } 6945 6946 tween = tween._next; 6947 } 6948 6949 return a; 6950}, 6951 _getClippedDuration = function _getClippedDuration(animation, excludeRootRepeats) { 6952 var max = 0, 6953 repeat = Math.max(0, animation._repeat), 6954 t = animation._first; 6955 6956 if (!t) { 6957 max = animation.duration(); 6958 } 6959 6960 while (t) { 6961 max = Math.max(max, t.totalDuration() > 999 ? t.endTime(false) : t._start + t._tDur / t._ts); 6962 t = t._next; 6963 } 6964 6965 return !excludeRootRepeats && repeat ? max * (repeat + 1) + animation._rDelay * repeat : max; 6966}, 6967 _globalizeTime = function _globalizeTime(animation, rawTime) { 6968 var a = animation, 6969 time = arguments.length > 1 ? +rawTime : a.rawTime(); 6970 6971 while (a) { 6972 time = a._start + time / (a._ts || 1); 6973 a = a.parent; 6974 } 6975 6976 return time; 6977}, 6978 _timeToProgress = function _timeToProgress(time, animation, defaultValue, relativeProgress) { 6979 var add, i, a; 6980 6981 if (_isString(time)) { 6982 if (time.charAt(1) === "=") { 6983 add = parseInt(time.charAt(0) + "1", 10) * parseFloat(time.substr(2)); 6984 6985 if (add < 0 && relativeProgress === 0) { 6986 //if something like inTime:"-=2", we measure it from the END, not the beginning 6987 relativeProgress = 100; 6988 } 6989 6990 time = relativeProgress / 100 * animation.duration() + add; 6991 } else if (isNaN(time) && animation.labels && animation.labels[time] !== -1) { 6992 time = animation.labels[time]; 6993 } else if (animation === _recordedRoot) { 6994 //perhaps they defined an id of an animation, like "myAnimation+=2" 6995 i = time.indexOf("="); 6996 6997 if (i > 0) { 6998 add = parseInt(time.charAt(i - 1) + "1", 10) * parseFloat(time.substr(i + 1)); 6999 time = time.substr(0, i - 1); 7000 } else { 7001 add = 0; 7002 } 7003 7004 a = gsap.getById(time); 7005 7006 if (a) { 7007 time = _globalizeTime(a, defaultValue / 100 * a.duration()) + add; 7008 } 7009 } 7010 } 7011 7012 time = isNaN(time) ? defaultValue : parseFloat(time); 7013 return Math.min(100, Math.max(0, time / animation.duration() * 100)); 7014}, 7015 _addedCSS, 7016 _createRootElement = function _createRootElement(element, minimal, css) { 7017 if (!_addedCSS) { 7018 _createElement("style", _docEl).innerHTML = '.gs-dev-tools{height:51px;bottom:0;left:0;right:0;display:block;position:fixed;overflow:visible;padding:0}.gs-dev-tools *{box-sizing:content-box;visibility:visible}.gs-dev-tools .gs-top{position:relative;z-index:499}.gs-dev-tools .gs-bottom{display:flex;align-items:center;justify-content:space-between;background-color:rgba(0,0,0,.6);height:42px;border-top:1px solid #999;position:relative}.gs-dev-tools .timeline{position:relative;height:8px;margin-left:15px;margin-right:15px;overflow:visible}.gs-dev-tools .progress-bar,.gs-dev-tools .timeline-track{height:8px;width:100%;position:absolute;top:0;left:0}.gs-dev-tools .timeline-track{background-color:#999;opacity:.6}.gs-dev-tools .progress-bar{background-color:#91e600;height:8px;top:0;width:0;pointer-events:none}.gs-dev-tools .seek-bar{width:100%;position:absolute;height:24px;top:-12px;left:0;background-color:transparent}.gs-dev-tools .in-point,.gs-dev-tools .out-point{width:15px;height:26px;position:absolute;top:-18px}.gs-dev-tools .in-point-shape{fill:#6d9900;stroke:rgba(0,0,0,.5);stroke-width:1}.gs-dev-tools .out-point-shape{fill:#994242;stroke:rgba(0,0,0,.5);stroke-width:1}.gs-dev-tools .in-point{transform:translateX(-100%)}.gs-dev-tools .out-point{left:100%}.gs-dev-tools .grab{stroke:rgba(255,255,255,.3);stroke-width:1}.gs-dev-tools .playhead{position:absolute;top:-5px;transform:translate(-50%,0);left:0;border-radius:50%;width:16px;height:16px;border:1px solid #6d9900;background-color:#91e600}.gs-dev-tools .gs-btn-white{fill:#fff}.gs-dev-tools .pause{opacity:0}.gs-dev-tools .select-animation{vertical-align:middle;position:relative;padding:6px 10px}.gs-dev-tools .select-animation-container{flex-grow:4;width:40%}.gs-dev-tools .select-arrow{display:inline-block;width:12px;height:7px;margin:0 7px;transform:translate(0,-2px)}.gs-dev-tools .select-arrow-shape{stroke:rgba(255,255,255,.6);stroke-width:2px;fill:none}.gs-dev-tools .rewind{height:16px;width:19px;padding:10px 4px;min-width:24px}.gs-dev-tools .rewind-path{opacity:.6}.gs-dev-tools .play-pause{width:24px;height:24px;padding:6px 10px;min-width:24px}.gs-dev-tools .ease{width:30px;height:30px;padding:10px;min-width:30px;display:none}.gs-dev-tools .ease-path{fill:none;stroke:rgba(255,255,255,.6);stroke-width:2px}.gs-dev-tools .ease-border{fill:rgba(255,255,255,.25)}.gs-dev-tools .time-scale{font-family:monospace;font-size:18px;text-align:center;color:rgba(255,255,255,.6);padding:4px 4px 4px 0;min-width:30px;margin-left:7px}.gs-dev-tools .loop{width:20px;padding:5px;min-width:20px}.gs-dev-tools .loop-path{fill:rgba(255,255,255,.6)}.gs-dev-tools label span{color:#fff;font-family:monospace;text-decoration:none;font-size:16px;line-height:18px}.gs-dev-tools .time-scale span{color:rgba(255,255,255,.6)}.gs-dev-tools button:focus,.gs-dev-tools select:focus{outline:0}.gs-dev-tools label{position:relative;cursor:pointer}.gs-dev-tools label.locked{text-decoration:none;cursor:auto}.gs-dev-tools label input,.gs-dev-tools label select{position:absolute;left:0;top:0;z-index:1;font:inherit;font-size:inherit;line-height:inherit;height:100%;width:100%;color:#000!important;opacity:0;background:0 0;border:none;padding:0;margin:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer}.gs-dev-tools label input+.display{position:relative;z-index:2}.gs-dev-tools .gs-bottom-right{vertical-align:middle;display:flex;align-items:center;flex-grow:4;width:40%;justify-content:flex-end}.gs-dev-tools .time-container{font-size:18px;font-family:monospace;color:rgba(255,255,255,.6);margin:0 5px}.gs-dev-tools .logo{width:32px;height:32px;position:relative;top:2px;margin:0 12px}.gs-dev-tools .gs-hit-area{background-color:transparent;width:100%;height:100%;top:0;position:absolute}.gs-dev-tools.minimal{height:auto;display:flex;align-items:stretch}.gs-dev-tools.minimal .gs-top{order:2;flex-grow:4;background-color:rgba(0,0,0,1)}.gs-dev-tools.minimal .gs-bottom{background-color:rgba(0,0,0,1);border-top:none}.gs-dev-tools.minimal .timeline{top:50%;transform:translate(0,-50%)}.gs-dev-tools.minimal .in-point,.gs-dev-tools.minimal .out-point{display:none}.gs-dev-tools.minimal .select-animation-container{display:none}.gs-dev-tools.minimal .rewind{display:none}.gs-dev-tools.minimal .play-pause{width:20px;height:20px;padding:4px 6px;margin-left:14px}.gs-dev-tools.minimal .time-scale{min-width:26px}.gs-dev-tools.minimal .loop{width:18px;min-width:18px;display:none}.gs-dev-tools.minimal .gs-bottom-right{display:none}@media only screen and (max-width:600px){.gs-dev-tools{height:auto;display:flex;align-items:stretch}.gs-dev-tools .gs-top{order:2;flex-grow:4;background-color:rgba(0,0,0,1);height:42px}.gs-dev-tools .gs-bottom{background-color:rgba(0,0,0,1);border-top:none}.gs-dev-tools .timeline{top:50%;transform:translate(0,-50%)}.gs-dev-tools .in-point,.gs-dev-tools .out-point{display:none}.gs-dev-tools .select-animation-container{display:none}.gs-dev-tools .rewind{display:none}.gs-dev-tools .play-pause{width:20px;height:20px;padding:4px 6px;margin-left:14px}.gs-dev-tools .time-scale{min-width:26px}.gs-dev-tools .loop{width:18px;min-width:18px;display:none}.gs-dev-tools .gs-bottom-right{display:none}}'; 7019 _addedCSS = true; 7020 } 7021 7022 if (_isString(element)) { 7023 element = _doc.querySelector(element); 7024 } 7025 7026 var root = _createElement("div", element || _docEl.getElementsByTagName("body")[0] || _docEl); 7027 7028 root.setAttribute("class", "gs-dev-tools" + (minimal ? " minimal" : "")); 7029 root.innerHTML = '<div class=gs-hit-area></div><div class=gs-top><div class=timeline><div class=timeline-track></div><div class=progress-bar></div><div class=seek-bar></div><svg class=in-point viewBox="0 0 15 26" xmlns=http://www.w3.org/2000/svg><polygon class=in-point-shape points=".5 .5 14.5 .5 14.5 25.5 .5 17.5"/><polyline class=grab points="5.5 4 5.5 15"/><polyline class=grab points="9.5 4 9.5 17"/></svg><svg class=out-point viewBox="0 0 15 26" xmlns=http://www.w3.org/2000/svg><polygon class=out-point-shape points=".5 .5 14.5 .5 14.5 17.5 .5 25.5"/><polyline class=grab points="5.5 4 5.5 17"/><polyline class=grab points="9.5 4 9.5 15"/></svg><div class=playhead></div></div></div><div class=gs-bottom><div class=select-animation-container><label class=select-animation><select class=animation-list><option>Global Timeline<option>myTimeline</select><nobr><span class="display animation-label">Global Timeline</span><svg class=select-arrow viewBox="0 0 12.05 6.73" xmlns=http://www.w3.org/2000/svg><polyline class=select-arrow-shape points="0.35 0.35 6.03 6.03 11.7 0.35"/></svg></nobr></label></div><svg class=rewind viewBox="0 0 12 15.38" xmlns=http://www.w3.org/2000/svg><path d=M0,.38H2v15H0Zm2,7,10,7.36V0Z class="gs-btn-white rewind-path"/></svg><svg class=play-pause viewBox="0 0 20.97 25.67" xmlns=http://www.w3.org/2000/svg><g class=play><path d="M8,4.88 C8,10.18 8,15.48 8,20.79 5.33,22.41 2.66,24.04 0,25.67 0,17.11 0,8.55 0,0 2.66,1.62 5.33,3.25 8,4.88" class="gs-btn-white play-1" style=stroke:#fff;stroke-width:.6px /><path d="M14.485,8.855 C16.64,10.18 18.8,11.5 20.97,12.83 16.64,15.48 12.32,18.13 8,20.79 8,15.48 8,10.18 8,4.88 10.16,6.2 12.32,7.53 14.48,8.85" class="gs-btn-white play-2" style=stroke:#fff;stroke-width:.6px /></g></svg> <svg class=loop viewBox="0 0 29 25.38" xmlns=http://www.w3.org/2000/svg><path d=M27.44,5.44,20.19,0V3.06H9.06A9.31,9.31,0,0,0,0,12.41,9.74,9.74,0,0,0,.69,16l3.06-2.23a6,6,0,0,1-.12-1.22,5.49,5.49,0,0,1,5.43-5.5H20.19v3.81Z class=loop-path /><path d=M25.25,11.54a5.18,5.18,0,0,1,.12,1.12,5.41,5.41,0,0,1-5.43,5.41H9.19V14.5L1.94,19.94l7.25,5.44V22.06H19.94A9.2,9.2,0,0,0,29,12.84a9.42,9.42,0,0,0-.68-3.53Z class=loop-path /></svg> <svg class=ease viewBox="0 0 25.67 25.67" xmlns=http://www.w3.org/2000/svg><path d=M.48,25.12c1.74-3.57,4.28-12.6,8.8-10.7s4.75,1.43,6.5-1.11S19.89,1.19,25.2.55 class=ease-path /><path d=M24.67,1V24.67H1V1H24.67m1-1H0V25.67H25.67V0Z class=ease-border /></svg><label class=time-scale><select><option value=10>10x<option value=5>5x<option value=2>2x<option value=1 selected>1x<option value=0.5>0.5x<option value=0.25>0.25x<option value=0.1>0.1x</select><span class="display time-scale-label">1x</span></label><div class=gs-bottom-right><div class=time-container><span class=time>0.00</span> / <span class=duration>0.00</span></div><a href="https://greensock.com/docs/v3/Plugins/GSDevTools?source=GSDevTools" target=_blank title=Docs><svg class=logo viewBox="0 0 100 100" xmlns=http://www.w3.org/2000/svg><path d="M60 15.4c-.3-.4-.5-.6-.5-.7.1-.6.2-1 .2-1.7v-.4c.6.6 1.3 1.3 1.8 1.7.2.2.5.3.8.3.2 0 .3 0 .5.1h1.6c.8 0 1.6.1 2 0 .1 0 .2 0 .3-.1.6-.3 1.4-1 2.1-1.6 0 .6.1 1.2.1 1.7v1.5c0 .3 0 .5.1.7-.1.1-.2.1-.4.2-.7.4-1.7 1-2.3.9-.5-.1-1.5-.3-2.6-.7-1.2-.3-2.4-.8-3.2-1.2 0 0-.1 0-.1-.1s-.2-.4-.4-.6zm24.6 21.9c-.5-1.7-1.9-2-4.2-.7.9-1.5 2.1-1.5 2.3-2.1.9-2.5-.6-4.6-1.2-5.3.7-1.8 1.4-4.5-1-6.8-1-1-2.4-1.2-3.6-1.1 1.8 1.7 3.4 4.4 2.5 7.2-.1.3-.9.7-1.7 1 0 0 .4 2-.3 3.5-.3.6-.8 1.5-1.3 2.6 1 .9 1.6 1 3 1.3-.9.1-1.2.4-1.2.5-.7 3 1 3.4 1.4 4.8 0 .1 0 .2.1.3v.4c-.3.3-1.4.5-2.5.5s-1.8 1-1.8 1c-.2.1-.3.3-.4.4v1c0 .1 0 .4.1.6.1.5.3 1.3.4 1.8.9.6 1.4.9 2.2 1.1.5.1 1 .2 1.5.1.3-.1.7-.3 1-.7 1.5-1.7 1.9-3.2 2.2-4.1 0-.1 0-.2.1-.2 0 .1.1.1.1.2 0 0 .1-.1.1-.2l.1-.1c1.3-1.6 2.9-4.5 2.1-7zM74.3 49.9c-.1-.3-.1-.7-.2-1.1v-.2c-.1-.2-.1-.4-.2-.6 0-.1-.1-.3-.1-.5s-.1-.5-.1-.7v-.1c0-.2-.1-.5-.1-.7-.1-.3-.1-.7-.2-1.1v-.1c0-.2 0-.3-.1-.5v-.9c0-.1 0-.2.1-.3V43h-.3c-1.1.1-3.8.4-6.7.2-1.2-.1-2.4-.3-3.6-.6-1-.3-1.8-.5-2.3-.7-1.2-.4-1.6-.6-1.8-.7 0 .2-.1.4-.1.7 0 .3-.1.5-.1.8-.1.2-.1.4-.2.6l.1.1c.5.5 1.5 1.3 1.5 2.1v.2c-.1.4-.4.5-.8.9-.1.1-.6.7-1.1 1.1l-.6.6c-.1 0-.1.1-.2.1-.1.1-.3.2-.4.3-.2.1-.7.5-.8.6-.1.1-.2.1-.3.1-2.8 8.8-2.2 13.5-1.5 16.1.1.5.3 1 .4 1.3-.4.5-.8 1-1.2 1.4-1.2 1.5-2 2.6-2.6 4.2 0 .1 0 .1-.1.2 0 .1 0 .2-.1.2-.2.5-.3 1-.4 1.5-.6 2.3-.8 4.5-.9 6.6-.1 2.4-.2 4.6-.5 6.9.7.3 3.1.9 4.7.6.2-.1 0-3.9.6-5.7l.6-1.5c.4-.9.9-1.9 1.3-3.1.3-.7.5-1.5.7-2.4.1-.5.2-1 .3-1.6V74v-.1c.1-.6.1-1.3.1-2 0-.2-.7.3-1.1.9.3-1.8 1.3-2.1 2-3.2.3-.5.6-1.1.6-2 2.5-1.7 4-3.7 5-5.7.2-.4.4-.9.6-1.4.3-.8.5-1.6.7-2.4.3-1.4.8-3.2 1.2-4.8v-.1c.4-1.2.8-2.2 1.2-2.6-.2.9-.4 1.7-.6 2.5v.2c-.6 3.5-.7 6.2-2 9.2 1 2.6 1.9 3.9 2 7.6-2 0-3.2 1.6-3.7 3.2 1.2.3 3.9.7 8.3.1h.3c.1-.5.3-1.1.5-1.5.3-.8.5-1.5.6-2.2.2-1.3.1-2.4 0-3.2 3.9-3.7 2.6-11 1.6-16.6zm.3-15.1c.1-.3.2-.6.4-.8.2-.3.3-.7.5-1 .1-.3.3-.6.4-.9.5-1.5.4-2.8.3-3.5-.1 0-.1-.1-.2-.1-.5-.2-.9-.4-1.4-.6-.1 0-.2-.1-.3-.1-3.8-1.2-7.9-.9-11.9.1-1 .2-1.9.5-2.9.1-2.3-.8-3.9-1.9-4.6-2.8l-.2-.2c-.1.2-.2.4-.4.6.2 2.3-.5 3.9-1.4 5.1.9 1.2 2.6 2.8 3.6 3.4 1.1.6 1.7.7 3.4.4-.6.7-1.1 1-1.9 1.4.1.7.2 2 .5 3.4.3.3 1.2.8 2.3 1.3.5.3 1.1.5 1.7.7.8.3 1.7.6 2.4.8.1 0 .2.1.3.1.5.1 1.1.2 1.8.2h.9c2.1 0 4.5-.2 5.4-.3h.1c-.1-2.7.2-4.6.7-6.2.2-.3.4-.7.5-1.1zm-23.2 9.3v.2c-.3 1.7.5 2.4 1.9 3.4.6.5 0 .5.5.8.3.2.7.3 1 .3.3 0 .5 0 .8-.1.2-.1.4-.3.6-.5.1-.1.3-.2.5-.4.3-.2.6-.5.7-.6.1-.1.2-.1.3-.2.2-.2.5-.5.6-.7.2-.2.4-.5.5-.7 0-.1.1-.1.1-.1v-.1c.1-.4-.3-.8-.8-1.3-.2-.2-.4-.3-.5-.5-.3-.3-.6-.5-1-.7-.9-.5-1.9-.7-3-.7l-.3-.3c-2.2-2.5-3.2-4.8-3.9-6.5-.9-2.1-1.9-3.3-3.9-4.9 1 .4 1.8.8 2.3 1.1.5.4 1.3.4 1.9.2.2-.1.5-.2.7-.3.2-.1.4-.2.6-.4 1.6-1.3 2.5-3.8 2.6-5.6v-.1c.2-.3.6-1.1.8-1.4l.1.1c.1.1.3.2.6.5.1 0 .1.1.2.1.1.1.2.1.2.2.8.6 1.9 1.3 2.6 1.7 1.4.7 2.3.7 5.3-.1 2.2-.6 4.8-.8 6.8-.8 1.4 0 2.7.3 4 .7.2.1.4.1.5.2.3.1.6.2.9.4 0 0 .1 0 .1.1.8.4 2.1 1.2 2.5-.3.1-2-.6-3.9-1.6-5.3 0 0-.1 0-.1-.1-.1-.1-.2-.2-.4-.3-.1-.1-.2-.1-.3-.2-.1-.1-.2-.2-.4-.2-.6-.4-1.2-.8-1.6-.9-.1-.1-.3-.1-.4-.2h-.1-.1c-.1 0-.3-.1-.4-.1-.1 0-.1 0-.2-.1h-.1l-.2-.4c-.2-.1-.4-.2-.5-.2h-.6c-.3 0-.5.1-.7.1-.7.1-1.2.3-1.7.4-.2 0-.3.1-.5.1-.5.1-1 .2-1.6.2-.4 0-.9-.1-1.5-.2-.4-.1-.8-.2-1.1-.3-.2-.1-.4-.1-.6-.2-.6-.2-1.1-.3-1.7-.4h-.2-1.8c-.3 0-.6.1-1 .1H57.9c-.8 0-1.5 0-2.3-.1-.2 0-.5-.1-.7-.1-.5-.1-.9-.2-1.3-.4-.2-.1-.3-.1-.4-.2-.1 0-.2 0-.2-.1-.3-.1-.6-.1-.9-.1H51h-.1c-.4 0-.9.1-1.4.2-1.1.2-2.1.6-3 1.3-.3.2-.6.5-.8.8-.1.1-.2.2-.2.3-.4.6-.8 1.2-.9 2 0 .2-.1.4-.1.6 0 .2 1.7.7 2.3 2.8-.8-1.2-2.3-2.5-4.1-1.4-1.5 1-1.1 3.1-2.4 5.4-.3.5-.6.9-1 1.4-.8 1-.7 2.1.2 4.4 1.4 3.4 7.6 5.3 11.5 8.3l.4.4zm8.7-36.3c0 .6.1 1 .2 1.6v.1c0 .3.1.6.1.9.1 1.2.4 2 1 2.9 0 .1.1.1.1.2.3.2.5.3.8.4 1.1.2 3.1.3 4.2 0 .2-.1.5-.3.7-.5.4-.4.7-1.1.9-1.7.1-.7.3-1.3.4-1.8 0-.2.1-.4.1-.5v-.1c0-.2 0-.3.1-.5.2-.7.2-2.4.3-2.8.1-.7 0-1.8-.1-2.5 0-.2-.1-.4-.1-.5v-.1c-.2-.5-1.4-1.4-4.3-1.4-3.1 0-4 1-4.1 1.5v.1c0 .1 0 .3-.1.5-.1.4-.2 1.4-.2 1.9v2.3zm-6 88.6c0-.1-.1-.2-.1-.3-.7-1.5-1.1-3.5-1.3-4.6.4.1.7.6.8.3.2-.5-.4-1.5-.5-2.2v-.1c-.5-.5-4-.5-3.7-.3-.4.8-1 .6-1.3 2.1-.1.7.8.1 1.7.1-1.4.9-3 2.1-3.4 3.2-.1.1-.1.2-.1.3 0 .2-.1.4-.1.5-.1 1.2.5 1.6 2 2.4H48.4c1.4.3 3 .3 4.3.3 1.2-.2 1.6-.7 1.6-1.4-.2-.1-.2-.2-.2-.3z" style=fill:#efefef /><path d="M56.1 36.5c.3 1.4.5 2.4.8 4.2h-.2c-.1.5-.1.9-.1 1.3-1-.4-2.2-.5-2.6-.5-3.7-4.4-2.9-6.1-4.4-8.3.4-.2 1-.4 1.5-.8 1.6 1.9 3.3 3 5 4.1zm-1.7 13.2s-1.4 0-2.3-1c0 0-.1-.5.1-.7 0 0-1.2-1-1.5-1.7-.2-.5-.3-1.1-.2-1.6-4.4-3.7-10.9-4.2-12.9-9.1-.5-1.2-1.3-2.9-.9-3.9-.3.1-.5.2-.8.3-2.9.9-11.7 5.3-17.9 8.8 1.6 1.7 2.6 4.3 3.2 7.2l.3 1.5c.1.5.1 1 .2 1.5.1 1.4.4 2.7.8 3.9.2.8.6 1.5.9 2.2.6 1 1.2 1.9 2.1 2.6.6.5 1.2.9 1.9 1.3 2.1 1.1 5 1.6 8.6 1.5H37.9c.5 0 1 .1 1.5.1h.1c.4.1.9.1 1.3.2h.2c.4.1.9.2 1.3.4h.1c.4.1.8.3 1.1.5h.1c.4.2.7.4 1.1.6h.1c.7.4 1.3.9 1.9 1.5l.1.1c.6.5 1.1 1.1 1.5 1.8 0 .1.1.1.1.2s.1.1.1.2c.4.6 1.2 1.1 1.9 1.3.7-.9 1.5-1.8 2.2-2.8-1.6-6 0-11.7 1.8-16.9zm-26-15.9c5-2.4 9-4.1 9.9-4.5.3-.6.6-1.4.9-2.6.1-.3.2-.5.3-.8 1-2.7 2.7-2.8 3.5-3v-.2c.1-1.1.5-2 1-2.8-8.8 2.5-18 5.5-28 11.7-.1.1-.2.2-.4.2C11.3 34.5 3 40.3 1.3 51c2.4-2.7 6-5.6 10.5-8.5.1-.1.3-.2.5-.3.2-.1.5-.3.7-.4 1.2-.7 2.4-1.4 3.6-2.2 2.2-1.2 4.5-2.4 6.7-3.5 1.8-.8 3.5-1.6 5.1-2.3zm54.9 61.3l-.3-.3c-.8-.6-4.1-1.2-5.5-2.3-.4-.3-1.1-.7-1.7-1.1-1.6-.9-3.5-1.8-3.5-2.1v-.1c-.2-1.7-.2-7 .1-8.8.3-1.8.7-4.4.8-5.1.1-.6.5-1.2.1-1.2h-.4c-.2 0-.4.1-.8.1-1.5.3-4.3.6-6.6.4-.9-.1-1.6-.2-2-.3-.5-.1-.7-.2-.9-.3H62.3c-.4.5 0 2.7.6 4.8.3 1.1.8 2 1.2 3 .3.8.6 1.8.8 3.1 0 .2.1.4.1.7.2 2.8.3 3.6-.2 4.9-.1.3-.3.6-.4 1-.4.9-.7 1.7-.6 2.3 0 .2.1.4.1.5.2.4.6.7 1.2.8.2 0 .3.1.5.1.3 0 .6.1.9.1 3.4 0 5.2 0 8.6.4 2.5.4 3.9.6 5.1.5.4 0 .9-.1 1.4-.1 1.2-.2 1.8-.5 1.9-.9-.1.2-.1.1-.2-.1zM60.2 16.4zm-.5 1.7zm3.8.5c.1 0 .3.1.5.1.4.1.7.2 1.2.3.3.1.6.1.9.1h1.3c.3-.1.7-.1 1-.2.7-.2 1.5-.4 2.7-.6h.3c.3 0 .6.1.9.3.1.1.2.1.4.2.3.2.8.2 1.2.4h.1c.1 0 .1.1.2.1.6.3 1.3.7 1.9 1.1l.3.3c.9-.1 1.6-.2 2.1-.2h.1c-.2-.4-.3-1.3-1.8-.6-.6-.7-.8-1.3-2.1-.9-.1-.2-.2-.3-.3-.4l-.1-.1c-.1-.1-.2-.3-.3-.4 0-.1-.1-.1-.1-.2-.2-.3-.5-.5-.9-.7-.7-.4-1.5-.6-2.3-.5-.2 0-.4.1-.6.2-.1 0-.2.1-.2.1-.1 0-.2.1-.3.2-.5.3-1.3.8-2.1 1-.1 0-.1 0-.2.1-.2 0-.4.1-.5.1H66.5h-.1c-.4-.1-1.1-.2-2-.5-.1 0-.2-.1-.3-.1-.9-.2-1.8-.5-2.7-.8-.3-.1-.7-.2-1-.3-.1 0-.1 0-.2-.1h-.1s-.1 0-.1-.1c-.3-.3-.7-.6-1.3-.8-.5-.2-1.2-.4-2.1-.5-.2 0-.5 0-.7.1-.4.2-.8.6-1.2.9.1.1.3.3.4.5.1.2.2.4.3.7l-.6-.6c-.5-.4-1.1-.8-1.7-.9-.8-.2-1.4.4-2.3.9 1 0 1.8.1 2.5.4.1 0 .1 0 .2.1h.1c.1 0 .2.1.3.1.9.4 1.8.6 2.7.6h1.3c.5 0 .8-.1 1.1-.1.1 0 .4 0 .7-.1h2.2c.4.4.9.6 1.6.8z" style=fill:#88ce02 /><path d="M100 51.8c0-19.5-12.5-36.1-30-42.1.1-1.2.2-2.4.3-3.1.1-1.5.2-3.9-.5-4.9-1.6-2.3-9.1-2.1-10.5-.1-.4.6-.7 3.6-.6 5.9-1.1-.1-2.2-.1-3.3-.1-16.5 0-30.9 9-38.6 22.3-2.4 1.4-4.7 2.8-6.1 4C5.4 38 2.2 43.2 1 47c-1.6 4.7-1.1 7.6.4 5.8 1.2-1.5 6.6-5.9 10.1-8.2-.4 2.3-.6 4.8-.6 7.2 0 21 14.5 38.5 34 43.3-.1 1.1.1 2 .7 2.6.9.8 3.2 2 6.4 1.6 2.9-.3 3.5-.5 3.2-2.9h.2c2.7 0 5.3-.2 7.8-.7.1.1.2.2.4.3 1.5 1 7.1.8 9.6.7s6.2.9 8.6.5c2.9-.5 3.4-2.3 1.6-3.2-1.5-.8-3.8-1.3-6.7-3.1C90.6 83.4 100 68.7 100 51.8zM60.1 5.5c0-.5.1-1.5.2-2.1 0-.2 0-.4.1-.5v-.1c.1-.5 1-1.5 4.1-1.5 2.9 0 4.2.9 4.3 1.4v.1c0 .1 0 .3.1.5.1.8.2 1.9.1 2.7 0 .5-.1 2.1-.2 2.9 0 .1 0 .3-.1.5v.1c0 .2-.1.3-.1.5-.1.5-.2 1.1-.4 1.8-.1.6-.5 1.2-.9 1.7-.2.3-.5.5-.7.5-1.1.3-3.1.3-4.2 0-.3-.1-.5-.2-.8-.4 0-.1-.1-.1-.1-.2-.6-.9-.9-1.7-1-2.9 0-.4-.1-.6-.1-.9v-.1c-.1-.6-.2-1-.2-1.6v-.3c-.1-1.3-.1-2.1-.1-2.1zm-.4 7.5v-.4c.6.6 1.3 1.3 1.8 1.7.2.2.5.3.8.3.2 0 .3 0 .5.1h1.6c.8 0 1.6.1 2 0 .1 0 .2 0 .3-.1.6-.3 1.4-1 2.1-1.6 0 .6.1 1.2.1 1.7v1.5c0 .3 0 .5.1.7-.1.1-.2.1-.4.2-.7.4-1.7 1-2.3.9-.5-.1-1.5-.3-2.6-.7-1.2-.3-2.4-.8-3.2-1.2 0 0-.1 0-.1-.1-.2-.3-.4-.5-.6-.7-.3-.4-.5-.6-.5-.7.3-.4.4-.9.4-1.6zm.5 3.4zm-7.3-.3c.6.1 1.2.5 1.7.9.2.2.5.4.6.6-.1-.2-.2-.5-.3-.7-.1-.2-.3-.4-.4-.5.4-.3.8-.7 1.2-.9.2-.1.4-.1.7-.1.9.1 1.6.2 2.1.5.6.2 1 .5 1.3.8 0 0 .1 0 .1.1h.1c.1 0 .1 0 .2.1.3.1.6.2 1 .3.9.3 1.9.6 2.7.8.1 0 .2.1.3.1.9.2 1.6.4 2 .5h.4c.2 0 .4 0 .5-.1.1 0 .1 0 .2-.1.7-.2 1.5-.7 2.1-1 .1-.1.2-.1.3-.2.1 0 .2-.1.2-.1.2-.1.4-.2.6-.2.8-.2 1.7.1 2.3.5.3.2.6.4.9.7 0 .1.1.1.1.2.1.2.2.3.3.4l.1.1c.1.1.2.2.3.4 1.3-.4 1.5.2 2.1.9 1.6-.7 1.7.2 1.8.6h-.1c-.5 0-1.2 0-2.1.2l-.3-.3c-.5-.4-1.2-.8-1.9-1.1-.1 0-.1-.1-.2-.1h-.1c-.4-.2-.8-.2-1.2-.4-.1-.1-.2-.1-.4-.2-.3-.1-.6-.3-.9-.3h-.3c-1.2.1-2 .4-2.7.6-.3.1-.7.2-1 .2-.4.1-.8.1-1.3 0-.3 0-.6-.1-.9-.1-.5-.1-.8-.2-1.2-.3-.2 0-.3-.1-.5-.1h-.1c-.6-.2-1.2-.3-1.8-.4h-.1-2.1c-.4.1-.6.1-.7.1-.3 0-.7.1-1.1.1h-1.3c-.9 0-1.9-.2-2.7-.6-.1 0-.2-.1-.3-.1H53c-.1 0-.1 0-.2-.1-.7-.3-1.6-.4-2.5-.4 1.2-.8 1.8-1.4 2.6-1.3zm6.8 2zm-15.2 4.1c.1-.7.4-1.4.9-2 .1-.1.2-.2.2-.3l.8-.8c.9-.6 1.9-1.1 3-1.3.5-.1 1-.2 1.4-.2H52c.3 0 .6.1.9.1.1 0 .2 0 .2.1.1.1.2.1.4.2.4.2.8.3 1.3.4.2 0 .5.1.7.1.7.1 1.5.1 2.3.1H58.7c.4 0 .7-.1 1-.1H61.7c.6.1 1.1.2 1.7.4.2 0 .4.1.6.2.3.1.7.2 1.1.3.6.1 1.1.2 1.5.2.6 0 1.1-.1 1.6-.2.2 0 .3-.1.5-.1.5-.1 1-.3 1.7-.4.2 0 .5-.1.7-.1h.6c.2 0 .4.1.5.2l.1.1h.1c.1 0 .1 0 .2.1.2.1.3.1.4.1h.2c.1.1.3.1.4.2.4.2 1 .6 1.6.9.1.1.2.2.4.2.1.1.2.1.3.2.2.1.3.3.4.3l.1.1c1.1 1.4 1.8 3.3 1.6 5.3-.3 1.5-1.6.7-2.5.3 0 0-.1 0-.1-.1-.3-.1-.6-.2-.9-.4-.2-.1-.4-.1-.5-.2-1.2-.4-2.5-.7-4-.7-2 0-4.6.1-6.8.8-3 .8-4 .8-5.3.1-.8-.4-1.8-1.1-2.6-1.7-.1-.1-.2-.1-.2-.2-.1-.1-.1-.1-.2-.1-.3-.2-.6-.4-.6-.5l-.1-.1c-.2.3-.6 1-.8 1.4v.1c-.1 1.7-1 4.2-2.6 5.6-.2.1-.4.3-.6.4-.2.1-.5.2-.7.3-.7.2-1.4.2-1.9-.2-.5-.3-1.3-.7-2.3-1.1 2 1.6 3 2.8 3.9 4.9.7 1.7 1.7 4 3.9 6.5l.3.3c1.1 0 2.1.2 3 .7.4.2.7.4 1 .7.2.2.4.3.5.5.5.4.9.8.8 1.3v.1s0 .1-.1.1c-.1.2-.3.5-.5.7-.1.1-.4.4-.6.7-.1.1-.2.2-.3.2-.1.1-.4.3-.7.6-.2.2-.4.3-.5.4-.2.1-.4.4-.6.5-.3.1-.5.2-.8.1-.3 0-.7-.2-1-.3-.5-.3.1-.3-.5-.8-1.4-1-2.2-1.7-1.9-3.4v-.2c-.2-.1-.3-.3-.5-.4-3.9-3-10.1-4.9-11.5-8.3-.9-2.3-1-3.4-.2-4.4.4-.5.8-1 1-1.4 1.3-2.3.9-4.4 2.4-5.4 1.8-1.2 3.3.2 4.1 1.4-.5-2.1-2.3-2.6-2.3-2.8.3.1.3-.1.3-.3zm29 20s-.1 0 0 0c-.1 0-.1 0 0 0-.9.1-3.3.3-5.4.3h-.9c-.7 0-1.3-.1-1.8-.2-.1 0-.2 0-.3-.1-.7-.2-1.6-.5-2.4-.8-.6-.2-1.2-.5-1.7-.7-1.1-.5-2.1-1.1-2.3-1.3-.5-1.4-.7-2.7-.7-3.4.8-.4 1.3-.7 1.9-1.4-1.7.3-2.4.2-3.4-.4-1-.5-2.6-2.2-3.6-3.4 1-1.2 1.7-2.9 1.4-5.1.1-.2.3-.4.4-.6 0 .1.1.1.2.2.7.9 2.4 2 4.6 2.8 1.1.4 2 .1 2.9-.1 4-1 8.1-1.3 11.9-.1.1 0 .2.1.3.1.5.2.9.4 1.4.6.1 0 .1.1.2.1.1.7.2 2-.3 3.5-.1.3-.2.6-.4.9-.2.3-.3.6-.5 1-.1.3-.2.5-.4.8-.2.4-.3.8-.5 1.3-.4 1.4-.7 3.4-.6 6zm-23.9-9c.4-.2 1-.4 1.5-.8 1.6 1.8 3.3 3 5 4.1.3 1.4.5 2.4.8 4.2h-.2c-.1.5-.1.9-.1 1.3-1-.4-2.2-.5-2.6-.5-3.7-4.3-3-6-4.4-8.3zm-32.9 6.5c-1.3.7-2.5 1.4-3.6 2.2-.2.1-.5.3-.7.4-.1.1-.3.2-.5.3-4.5 2.9-8.1 5.8-10.5 8.5 1.7-10.8 10-16.5 14.3-19.2.1-.1.2-.2.4-.2 10-6.2 19.2-9.2 28-11.7-.5.8-.9 1.7-1 2.8v.2c-.8.1-2.5.2-3.5 3-.1.2-.2.5-.3.8-.3 1.2-.6 2-.9 2.6-.9.4-5 2.2-9.9 4.5-1.6.8-3.3 1.6-5 2.4-2.3 1-4.6 2.2-6.8 3.4zm28 24.8s0-.1 0 0c-.4-.3-.8-.5-1.2-.7h-.1c-.4-.2-.7-.3-1.1-.5h-.1c-.4-.1-.8-.3-1.3-.4h-.2c-.4-.1-.8-.2-1.3-.2h-.1c-.5-.1-1-.1-1.5-.1H35.9c-3.7.1-6.5-.4-8.6-1.5-.7-.4-1.4-.8-1.9-1.3-.9-.7-1.5-1.6-2.1-2.6-.4-.7-.7-1.4-.9-2.2-.4-1.2-.6-2.5-.8-3.9 0-.5-.1-1-.2-1.5l-.3-1.5c-.6-2.9-1.6-5.5-3.2-7.2 6.3-3.5 15-7.9 17.8-8.8.3-.1.6-.2.8-.3-.3 1.1.4 2.7.9 3.9 2.1 4.9 8.6 5.4 12.9 9.1 0 .5 0 1.1.2 1.6.5.6 1.7 1.6 1.7 1.6-.2.2-.1.7-.1.7.9 1 2.3 1 2.3 1-1.8 5.2-3.4 10.9-1.9 16.9-.7 1-1.5 1.8-2.2 2.8-.7-.2-1.4-.6-1.9-1.3 0-.1-.1-.1-.1-.2s-.1-.1-.1-.2l-1.5-1.8-.1-.1c-.5-.4-1.2-.9-1.9-1.3zm7.9 33.6c-1.3.1-2.9 0-4.3-.3h-.2-.1c-1.5-.8-2.1-1.2-2-2.4 0-.2 0-.3.1-.5 0-.1.1-.2.1-.3.5-1.1 2.1-2.2 3.4-3.2-.8 0-1.8.7-1.7-.1.2-1.5.9-1.3 1.3-2.1-.2-.3 3.3-.2 3.8.3v.1c0 .7.7 1.7.5 2.2-.1.3-.4-.2-.8-.3.2 1.1.6 3.1 1.3 4.6.1.1.1.2.1.3 0 .1.1.2.1.3 0 .7-.4 1.2-1.6 1.4zM59 67.7c0 .9-.3 1.6-.6 2-.7 1.1-1.7 1.4-2 3.2.4-.6 1.1-1.1 1.1-.9 0 .8-.1 1.4-.1 2v.2c-.1.6-.2 1.1-.3 1.6-.2.9-.5 1.7-.7 2.4-.4 1.2-.9 2.1-1.3 3.1l-.6 1.5c-.6 1.7-.4 5.6-.6 5.7-1.6.3-4.1-.3-4.7-.6.3-2.2.4-4.5.5-6.9.1-2.1.3-4.3.9-6.6.1-.5.3-1 .4-1.5 0-.1 0-.2.1-.2 0-.1 0-.1.1-.2.5-1.6 1.4-2.7 2.6-4.2.4-.4.7-.9 1.2-1.4-.1-.4-.2-.8-.4-1.3-.7-2.6-1.3-7.3 1.5-16.1.1 0 .2-.1.3-.1.2-.1.7-.5.8-.6.1-.1.3-.2.4-.3.1 0 .1-.1.2-.1l.6-.6 1.1-1.1c.4-.4.7-.5.8-.9v-.2c0-.8-1.1-1.5-1.5-2.1l-.1-.1c.1-.2.1-.4.2-.6 0-.2.1-.5.1-.8 0-.2.1-.5.1-.7.1.1.6.4 1.8.7.6.2 1.3.4 2.3.7 1.1.3 2.4.5 3.6.6 2.9.2 5.6 0 6.7-.2h.3v.1c0 .1 0 .2-.1.3v.9c0 .2 0 .3.1.5v.1c0 .4.1.7.2 1.1 0 .3.1.5.1.7v.1c0 .3.1.5.1.7 0 .2.1.3.1.5.1.2.1.4.2.6v.2c.1.4.2.8.2 1.1 1 5.7 2.3 12.9-1.1 16.7.2.8.3 1.9 0 3.2-.1.7-.3 1.4-.6 2.2-.2.5-.3 1-.5 1.5h-.3c-4.5.6-7.1.2-8.3-.1.5-1.6 1.7-3.3 3.7-3.2-.1-3.7-1.1-5-2-7.6 1.3-3 1.3-5.7 2-9.2v-.2c.2-.8.3-1.6.6-2.5-.4.5-.8 1.5-1.2 2.6v.1c-.5 1.5-.9 3.4-1.2 4.8-.2.8-.4 1.6-.7 2.4-.2.5-.4.9-.6 1.4-1.5 1.9-3 3.9-5.5 5.6zm18.5 24.9c1.5 1.1 4.7 1.8 5.5 2.3l.3.3c.1.1.1.2.1.3-.1.4-.7.7-1.9.9-.5.1-.9.1-1.4.1-1.3 0-2.6-.2-5.1-.5-3.4-.5-5.2-.4-8.6-.4-.3 0-.6 0-.9-.1-.2 0-.4-.1-.5-.1-.6-.2-1-.5-1.2-.8-.1-.2-.1-.3-.1-.5-.1-.7.2-1.5.6-2.3.2-.4.3-.7.4-1 .5-1.3.4-2.1.2-4.9 0-.2-.1-.4-.1-.7-.2-1.3-.5-2.3-.8-3.1-.4-1.1-.9-1.9-1.2-3-.6-2.1-1-4.3-.6-4.8H62.5c.2.1.5.2.9.3.5.1 1.1.2 2 .3 2.2.2 5.1-.2 6.6-.4.3-.1.6-.1.8-.1h.4c.4 0 .1.6-.1 1.2-.1.7-.5 3.3-.8 5.1-.3 1.8-.2 7.1-.1 8.8v.1c0 .3 1.9 1.2 3.5 2.1.7.2 1.4.5 1.8.9zm4.8-48.2c0 .1 0 .1 0 0-.1.1-.2.2-.2.3 0-.1-.1-.1-.1-.2 0 .1 0 .2-.1.2-.2.9-.6 2.4-2.2 4.1-.4.4-.7.6-1 .7-.5.1-.9 0-1.5-.1-.9-.2-1.3-.6-2.2-1.1-.1-.6-.3-1.3-.4-1.8 0-.3-.1-.5-.1-.6v-1l.4-.4s.7-1 1.8-1 2.2-.2 2.5-.5v-.1-.3c0-.1 0-.2-.1-.3-.4-1.4-2.1-1.8-1.4-4.8 0-.2.3-.5 1.2-.5-1.4-.3-2-.4-3-1.3.5-1.1 1-1.9 1.3-2.6.8-1.5.3-3.5.3-3.5.8-.3 1.6-.7 1.7-1 .9-2.8-.7-5.5-2.5-7.2 1.2-.1 2.6.1 3.6 1.1 2.4 2.4 1.8 5 1 6.8.6.7 2.1 2.9 1.2 5.3-.2.6-1.4.6-2.3 2.1 2.3-1.3 3.7-1 4.2.7 1 2.4-.6 5.3-2.1 7z"/><path d="M22 53.4v-.2c0-.2-.1-.5-.2-.9s-.1-.8-.2-1.3c-.5-4.7-1.9-9.4-4.9-11.3 3.7-2 16.8-8.5 21.9-10.5 2.9-1.2.8-.4-.2 1.4-.8 1.4-.3 2.9-.5 3.2-.6.8-12.6 10.5-15.9 19.6zm32.2-2.3c-3.4 3.8-12 11-18.2 11.4 8.7-.2 12.2 4.1 14.7 9.7 2.6-5.2 2.7-10.3 2.6-16.1 0-2.6 1.8-6 .9-5zm5.3-23L54.3 24s-1.1 3.1-1 4.6c.1 1.6-1.8 2.7-.9 3.6.9.9 3.2 2.5 4 3.4.7.9 1.1 7.1 1.1 7.1l2.2 2.7s1-1.8 1.1-6.3c.2-5.4-2.9-7.1-3.3-8.6-.4-1.4.6-2.9 2-2.4zm3.1 45.6l3.9.3s1.2-2.2 2.1-3.5c.9-1.4.4-1.6 0-4.6-.4-3-1.4-9.3-1.2-13.6l-3.1 10.2s1.8 5.6 1.6 6.4c-.1.8-3.3 4.8-3.3 4.8zm5 18.8c-1.1 0-2.5-.4-3.5-.8l-1 .3.2 4s5.2.7 4.6-.4c-.6-1.2-.3-3.1-.3-3.1zm12 .6c-1 0-.3.2.4 1.2.8 1 .1 2-.8 2.3l3.2.5 1.9-1.7c.1 0-3.7-2.3-4.7-2.3zM73 76c-1.6.5-4.2.8-5.9.8-1.7.1-3.7-.1-5-.5v1.4s1.2.5 5.4.5c3.5.1 5.7-.8 5.7-.8l.9-.8c-.1.1.5-1.1-1.1-.6zm-.2 3.1c-1.6.6-3.9.6-5.6.7-1.7.1-3.7-.1-5-.5l.1 1.4s.7.3 4.9.4c3.5.1 5.7-.7 5.7-.7l.3-.5c-.1-.1.3-1-.4-.8zm5.9-42.7c-.9-.8-1.4-2.4-1.5-3.3l-1.9 2.5.7 1.2s2.5.1 2.8.1c.4 0 .3-.1-.1-.5zM69 14.7c.6-.7.2-2.7.2-2.7L66 14.6l-4.4-.8-.5-1.3-1.3-.1c.8 1.8 1.8 2.5 3.3 3.1.9.4 4.5.9 5.9-.8z" style=opacity:.4;fill-rule:evenodd;clip-rule:evenodd /></svg></a></div></div>'; 7030 7031 if (element) { 7032 root.style.position = "absolute"; 7033 root.style.top = minimal ? "calc(100% - 42px)" : "calc(100% - 51px)"; 7034 } 7035 7036 if (css) { 7037 if (_isString(css)) { 7038 root.style.cssText = css; 7039 } else if (_isObject(css)) { 7040 css.data = "root"; 7041 gsap.set(root, css).kill(); 7042 } 7043 7044 if (root.style.top) { 7045 root.style.bottom = "auto"; 7046 } 7047 7048 if (root.style.width) { 7049 gsap.set(root, { 7050 xPercent: -50, 7051 left: "50%", 7052 right: "auto", 7053 data: "root" 7054 }).kill(); 7055 } 7056 } 7057 7058 if (!minimal && root.offsetWidth < 600) { 7059 root.setAttribute("class", "gs-dev-tools minimal"); 7060 7061 if (element) { 7062 root.style.top = "calc(100% - 42px)"; 7063 } 7064 } 7065 7066 return root; 7067}, 7068 _clickedOnce = true, 7069 //perhaps we shouldn't preventDefault() on the first mousedown/touchstart/pointerdown so that iframes get focus properly. Did that previously, but now it seems to prevent interaction on the first click (annoying). 7070_addListener = function _addListener(e, type, callback, capture) { 7071 var handler, altType; 7072 7073 if (type === "mousedown" || type === "mouseup") { 7074 e.style.cursor = "pointer"; 7075 } 7076 7077 if (type === "mousedown") { 7078 //some browsers call BOTH mousedown AND touchstart, for example, on a single interaction so we need to skip one of them if both are called within 100ms. 7079 altType = !_isUndefined(e.onpointerdown) ? "pointerdown" : !_isUndefined(e.ontouchstart) ? "touchstart" : null; 7080 7081 if (altType) { 7082 handler = function handler(event) { 7083 if (event.target.nodeName.toLowerCase() !== "select" && event.type === altType) { 7084 //don't preventDefault() on a <select> or else it won't open! 7085 event.stopPropagation(); 7086 7087 if (_clickedOnce) { 7088 //otherwise, both touchstart and mousedown will get called. 7089 event.preventDefault(); 7090 callback.call(e, event); 7091 } 7092 } else if (event.type !== altType) { 7093 callback.call(e, event); 7094 } 7095 7096 _clickedOnce = true; 7097 }; 7098 7099 e.addEventListener(altType, handler, capture); 7100 7101 if (altType !== "pointerdown") { 7102 e.addEventListener(type, handler, capture); 7103 } 7104 7105 return; 7106 } 7107 } 7108 7109 e.addEventListener(type, callback, capture); 7110}, 7111 _removeListener = function _removeListener(e, type, callback) { 7112 e.removeEventListener(type, callback); 7113 type = type !== "mousedown" ? null : !_isUndefined(e.onpointerdown) ? "pointerdown" : !_isUndefined(e.ontouchstart) ? "touchstart" : null; 7114 7115 if (type) { 7116 e.removeEventListener(type, callback); 7117 } 7118}, 7119 _selectValue = function _selectValue(element, value, label, insertIfAbsent) { 7120 var options = element.options, 7121 i = options.length, 7122 option; 7123 value += ""; 7124 7125 while (--i > -1) { 7126 if (options[i].innerHTML === value || options[i].value === value) { 7127 element.selectedIndex = i; 7128 label.innerHTML = options[i].innerHTML; 7129 return options[i]; 7130 } 7131 } 7132 7133 if (insertIfAbsent) { 7134 option = _createElement("option", element); 7135 option.setAttribute("value", value); 7136 option.innerHTML = label.innerHTML = _isString(insertIfAbsent) ? insertIfAbsent : value; 7137 element.selectedIndex = options.length - 1; 7138 } 7139}, 7140 //increments the selected value of a <select> up or down by a certain amount. 7141_shiftSelectedValue = function _shiftSelectedValue(element, amount, label) { 7142 var options = element.options, 7143 i = Math.min(options.length - 1, Math.max(0, element.selectedIndex + amount)); 7144 element.selectedIndex = i; 7145 7146 if (label) { 7147 label.innerHTML = options[i].innerHTML; 7148 } 7149 7150 return options[i].value; 7151}, 7152 //moves everything from _globalTimeline into _recordedRoot and updates the _rootTween if it is currently controlling the Global timeline (_recordedRoot). _recordedTemp is just a temporary recording area for anything that happens while _recordedRoot is paused. Returns true if the _recordedRoot's duration changed due to the merge. 7153_merge = function _merge() { 7154 var t = _globalTimeline._first, 7155 duration, 7156 next, 7157 target; 7158 7159 if (_rootInstance) { 7160 duration = _recordedRoot._dur; 7161 7162 while (t) { 7163 next = t._next; 7164 target = t._targets && t._targets[0]; 7165 7166 if (!(_isFunction(target) && target === t.vars.onComplete && !t._dur) && !(target && target._gsIgnore)) { 7167 //typically, delayedCalls aren't included in the _recordedTemp, but since the hijacked add() below fires BEFORE TweenLite's constructor sets the target, we couldn't check that target === vars.onComplete there. And Draggable creates a tween with just an onComplete (no onReverseComplete), thus it fails that test. Therefore, we test again here to avoid merging that in. 7168 _recordedRoot.add(t, t._start - t._delay); 7169 } 7170 7171 t = next; 7172 } 7173 7174 return duration !== _recordedRoot.duration(); 7175 } 7176}, 7177 _updateRootDuration = function _updateRootDuration() { 7178 if (_rootInstance) { 7179 _rootInstance.update(); 7180 7181 _rootIsDirty = false; 7182 } 7183 7184 gsap.ticker.remove(_updateRootDuration); 7185}, 7186 _buildPlayPauseMorph = function _buildPlayPauseMorph(svg) { 7187 var tl = gsap.timeline({ 7188 data: "root", 7189 parent: _independentRoot, 7190 onComplete: function onComplete() { 7191 return tl.kill(); 7192 } 7193 }); 7194 tl.to(svg.querySelector(".play-1"), { 7195 duration: 0.4, 7196 attr: { 7197 d: "M5.75,3.13 C5.75,9.79 5.75,16.46 5.75,23.13 4.08,23.13 2.41,23.13 0.75,23.13 0.75,16.46 0.75,9.79 0.75,3.12 2.41,3.12 4.08,3.12 5.75,3.12" 7198 }, 7199 ease: "power2.inOut", 7200 rotation: 360, 7201 transformOrigin: "50% 50%" 7202 }).to(svg.querySelector(".play-2"), { 7203 duration: 0.4, 7204 attr: { 7205 d: "M16.38,3.13 C16.38,9.79 16.38,16.46 16.38,23.13 14.71,23.13 13.04,23.13 11.38,23.13 11.38,16.46 11.38,9.79 11.38,3.12 13.04,3.12 14.71,3.12 16.38,3.12" 7206 }, 7207 ease: "power2.inOut", 7208 rotation: 360, 7209 transformOrigin: "50% 50%" 7210 }, 0.05); 7211 return tl; 7212}, 7213 _buildLoopAnimation = function _buildLoopAnimation(svg) { 7214 var tl = gsap.timeline({ 7215 data: "root", 7216 id: "loop", 7217 parent: _independentRoot, 7218 paused: true, 7219 onComplete: function onComplete() { 7220 return tl.kill(); 7221 } 7222 }); 7223 tl.to(svg, { 7224 duration: 0.5, 7225 rotation: 360, 7226 ease: "power3.inOut", 7227 transformOrigin: "50% 50%" 7228 }).to(svg.querySelectorAll(".loop-path"), { 7229 duration: 0.5, 7230 fill: "#91e600", 7231 ease: "none" 7232 }, 0); 7233 return tl; 7234}, 7235 _getAnimationById = function _getAnimationById(id) { 7236 return gsap.getById(id) || _independentRoot.getById(id) || id === _recordedRoot.vars.id && _recordedRoot; 7237}, 7238 _initCore = function _initCore(core) { 7239 gsap = core || _getGSAP(); 7240 7241 if (!_coreInitted) { 7242 if (gsap && _windowExists()) { 7243 _doc = document; 7244 _docEl = _doc.documentElement; 7245 _win = window; 7246 gsap.registerPlugin(_Draggable_js__WEBPACK_IMPORTED_MODULE_0__["Draggable"]); 7247 _globalTimeline = gsap.globalTimeline; 7248 _globalTimeline._sort = true; 7249 _globalTimeline.autoRemoveChildren = false; 7250 Animation = gsap.core.Animation; 7251 _independentRoot = gsap.timeline({ 7252 data: "indy", 7253 autoRemoveChildren: true, 7254 smoothChildTiming: true 7255 }); 7256 7257 _independentRoot.kill(); 7258 7259 _independentRoot._dp = 0; //don't let it revert to the global timeline as its parent. 7260 7261 _independentRoot.to({}, { 7262 duration: 1e12 7263 }); 7264 7265 _recordedRoot = gsap.timeline({ 7266 data: "root", 7267 id: "Global Timeline", 7268 autoRemoveChildren: false, 7269 smoothChildTiming: true, 7270 parent: _independentRoot 7271 }); 7272 _rootTween = gsap.to(_recordedRoot, { 7273 duration: 1, 7274 time: 1, 7275 ease: "none", 7276 data: "root", 7277 id: "_rootTween", 7278 paused: true, 7279 immediateRender: false, 7280 parent: _independentRoot 7281 }); // so that auto-overwriting works. Initially we transferred the tweens to the _recordedRoot. 7282 7283 _globalTimeline.killTweensOf = function (targets, props, onlyActive) { 7284 _recordedRoot.killTweensOf(targets, props, onlyActive); 7285 7286 _recordedRoot.killTweensOf.call(_globalTimeline, targets, props, onlyActive); 7287 }; 7288 7289 _independentRoot._start = gsap.ticker.time; 7290 gsap.ticker.add(function (time) { 7291 return _independentRoot.render(time - _independentRoot._start); 7292 }); //align the all of the playheads so they're starting at 0 now. 7293 7294 _globalTimeline._start += _globalTimeline._time; 7295 _recordedRoot._start = _globalTimeline._time = _globalTimeline._tTime = 0; 7296 7297 _delayedCall = function _delayedCall(delay, callback, params, scope) { 7298 return gsap.to(callback, { 7299 delay: delay, 7300 duration: 0, 7301 onComplete: callback, 7302 onReverseComplete: callback, 7303 onCompleteParams: params, 7304 onReverseCompleteParams: params, 7305 callbackScope: scope, 7306 parent: _independentRoot 7307 }); 7308 }; //in case GSDevTools.create() is called before anything is actually on the global timeline, we've gotta update it or else the duration will be 0 and it'll be stuck. 7309 7310 7311 _delayedCall(0.01, function () { 7312 return _rootInstance ? _rootInstance.update() : _merge(); 7313 }); //initially we record everything into the _recordedRoot Timeline because developers might call GSDevTools.create() AFTER some of their code executes, but after 2 seconds if there aren't any GSDevTool instances that have globalSync enabled, we should dump all the stuff from _recordedRoot into the global timeline to improve performance and avoid issues where _recordedRoot is paused and reaches its end and wants to stop the playhead. 7314 7315 7316 _delayedCall(2, function () { 7317 var t, next, offset; 7318 7319 if (!_rootInstance) { 7320 _merge(); 7321 7322 t = _recordedRoot._first; 7323 offset = _recordedRoot._start; 7324 7325 while (t) { 7326 next = t._next; //any animations that aren't finished should be dumped into the root timeline. If they're done, just kill them. 7327 7328 if (t._tDur !== t._tTime || !t._dur && t.progress() !== 1) { 7329 _globalTimeline.add(t, t._start - t._delay + offset); 7330 } else { 7331 t.kill(); 7332 } 7333 7334 t = next; 7335 } 7336 } 7337 7338 if (GSDevTools.globalRecordingTime > 2) { 7339 _delayedCall(GSDevTools.globalRecordingTime - 2, function () { 7340 _rootInstance && _rootInstance.update(); 7341 _recording = false; 7342 _globalTimeline.autoRemoveChildren = true; 7343 }); 7344 } else { 7345 _recording = false; 7346 _globalTimeline.autoRemoveChildren = true; 7347 } 7348 7349 _startupPhase = false; 7350 }); 7351 7352 _coreInitted = 1; 7353 } 7354 } 7355}, 7356 _checkIndependence = function _checkIndependence(animation, vars) { 7357 if (!vars.globalSync && animation.parent !== _globalTimeline) { 7358 //in case it's nested in a timeline (playing it won't help if the parent timeline isn't playing). 7359 _globalTimeline.add(animation, _globalTimeline.time()); 7360 } 7361}, 7362 GSDevTools = function GSDevTools(vars) { 7363 if (!_coreInitted) { 7364 _initCore(); 7365 7366 gsap || console.warn("Please gsap.registerPlugin(GSDevTools)"); 7367 } 7368 7369 this.vars = vars = vars || {}; 7370 7371 if (vars.animation) { 7372 (GSDevTools.getByAnimation(vars.animation) || { 7373 kill: function kill() { 7374 return 0; 7375 } 7376 }).kill(); 7377 } 7378 7379 vars.id = vars.id || (_isString(vars.animation) ? vars.animation : _idSeed++); //try to find a unique ID so that sessionStorage can be mapped to it (otherwise, for example, all the embedded codepens on a page would share the same settings). So if no id is defined, see if there's a string-based "animation" defined. Last of all, we default to a numeric counter that we increment. 7380 7381 _lookup[vars.id + ""] = this; 7382 "globalSync" in vars || (vars.globalSync = !vars.animation); //if the user calls create() and passes in an animation AFTER the initial recording time has elapsed, there's a good chance the animation won't be in the recordedRoot, so we change the default globalSync to false because that's the most intuitive behavior. 7383 //GENERAL/UTILITY 7384 7385 var _self = this, 7386 root = _createRootElement(vars.container, vars.minimal, vars.css), 7387 find = function find(s) { 7388 return root.querySelector(s); 7389 }, 7390 record = function record(key, value) { 7391 if (vars.persist !== false && _supportsStorage) { 7392 sessionStorage.setItem("gs-dev-" + key + vars.id, value); 7393 } 7394 7395 return value; 7396 }, 7397 recall = function recall(key) { 7398 var value; 7399 7400 if (vars.persist !== false && _supportsStorage) { 7401 value = sessionStorage.getItem("gs-dev-" + key + vars.id); 7402 return key === "animation" ? value : key === "loop" ? value === "true" : parseFloat(value); // handle data typing too. 7403 } 7404 }, 7405 //SCRUBBER/PROGRESS 7406 playhead = find(".playhead"), 7407 timelineTrack = find(".timeline-track"), 7408 progressBar = find(".progress-bar"), 7409 timeLabel = find(".time"), 7410 durationLabel = find(".duration"), 7411 pixelToTimeRatio, 7412 timeAtDragStart, 7413 dragged, 7414 skipDragUpdates, 7415 progress = 0, 7416 inPoint = find(".in-point"), 7417 outPoint = find(".out-point"), 7418 inProgress = 0, 7419 outProgress = 100, 7420 pausedWhenDragStarted, 7421 list = find(".animation-list"), 7422 animationLabel = find(".animation-label"), 7423 selectedAnimation, 7424 //the currently selected animation 7425 linkedAnimation, 7426 //the animation that's linked to all the controls and scrubber. This is always _rootTween if globalSync is true, so it can be different than the selectedAnimation! 7427 declaredAnimation, 7428 //whatever the user defines in the config object initially (often this will be null). If the user defines a string, it'll be resolved to a real Animation instance for this variable. 7429 startTime, 7430 endTime, 7431 _fullyInitialized, 7432 //we call initialize() initially, and then again on the very next tick just in case someone called GSDevTools.create() BEFORE they create their animations. This variable tracks that state. Note: we don't record sessionStorage.setItem() until we're fully initialized, otherwise we may inadvertently set in/out points to the defaults just because the animation couldn't be found (yet). 7433 keyboardHandler, 7434 playPauseButton = find(".play-pause"), 7435 playPauseMorph = _buildPlayPauseMorph(playPauseButton), 7436 paused = false, 7437 loopButton = find(".loop"), 7438 loopAnimation = _buildLoopAnimation(loopButton), 7439 loopEnabled, 7440 timeScale = find(".time-scale select"), 7441 timeScaleLabel = find(".time-scale-label"), 7442 //spits back a common onPress function for anything that's dragged along the timeline (playhead, inPoint, outPoint). The originRatio is a value from 0-1 indicating how far along the x-axis the origin is located (0.5 is in the center, 0 is left, 1 is on right side). limitElement is optional, and sets the bounds such that the element can't be dragged past the limitElement. 7443 onPressTimeline = function onPressTimeline(element, originRatio, limitToInOut) { 7444 return function (e) { 7445 var trackBounds = timelineTrack.getBoundingClientRect(), 7446 elementBounds = element.getBoundingClientRect(), 7447 left = elementBounds.width * originRatio, 7448 x = gsap.getProperty(element, "x"), 7449 minX = trackBounds.left - elementBounds.left - left + x, 7450 maxX = trackBounds.right - elementBounds.right + (elementBounds.width - left) + x, 7451 unlimitedMinX = minX, 7452 limitBounds; 7453 7454 if (limitToInOut) { 7455 if (element !== inPoint) { 7456 limitBounds = inPoint.getBoundingClientRect(); 7457 7458 if (limitBounds.left) { 7459 //if inPoint is hidden (like display:none), ignore. 7460 minX += limitBounds.left + limitBounds.width - trackBounds.left; 7461 } 7462 } 7463 7464 if (element !== outPoint) { 7465 limitBounds = outPoint.getBoundingClientRect(); 7466 7467 if (limitBounds.left) { 7468 //if outPoint is hidden (like display:none), ignore. 7469 maxX -= trackBounds.left + trackBounds.width - limitBounds.left; 7470 } 7471 } 7472 } 7473 7474 pausedWhenDragStarted = paused; 7475 this.applyBounds({ 7476 minX: minX, 7477 maxX: maxX 7478 }); 7479 pixelToTimeRatio = linkedAnimation.duration() / trackBounds.width; 7480 timeAtDragStart = -unlimitedMinX * pixelToTimeRatio; 7481 7482 if (!skipDragUpdates) { 7483 linkedAnimation.pause(timeAtDragStart + pixelToTimeRatio * this.x); 7484 } else { 7485 linkedAnimation.pause(); 7486 } 7487 7488 if (this.target === playhead) { 7489 if (this.activated) { 7490 this.allowEventDefault = false; 7491 } 7492 7493 this.activated = true; 7494 } 7495 7496 dragged = true; 7497 }; 7498 }, 7499 progressDrag = _Draggable_js__WEBPACK_IMPORTED_MODULE_0__["Draggable"].create(playhead, { 7500 type: "x", 7501 cursor: "ew-resize", 7502 allowNativeTouchScrolling: false, 7503 allowEventDefault: true, 7504 //otherwise, when dragged outside an iframe, the mouseup doesn't bubble up so it could seem "stuck" to the mouse. 7505 onPress: onPressTimeline(playhead, 0.5, true), 7506 onDrag: function onDrag() { 7507 var time = timeAtDragStart + pixelToTimeRatio * this.x; 7508 7509 if (time < 0) { 7510 time = 0; 7511 } else if (time > linkedAnimation._dur) { 7512 time = linkedAnimation._dur; 7513 } 7514 7515 if (!skipDragUpdates) { 7516 linkedAnimation.time(time); 7517 } 7518 7519 progressBar.style.width = Math.min(outProgress - inProgress, Math.max(0, time / linkedAnimation._dur * 100 - inProgress)) + "%"; 7520 timeLabel.innerHTML = time.toFixed(2); 7521 }, 7522 onRelease: function onRelease() { 7523 paused || linkedAnimation.resume(); 7524 } 7525 })[0], 7526 resetInOut = function resetInOut() { 7527 inProgress = 0; 7528 outProgress = 100; 7529 inPoint.style.left = "0%"; 7530 outPoint.style.left = "100%"; 7531 record("in", inProgress); 7532 record("out", outProgress); 7533 updateProgress(true); 7534 }, 7535 inDrag = _Draggable_js__WEBPACK_IMPORTED_MODULE_0__["Draggable"].create(inPoint, { 7536 type: "x", 7537 cursor: "ew-resize", 7538 zIndexBoost: false, 7539 allowNativeTouchScrolling: false, 7540 allowEventDefault: true, 7541 //otherwise, when dragged outside an iframe, the mouseup doesn't bubble up so it could seem "stuck" to the mouse. 7542 onPress: onPressTimeline(inPoint, 1, true), 7543 onDoubleClick: resetInOut, 7544 onDrag: function onDrag() { 7545 inProgress = (timeAtDragStart + pixelToTimeRatio * this.x) / linkedAnimation.duration() * 100; 7546 linkedAnimation.progress(inProgress / 100); 7547 updateProgress(true); 7548 }, 7549 onRelease: function onRelease() { 7550 if (inProgress < 0) { 7551 inProgress = 0; 7552 } 7553 7554 _clearSelection(); //for responsiveness, convert the px-based transform into %-based left position. 7555 7556 7557 inPoint.style.left = inProgress + "%"; 7558 record("in", inProgress); 7559 gsap.set(inPoint, { 7560 x: 0, 7561 data: "root", 7562 display: "block" 7563 }); //set display:block so that it remains visible even when the minimal skin is enabled. 7564 7565 if (!paused) { 7566 linkedAnimation.resume(); 7567 } 7568 } 7569 })[0], 7570 outDrag = _Draggable_js__WEBPACK_IMPORTED_MODULE_0__["Draggable"].create(outPoint, { 7571 type: "x", 7572 cursor: "ew-resize", 7573 allowNativeTouchScrolling: false, 7574 allowEventDefault: true, 7575 //otherwise, when dragged outside an iframe, the mouseup doesn't bubble up so it could seem "stuck" to the mouse. 7576 zIndexBoost: false, 7577 onPress: onPressTimeline(outPoint, 0, true), 7578 onDoubleClick: resetInOut, 7579 onDrag: function onDrag() { 7580 outProgress = (timeAtDragStart + pixelToTimeRatio * this.x) / linkedAnimation.duration() * 100; 7581 linkedAnimation.progress(outProgress / 100); 7582 updateProgress(true); 7583 }, 7584 onRelease: function onRelease() { 7585 if (outProgress > 100) { 7586 outProgress = 100; 7587 } 7588 7589 _clearSelection(); //for responsiveness, convert the px-based transform into %-based left position. 7590 7591 7592 outPoint.style.left = outProgress + "%"; 7593 record("out", outProgress); 7594 gsap.set(outPoint, { 7595 x: 0, 7596 data: "root", 7597 display: "block" 7598 }); //set display:block so that it remains visible even when the minimal skin is enabled. 7599 7600 if (!pausedWhenDragStarted) { 7601 play(); 7602 linkedAnimation.resume(); 7603 } 7604 } 7605 })[0], 7606 updateProgress = function updateProgress(force) { 7607 // NOTE: "force" is actually the "time" when this method gets called by the gsap.ticker! 7608 if (progressDrag.isPressed && force !== true) { 7609 return; 7610 } 7611 7612 var p = !loopEnabled && selectedAnimation._repeat === -1 ? selectedAnimation.totalTime() / selectedAnimation.duration() * 100 : linkedAnimation.progress() * 100 || 0, 7613 repeatDelayPhase = selectedAnimation._repeat && selectedAnimation._rDelay && selectedAnimation.totalTime() % (selectedAnimation.duration() + selectedAnimation._rDelay) > selectedAnimation.duration(), 7614 target; 7615 7616 if (p > 100) { 7617 p = 100; 7618 } 7619 7620 if (p >= outProgress) { 7621 if (loopEnabled && !linkedAnimation.paused() && !progressDrag.isDragging) { 7622 if (!repeatDelayPhase) { 7623 p = inProgress; 7624 target = linkedAnimation._targets && linkedAnimation._targets[0]; 7625 7626 if (target === selectedAnimation) { 7627 //in case there are callbacks on the timeline, when we jump back to the start we should seek() so that the playhead doesn't drag [backward] past those and trigger them. 7628 target.seek(startTime + (endTime - startTime) * inProgress / 100); 7629 } 7630 7631 if (selectedAnimation._repeat > 0 && !inProgress && outProgress === 100) { 7632 if (selectedAnimation.totalProgress() === 1) { 7633 linkedAnimation.totalProgress(0, true).resume(); 7634 } 7635 } else { 7636 linkedAnimation.progress(p / 100, true).resume(); 7637 } 7638 } 7639 } else { 7640 if (p !== outProgress || selectedAnimation._repeat === -1) { 7641 p = outProgress; 7642 linkedAnimation.progress(p / 100); 7643 } 7644 7645 if (!paused && (outProgress < 100 || selectedAnimation.totalProgress() === 1 || selectedAnimation._repeat === -1)) { 7646 pause(); 7647 } 7648 } 7649 } else if (p < inProgress) { 7650 p = inProgress; 7651 linkedAnimation.progress(p / 100, true); 7652 } 7653 7654 if (p !== progress || force === true) { 7655 progressBar.style.left = inProgress + "%"; 7656 progressBar.style.width = Math.max(0, p - inProgress) + "%"; 7657 playhead.style.left = p + "%"; 7658 timeLabel.innerHTML = linkedAnimation._time.toFixed(2); 7659 durationLabel.innerHTML = linkedAnimation._dur.toFixed(2); 7660 7661 if (dragged) { 7662 playhead.style.transform = "translate(-50%,0)"; 7663 playhead._gsap.x = "0px"; 7664 playhead._gsap.xPercent = -50; 7665 dragged = false; 7666 } 7667 7668 progress = p; 7669 } 7670 7671 linkedAnimation.paused() !== paused && togglePlayPause(); // if the user has an addPause() in the middle of the animation. 7672 }, 7673 onPressSeekBar = function onPressSeekBar(e) { 7674 if (progressDrag.isPressed) { 7675 return; 7676 } 7677 7678 var bounds = e.target.getBoundingClientRect(), 7679 x = (e.changedTouches ? e.changedTouches[0] : e).clientX, 7680 p = (x - bounds.left) / bounds.width * 100; 7681 7682 if (p < inProgress) { 7683 inProgress = p = Math.max(0, p); 7684 inPoint.style.left = inProgress + "%"; 7685 inDrag.startDrag(e); 7686 return; 7687 } else if (p > outProgress) { 7688 outProgress = p = Math.min(100, p); 7689 outPoint.style.left = outProgress + "%"; 7690 outDrag.startDrag(e); 7691 return; 7692 } 7693 7694 linkedAnimation.progress(p / 100).pause(); 7695 updateProgress(true); 7696 progressDrag.startDrag(e); 7697 }, 7698 //PLAY/PAUSE button 7699 play = function play() { 7700 if (linkedAnimation.progress() >= outProgress / 100) { 7701 _checkIndependence(linkedAnimation, vars); 7702 7703 var target = linkedAnimation._targets && linkedAnimation._targets[0]; 7704 7705 if (target === selectedAnimation) { 7706 //in case there are callbacks on the timeline, when we jump back to the start we should seek() so that the playhead doesn't drag [backward] past those and trigger them. 7707 target.seek(startTime + (endTime - startTime) * inProgress / 100); 7708 } 7709 7710 if (linkedAnimation._repeat && !inProgress) { 7711 linkedAnimation.totalProgress(0, true); //for repeating animations, don't get stuck in the last iteration - jump all the way back to the start. 7712 } else if (!linkedAnimation.reversed()) { 7713 linkedAnimation.progress(inProgress / 100, true); 7714 } 7715 } 7716 7717 playPauseMorph.play(); 7718 linkedAnimation.resume(); 7719 7720 if (paused) { 7721 _self.update(); 7722 } 7723 7724 paused = false; 7725 }, 7726 pause = function pause() { 7727 playPauseMorph.reverse(); 7728 7729 if (linkedAnimation) { 7730 linkedAnimation.pause(); 7731 } 7732 7733 paused = true; 7734 }, 7735 togglePlayPause = function togglePlayPause() { 7736 if (paused) { 7737 play(); 7738 } else { 7739 pause(); 7740 } 7741 }, 7742 //REWIND button 7743 onPressRewind = function onPressRewind(e) { 7744 if (progressDrag.isPressed) { 7745 return; 7746 } //_self.update(); 7747 7748 7749 _checkIndependence(linkedAnimation, vars); 7750 7751 var target = linkedAnimation._targets && linkedAnimation._targets[0]; 7752 7753 if (target === selectedAnimation) { 7754 //in case there are callbacks on the timeline, when we jump back to the start we should seek() so that the playhead doesn't drag [backward] past those and trigger them. 7755 target.seek(startTime + (endTime - startTime) * inProgress / 100); 7756 } 7757 7758 linkedAnimation.progress(inProgress / 100, true); 7759 7760 if (!paused) { 7761 linkedAnimation.resume(); 7762 } 7763 }, 7764 //LOOP button 7765 loop = function loop(value) { 7766 loopEnabled = value; 7767 record("loop", loopEnabled); 7768 7769 if (loopEnabled) { 7770 loopAnimation.play(); 7771 7772 if (linkedAnimation.progress() >= outProgress / 100) { 7773 var target = linkedAnimation._targets && linkedAnimation._targets[0]; 7774 7775 if (target === selectedAnimation) { 7776 //in case there are callbacks on the timeline, when we jump back to the start we should seek() so that the playhead doesn't drag [backward] past those and trigger them. 7777 target.seek(startTime + (endTime - startTime) * inProgress / 100); 7778 } 7779 7780 if (selectedAnimation._repeat && !inProgress && outProgress === 100) { 7781 linkedAnimation.totalProgress(0, true); 7782 } else { 7783 linkedAnimation.progress(inProgress / 100, true); 7784 } 7785 7786 play(); 7787 } 7788 } else { 7789 loopAnimation.reverse(); 7790 } 7791 }, 7792 toggleLoop = function toggleLoop() { 7793 return loop(!loopEnabled); 7794 }, 7795 //ANIMATIONS list 7796 updateList = function updateList() { 7797 var animations = _getChildrenOf(declaredAnimation && !vars.globalSync ? declaredAnimation : _recordedRoot, true), 7798 options = list.children, 7799 matches = 0, 7800 option, 7801 i; 7802 7803 if (declaredAnimation && !vars.globalSync) { 7804 animations.unshift(declaredAnimation); 7805 } else if (!vars.hideGlobalTimeline) { 7806 animations.unshift(_recordedRoot); 7807 } 7808 7809 for (i = 0; i < animations.length; i++) { 7810 option = options[i] || _createElement("option", list); 7811 option.animation = animations[i]; 7812 matches = i && animations[i].vars.id === animations[i - 1].vars.id ? matches + 1 : 0; 7813 option.setAttribute("value", option.innerHTML = animations[i].vars.id + (matches ? " [" + matches + "]" : animations[i + 1] && animations[i + 1].vars.id === animations[i].vars.id ? " [0]" : "")); 7814 } 7815 7816 for (; i < options.length; i++) { 7817 list.removeChild(options[i]); 7818 } 7819 }, 7820 animation = function animation(anim) { 7821 var ts = parseFloat(timeScale.options[timeScale.selectedIndex].value) || 1, 7822 tl, 7823 maxDuration; 7824 7825 if (!arguments.length) { 7826 return selectedAnimation; 7827 } 7828 7829 if (_isString(anim)) { 7830 anim = _getAnimationById(anim); 7831 } //console.log("animation() ", anim.vars.id); 7832 7833 7834 if (!(anim instanceof Animation)) { 7835 console.warn("GSDevTools error: invalid animation."); 7836 } 7837 7838 if (anim === selectedAnimation) { 7839 return; 7840 } 7841 7842 if (selectedAnimation) { 7843 selectedAnimation._inProgress = inProgress; 7844 selectedAnimation._outProgress = outProgress; 7845 } 7846 7847 selectedAnimation = anim; 7848 7849 if (linkedAnimation) { 7850 ts = linkedAnimation.timeScale(); 7851 7852 if (linkedAnimation._targets && linkedAnimation._targets[0] === declaredAnimation) { 7853 declaredAnimation.resume(); 7854 linkedAnimation.kill(); 7855 } 7856 } 7857 7858 inProgress = selectedAnimation._inProgress || 0; 7859 outProgress = selectedAnimation._outProgress || 100; 7860 inPoint.style.left = inProgress + "%"; 7861 outPoint.style.left = outProgress + "%"; 7862 7863 if (_fullyInitialized) { 7864 //don't record inProgress/outProgress unless we're fully instantiated because people may call GSDevTools.create() before creating/defining their animations, thus the inTime/outTime may not exist yet. 7865 record("animation", selectedAnimation.vars.id); 7866 record("in", inProgress); 7867 record("out", outProgress); 7868 } 7869 7870 startTime = 0; 7871 maxDuration = vars.maxDuration || Math.min(1000, _getClippedDuration(selectedAnimation)); 7872 7873 if (selectedAnimation === _recordedRoot || vars.globalSync) { 7874 _merge(); 7875 7876 linkedAnimation = _rootTween; 7877 _rootInstance && _rootInstance !== _self && console.warn("Error: GSDevTools can only have one instance that's globally synchronized."); 7878 _rootInstance = _self; 7879 7880 if (selectedAnimation !== _recordedRoot) { 7881 tl = selectedAnimation; 7882 endTime = tl.totalDuration(); 7883 7884 if (endTime > 99999999) { 7885 //in the case of an infinitely repeating animation, just use a single iteration's duration instead. 7886 endTime = tl.duration(); 7887 } 7888 7889 while (tl.parent.parent) { 7890 startTime = startTime / tl._ts + tl._start; 7891 endTime = endTime / tl._ts + tl._start; 7892 tl = tl.parent; 7893 } 7894 } else { 7895 endTime = _recordedRoot.duration(); 7896 } 7897 7898 if (endTime - startTime > maxDuration) { 7899 //cap end time at 1000 because it doesn't seem reasonable to accommodate super long stuff. 7900 endTime = startTime + maxDuration; 7901 } 7902 7903 _recordedRoot.pause(startTime); 7904 7905 _rootTween.vars.time = endTime; 7906 7907 _rootTween.invalidate(); 7908 7909 _rootTween.duration(endTime - startTime).timeScale(ts); //wait for a tick before starting because some browsers freeze things immediately following a <select> selection, like on MacOS it flashes a few times before disappearing, so this prevents a "jump". 7910 7911 7912 if (paused) { 7913 //jump forward and then back in order to make sure the start/end values are recorded internally right away and don't drift outside this tween. 7914 _rootTween.progress(1).pause(0); 7915 } else { 7916 _delayedCall(0.01, function () { 7917 _rootTween.resume().progress(inProgress / 100); 7918 7919 if (paused) { 7920 play(); 7921 } 7922 }); 7923 } 7924 } else { 7925 if (_rootInstance === _self) { 7926 _rootInstance = null; 7927 } 7928 7929 if (selectedAnimation === declaredAnimation || !declaredAnimation) { 7930 linkedAnimation = selectedAnimation; 7931 7932 if (!loopEnabled && linkedAnimation._repeat) { 7933 loop(true); 7934 } 7935 } else { 7936 //if an animation is declared in the config object, and the user chooses a sub-animation (nested), we tween the playhead of the declaredAnimation to keep everything synchronized even though globalSync isn't true. 7937 tl = selectedAnimation; 7938 endTime = tl.totalDuration(); 7939 7940 if (endTime > 99999999) { 7941 //in the case of an infinitely repeating animation, just use a single iteration's duration instead. 7942 endTime = tl.duration(); 7943 } 7944 7945 while (tl.parent.parent && tl !== declaredAnimation) { 7946 startTime = startTime / (tl._ts || tl._pauseTS) + tl._start; 7947 endTime = endTime / (tl._ts || tl._pauseTS) + tl._start; 7948 tl = tl.parent; 7949 } 7950 7951 if (endTime - startTime > maxDuration) { 7952 //cap end time at 1000 because it doesn't seem reasonable to accommodate super long stuff. 7953 endTime = startTime + maxDuration; 7954 } 7955 7956 declaredAnimation.pause(startTime); 7957 linkedAnimation = gsap.to(declaredAnimation, { 7958 duration: endTime - startTime, 7959 time: endTime, 7960 ease: "none", 7961 data: "root", 7962 parent: _independentRoot 7963 }); 7964 } 7965 7966 linkedAnimation.timeScale(ts); 7967 7968 _rootTween.pause(); 7969 7970 _recordedRoot.resume(); 7971 7972 linkedAnimation.seek(0); 7973 } 7974 7975 durationLabel.innerHTML = linkedAnimation.duration().toFixed(2); 7976 7977 _selectValue(list, selectedAnimation.vars.id, animationLabel); 7978 }, 7979 updateRootDuration = function updateRootDuration() { 7980 var time, ratio, duration; 7981 7982 if (selectedAnimation === _recordedRoot) { 7983 time = _recordedRoot._time; 7984 7985 _recordedRoot.progress(1, true).time(time, true); //jump to the end and back again because sometimes a tween that hasn't rendered yet will affect duration, like a TimelineMax.tweenTo() where the duration gets set in the onStart. 7986 7987 7988 time = (_rootTween._dp._time - _rootTween._start) * _rootTween._ts; 7989 duration = Math.min(1000, _recordedRoot.duration()); 7990 7991 if (duration === 1000) { 7992 duration = Math.min(1000, _getClippedDuration(_recordedRoot)); 7993 } 7994 7995 ratio = _rootTween.duration() / duration; 7996 7997 if (ratio !== 1 && duration) { 7998 inProgress *= ratio; 7999 8000 if (outProgress < 100) { 8001 outProgress *= ratio; 8002 } 8003 8004 _rootTween.seek(0); 8005 8006 _rootTween.vars.time = duration; 8007 8008 _rootTween.invalidate(); 8009 8010 _rootTween.duration(duration); 8011 8012 _rootTween.time(time); 8013 8014 durationLabel.innerHTML = duration.toFixed(2); 8015 inPoint.style.left = inProgress + "%"; 8016 outPoint.style.left = outProgress + "%"; 8017 updateProgress(true); 8018 } 8019 } 8020 }, 8021 onChangeAnimation = function onChangeAnimation(e) { 8022 animation(list.options[list.selectedIndex].animation); 8023 8024 if (e.target && e.target.blur) { 8025 //so that if an option is selected, and then the user tries to hit the up/down arrow, it doesn't just try selecting something else in the <select>. 8026 e.target.blur(); 8027 } 8028 8029 paused && play(); 8030 }, 8031 //TIMESCALE button 8032 onChangeTimeScale = function onChangeTimeScale(e) { 8033 var ts = parseFloat(timeScale.options[timeScale.selectedIndex].value) || 1, 8034 target; 8035 linkedAnimation.timeScale(ts); 8036 record("timeScale", ts); 8037 8038 if (!paused) { 8039 if (linkedAnimation.progress() >= outProgress / 100) { 8040 target = linkedAnimation._targets && linkedAnimation._targets[0]; 8041 8042 if (target === selectedAnimation) { 8043 //in case there are callbacks on the timeline, when we jump back to the start we should seek() so that the playhead doesn't drag [backward] past those and trigger them. 8044 target.seek(startTime + (endTime - startTime) * inProgress / 100); 8045 } 8046 8047 linkedAnimation.progress(inProgress / 100, true).pause(); 8048 } else { 8049 linkedAnimation.pause(); 8050 } 8051 8052 _delayedCall(0.01, function () { 8053 return linkedAnimation.resume(); 8054 }); 8055 } 8056 8057 timeScaleLabel.innerHTML = ts + "x"; 8058 8059 if (timeScale.blur) { 8060 //so that if an option is selected, and then the user tries to hit the up/down arrow, it doesn't just try selecting something else in the <select>. 8061 timeScale.blur(); 8062 } 8063 }, 8064 //AUTOHIDE 8065 autoHideTween = gsap.to([find(".gs-bottom"), find(".gs-top")], { 8066 duration: 0.3, 8067 autoAlpha: 0, 8068 y: 50, 8069 ease: "power2.in", 8070 data: "root", 8071 paused: true, 8072 parent: _independentRoot 8073 }), 8074 hidden = false, 8075 onMouseOut = function onMouseOut(e) { 8076 if (!_Draggable_js__WEBPACK_IMPORTED_MODULE_0__["Draggable"].hitTest(e, root) && !progressDrag.isDragging && !inDrag.isDragging && !outDrag.isDragging) { 8077 autoHideDelayedCall.restart(true); 8078 } 8079 }, 8080 hide = function hide() { 8081 if (!hidden) { 8082 autoHideTween.play(); 8083 autoHideDelayedCall.pause(); 8084 hidden = true; 8085 } 8086 }, 8087 show = function show() { 8088 autoHideDelayedCall.pause(); 8089 8090 if (hidden) { 8091 autoHideTween.reverse(); 8092 hidden = false; 8093 } 8094 }, 8095 toggleHide = function toggleHide() { 8096 if (hidden) { 8097 show(); 8098 } else { 8099 hide(); 8100 } 8101 }, 8102 autoHideDelayedCall = _delayedCall(1.3, hide).pause(), 8103 initialize = function initialize(preliminary) { 8104 //if on startup, someone does a timeline.seek(), we must honor it, so when initialize() is called, we record _recordedRoot._start so that we can use that as an offset. Remember, however, that we call initialize() twice on startup, once after a tick has elapsed just in case someone called GSDevTools.create() before their animation code, so we must record the value (once). 8105 if (_startupPhase && !_globalStartTime) { 8106 _globalStartTime = _recordedRoot._start; 8107 } 8108 8109 _fullyInitialized = !preliminary; 8110 declaredAnimation = _parseAnimation(vars.animation); 8111 8112 if (declaredAnimation && !declaredAnimation.vars.id) { 8113 declaredAnimation.vars.id = "[no id]"; 8114 } 8115 8116 _merge(); 8117 8118 updateList(); 8119 8120 var savedAnimation = _getAnimationById(recall("animation")); 8121 8122 if (savedAnimation) { 8123 savedAnimation._inProgress = recall("in") || 0; 8124 savedAnimation._outProgress = recall("out") || 100; 8125 } 8126 8127 vars.paused && pause(); 8128 selectedAnimation = null; 8129 animation(declaredAnimation || savedAnimation || _recordedRoot); 8130 var ts = vars.timeScale || recall("timeScale"), 8131 savedInOut = savedAnimation === selectedAnimation; 8132 8133 if (ts) { 8134 _selectValue(timeScale, ts, timeScaleLabel, ts + "x"); 8135 8136 linkedAnimation.timeScale(ts); 8137 } 8138 8139 inProgress = ("inTime" in vars ? _timeToProgress(vars.inTime, selectedAnimation, 0, 0) : savedInOut ? savedAnimation._inProgress : 0) || 0; 8140 8141 if (inProgress === 100 && !vars.animation && savedAnimation) { 8142 //in case there's a recorded animation (sessionStorage) and then the user defines an inTime that exceeds that animation's duration, just default back to the Global Timeline. Otherwise the in/out point will be at the very end and it'd be weird. 8143 animation(_recordedRoot); 8144 inProgress = _timeToProgress(vars.inTime, selectedAnimation, 0, 0) || 0; 8145 } 8146 8147 if (inProgress) { 8148 inPoint.style.left = inProgress + "%"; 8149 inPoint.style.display = outPoint.style.display = "block"; //set display:block so that it remains visible even when the minimal skin is enabled. 8150 } 8151 8152 outProgress = ("outTime" in vars ? _timeToProgress(vars.outTime, selectedAnimation, 100, inProgress) : savedInOut ? savedAnimation._outProgress : 0) || 100; 8153 8154 if (outProgress < inProgress) { 8155 outProgress = 100; 8156 } 8157 8158 if (outProgress !== 100) { 8159 outPoint.style.left = outProgress + "%"; 8160 inPoint.style.display = outPoint.style.display = "block"; //set display:block so that it remains visible even when the minimal skin is enabled. 8161 } 8162 8163 loopEnabled = "loop" in vars ? vars.loop : recall("loop"); 8164 loopEnabled && loop(true); 8165 vars.paused && linkedAnimation.progress(inProgress / 100, true).pause(); 8166 8167 if (_startupPhase && selectedAnimation === _recordedRoot && _globalStartTime && vars.globalSync && !paused) { 8168 linkedAnimation.time(-_globalStartTime, true); 8169 } 8170 8171 updateProgress(true); 8172 }; //INITIALIZATION TASKS 8173 8174 8175 _addListener(list, "change", onChangeAnimation); 8176 8177 _addListener(list, "mousedown", updateList); 8178 8179 _addListener(playPauseButton, "mousedown", togglePlayPause); 8180 8181 _addListener(find(".seek-bar"), "mousedown", onPressSeekBar); 8182 8183 _addListener(find(".rewind"), "mousedown", onPressRewind); 8184 8185 _addListener(loopButton, "mousedown", toggleLoop); 8186 8187 _addListener(timeScale, "change", onChangeTimeScale); 8188 8189 if (vars.visibility === "auto") { 8190 _addListener(root, "mouseout", onMouseOut); //_addListener(find(".gs-hit-area"), "mouseover", show); 8191 8192 8193 _addListener(root, "mouseover", show); 8194 } else if (vars.visibility === "hidden") { 8195 hidden = true; 8196 autoHideTween.progress(1); 8197 } 8198 8199 if (vars.keyboard !== false) { 8200 if (_keyboardInstance && vars.keyboard) { 8201 console.warn("[GSDevTools warning] only one instance can be affected by keyboard shortcuts. There is already one active."); 8202 } else { 8203 _keyboardInstance = _self; //we can't have multiple instances all affected by the keyboard. 8204 8205 keyboardHandler = function keyboardHandler(e) { 8206 //window.parent allows things to work inside of an iframe, like on codepen. 8207 var key = e.keyCode ? e.keyCode : e.which, 8208 ts; 8209 8210 if (key === 32) { 8211 //spacebar 8212 togglePlayPause(); 8213 } else if (key === 38) { 8214 //up arrow 8215 ts = parseFloat(_shiftSelectedValue(timeScale, -1, timeScaleLabel)); 8216 linkedAnimation.timeScale(ts); 8217 record("timeScale", ts); 8218 } else if (key === 40) { 8219 //down arrow 8220 ts = parseFloat(_shiftSelectedValue(timeScale, 1, timeScaleLabel)); 8221 linkedAnimation.timeScale(ts); 8222 record("timeScale", ts); 8223 } else if (key === 37) { 8224 //left arrow 8225 onPressRewind(e); 8226 } else if (key === 39) { 8227 //right arrow 8228 linkedAnimation.progress(outProgress / 100); 8229 } else if (key === 76) { 8230 //"L" key 8231 toggleLoop(); 8232 } else if (key === 72) { 8233 //"H" key 8234 toggleHide(); 8235 } else if (key === 73) { 8236 //"I" key 8237 inProgress = linkedAnimation.progress() * 100; 8238 record("in", inProgress); 8239 inPoint.style.left = inProgress + "%"; 8240 updateProgress(true); 8241 } else if (key === 79) { 8242 //"O" key 8243 outProgress = linkedAnimation.progress() * 100; 8244 record("out", outProgress); 8245 outPoint.style.left = outProgress + "%"; 8246 updateProgress(true); 8247 } 8248 }; 8249 8250 _addListener(_docEl, "keydown", keyboardHandler); 8251 } 8252 } 8253 8254 gsap.set(playhead, { 8255 xPercent: -50, 8256 x: 0, 8257 data: "root" 8258 }); //so that when we drag, x is properly discerned (browsers report in pure pixels rather than percents) 8259 8260 gsap.set(inPoint, { 8261 xPercent: -100, 8262 x: 0, 8263 data: "root" 8264 }); 8265 inPoint._gsIgnore = outPoint._gsIgnore = playhead._gsIgnore = playPauseButton._gsIgnore = loopButton._gsIgnore = true; //Draggable fires off a TweenLite.set() that affects the transforms, and we don't want them to get into the _recordedRoot, so kill those tweens. 8266 8267 gsap.killTweensOf([inPoint, outPoint, playhead]); 8268 initialize(_startupPhase); 8269 8270 if (_startupPhase) { 8271 //developers may call GSDevTools.create() before they even create some of their animations, so the inTime/outTime or animation values may not exist, thus we wait for 1 tick and initialize again, just in case. 8272 _delayedCall(0.0001, initialize, [false], this); 8273 } 8274 8275 gsap.ticker.add(updateProgress); 8276 8277 this.update = function (forceMerge) { 8278 if (_rootInstance === _self) { 8279 if (!_rootTween.paused() || forceMerge) { 8280 _merge(); 8281 } 8282 8283 updateRootDuration(); 8284 } 8285 }; 8286 8287 this.kill = function () { 8288 _removeListener(list, "change", onChangeAnimation); 8289 8290 _removeListener(list, "mousedown", updateList); 8291 8292 _removeListener(playPauseButton, "mousedown", togglePlayPause); 8293 8294 _removeListener(find(".seek-bar"), "mousedown", onPressSeekBar); 8295 8296 _removeListener(find(".rewind"), "mousedown", onPressRewind); 8297 8298 _removeListener(loopButton, "mousedown", toggleLoop); 8299 8300 _removeListener(timeScale, "change", onChangeTimeScale); 8301 8302 progressDrag.disable(); 8303 inDrag.disable(); 8304 outDrag.disable(); 8305 gsap.ticker.remove(updateProgress); 8306 8307 _removeListener(root, "mouseout", onMouseOut); 8308 8309 _removeListener(root, "mouseover", show); 8310 8311 _removeListener(_docEl, "keydown", keyboardHandler); 8312 8313 root.parentNode.removeChild(root); 8314 8315 if (_rootInstance === _self) { 8316 _rootInstance = null; 8317 } 8318 8319 delete _lookup[vars.id + ""]; 8320 }; 8321 8322 this.minimal = function (value) { 8323 var isMinimal = root.classList.contains("minimal"), 8324 p; 8325 8326 if (!arguments.length || isMinimal === value) { 8327 return isMinimal; 8328 } 8329 8330 if (value) { 8331 root.classList.add("minimal"); 8332 } else { 8333 root.classList.remove("minimal"); 8334 } 8335 8336 if (vars.container) { 8337 root.style.top = value ? "calc(100% - 42px)" : "calc(100% - 51px)"; 8338 } 8339 8340 if (progressDrag.isPressed) { 8341 skipDragUpdates = true; //just in case there's actually a tween/timeline in the linkedAnimation that is altering this GSDevTool instance's "minimal()" value, it could trigger a recursive loop in the drag handlers, like if they update linkedAnimation's time/progress which in turn triggers this minimal() function which in turn dues the same, and so on. 8342 8343 progressDrag.endDrag(progressDrag.pointerEvent); 8344 skipDragUpdates = false; 8345 p = linkedAnimation.progress() * 100; 8346 progressBar.style.width = Math.max(0, p - inProgress) + "%"; 8347 playhead.style.left = p + "%"; 8348 playhead.style.transform = "translate(-50%,0)"; 8349 playhead._gsap.x = "0px"; 8350 playhead._gsap.xPercent = -50; 8351 progressDrag.startDrag(progressDrag.pointerEvent, true); 8352 } 8353 }; //expose methods: 8354 8355 8356 this.animation = animation; 8357 this.updateList = updateList; 8358}; //if on startup, someone does a timeline.seek(), we need to honor it, so when initialize() is called, it'll check the _recordedRoot._start so that we can use that as an offset. Remember, however, that we call initialize() twice on startup, once after a tick has elapsed just in case someone called GSDevTools.create() before their animation code, so we must record the value (once). 8359 8360 8361GSDevTools.version = "3.6.0"; 8362GSDevTools.globalRecordingTime = 2; 8363 8364GSDevTools.getById = function (id) { 8365 return id ? _lookup[id] : _rootInstance; 8366}; 8367 8368GSDevTools.getByAnimation = function (animation) { 8369 if (_isString(animation)) { 8370 animation = gsap.getById(animation); 8371 } 8372 8373 for (var p in _lookup) { 8374 if (_lookup[p].animation() === animation) { 8375 return _lookup[p]; 8376 } 8377 } 8378}; 8379 8380GSDevTools.create = function (vars) { 8381 return new GSDevTools(vars); 8382}; 8383 8384GSDevTools.register = _initCore; 8385_getGSAP() && gsap.registerPlugin(GSDevTools); 8386 8387 8388/***/ }), 8389
vendor: 16,922 bytes, lines 8390-8873
8390/***/ "./node_modules/gsap/InertiaPlugin.js": 8391/*!********************************************!*\ 8392 !*** ./node_modules/gsap/InertiaPlugin.js ***! 8393 \********************************************/ 8394/*! exports provided: InertiaPlugin, default, VelocityTracker */ 8395/***/ (function(module, __webpack_exports__, __webpack_require__) { 8396 8397"use strict"; 8398__webpack_require__.r(__webpack_exports__); 8399/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "InertiaPlugin", function() { return InertiaPlugin; }); 8400/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return InertiaPlugin; }); 8401/* harmony import */ var _utils_VelocityTracker_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/VelocityTracker.js */ "./node_modules/gsap/utils/VelocityTracker.js"); 8402/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VelocityTracker", function() { return _utils_VelocityTracker_js__WEBPACK_IMPORTED_MODULE_0__["VelocityTracker"]; }); 8403 8404/*! 8405 * InertiaPlugin 3.6.0 8406 * https://greensock.com 8407 * 8408 * @license Copyright 2008-2021, GreenSock. All rights reserved. 8409 * Subject to the terms at https://greensock.com/standard-license or for 8410 * Club GreenSock members, the agreement issued with that membership. 8411 * @author: Jack Doyle, [email protected] 8412*/ 8413 8414/* eslint-disable */ 8415 8416 8417var gsap, 8418 _coreInitted, 8419 _parseEase, 8420 _toArray, 8421 _power3, 8422 _config, 8423 _getUnit, 8424 PropTween, 8425 _getCache, 8426 _checkPointRatio, 8427 _clamp, 8428 _processingVars, 8429 _getTracker = _utils_VelocityTracker_js__WEBPACK_IMPORTED_MODULE_0__["VelocityTracker"].getByTarget, 8430 _getGSAP = function _getGSAP() { 8431 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 8432}, 8433 _isString = function _isString(value) { 8434 return typeof value === "string"; 8435}, 8436 _isNumber = function _isNumber(value) { 8437 return typeof value === "number"; 8438}, 8439 _isObject = function _isObject(value) { 8440 return typeof value === "object"; 8441}, 8442 _isFunction = function _isFunction(value) { 8443 return typeof value === "function"; 8444}, 8445 _bonusValidated = 1, 8446 //<name>InertiaPlugin</name> 8447_isArray = Array.isArray, 8448 _emptyFunc = function _emptyFunc(p) { 8449 return p; 8450}, 8451 _bigNum = 1e10, 8452 _tinyNum = 1 / _bigNum, 8453 _checkPoint = 0.05, 8454 _round = function _round(value) { 8455 return Math.round(value * 10000) / 10000; 8456}, 8457 _extend = function _extend(obj, defaults, exclude) { 8458 for (var p in defaults) { 8459 if (!(p in obj) && p !== exclude) { 8460 obj[p] = defaults[p]; 8461 } 8462 } 8463 8464 return obj; 8465}, 8466 _deepClone = function _deepClone(obj) { 8467 var copy = {}, 8468 p, 8469 v; 8470 8471 for (p in obj) { 8472 copy[p] = _isObject(v = obj[p]) ? _deepClone(v) : v; 8473 } 8474 8475 return copy; 8476}, 8477 _getClosest = function _getClosest(n, values, max, min, radius) { 8478 var i = values.length, 8479 closest = 0, 8480 absDif = _bigNum, 8481 val, 8482 dif, 8483 p, 8484 dist; 8485 8486 if (_isObject(n)) { 8487 while (i--) { 8488 val = values[i]; 8489 dif = 0; 8490 8491 for (p in n) { 8492 dist = val[p] - n[p]; 8493 dif += dist * dist; 8494 } 8495 8496 if (dif < absDif) { 8497 closest = i; 8498 absDif = dif; 8499 } 8500 } 8501 8502 if ((radius || _bigNum) < _bigNum && radius < Math.sqrt(absDif)) { 8503 return n; 8504 } 8505 } else { 8506 while (i--) { 8507 val = values[i]; 8508 dif = val - n; 8509 8510 if (dif < 0) { 8511 dif = -dif; 8512 } 8513 8514 if (dif < absDif && val >= min && val <= max) { 8515 closest = i; 8516 absDif = dif; 8517 } 8518 } 8519 } 8520 8521 return values[closest]; 8522}, 8523 _parseEnd = function _parseEnd(curProp, end, max, min, name, radius) { 8524 if (curProp.end === "auto") { 8525 return curProp; 8526 } 8527 8528 var endVar = curProp.end, 8529 adjustedEnd, 8530 p; 8531 max = isNaN(max) ? _bigNum : max; 8532 min = isNaN(min) ? -_bigNum : min; 8533 8534 if (_isObject(end)) { 8535 //for objects, like {x, y} where they're linked and we must pass an object to the function or find the closest value in an array. 8536 adjustedEnd = end.calculated ? end : (_isFunction(endVar) ? endVar(end) : _getClosest(end, endVar, max, min, radius)) || end; 8537 8538 if (!end.calculated) { 8539 for (p in adjustedEnd) { 8540 end[p] = adjustedEnd[p]; 8541 } 8542 8543 end.calculated = true; 8544 } 8545 8546 adjustedEnd = adjustedEnd[name]; 8547 } else { 8548 adjustedEnd = _isFunction(endVar) ? endVar(end) : _isArray(endVar) ? _getClosest(end, endVar, max, min, radius) : parseFloat(endVar); 8549 } 8550 8551 if (adjustedEnd > max) { 8552 adjustedEnd = max; 8553 } else if (adjustedEnd < min) { 8554 adjustedEnd = min; 8555 } 8556 8557 return { 8558 max: adjustedEnd, 8559 min: adjustedEnd, 8560 unitFactor: curProp.unitFactor 8561 }; 8562}, 8563 _getNumOrDefault = function _getNumOrDefault(vars, property, defaultValue) { 8564 return isNaN(vars[property]) ? defaultValue : +vars[property]; 8565}, 8566 _calculateChange = function _calculateChange(velocity, duration) { 8567 return duration * _checkPoint * velocity / _checkPointRatio; 8568}, 8569 _calculateDuration = function _calculateDuration(start, end, velocity) { 8570 return Math.abs((end - start) * _checkPointRatio / velocity / _checkPoint); 8571}, 8572 _reservedProps = { 8573 resistance: 1, 8574 checkpoint: 1, 8575 preventOvershoot: 1, 8576 linkedProps: 1, 8577 radius: 1, 8578 duration: 1 8579}, 8580 _processLinkedProps = function _processLinkedProps(target, vars, getVal, resistance) { 8581 if (vars.linkedProps) { 8582 //when there are linkedProps (typically "x,y" where snapping has to factor in multiple properties, we must first populate an object with all of those end values, then feed it to the function that make any necessary alterations. So the point of this first loop is to simply build an object (like {x:100, y:204.5}) for feeding into that function which we'll do later in the "real" loop. 8583 var linkedPropNames = vars.linkedProps.split(","), 8584 linkedProps = {}, 8585 i, 8586 p, 8587 curProp, 8588 curVelocity, 8589 tracker, 8590 curDuration; 8591 8592 for (i = 0; i < linkedPropNames.length; i++) { 8593 p = linkedPropNames[i]; 8594 curProp = vars[p]; 8595 8596 if (curProp) { 8597 if (_isNumber(curProp.velocity)) { 8598 curVelocity = curProp.velocity; 8599 } else { 8600 tracker = tracker || _getTracker(target); 8601 curVelocity = tracker && tracker.isTracking(p) ? tracker.get(p) : 0; 8602 } 8603 8604 curDuration = Math.abs(curVelocity / _getNumOrDefault(curProp, "resistance", resistance)); 8605 linkedProps[p] = parseFloat(getVal(target, p)) + _calculateChange(curVelocity, curDuration); 8606 } 8607 } 8608 8609 return linkedProps; 8610 } 8611}, 8612 _calculateTweenDuration = function _calculateTweenDuration(target, vars, maxDuration, minDuration, overshootTolerance, recordEnd) { 8613 if (maxDuration === void 0) { 8614 maxDuration = 10; 8615 } 8616 8617 if (minDuration === void 0) { 8618 minDuration = 0.2; 8619 } 8620 8621 if (overshootTolerance === void 0) { 8622 overshootTolerance = 1; 8623 } 8624 8625 if (recordEnd === void 0) { 8626 recordEnd = 0; 8627 } 8628 8629 _isString(target) && (target = _toArray(target)[0]); 8630 8631 if (!target) { 8632 return 0; 8633 } 8634 8635 var duration = 0, 8636 clippedDuration = _bigNum, 8637 inertiaVars = vars.inertia || vars, 8638 getVal = _getCache(target).get, 8639 resistance = _getNumOrDefault(inertiaVars, "resistance", _config.resistance), 8640 p, 8641 curProp, 8642 curDuration, 8643 curVelocity, 8644 curVal, 8645 end, 8646 curClippedDuration, 8647 tracker, 8648 unitFactor, 8649 linkedProps; //when there are linkedProps (typically "x,y" where snapping has to factor in multiple properties, we must first populate an object with all of those end values, then feed it to the function that make any necessary alterations. So the point of this first loop is to simply build an object (like {x:100, y:204.5}) for feeding into that function which we'll do later in the "real" loop. 8650 8651 8652 linkedProps = _processLinkedProps(target, inertiaVars, getVal, resistance); 8653 8654 for (p in inertiaVars) { 8655 if (!_reservedProps[p]) { 8656 curProp = inertiaVars[p]; 8657 8658 if (!_isObject(curProp)) { 8659 tracker = tracker || _getTracker(target); 8660 8661 if (tracker && tracker.isTracking(p)) { 8662 curProp = _isNumber(curProp) ? { 8663 velocity: curProp 8664 } : { 8665 velocity: tracker.get(p) 8666 }; //if we're tracking this property, we should use the tracking velocity and then use the numeric value that was passed in as the min and max so that it tweens exactly there. 8667 } else { 8668 curVelocity = +curProp || 0; 8669 curDuration = Math.abs(curVelocity / resistance); 8670 } 8671 } 8672 8673 if (_isObject(curProp)) { 8674 if (_isNumber(curProp.velocity)) { 8675 curVelocity = curProp.velocity; 8676 } else { 8677 tracker = tracker || _getTracker(target); 8678 curVelocity = tracker && tracker.isTracking(p) ? tracker.get(p) : 0; 8679 } 8680 8681 curDuration = _clamp(minDuration, maxDuration, Math.abs(curVelocity / _getNumOrDefault(curProp, "resistance", resistance))); 8682 curVal = parseFloat(getVal(target, p)) || 0; 8683 end = curVal + _calculateChange(curVelocity, curDuration); 8684 8685 if ("end" in curProp) { 8686 curProp = _parseEnd(curProp, linkedProps && p in linkedProps ? linkedProps : end, curProp.max, curProp.min, p, inertiaVars.radius); 8687 8688 if (recordEnd) { 8689 _processingVars === vars && (_processingVars = inertiaVars = _deepClone(vars)); 8690 inertiaVars[p] = _extend(curProp, inertiaVars[p], "end"); 8691 } 8692 } 8693 8694 if ("max" in curProp && end > +curProp.max + _tinyNum) { 8695 unitFactor = curProp.unitFactor || _config.unitFactors[p] || 1; //some values are measured in special units like radians in which case our thresholds need to be adjusted accordingly. 8696 //if the value is already exceeding the max or the velocity is too low, the duration can end up being uncomfortably long but in most situations, users want the snapping to occur relatively quickly (0.75 seconds), so we implement a cap here to make things more intuitive. If the max and min match, it means we're animating to a particular value and we don't want to shorten the time unless the velocity is really slow. Example: a rotation where the start and natural end value are less than the snapping spot, but the natural end is pretty close to the snap. 8697 8698 curClippedDuration = curVal > curProp.max && curProp.min !== curProp.max || curVelocity * unitFactor > -15 && curVelocity * unitFactor < 45 ? minDuration + (maxDuration - minDuration) * 0.1 : _calculateDuration(curVal, curProp.max, curVelocity); 8699 8700 if (curClippedDuration + overshootTolerance < clippedDuration) { 8701 clippedDuration = curClippedDuration + overshootTolerance; 8702 } 8703 } else if ("min" in curProp && end < +curProp.min - _tinyNum) { 8704 unitFactor = curProp.unitFactor || _config.unitFactors[p] || 1; //some values are measured in special units like radians in which case our thresholds need to be adjusted accordingly. 8705 //if the value is already exceeding the min or if the velocity is too low, the duration can end up being uncomfortably long but in most situations, users want the snapping to occur relatively quickly (0.75 seconds), so we implement a cap here to make things more intuitive. 8706 8707 curClippedDuration = curVal < curProp.min && curProp.min !== curProp.max || curVelocity * unitFactor > -45 && curVelocity * unitFactor < 15 ? minDuration + (maxDuration - minDuration) * 0.1 : _calculateDuration(curVal, curProp.min, curVelocity); 8708 8709 if (curClippedDuration + overshootTolerance < clippedDuration) { 8710 clippedDuration = curClippedDuration + overshootTolerance; 8711 } 8712 } 8713 8714 curClippedDuration > duration && (duration = curClippedDuration); 8715 } 8716 8717 curDuration > duration && (duration = curDuration); 8718 } 8719 } 8720 8721 duration > clippedDuration && (duration = clippedDuration); 8722 return duration > maxDuration ? maxDuration : duration < minDuration ? minDuration : duration; 8723}, 8724 _initCore = function _initCore() { 8725 gsap = _getGSAP(); 8726 8727 if (gsap) { 8728 _parseEase = gsap.parseEase; 8729 _toArray = gsap.utils.toArray; 8730 _getUnit = gsap.utils.getUnit; 8731 _getCache = gsap.core.getCache; 8732 _clamp = gsap.utils.clamp; 8733 _power3 = _parseEase("power3"); 8734 _checkPointRatio = _power3(0.05); 8735 PropTween = gsap.core.PropTween; 8736 gsap.config({ 8737 resistance: 100, 8738 unitFactors: { 8739 time: 1000, 8740 totalTime: 1000, 8741 progress: 1000, 8742 totalProgress: 1000 8743 } 8744 }); 8745 _config = gsap.config(); 8746 gsap.registerPlugin(_utils_VelocityTracker_js__WEBPACK_IMPORTED_MODULE_0__["VelocityTracker"]); 8747 _coreInitted = 1; 8748 } 8749}; 8750 8751var InertiaPlugin = { 8752 version: "3.6.0", 8753 name: "inertia", 8754 register: function register(core) { 8755 gsap = core; 8756 8757 _initCore(); 8758 }, 8759 init: function init(target, vars, tween, index, targets) { 8760 _coreInitted || _initCore(); 8761 8762 var tracker = _getTracker(target); 8763 8764 if (vars === "auto") { 8765 if (!tracker) { 8766 console.warn("No inertia tracking on " + target + ". InertiaPlugin.track(target) first."); 8767 return; 8768 } 8769 8770 vars = tracker.getAll(); 8771 } 8772 8773 this.target = target; 8774 this.tween = tween; 8775 _processingVars = vars; // gets swapped inside _calculateTweenDuration() if there's a function-based value encountered (to avoid double-calling it) 8776 8777 var cache = target._gsap, 8778 getVal = cache.get, 8779 dur = vars.duration, 8780 durIsObj = _isObject(dur), 8781 preventOvershoot = vars.preventOvershoot || durIsObj && dur.overshoot === 0, 8782 resistance = _getNumOrDefault(vars, "resistance", _config.resistance), 8783 duration = _isNumber(dur) ? dur : _calculateTweenDuration(target, vars, durIsObj && dur.max || 10, durIsObj && dur.min || 0.2, durIsObj && "overshoot" in dur ? +dur.overshoot : preventOvershoot ? 0 : 1, true), 8784 p, 8785 curProp, 8786 curVal, 8787 unit, 8788 velocity, 8789 change1, 8790 end, 8791 change2, 8792 linkedProps; 8793 8794 vars = _processingVars; 8795 _processingVars = 0; //when there are linkedProps (typically "x,y" where snapping has to factor in multiple properties, we must first populate an object with all of those end values, then feed it to the function that make any necessary alterations. So the point of this first loop is to simply build an object (like {x:100, y:204.5}) for feeding into that function which we'll do later in the "real" loop. 8796 8797 linkedProps = _processLinkedProps(target, vars, getVal, resistance); 8798 8799 for (p in vars) { 8800 if (!_reservedProps[p]) { 8801 curProp = vars[p]; 8802 _isFunction(curProp) && (curProp = curProp(index, target, targets)); 8803 8804 if (_isNumber(curProp)) { 8805 velocity = curProp; 8806 } else if (_isObject(curProp) && !isNaN(curProp.velocity)) { 8807 velocity = +curProp.velocity; 8808 } else { 8809 if (tracker && tracker.isTracking(p)) { 8810 velocity = tracker.get(p); 8811 } else { 8812 console.warn("ERROR: No velocity was defined for " + target + " property: " + p); 8813 } 8814 } 8815 8816 change1 = _calculateChange(velocity, duration); 8817 change2 = 0; 8818 curVal = getVal(target, p); 8819 unit = _getUnit(curVal); 8820 curVal = parseFloat(curVal); 8821 8822 if (_isObject(curProp)) { 8823 end = curVal + change1; 8824 8825 if ("end" in curProp) { 8826 curProp = _parseEnd(curProp, linkedProps && p in linkedProps ? linkedProps : end, curProp.max, curProp.min, p, vars.radius); 8827 } 8828 8829 if ("max" in curProp && +curProp.max < end) { 8830 if (preventOvershoot || curProp.preventOvershoot) { 8831 change1 = curProp.max - curVal; 8832 } else { 8833 change2 = curProp.max - curVal - change1; 8834 } 8835 } else if ("min" in curProp && +curProp.min > end) { 8836 if (preventOvershoot || curProp.preventOvershoot) { 8837 change1 = curProp.min - curVal; 8838 } else { 8839 change2 = curProp.min - curVal - change1; 8840 } 8841 } 8842 } 8843 8844 this._props.push(p); 8845 8846 this._pt = new PropTween(this._pt, target, p, curVal, 0, _emptyFunc, 0, cache.set(target, p, this)); 8847 this._pt.u = unit || 0; 8848 this._pt.c1 = change1; 8849 this._pt.c2 = change2; 8850 } 8851 } 8852 8853 tween.duration(duration); 8854 return _bonusValidated; 8855 }, 8856 render: function render(ratio, data) { 8857 var pt = data._pt; 8858 ratio = _power3(data.tween._time / data.tween._dur); 8859 8860 while (pt) { 8861 pt.set(pt.t, pt.p, _round(pt.s + pt.c1 * ratio + pt.c2 * ratio * ratio) + pt.u, pt.d, ratio); 8862 pt = pt._next; 8863 } 8864 } 8865}; 8866"track,untrack,isTracking,getVelocity,getByTarget".split(",").forEach(function (name) { 8867 return InertiaPlugin[name] = _utils_VelocityTracker_js__WEBPACK_IMPORTED_MODULE_0__["VelocityTracker"][name]; 8868}); 8869_getGSAP() && gsap.registerPlugin(InertiaPlugin); 8870 8871 8872/***/ }), 8873
vendor: 35,065 bytes, lines 8874-9955
8874/***/ "./node_modules/gsap/MorphSVGPlugin.js": 8875/*!*********************************************!*\ 8876 !*** ./node_modules/gsap/MorphSVGPlugin.js ***! 8877 \*********************************************/ 8878/*! exports provided: MorphSVGPlugin, default */ 8879/***/ (function(module, __webpack_exports__, __webpack_require__) { 8880 8881"use strict"; 8882__webpack_require__.r(__webpack_exports__); 8883/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MorphSVGPlugin", function() { return MorphSVGPlugin; }); 8884/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return MorphSVGPlugin; }); 8885/* harmony import */ var _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/paths.js */ "./node_modules/gsap/utils/paths.js"); 8886/*! 8887 * MorphSVGPlugin 3.6.0 8888 * https://greensock.com 8889 * 8890 * @license Copyright 2008-2021, GreenSock. All rights reserved. 8891 * Subject to the terms at https://greensock.com/standard-license or for 8892 * Club GreenSock members, the agreement issued with that membership. 8893 * @author: Jack Doyle, [email protected] 8894*/ 8895 8896/* eslint-disable */ 8897 8898 8899var gsap, 8900 _toArray, 8901 _lastLinkedAnchor, 8902 _doc, 8903 _coreInitted, 8904 PluginClass, 8905 _getGSAP = function _getGSAP() { 8906 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 8907}, 8908 _isFunction = function _isFunction(value) { 8909 return typeof value === "function"; 8910}, 8911 _atan2 = Math.atan2, 8912 _cos = Math.cos, 8913 _sin = Math.sin, 8914 _sqrt = Math.sqrt, 8915 _PI = Math.PI, 8916 _2PI = _PI * 2, 8917 _angleMin = _PI * 0.3, 8918 _angleMax = _PI * 0.7, 8919 _bigNum = 1e20, 8920 _numExp = /[-+=\.]*\d+[\.e\-\+]*\d*[e\-\+]*\d*/gi, 8921 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 8922_selectorExp = /(^[#\.][a-z]|[a-y][a-z])/i, 8923 _commands = /[achlmqstvz]/i, 8924 _log = function _log(message) { 8925 return console && console.warn(message); 8926}, 8927 _bonusValidated = 1, 8928 //<name>MorphSVGPlugin</name> 8929_getAverageXY = function _getAverageXY(segment) { 8930 var l = segment.length, 8931 x = 0, 8932 y = 0, 8933 i; 8934 8935 for (i = 0; i < l; i++) { 8936 x += segment[i++]; 8937 y += segment[i]; 8938 } 8939 8940 return [x / (l / 2), y / (l / 2)]; 8941}, 8942 _getSize = function _getSize(segment) { 8943 //rough estimate of the bounding box (based solely on the anchors) of a single segment. sets "size", "centerX", and "centerY" properties on the bezier array itself, and returns the size (width * height) 8944 var l = segment.length, 8945 xMax = segment[0], 8946 xMin = xMax, 8947 yMax = segment[1], 8948 yMin = yMax, 8949 x, 8950 y, 8951 i; 8952 8953 for (i = 6; i < l; i += 6) { 8954 x = segment[i]; 8955 y = segment[i + 1]; 8956 8957 if (x > xMax) { 8958 xMax = x; 8959 } else if (x < xMin) { 8960 xMin = x; 8961 } 8962 8963 if (y > yMax) { 8964 yMax = y; 8965 } else if (y < yMin) { 8966 yMin = y; 8967 } 8968 } 8969 8970 segment.centerX = (xMax + xMin) / 2; 8971 segment.centerY = (yMax + yMin) / 2; 8972 return segment.size = (xMax - xMin) * (yMax - yMin); 8973}, 8974 _getTotalSize = function _getTotalSize(rawPath, samplesPerBezier) { 8975 if (samplesPerBezier === void 0) { 8976 samplesPerBezier = 3; 8977 } 8978 8979 //rough estimate of the bounding box of the entire list of Bezier segments (based solely on the anchors). sets "size", "centerX", and "centerY" properties on the bezier array itself, and returns the size (width * height) 8980 var j = rawPath.length, 8981 xMax = rawPath[0][0], 8982 xMin = xMax, 8983 yMax = rawPath[0][1], 8984 yMin = yMax, 8985 inc = 1 / samplesPerBezier, 8986 l, 8987 x, 8988 y, 8989 i, 8990 segment, 8991 k, 8992 t, 8993 inv, 8994 x1, 8995 y1, 8996 x2, 8997 x3, 8998 x4, 8999 y2, 9000 y3, 9001 y4; 9002 9003 while (--j > -1) { 9004 segment = rawPath[j]; 9005 l = segment.length; 9006 9007 for (i = 6; i < l; i += 6) { 9008 x1 = segment[i]; 9009 y1 = segment[i + 1]; 9010 x2 = segment[i + 2] - x1; 9011 y2 = segment[i + 3] - y1; 9012 x3 = segment[i + 4] - x1; 9013 y3 = segment[i + 5] - y1; 9014 x4 = segment[i + 6] - x1; 9015 y4 = segment[i + 7] - y1; 9016 k = samplesPerBezier; 9017 9018 while (--k > -1) { 9019 t = inc * k; 9020 inv = 1 - t; 9021 x = (t * t * x4 + 3 * inv * (t * x3 + inv * x2)) * t + x1; 9022 y = (t * t * y4 + 3 * inv * (t * y3 + inv * y2)) * t + y1; 9023 9024 if (x > xMax) { 9025 xMax = x; 9026 } else if (x < xMin) { 9027 xMin = x; 9028 } 9029 9030 if (y > yMax) { 9031 yMax = y; 9032 } else if (y < yMin) { 9033 yMin = y; 9034 } 9035 } 9036 } 9037 } 9038 9039 rawPath.centerX = (xMax + xMin) / 2; 9040 rawPath.centerY = (yMax + yMin) / 2; 9041 rawPath.left = xMin; 9042 rawPath.width = xMax - xMin; 9043 rawPath.top = yMin; 9044 rawPath.height = yMax - yMin; 9045 return rawPath.size = (xMax - xMin) * (yMax - yMin); 9046}, 9047 _sortByComplexity = function _sortByComplexity(a, b) { 9048 return b.length - a.length; 9049}, 9050 _sortBySize = function _sortBySize(a, b) { 9051 var sizeA = a.size || _getSize(a), 9052 sizeB = b.size || _getSize(b); 9053 9054 return Math.abs(sizeB - sizeA) < (sizeA + sizeB) / 20 ? b.centerX - a.centerX || b.centerY - a.centerY : sizeB - sizeA; //if the size is within 10% of each other, prioritize position from left to right, then top to bottom. 9055}, 9056 _offsetSegment = function _offsetSegment(segment, shapeIndex) { 9057 var a = segment.slice(0), 9058 l = segment.length, 9059 wrap = l - 2, 9060 i, 9061 index; 9062 shapeIndex = shapeIndex | 0; 9063 9064 for (i = 0; i < l; i++) { 9065 index = (i + shapeIndex) % wrap; 9066 segment[i++] = a[index]; 9067 segment[i] = a[index + 1]; 9068 } 9069}, 9070 _getTotalMovement = function _getTotalMovement(sb, eb, shapeIndex, offsetX, offsetY) { 9071 var l = sb.length, 9072 d = 0, 9073 wrap = l - 2, 9074 index, 9075 i, 9076 x, 9077 y; 9078 shapeIndex *= 6; 9079 9080 for (i = 0; i < l; i += 6) { 9081 index = (i + shapeIndex) % wrap; 9082 y = sb[index] - (eb[i] - offsetX); 9083 x = sb[index + 1] - (eb[i + 1] - offsetY); 9084 d += _sqrt(x * x + y * y); 9085 } 9086 9087 return d; 9088}, 9089 _getClosestShapeIndex = function _getClosestShapeIndex(sb, eb, checkReverse) { 9090 //finds the index in a closed cubic bezier array that's closest to the angle provided (angle measured from the center or average x/y). 9091 var l = sb.length, 9092 sCenter = _getAverageXY(sb), 9093 //when comparing distances, adjust the coordinates as if the shapes are centered with each other. 9094 eCenter = _getAverageXY(eb), 9095 offsetX = eCenter[0] - sCenter[0], 9096 offsetY = eCenter[1] - sCenter[1], 9097 min = _getTotalMovement(sb, eb, 0, offsetX, offsetY), 9098 minIndex = 0, 9099 copy, 9100 d, 9101 i; 9102 9103 for (i = 6; i < l; i += 6) { 9104 d = _getTotalMovement(sb, eb, i / 6, offsetX, offsetY); 9105 9106 if (d < min) { 9107 min = d; 9108 minIndex = i; 9109 } 9110 } 9111 9112 if (checkReverse) { 9113 copy = sb.slice(0); 9114 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["reverseSegment"])(copy); 9115 9116 for (i = 6; i < l; i += 6) { 9117 d = _getTotalMovement(copy, eb, i / 6, offsetX, offsetY); 9118 9119 if (d < min) { 9120 min = d; 9121 minIndex = -i; 9122 } 9123 } 9124 } 9125 9126 return minIndex / 6; 9127}, 9128 _getClosestAnchor = function _getClosestAnchor(rawPath, x, y) { 9129 //finds the x/y of the anchor that's closest to the provided x/y coordinate (returns an array, like [x, y]). The bezier should be the top-level type that contains an array for each segment. 9130 var j = rawPath.length, 9131 closestDistance = _bigNum, 9132 closestX = 0, 9133 closestY = 0, 9134 segment, 9135 dx, 9136 dy, 9137 d, 9138 i, 9139 l; 9140 9141 while (--j > -1) { 9142 segment = rawPath[j]; 9143 l = segment.length; 9144 9145 for (i = 0; i < l; i += 6) { 9146 dx = segment[i] - x; 9147 dy = segment[i + 1] - y; 9148 d = _sqrt(dx * dx + dy * dy); 9149 9150 if (d < closestDistance) { 9151 closestDistance = d; 9152 closestX = segment[i]; 9153 closestY = segment[i + 1]; 9154 } 9155 } 9156 } 9157 9158 return [closestX, closestY]; 9159}, 9160 _getClosestSegment = function _getClosestSegment(bezier, pool, startIndex, sortRatio, offsetX, offsetY) { 9161 //matches the bezier to the closest one in a pool (array) of beziers, assuming they are in order of size and we shouldn't drop more than 20% of the size, otherwise prioritizing location (total distance to the center). Extracts the segment out of the pool array and returns it. 9162 var l = pool.length, 9163 index = 0, 9164 minSize = Math.min(bezier.size || _getSize(bezier), pool[startIndex].size || _getSize(pool[startIndex])) * sortRatio, 9165 //limit things based on a percentage of the size of either the bezier or the next element in the array, whichever is smaller. 9166 min = _bigNum, 9167 cx = bezier.centerX + offsetX, 9168 cy = bezier.centerY + offsetY, 9169 size, 9170 i, 9171 dx, 9172 dy, 9173 d; 9174 9175 for (i = startIndex; i < l; i++) { 9176 size = pool[i].size || _getSize(pool[i]); 9177 9178 if (size < minSize) { 9179 break; 9180 } 9181 9182 dx = pool[i].centerX - cx; 9183 dy = pool[i].centerY - cy; 9184 d = _sqrt(dx * dx + dy * dy); 9185 9186 if (d < min) { 9187 index = i; 9188 min = d; 9189 } 9190 } 9191 9192 d = pool[index]; 9193 pool.splice(index, 1); 9194 return d; 9195}, 9196 _subdivideSegmentQty = function _subdivideSegmentQty(segment, quantity) { 9197 var tally = 0, 9198 max = 0.999999, 9199 l = segment.length, 9200 newPointsPerSegment = quantity / ((l - 2) / 6), 9201 ax, 9202 ay, 9203 cp1x, 9204 cp1y, 9205 cp2x, 9206 cp2y, 9207 bx, 9208 by, 9209 x1, 9210 y1, 9211 x2, 9212 y2, 9213 i, 9214 t; 9215 9216 for (i = 2; i < l; i += 6) { 9217 tally += newPointsPerSegment; 9218 9219 while (tally > max) { 9220 //compare with 0.99999 instead of 1 in order to prevent rounding errors 9221 ax = segment[i - 2]; 9222 ay = segment[i - 1]; 9223 cp1x = segment[i]; 9224 cp1y = segment[i + 1]; 9225 cp2x = segment[i + 2]; 9226 cp2y = segment[i + 3]; 9227 bx = segment[i + 4]; 9228 by = segment[i + 5]; 9229 t = 1 / ((Math.floor(tally) || 1) + 1); //progress along the bezier (value between 0 and 1) 9230 9231 x1 = ax + (cp1x - ax) * t; 9232 x2 = cp1x + (cp2x - cp1x) * t; 9233 x1 += (x2 - x1) * t; 9234 x2 += (cp2x + (bx - cp2x) * t - x2) * t; 9235 y1 = ay + (cp1y - ay) * t; 9236 y2 = cp1y + (cp2y - cp1y) * t; 9237 y1 += (y2 - y1) * t; 9238 y2 += (cp2y + (by - cp2y) * t - y2) * t; 9239 segment.splice(i, 4, ax + (cp1x - ax) * t, //first control point 9240 ay + (cp1y - ay) * t, x1, //second control point 9241 y1, x1 + (x2 - x1) * t, //new fabricated anchor on line 9242 y1 + (y2 - y1) * t, x2, //third control point 9243 y2, cp2x + (bx - cp2x) * t, //fourth control point 9244 cp2y + (by - cp2y) * t); 9245 i += 6; 9246 l += 6; 9247 tally--; 9248 } 9249 } 9250 9251 return segment; 9252}, 9253 _equalizeSegmentQuantity = function _equalizeSegmentQuantity(start, end, shapeIndex, map, fillSafe) { 9254 //returns an array of shape indexes, 1 for each segment. 9255 var dif = end.length - start.length, 9256 longer = dif > 0 ? end : start, 9257 shorter = dif > 0 ? start : end, 9258 added = 0, 9259 sortMethod = map === "complexity" ? _sortByComplexity : _sortBySize, 9260 sortRatio = map === "position" ? 0 : typeof map === "number" ? map : 0.8, 9261 i = shorter.length, 9262 shapeIndices = typeof shapeIndex === "object" && shapeIndex.push ? shapeIndex.slice(0) : [shapeIndex], 9263 reverse = shapeIndices[0] === "reverse" || shapeIndices[0] < 0, 9264 log = shapeIndex === "log", 9265 eb, 9266 sb, 9267 b, 9268 x, 9269 y, 9270 offsetX, 9271 offsetY; 9272 9273 if (!shorter[0]) { 9274 return; 9275 } 9276 9277 if (longer.length > 1) { 9278 start.sort(sortMethod); 9279 end.sort(sortMethod); 9280 offsetX = longer.size || _getTotalSize(longer); //ensures centerX and centerY are defined (used below). 9281 9282 offsetX = shorter.size || _getTotalSize(shorter); 9283 offsetX = longer.centerX - shorter.centerX; 9284 offsetY = longer.centerY - shorter.centerY; 9285 9286 if (sortMethod === _sortBySize) { 9287 for (i = 0; i < shorter.length; i++) { 9288 longer.splice(i, 0, _getClosestSegment(shorter[i], longer, i, sortRatio, offsetX, offsetY)); 9289 } 9290 } 9291 } 9292 9293 if (dif) { 9294 if (dif < 0) { 9295 dif = -dif; 9296 } 9297 9298 if (longer[0].length > shorter[0].length) { 9299 //since we use shorter[0] as the one to map the origination point of any brand new fabricated segments, do any subdividing first so that there are more points to choose from (if necessary) 9300 _subdivideSegmentQty(shorter[0], (longer[0].length - shorter[0].length) / 6 | 0); 9301 } 9302 9303 i = shorter.length; 9304 9305 while (added < dif) { 9306 x = longer[i].size || _getSize(longer[i]); //just to ensure centerX and centerY are calculated which we use on the next line. 9307 9308 b = _getClosestAnchor(shorter, longer[i].centerX, longer[i].centerY); 9309 x = b[0]; 9310 y = b[1]; 9311 shorter[i++] = [x, y, x, y, x, y, x, y]; 9312 shorter.totalPoints += 8; 9313 added++; 9314 } 9315 } 9316 9317 for (i = 0; i < start.length; i++) { 9318 eb = end[i]; 9319 sb = start[i]; 9320 dif = eb.length - sb.length; 9321 9322 if (dif < 0) { 9323 _subdivideSegmentQty(eb, -dif / 6 | 0); 9324 } else if (dif > 0) { 9325 _subdivideSegmentQty(sb, dif / 6 | 0); 9326 } 9327 9328 if (reverse && fillSafe !== false && !sb.reversed) { 9329 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["reverseSegment"])(sb); 9330 } 9331 9332 shapeIndex = shapeIndices[i] || shapeIndices[i] === 0 ? shapeIndices[i] : "auto"; 9333 9334 if (shapeIndex) { 9335 //if start shape is closed, find the closest point to the start/end, and re-organize the bezier points accordingly so that the shape morphs in a more intuitive way. 9336 if (sb.closed || Math.abs(sb[0] - sb[sb.length - 2]) < 0.5 && Math.abs(sb[1] - sb[sb.length - 1]) < 0.5) { 9337 if (shapeIndex === "auto" || shapeIndex === "log") { 9338 shapeIndices[i] = shapeIndex = _getClosestShapeIndex(sb, eb, !i || fillSafe === false); 9339 9340 if (shapeIndex < 0) { 9341 reverse = true; 9342 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["reverseSegment"])(sb); 9343 shapeIndex = -shapeIndex; 9344 } 9345 9346 _offsetSegment(sb, shapeIndex * 6); 9347 } else if (shapeIndex !== "reverse") { 9348 if (i && shapeIndex < 0) { 9349 //only happens if an array is passed as shapeIndex and a negative value is defined for an index beyond 0. Very rare, but helpful sometimes. 9350 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["reverseSegment"])(sb); 9351 } 9352 9353 _offsetSegment(sb, (shapeIndex < 0 ? -shapeIndex : shapeIndex) * 6); 9354 } //otherwise, if it's not a closed shape, consider reversing it if that would make the overall travel less 9355 9356 } else if (!reverse && (shapeIndex === "auto" && Math.abs(eb[0] - sb[0]) + Math.abs(eb[1] - sb[1]) + Math.abs(eb[eb.length - 2] - sb[sb.length - 2]) + Math.abs(eb[eb.length - 1] - sb[sb.length - 1]) > Math.abs(eb[0] - sb[sb.length - 2]) + Math.abs(eb[1] - sb[sb.length - 1]) + Math.abs(eb[eb.length - 2] - sb[0]) + Math.abs(eb[eb.length - 1] - sb[1]) || shapeIndex % 2)) { 9357 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["reverseSegment"])(sb); 9358 shapeIndices[i] = -1; 9359 reverse = true; 9360 } else if (shapeIndex === "auto") { 9361 shapeIndices[i] = 0; 9362 } else if (shapeIndex === "reverse") { 9363 shapeIndices[i] = -1; 9364 } 9365 9366 if (sb.closed !== eb.closed) { 9367 //if one is closed and one isn't, don't close either one otherwise the tweening will look weird (but remember, the beginning and final states will honor the actual values, so this only affects the inbetween state) 9368 sb.closed = eb.closed = false; 9369 } 9370 } 9371 } 9372 9373 if (log) { 9374 _log("shapeIndex:[" + shapeIndices.join(",") + "]"); 9375 } 9376 9377 start.shapeIndex = shapeIndices; 9378 return shapeIndices; 9379}, 9380 _pathFilter = function _pathFilter(a, shapeIndex, map, precompile, fillSafe) { 9381 var start = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(a[0]), 9382 end = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(a[1]); 9383 9384 if (!_equalizeSegmentQuantity(start, end, shapeIndex || shapeIndex === 0 ? shapeIndex : "auto", map, fillSafe)) { 9385 return; //malformed path data or null target 9386 } 9387 9388 a[0] = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(start); 9389 a[1] = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(end); 9390 9391 if (precompile === "log" || precompile === true) { 9392 _log('precompile:["' + a[0] + '","' + a[1] + '"]'); 9393 } 9394}, 9395 _offsetPoints = function _offsetPoints(text, offset) { 9396 if (!offset) { 9397 return text; 9398 } 9399 9400 var a = text.match(_numExp) || [], 9401 l = a.length, 9402 s = "", 9403 inc, 9404 i, 9405 j; 9406 9407 if (offset === "reverse") { 9408 i = l - 1; 9409 inc = -2; 9410 } else { 9411 i = ((parseInt(offset, 10) || 0) * 2 + 1 + l * 100) % l; 9412 inc = 2; 9413 } 9414 9415 for (j = 0; j < l; j += 2) { 9416 s += a[i - 1] + "," + a[i] + " "; 9417 i = (i + inc) % l; 9418 } 9419 9420 return s; 9421}, 9422 //adds a certain number of points while maintaining the polygon/polyline shape (so that the start/end values can have a matching quantity of points to animate). Returns the revised string. 9423_equalizePointQuantity = function _equalizePointQuantity(a, quantity) { 9424 var tally = 0, 9425 x = parseFloat(a[0]), 9426 y = parseFloat(a[1]), 9427 s = x + "," + y + " ", 9428 max = 0.999999, 9429 newPointsPerSegment, 9430 i, 9431 l, 9432 j, 9433 factor, 9434 nextX, 9435 nextY; 9436 l = a.length; 9437 newPointsPerSegment = quantity * 0.5 / (l * 0.5 - 1); 9438 9439 for (i = 0; i < l - 2; i += 2) { 9440 tally += newPointsPerSegment; 9441 nextX = parseFloat(a[i + 2]); 9442 nextY = parseFloat(a[i + 3]); 9443 9444 if (tally > max) { 9445 //compare with 0.99999 instead of 1 in order to prevent rounding errors 9446 factor = 1 / (Math.floor(tally) + 1); 9447 j = 1; 9448 9449 while (tally > max) { 9450 s += (x + (nextX - x) * factor * j).toFixed(2) + "," + (y + (nextY - y) * factor * j).toFixed(2) + " "; 9451 tally--; 9452 j++; 9453 } 9454 } 9455 9456 s += nextX + "," + nextY + " "; 9457 x = nextX; 9458 y = nextY; 9459 } 9460 9461 return s; 9462}, 9463 _pointsFilter = function _pointsFilter(a) { 9464 var startNums = a[0].match(_numExp) || [], 9465 endNums = a[1].match(_numExp) || [], 9466 dif = endNums.length - startNums.length; 9467 9468 if (dif > 0) { 9469 a[0] = _equalizePointQuantity(startNums, dif); 9470 } else { 9471 a[1] = _equalizePointQuantity(endNums, -dif); 9472 } 9473}, 9474 _buildPointsFilter = function _buildPointsFilter(shapeIndex) { 9475 return !isNaN(shapeIndex) ? function (a) { 9476 _pointsFilter(a); 9477 9478 a[1] = _offsetPoints(a[1], parseInt(shapeIndex, 10)); 9479 } : _pointsFilter; 9480}, 9481 _parseShape = function _parseShape(shape, forcePath, target) { 9482 var isString = typeof shape === "string", 9483 e, 9484 type; 9485 9486 if (!isString || _selectorExp.test(shape) || (shape.match(_numExp) || []).length < 3) { 9487 e = _toArray(shape)[0]; 9488 9489 if (e) { 9490 type = (e.nodeName + "").toUpperCase(); 9491 9492 if (forcePath && type !== "PATH") { 9493 //if we were passed an element (or selector text for an element) that isn't a path, convert it. 9494 e = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["convertToPath"])(e, false); 9495 type = "PATH"; 9496 } 9497 9498 shape = e.getAttribute(type === "PATH" ? "d" : "points") || ""; 9499 9500 if (e === target) { 9501 //if the shape matches the target element, the user wants to revert to the original which should have been stored in the data-original attribute 9502 shape = e.getAttributeNS(null, "data-original") || shape; 9503 } 9504 } else { 9505 _log("WARNING: invalid morph to: " + shape); 9506 9507 shape = false; 9508 } 9509 } 9510 9511 return shape; 9512}, 9513 //adds an "isSmooth" array to each segment and populates it with a boolean value indicating whether or not it's smooth (the control points have basically the same slope). For any smooth control points, it converts the coordinates into angle (x, in radians) and length (y) and puts them into the same index value in a smoothData array. 9514_populateSmoothData = function _populateSmoothData(rawPath, tolerance) { 9515 var j = rawPath.length, 9516 limit = 0.2 * (tolerance || 1), 9517 smooth, 9518 segment, 9519 x, 9520 y, 9521 x2, 9522 y2, 9523 i, 9524 l, 9525 a, 9526 a2, 9527 isSmooth, 9528 smoothData; 9529 9530 while (--j > -1) { 9531 segment = rawPath[j]; 9532 isSmooth = segment.isSmooth = segment.isSmooth || [0, 0, 0, 0]; 9533 smoothData = segment.smoothData = segment.smoothData || [0, 0, 0, 0]; 9534 isSmooth.length = 4; 9535 l = segment.length - 2; 9536 9537 for (i = 6; i < l; i += 6) { 9538 x = segment[i] - segment[i - 2]; 9539 y = segment[i + 1] - segment[i - 1]; 9540 x2 = segment[i + 2] - segment[i]; 9541 y2 = segment[i + 3] - segment[i + 1]; 9542 a = _atan2(y, x); 9543 a2 = _atan2(y2, x2); 9544 smooth = Math.abs(a - a2) < limit; 9545 9546 if (smooth) { 9547 smoothData[i - 2] = a; 9548 smoothData[i + 2] = a2; 9549 smoothData[i - 1] = _sqrt(x * x + y * y); 9550 smoothData[i + 3] = _sqrt(x2 * x2 + y2 * y2); 9551 } 9552 9553 isSmooth.push(smooth, smooth, 0, 0, smooth, smooth); 9554 } //if the first and last points are identical, check to see if there's a smooth transition. We must handle this a bit differently due to their positions in the array. 9555 9556 9557 if (segment[l] === segment[0] && segment[l + 1] === segment[1]) { 9558 x = segment[0] - segment[l - 2]; 9559 y = segment[1] - segment[l - 1]; 9560 x2 = segment[2] - segment[0]; 9561 y2 = segment[3] - segment[1]; 9562 a = _atan2(y, x); 9563 a2 = _atan2(y2, x2); 9564 9565 if (Math.abs(a - a2) < limit) { 9566 smoothData[l - 2] = a; 9567 smoothData[2] = a2; 9568 smoothData[l - 1] = _sqrt(x * x + y * y); 9569 smoothData[3] = _sqrt(x2 * x2 + y2 * y2); 9570 isSmooth[l - 2] = isSmooth[l - 1] = true; //don't change indexes 2 and 3 because we'll trigger everything from the END, and this will optimize file size a bit. 9571 } 9572 } 9573 } 9574 9575 return rawPath; 9576}, 9577 _parseOriginFactors = function _parseOriginFactors(v) { 9578 var a = v.trim().split(" "), 9579 x = ~v.indexOf("left") ? 0 : ~v.indexOf("right") ? 100 : isNaN(parseFloat(a[0])) ? 50 : parseFloat(a[0]), 9580 y = ~v.indexOf("top") ? 0 : ~v.indexOf("bottom") ? 100 : isNaN(parseFloat(a[1])) ? 50 : parseFloat(a[1]); 9581 return { 9582 x: x / 100, 9583 y: y / 100 9584 }; 9585}, 9586 _shortAngle = function _shortAngle(dif) { 9587 return dif !== dif % _PI ? dif + (dif < 0 ? _2PI : -_2PI) : dif; 9588}, 9589 _morphMessage = "Use MorphSVGPlugin.convertToPath() to convert to a path before morphing.", 9590 _tweenRotation = function _tweenRotation(start, end, i, linkedPT) { 9591 var so = this._origin, 9592 //starting origin 9593 eo = this._eOrigin, 9594 //ending origin 9595 dx = start[i] - so.x, 9596 dy = start[i + 1] - so.y, 9597 d = _sqrt(dx * dx + dy * dy), 9598 //length from starting origin to starting point 9599 sa = _atan2(dy, dx), 9600 angleDif, 9601 _short; 9602 9603 dx = end[i] - eo.x; 9604 dy = end[i + 1] - eo.y; 9605 angleDif = _atan2(dy, dx) - sa; 9606 _short = _shortAngle(angleDif); //in the case of control points, we ALWAYS link them to their anchor so that they don't get torn apart and rotate the opposite direction. If it's not a control point, we look at the most recently linked point as long as they're within a certain rotational range of each other. 9607 9608 if (!linkedPT && _lastLinkedAnchor && Math.abs(_short + _lastLinkedAnchor.ca) < _angleMin) { 9609 linkedPT = _lastLinkedAnchor; 9610 } 9611 9612 return this._anchorPT = _lastLinkedAnchor = { 9613 _next: this._anchorPT, 9614 t: start, 9615 sa: sa, 9616 //starting angle 9617 ca: linkedPT && _short * linkedPT.ca < 0 && Math.abs(_short) > _angleMax ? angleDif : _short, 9618 //change in angle 9619 sl: d, 9620 //starting length 9621 cl: _sqrt(dx * dx + dy * dy) - d, 9622 //change in length 9623 i: i 9624 }; 9625}, 9626 _initCore = function _initCore(required) { 9627 gsap = _getGSAP(); 9628 PluginClass = PluginClass || gsap && gsap.plugins.morphSVG; 9629 9630 if (gsap && PluginClass) { 9631 _toArray = gsap.utils.toArray; 9632 _doc = document; 9633 PluginClass.prototype._tweenRotation = _tweenRotation; 9634 _coreInitted = 1; 9635 } else if (required) { 9636 _log("Please gsap.registerPlugin(MorphSVGPlugin)"); 9637 } 9638}; 9639 9640var MorphSVGPlugin = { 9641 version: "3.6.0", 9642 name: "morphSVG", 9643 rawVars: 1, 9644 // otherwise "render" would be interpreted as a function-based value. 9645 register: function register(core, Plugin) { 9646 gsap = core; 9647 PluginClass = Plugin; 9648 9649 _initCore(); 9650 }, 9651 init: function init(target, value, tween, index, targets) { 9652 _coreInitted || _initCore(1); 9653 9654 if (!value) { 9655 _log("invalid shape"); 9656 9657 return false; 9658 } 9659 9660 _isFunction(value) && (value = value.call(tween, index, target, targets)); 9661 var type, p, pt, shape, isPoly, shapeIndex, map, startSmooth, endSmooth, start, end, i, j, l, startSeg, endSeg, precompiled, sData, eData, originFactors, useRotation, offset; 9662 9663 if (typeof value === "string" || value.getBBox || value[0]) { 9664 value = { 9665 shape: value 9666 }; 9667 } else if (typeof value === "object") { 9668 // if there are any function-based values, parse them here (and make a copy of the object so we're not modifying the original) 9669 type = {}; 9670 9671 for (p in value) { 9672 type[p] = _isFunction(value[p]) && p !== "render" ? value[p].call(tween, index, target, targets) : value[p]; 9673 } 9674 9675 value = type; 9676 } 9677 9678 var cs = target.nodeType ? window.getComputedStyle(target) : {}, 9679 fill = cs.fill + "", 9680 fillSafe = !(fill === "none" || (fill.match(_numExp) || [])[3] === "0" || cs.fillRule === "evenodd"), 9681 origins = (value.origin || "50 50").split(","); 9682 type = (target.nodeName + "").toUpperCase(); 9683 isPoly = type === "POLYLINE" || type === "POLYGON"; 9684 9685 if (type !== "PATH" && !isPoly && !value.prop) { 9686 _log("Cannot morph a <" + type + "> element. " + _morphMessage); 9687 9688 return false; 9689 } 9690 9691 p = type === "PATH" ? "d" : "points"; 9692 9693 if (!value.prop && !_isFunction(target.setAttribute)) { 9694 return false; 9695 } 9696 9697 shape = _parseShape(value.shape || value.d || value.points || "", p === "d", target); 9698 9699 if (isPoly && _commands.test(shape)) { 9700 _log("A <" + type + "> cannot accept path data. " + _morphMessage); 9701 9702 return false; 9703 } 9704 9705 shapeIndex = value.shapeIndex || value.shapeIndex === 0 ? value.shapeIndex : "auto"; 9706 map = value.map || MorphSVGPlugin.defaultMap; 9707 this._prop = value.prop; 9708 this._render = value.render || MorphSVGPlugin.defaultRender; 9709 this._apply = "updateTarget" in value ? value.updateTarget : MorphSVGPlugin.defaultUpdateTarget; 9710 this._rnd = Math.pow(10, isNaN(value.precision) ? 2 : +value.precision); 9711 this._tween = tween; 9712 9713 if (shape) { 9714 this._target = target; 9715 precompiled = typeof value.precompile === "object"; 9716 start = this._prop ? target[this._prop] : target.getAttribute(p); 9717 9718 if (!this._prop && !target.getAttributeNS(null, "data-original")) { 9719 target.setAttributeNS(null, "data-original", start); //record the original state in a data-original attribute so that we can revert to it later. 9720 } 9721 9722 if (p === "d" || this._prop) { 9723 start = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(precompiled ? value.precompile[0] : start); 9724 end = Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(precompiled ? value.precompile[1] : shape); 9725 9726 if (!precompiled && !_equalizeSegmentQuantity(start, end, shapeIndex, map, fillSafe)) { 9727 return false; //malformed path data or null target 9728 } 9729 9730 if (value.precompile === "log" || value.precompile === true) { 9731 _log('precompile:["' + Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(start) + '","' + Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(end) + '"]'); 9732 } 9733 9734 useRotation = (value.type || MorphSVGPlugin.defaultType) !== "linear"; 9735 9736 if (useRotation) { 9737 start = _populateSmoothData(start, value.smoothTolerance); 9738 end = _populateSmoothData(end, value.smoothTolerance); 9739 9740 if (!start.size) { 9741 _getTotalSize(start); //adds top/left/width/height values 9742 9743 } 9744 9745 if (!end.size) { 9746 _getTotalSize(end); 9747 } 9748 9749 originFactors = _parseOriginFactors(origins[0]); 9750 this._origin = start.origin = { 9751 x: start.left + originFactors.x * start.width, 9752 y: start.top + originFactors.y * start.height 9753 }; 9754 9755 if (origins[1]) { 9756 originFactors = _parseOriginFactors(origins[1]); 9757 } 9758 9759 this._eOrigin = { 9760 x: end.left + originFactors.x * end.width, 9761 y: end.top + originFactors.y * end.height 9762 }; 9763 } 9764 9765 this._rawPath = target._gsRawPath = start; 9766 j = start.length; 9767 9768 while (--j > -1) { 9769 startSeg = start[j]; 9770 endSeg = end[j]; 9771 startSmooth = startSeg.isSmooth || []; 9772 endSmooth = endSeg.isSmooth || []; 9773 l = startSeg.length; 9774 _lastLinkedAnchor = 0; //reset; we use _lastLinkedAnchor in the _tweenRotation() method to help make sure that close points don't get ripped apart and rotate opposite directions. Typically we want to go the shortest direction, but if the previous anchor is going a different direction, we override this logic (within certain thresholds) 9775 9776 for (i = 0; i < l; i += 2) { 9777 if (endSeg[i] !== startSeg[i] || endSeg[i + 1] !== startSeg[i + 1]) { 9778 if (useRotation) { 9779 if (startSmooth[i] && endSmooth[i]) { 9780 //if BOTH starting and ending values are smooth (meaning control points have basically the same slope), interpolate the rotation and length instead of the coordinates (this is what makes things smooth). 9781 sData = startSeg.smoothData; 9782 eData = endSeg.smoothData; 9783 offset = i + (i === l - 4 ? 7 - l : 5); //helps us accommodate wrapping (like if the end and start anchors are identical and the control points are smooth). 9784 9785 this._controlPT = { 9786 _next: this._controlPT, 9787 i: i, 9788 j: j, 9789 l1s: sData[i + 1], 9790 l1c: eData[i + 1] - sData[i + 1], 9791 l2s: sData[offset], 9792 l2c: eData[offset] - sData[offset] 9793 }; 9794 pt = this._tweenRotation(startSeg, endSeg, i + 2); 9795 9796 this._tweenRotation(startSeg, endSeg, i, pt); 9797 9798 this._tweenRotation(startSeg, endSeg, offset - 1, pt); 9799 9800 i += 4; 9801 } else { 9802 this._tweenRotation(startSeg, endSeg, i); 9803 } 9804 } else { 9805 pt = this.add(startSeg, i, startSeg[i], endSeg[i]); 9806 pt = this.add(startSeg, i + 1, startSeg[i + 1], endSeg[i + 1]) || pt; 9807 } 9808 } 9809 } 9810 } 9811 } else { 9812 pt = this.add(target, "setAttribute", target.getAttribute(p) + "", shape + "", index, targets, 0, _buildPointsFilter(shapeIndex), p); 9813 } 9814 9815 if (useRotation) { 9816 this.add(this._origin, "x", this._origin.x, this._eOrigin.x); 9817 pt = this.add(this._origin, "y", this._origin.y, this._eOrigin.y); 9818 } 9819 9820 if (pt) { 9821 this._props.push("morphSVG"); 9822 9823 pt.end = shape; 9824 pt.endProp = p; 9825 } 9826 } 9827 9828 return _bonusValidated; 9829 }, 9830 render: function render(ratio, data) { 9831 var rawPath = data._rawPath, 9832 controlPT = data._controlPT, 9833 anchorPT = data._anchorPT, 9834 rnd = data._rnd, 9835 target = data._target, 9836 pt = data._pt, 9837 s, 9838 space, 9839 easeInOut, 9840 segment, 9841 l, 9842 angle, 9843 i, 9844 j, 9845 x, 9846 y, 9847 sin, 9848 cos, 9849 offset; 9850 9851 while (pt) { 9852 pt.r(ratio, pt.d); 9853 pt = pt._next; 9854 } 9855 9856 if (ratio === 1 && data._apply) { 9857 pt = data._pt; 9858 9859 while (pt) { 9860 if (pt.end) { 9861 if (data._prop) { 9862 target[data._prop] = pt.end; 9863 } else { 9864 target.setAttribute(pt.endProp, pt.end); //make sure the end value is exactly as specified (in case we had to add fabricated points during the tween) 9865 } 9866 } 9867 9868 pt = pt._next; 9869 } 9870 } else if (rawPath) { 9871 //rotationally position the anchors 9872 while (anchorPT) { 9873 angle = anchorPT.sa + ratio * anchorPT.ca; 9874 l = anchorPT.sl + ratio * anchorPT.cl; //length 9875 9876 anchorPT.t[anchorPT.i] = data._origin.x + _cos(angle) * l; 9877 anchorPT.t[anchorPT.i + 1] = data._origin.y + _sin(angle) * l; 9878 anchorPT = anchorPT._next; 9879 } //smooth out the control points 9880 9881 9882 easeInOut = ratio < 0.5 ? 2 * ratio * ratio : (4 - 2 * ratio) * ratio - 1; 9883 9884 while (controlPT) { 9885 i = controlPT.i; 9886 segment = rawPath[controlPT.j]; 9887 offset = i + (i === segment.length - 4 ? 7 - segment.length : 5); //accommodates wrapping around of smooth points, like if the start and end anchors are on top of each other and their handles are smooth. 9888 9889 angle = _atan2(segment[offset] - segment[i + 1], segment[offset - 1] - segment[i]); //average the angles 9890 9891 sin = _sin(angle); 9892 cos = _cos(angle); 9893 x = segment[i + 2]; 9894 y = segment[i + 3]; 9895 l = controlPT.l1s + easeInOut * controlPT.l1c; //length 9896 9897 segment[i] = x - cos * l; 9898 segment[i + 1] = y - sin * l; 9899 l = controlPT.l2s + easeInOut * controlPT.l2c; 9900 segment[offset - 1] = x + cos * l; 9901 segment[offset] = y + sin * l; 9902 controlPT = controlPT._next; 9903 } 9904 9905 target._gsRawPath = rawPath; 9906 9907 if (data._apply) { 9908 s = ""; 9909 space = " "; 9910 9911 for (j = 0; j < rawPath.length; j++) { 9912 segment = rawPath[j]; 9913 l = segment.length; 9914 s += "M" + (segment[0] * rnd | 0) / rnd + space + (segment[1] * rnd | 0) / rnd + " C"; 9915 9916 for (i = 2; i < l; i++) { 9917 //this is actually faster than just doing a join() on the array, possibly because the numbers have so many decimal places 9918 s += (segment[i] * rnd | 0) / rnd + space; 9919 } 9920 } 9921 9922 if (data._prop) { 9923 target[data._prop] = s; 9924 } else { 9925 target.setAttribute("d", s); 9926 } 9927 } 9928 } 9929 9930 data._render && rawPath && data._render.call(data._tween, rawPath, target); 9931 }, 9932 kill: function kill(property) { 9933 this._pt = this._rawPath = 0; 9934 }, 9935 getRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getRawPath"], 9936 stringToRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"], 9937 rawPathToString: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"], 9938 pathFilter: _pathFilter, 9939 pointsFilter: _pointsFilter, 9940 getTotalSize: _getTotalSize, 9941 equalizeSegmentQuantity: _equalizeSegmentQuantity, 9942 convertToPath: function convertToPath(targets, swap) { 9943 return _toArray(targets).map(function (target) { 9944 return Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["convertToPath"])(target, swap !== false); 9945 }); 9946 }, 9947 defaultType: "linear", 9948 defaultUpdateTarget: true, 9949 defaultMap: "size" 9950}; 9951_getGSAP() && gsap.registerPlugin(MorphSVGPlugin); 9952 9953 9954/***/ }), 9955
vendor: 11,695 bytes, lines 9956-10314
9956/***/ "./node_modules/gsap/MotionPathHelper.js": 9957/*!***********************************************!*\ 9958 !*** ./node_modules/gsap/MotionPathHelper.js ***! 9959 \***********************************************/ 9960/*! exports provided: MotionPathHelper, default */ 9961/***/ (function(module, __webpack_exports__, __webpack_require__) { 9962 9963"use strict"; 9964__webpack_require__.r(__webpack_exports__); 9965/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MotionPathHelper", function() { return MotionPathHelper; }); 9966/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return MotionPathHelper; }); 9967/* harmony import */ var _utils_PathEditor_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/PathEditor.js */ "./node_modules/gsap/utils/PathEditor.js"); 9968/*! 9969 * MotionPathHelper 3.6.0 9970 * https://greensock.com 9971 * 9972 * @license Copyright 2008-2021, GreenSock. All rights reserved. 9973 * Subject to the terms at https://greensock.com/standard-license or for 9974 * Club GreenSock members, the agreement issued with that membership. 9975 * @author: Jack Doyle, [email protected] 9976*/ 9977 9978/* eslint-disable */ 9979 9980 9981var gsap, 9982 _win, 9983 _doc, 9984 _docEl, 9985 _body, 9986 MotionPathPlugin, 9987 _arrayToRawPath, 9988 _rawPathToString, 9989 _bonusValidated = 1, 9990 //<name>MotionPathHelper</name> 9991_selectorExp = /(^[#\.][a-z]|[a-y][a-z])/i, 9992 _isString = function _isString(value) { 9993 return typeof value === "string"; 9994}, 9995 _createElement = function _createElement(type, ns) { 9996 var e = _doc.createElementNS ? _doc.createElementNS((ns || "http://www.w3.org/1999/xhtml").replace(/^https/, "http"), type) : _doc.createElement(type); //some servers swap in https for http in the namespace which can break things, making "style" inaccessible. 9997 9998 return e.style ? e : _doc.createElement(type); //some environments won't allow access to the element's style when created with a namespace in which case we default to the standard createElement() to work around the issue. Also note that when GSAP is embedded directly inside an SVG file, createElement() won't allow access to the style object in Firefox (see https://greensock.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). 9999}, 10000 _getPositionOnPage = function _getPositionOnPage(target) { 10001 var bounds = target.getBoundingClientRect(), 10002 windowOffsetY = _docEl.clientTop - (_win.pageYOffset || _docEl.scrollTop || _body.scrollTop || 0), 10003 windowOffsetX = _docEl.clientLeft - (_win.pageXOffset || _docEl.scrollLeft || _body.scrollLeft || 0); 10004 return { 10005 left: bounds.left + windowOffsetX, 10006 top: bounds.top + windowOffsetY, 10007 right: bounds.right + windowOffsetX, 10008 bottom: bounds.bottom + windowOffsetY 10009 }; 10010}, 10011 _getInitialPath = function _getInitialPath(x, y) { 10012 var coordinates = [0, 31, 8, 58, 24, 75, 40, 90, 69, 100, 100, 100], 10013 i; 10014 10015 for (i = 0; i < coordinates.length; i += 2) { 10016 coordinates[i] += x; 10017 coordinates[i + 1] += y; 10018 } 10019 10020 return "M" + x + "," + y + "C" + coordinates.join(","); 10021}, 10022 _getGlobalTime = function _getGlobalTime(animation) { 10023 var time = animation.totalTime(); 10024 10025 while (animation) { 10026 time = animation.startTime() + time / (animation.timeScale() || 1); 10027 animation = animation.parent; 10028 } 10029 10030 return time; 10031}, 10032 _copyElement, 10033 _initCopyToClipboard = function _initCopyToClipboard() { 10034 _copyElement = _createElement("textarea"); 10035 _copyElement.style.display = "none"; 10036 10037 _body.appendChild(_copyElement); 10038}, 10039 _parsePath = function _parsePath(path, target, vars) { 10040 return _isString(path) && _selectorExp.test(path) ? _doc.querySelector(path) : Array.isArray(path) ? _rawPathToString(_arrayToRawPath([{ 10041 x: gsap.getProperty(target, "x"), 10042 y: gsap.getProperty(target, "y") 10043 }].concat(path), vars)) : _isString(path) || path && (path.tagName + "").toLowerCase() === "path" ? path : 0; 10044}, 10045 _addCopyToClipboard = function _addCopyToClipboard(target, getter, onComplete) { 10046 target.addEventListener('click', function (e) { 10047 if (e.target._gsHelper) { 10048 var c = getter(e.target); 10049 _copyElement.value = c; 10050 10051 if (c && _copyElement.select) { 10052 console.log(c); 10053 _copyElement.style.display = "block"; 10054 10055 _copyElement.select(); 10056 10057 try { 10058 _doc.execCommand('copy'); 10059 10060 _copyElement.blur(); 10061 10062 onComplete && onComplete(target); 10063 } catch (err) { 10064 console.warn("Copy didn't work; this browser doesn't permit that."); 10065 } 10066 10067 _copyElement.style.display = "none"; 10068 } 10069 } 10070 }); 10071}, 10072 _identityMatrixObject = { 10073 matrix: { 10074 a: 1, 10075 b: 0, 10076 c: 0, 10077 d: 1, 10078 e: 0, 10079 f: 0 10080 } 10081}, 10082 _getConsolidatedMatrix = function _getConsolidatedMatrix(target) { 10083 return (target.transform.baseVal.consolidate() || _identityMatrixObject).matrix; 10084}, 10085 _findMotionPathTween = function _findMotionPathTween(target) { 10086 var tweens = gsap.getTweensOf(target), 10087 i = 0; 10088 10089 for (; i < tweens.length; i++) { 10090 if (tweens[i].vars.motionPath) { 10091 return tweens[i]; 10092 } else if (tweens[i].timeline) { 10093 tweens.push.apply(tweens, tweens[i].timeline.getChildren()); 10094 } 10095 } 10096}, 10097 _initCore = function _initCore(core, required) { 10098 var message = "Please gsap.registerPlugin(MotionPathPlugin)"; 10099 _win = window; 10100 gsap = gsap || core || _win.gsap || console.warn(message); 10101 _doc = document; 10102 _body = _doc.body; 10103 _docEl = _doc.documentElement; 10104 MotionPathPlugin = gsap && gsap.plugins.motionPath; 10105 10106 if (!MotionPathPlugin) { 10107 required === true && console.warn(message); 10108 } else { 10109 _initCopyToClipboard(); 10110 10111 _arrayToRawPath = MotionPathPlugin.arrayToRawPath; 10112 _rawPathToString = MotionPathPlugin.rawPathToString; 10113 } 10114}; 10115 10116var MotionPathHelper = /*#__PURE__*/function () { 10117 function MotionPathHelper(targetOrTween, vars) { 10118 if (vars === void 0) { 10119 vars = {}; 10120 } 10121 10122 if (!MotionPathPlugin) { 10123 _initCore(vars.gsap, 1); 10124 } 10125 10126 var copyButton = _createElement("div"), 10127 self = this, 10128 offset = { 10129 x: 0, 10130 y: 0 10131 }, 10132 target, 10133 path, 10134 isSVG, 10135 startX, 10136 startY, 10137 position, 10138 svg, 10139 animation, 10140 svgNamespace, 10141 temp, 10142 matrix, 10143 refreshPath, 10144 animationToScrub; 10145 10146 if (targetOrTween instanceof gsap.core.Tween) { 10147 animation = targetOrTween; 10148 target = animation.targets()[0]; 10149 } else { 10150 target = gsap.utils.toArray(targetOrTween)[0]; 10151 animation = _findMotionPathTween(target); 10152 } 10153 10154 path = _parsePath(vars.path, target, vars); 10155 this.offset = offset; 10156 position = _getPositionOnPage(target); 10157 startX = parseFloat(gsap.getProperty(target, "x", "px")); 10158 startY = parseFloat(gsap.getProperty(target, "y", "px")); 10159 isSVG = target.getCTM && target.tagName.toLowerCase() !== "svg"; 10160 10161 if (animation && !path) { 10162 path = _parsePath(animation.vars.motionPath.path || animation.vars.motionPath, target, animation.vars.motionPath); 10163 } 10164 10165 copyButton.setAttribute("class", "copy-motion-path"); 10166 copyButton.style.cssText = "border-radius:8px; background-color:rgba(85, 85, 85, 0.7); color:#fff; cursor:pointer; padding:6px 12px; font-family:Signika Negative, Arial, sans-serif; position:fixed; left:50%; transform:translate(-50%, 0); font-size:19px; bottom:10px"; 10167 copyButton.innerText = "COPY MOTION PATH"; 10168 copyButton._gsHelper = self; 10169 10170 (gsap.utils.toArray(vars.container)[0] || _body).appendChild(copyButton); 10171 10172 _addCopyToClipboard(copyButton, function () { 10173 return self.getString(); 10174 }, function () { 10175 return gsap.fromTo(copyButton, { 10176 backgroundColor: "white" 10177 }, { 10178 duration: 0.5, 10179 backgroundColor: "rgba(85, 85, 85, 0.6)" 10180 }); 10181 }); 10182 10183 svg = path && path.ownerSVGElement; 10184 10185 if (!svg) { 10186 svgNamespace = isSVG && target.ownerSVGElement && target.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"; 10187 10188 if (isSVG) { 10189 svg = target.ownerSVGElement; 10190 temp = target.getBBox(); 10191 matrix = _getConsolidatedMatrix(target); 10192 startX = matrix.e; 10193 startY = matrix.f; 10194 offset.x = temp.x; 10195 offset.y = temp.y; 10196 } else { 10197 svg = _createElement("svg", svgNamespace); 10198 10199 _body.appendChild(svg); 10200 10201 svg.setAttribute("viewBox", "0 0 100 100"); 10202 svg.style.cssText = "overflow:visible; background-color: transparent; position:absolute; width:100px; height:100px; top:" + position.top + "px; left:" + position.left + "px;"; 10203 } 10204 10205 temp = _isString(path) && !_selectorExp.test(path) ? path : _getInitialPath(startX, startY); 10206 path = _createElement("path", svgNamespace); 10207 path.setAttribute("d", temp); 10208 path.setAttribute("vector-effect", "non-scaling-stroke"); 10209 path.style.cssText = "fill:transparent; stroke-width:" + (vars.pathWidth || 3) + "; stroke:" + (vars.pathColor || "#555") + "; opacity:" + (vars.pathOpacity || 0.6); 10210 svg.appendChild(path); 10211 10212 if (offset.x || offset.y) { 10213 gsap.set(path, { 10214 x: offset.x, 10215 y: offset.y 10216 }); 10217 } 10218 } 10219 10220 if (!("selected" in vars)) { 10221 vars.selected = true; 10222 } 10223 10224 if (!("anchorSnap" in vars)) { 10225 vars.anchorSnap = function (p) { 10226 if (p.x * p.x + p.y * p.y < 16) { 10227 p.x = p.y = 0; 10228 } 10229 }; 10230 } 10231 10232 animationToScrub = animation && animation.parent.data === "nested" ? animation.parent.parent : animation; 10233 10234 vars.onPress = function () { 10235 animationToScrub.pause(0); 10236 }; 10237 10238 refreshPath = function refreshPath() { 10239 //let m = _getConsolidatedMatrix(path); 10240 //animation.vars.motionPath.offsetX = m.e - offset.x; 10241 //animation.vars.motionPath.offsetY = m.f - offset.y; 10242 animation.invalidate(); 10243 animationToScrub.restart(); 10244 }; 10245 10246 vars.onRelease = vars.onDeleteAnchor = refreshPath; 10247 this.editor = _utils_PathEditor_js__WEBPACK_IMPORTED_MODULE_0__["default"].create(path, vars); 10248 10249 if (vars.center) { 10250 gsap.set(target, { 10251 transformOrigin: "50% 50%", 10252 xPercent: -50, 10253 yPercent: -50 10254 }); 10255 } 10256 10257 if (animation) { 10258 if (animation.vars.motionPath.path) { 10259 animation.vars.motionPath.path = path; 10260 } else { 10261 animation.vars.motionPath = { 10262 path: path 10263 }; 10264 } 10265 10266 if (animationToScrub.parent !== gsap.globalTimeline) { 10267 gsap.globalTimeline.add(animationToScrub, _getGlobalTime(animationToScrub) - animationToScrub.delay()); 10268 } 10269 10270 animationToScrub.repeat(-1).repeatDelay(1); 10271 } else { 10272 animation = animationToScrub = gsap.to(target, { 10273 motionPath: { 10274 path: path, 10275 start: vars.start || 0, 10276 end: "end" in vars ? vars.end : 1, 10277 autoRotate: "autoRotate" in vars ? vars.autoRotate : false, 10278 align: path, 10279 alignOrigin: vars.alignOrigin 10280 }, 10281 duration: vars.duration || 5, 10282 ease: vars.ease || "power1.inOut", 10283 repeat: -1, 10284 repeatDelay: 1, 10285 paused: !vars.path 10286 }); 10287 } 10288 10289 this.animation = animation; 10290 } 10291 10292 var _proto = MotionPathHelper.prototype; 10293 10294 _proto.getString = function getString() { 10295 return this.editor.getString(true, -this.offset.x, -this.offset.y); 10296 }; 10297 10298 return MotionPathHelper; 10299}(); 10300MotionPathHelper.register = _initCore; 10301 10302MotionPathHelper.create = function (target, vars) { 10303 return new MotionPathHelper(target, vars); 10304}; 10305 10306MotionPathHelper.editPath = function (path, vars) { 10307 return _utils_PathEditor_js__WEBPACK_IMPORTED_MODULE_0__["default"].create(path, vars); 10308}; 10309 10310MotionPathHelper.version = "3.6.0"; 10311 10312 10313/***/ }), 10314
vendor: 13,903 bytes, lines 10315-10673
10315/***/ "./node_modules/gsap/MotionPathPlugin.js": 10316/*!***********************************************!*\ 10317 !*** ./node_modules/gsap/MotionPathPlugin.js ***! 10318 \***********************************************/ 10319/*! exports provided: MotionPathPlugin, default */ 10320/***/ (function(module, __webpack_exports__, __webpack_require__) { 10321 10322"use strict"; 10323__webpack_require__.r(__webpack_exports__); 10324/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "MotionPathPlugin", function() { return MotionPathPlugin; }); 10325/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return MotionPathPlugin; }); 10326/* harmony import */ var _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/paths.js */ "./node_modules/gsap/utils/paths.js"); 10327/* harmony import */ var _utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/matrix.js */ "./node_modules/gsap/utils/matrix.js"); 10328/*! 10329 * MotionPathPlugin 3.6.0 10330 * https://greensock.com 10331 * 10332 * @license Copyright 2008-2021, GreenSock. All rights reserved. 10333 * Subject to the terms at https://greensock.com/standard-license or for 10334 * Club GreenSock members, the agreement issued with that membership. 10335 * @author: Jack Doyle, [email protected] 10336*/ 10337 10338/* eslint-disable */ 10339 10340 10341 10342var _xProps = "x,translateX,left,marginLeft,xPercent".split(","), 10343 _yProps = "y,translateY,top,marginTop,yPercent".split(","), 10344 _DEG2RAD = Math.PI / 180, 10345 gsap, 10346 PropTween, 10347 _getUnit, 10348 _toArray, 10349 _getGSAP = function _getGSAP() { 10350 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 10351}, 10352 _populateSegmentFromArray = function _populateSegmentFromArray(segment, values, property, mode) { 10353 //mode: 0 = x but don't fill y yet, 1 = y, 2 = x and fill y with 0. 10354 var l = values.length, 10355 si = mode === 2 ? 0 : mode, 10356 i = 0, 10357 v; 10358 10359 for (; i < l; i++) { 10360 segment[si] = v = parseFloat(values[i][property]); 10361 mode === 2 && (segment[si + 1] = 0); 10362 si += 2; 10363 } 10364 10365 return segment; 10366}, 10367 _getPropNum = function _getPropNum(target, prop, unit) { 10368 return parseFloat(target._gsap.get(target, prop, unit || "px")) || 0; 10369}, 10370 _relativize = function _relativize(segment) { 10371 var x = segment[0], 10372 y = segment[1], 10373 i; 10374 10375 for (i = 2; i < segment.length; i += 2) { 10376 x = segment[i] += x; 10377 y = segment[i + 1] += y; 10378 } 10379}, 10380 _segmentToRawPath = function _segmentToRawPath(plugin, segment, target, x, y, slicer, vars, unitX, unitY) { 10381 if (vars.type === "cubic") { 10382 segment = [segment]; 10383 } else { 10384 segment.unshift(_getPropNum(target, x, unitX), y ? _getPropNum(target, y, unitY) : 0); 10385 vars.relative && _relativize(segment); 10386 var pointFunc = y ? _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["pointsToSegment"] : _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["flatPointsToSegment"]; 10387 segment = [pointFunc(segment, vars.curviness)]; 10388 } 10389 10390 segment = slicer(_align(segment, target, vars)); 10391 10392 _addDimensionalPropTween(plugin, target, x, segment, "x", unitX); 10393 10394 y && _addDimensionalPropTween(plugin, target, y, segment, "y", unitY); 10395 return Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["cacheRawPathMeasurements"])(segment, vars.resolution || (vars.curviness === 0 ? 20 : 12)); //when curviness is 0, it creates control points right on top of the anchors which makes it more sensitive to resolution, thus we change the default accordingly. 10396}, 10397 _emptyFunc = function _emptyFunc(v) { 10398 return v; 10399}, 10400 _numExp = /[-+\.]*\d+[\.e\-\+]*\d*[e\-\+]*\d*/g, 10401 _originToPoint = function _originToPoint(element, origin, parentMatrix) { 10402 // origin is an array of normalized values (0-1) in relation to the width/height, so [0.5, 0.5] would be the center. It can also be "auto" in which case it will be the top left unless it's a <path>, when it will start at the beginning of the path itself. 10403 var m = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(element), 10404 svg, 10405 x, 10406 y; 10407 10408 if ((element.tagName + "").toLowerCase() === "svg") { 10409 svg = element.viewBox.baseVal; 10410 x = svg.x; 10411 y = svg.y; 10412 svg.width || (svg = { 10413 width: +element.getAttribute("width"), 10414 height: +element.getAttribute("height") 10415 }); 10416 } else { 10417 svg = origin && element.getBBox && element.getBBox(); 10418 x = y = 0; 10419 } 10420 10421 if (origin && origin !== "auto") { 10422 x += origin.push ? origin[0] * (svg ? svg.width : element.offsetWidth || 0) : origin.x; 10423 y += origin.push ? origin[1] * (svg ? svg.height : element.offsetHeight || 0) : origin.y; 10424 } 10425 10426 return parentMatrix.apply(x || y ? m.apply({ 10427 x: x, 10428 y: y 10429 }) : { 10430 x: m.e, 10431 y: m.f 10432 }); 10433}, 10434 _getAlignMatrix = function _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin) { 10435 var parentMatrix = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(fromElement.parentNode, true, true), 10436 m = parentMatrix.clone().multiply(Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(toElement)), 10437 fromPoint = _originToPoint(fromElement, fromOrigin, parentMatrix), 10438 _originToPoint2 = _originToPoint(toElement, toOrigin, parentMatrix), 10439 x = _originToPoint2.x, 10440 y = _originToPoint2.y, 10441 p; 10442 10443 m.e = m.f = 0; 10444 10445 if (toOrigin === "auto" && toElement.getTotalLength && toElement.tagName.toLowerCase() === "path") { 10446 p = toElement.getAttribute("d").match(_numExp) || []; 10447 p = m.apply({ 10448 x: +p[0], 10449 y: +p[1] 10450 }); 10451 x += p.x; 10452 y += p.y; 10453 } 10454 10455 if (p || toElement.getBBox && fromElement.getBBox && toElement.ownerSVGElement === fromElement.ownerSVGElement) { 10456 p = m.apply(toElement.getBBox()); 10457 x -= p.x; 10458 y -= p.y; 10459 } 10460 10461 m.e = x - fromPoint.x; 10462 m.f = y - fromPoint.y; 10463 return m; 10464}, 10465 _align = function _align(rawPath, target, _ref) { 10466 var align = _ref.align, 10467 matrix = _ref.matrix, 10468 offsetX = _ref.offsetX, 10469 offsetY = _ref.offsetY, 10470 alignOrigin = _ref.alignOrigin; 10471 10472 var x = rawPath[0][0], 10473 y = rawPath[0][1], 10474 curX = _getPropNum(target, "x"), 10475 curY = _getPropNum(target, "y"), 10476 alignTarget, 10477 m, 10478 p; 10479 10480 if (!rawPath || !rawPath.length) { 10481 return Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getRawPath"])("M0,0L0,0"); 10482 } 10483 10484 if (align) { 10485 if (align === "self" || (alignTarget = _toArray(align)[0] || target) === target) { 10486 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(rawPath, 1, 0, 0, 1, curX - x, curY - y); 10487 } else { 10488 if (alignOrigin && alignOrigin[2] !== false) { 10489 gsap.set(target, { 10490 transformOrigin: alignOrigin[0] * 100 + "% " + alignOrigin[1] * 100 + "%" 10491 }); 10492 } else { 10493 alignOrigin = [_getPropNum(target, "xPercent") / -100, _getPropNum(target, "yPercent") / -100]; 10494 } 10495 10496 m = _getAlignMatrix(target, alignTarget, alignOrigin, "auto"); 10497 p = m.apply({ 10498 x: x, 10499 y: y 10500 }); 10501 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(rawPath, m.a, m.b, m.c, m.d, curX + m.e - (p.x - m.e), curY + m.f - (p.y - m.f)); 10502 } 10503 } 10504 10505 if (matrix) { 10506 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(rawPath, matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f); 10507 } else if (offsetX || offsetY) { 10508 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(rawPath, 1, 0, 0, 1, offsetX || 0, offsetY || 0); 10509 } 10510 10511 return rawPath; 10512}, 10513 _addDimensionalPropTween = function _addDimensionalPropTween(plugin, target, property, rawPath, pathProperty, forceUnit) { 10514 var cache = target._gsap, 10515 harness = cache.harness, 10516 alias = harness && harness.aliases && harness.aliases[property], 10517 prop = alias && alias.indexOf(",") < 0 ? alias : property, 10518 pt = plugin._pt = new PropTween(plugin._pt, target, prop, 0, 0, _emptyFunc, 0, cache.set(target, prop, plugin)); 10519 pt.u = _getUnit(cache.get(target, prop, forceUnit)) || 0; 10520 pt.path = rawPath; 10521 pt.pp = pathProperty; 10522 10523 plugin._props.push(prop); 10524}, 10525 _sliceModifier = function _sliceModifier(start, end) { 10526 return function (rawPath) { 10527 return start || end !== 1 ? Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["sliceRawPath"])(rawPath, start, end) : rawPath; 10528 }; 10529}; 10530 10531var MotionPathPlugin = { 10532 version: "3.6.0", 10533 name: "motionPath", 10534 register: function register(core, Plugin, propTween) { 10535 gsap = core; 10536 _getUnit = gsap.utils.getUnit; 10537 _toArray = gsap.utils.toArray; 10538 PropTween = propTween; 10539 }, 10540 init: function init(target, vars) { 10541 if (!gsap) { 10542 console.warn("Please gsap.registerPlugin(MotionPathPlugin)"); 10543 return false; 10544 } 10545 10546 if (!(typeof vars === "object" && !vars.style) || !vars.path) { 10547 vars = { 10548 path: vars 10549 }; 10550 } 10551 10552 var rawPaths = [], 10553 _vars = vars, 10554 path = _vars.path, 10555 autoRotate = _vars.autoRotate, 10556 unitX = _vars.unitX, 10557 unitY = _vars.unitY, 10558 x = _vars.x, 10559 y = _vars.y, 10560 firstObj = path[0], 10561 slicer = _sliceModifier(vars.start, "end" in vars ? vars.end : 1), 10562 rawPath, 10563 p; 10564 10565 this.rawPaths = rawPaths; 10566 this.target = target; 10567 10568 if (this.rotate = autoRotate || autoRotate === 0) { 10569 //get the rotational data FIRST so that the setTransform() method is called in the correct order in the render() loop - rotation gets set last. 10570 this.rOffset = parseFloat(autoRotate) || 0; 10571 this.radians = !!vars.useRadians; 10572 this.rProp = vars.rotation || "rotation"; // rotation property 10573 10574 this.rSet = target._gsap.set(target, this.rProp, this); // rotation setter 10575 10576 this.ru = _getUnit(target._gsap.get(target, this.rProp)) || 0; // rotation units 10577 } 10578 10579 if (Array.isArray(path) && !("closed" in path) && typeof firstObj !== "number") { 10580 for (p in firstObj) { 10581 if (!x && ~_xProps.indexOf(p)) { 10582 x = p; 10583 } else if (!y && ~_yProps.indexOf(p)) { 10584 y = p; 10585 } 10586 } 10587 10588 if (x && y) { 10589 //correlated values 10590 rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray(_populateSegmentFromArray([], path, x, 0), path, y, 1), target, x, y, slicer, vars, unitX || _getUnit(path[0][x]), unitY || _getUnit(path[0][y]))); 10591 } else { 10592 x = y = 0; 10593 } 10594 10595 for (p in firstObj) { 10596 p !== x && p !== y && rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray([], path, p, 2), target, p, 0, slicer, vars, _getUnit(path[0][p]))); 10597 } 10598 } else { 10599 rawPath = slicer(_align(Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getRawPath"])(vars.path), target, vars)); 10600 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["cacheRawPathMeasurements"])(rawPath, vars.resolution); 10601 rawPaths.push(rawPath); 10602 10603 _addDimensionalPropTween(this, target, vars.x || "x", rawPath, "x", vars.unitX || "px"); 10604 10605 _addDimensionalPropTween(this, target, vars.y || "y", rawPath, "y", vars.unitY || "px"); 10606 } 10607 }, 10608 render: function render(ratio, data) { 10609 var rawPaths = data.rawPaths, 10610 i = rawPaths.length, 10611 pt = data._pt; 10612 10613 if (ratio > 1) { 10614 ratio = 1; 10615 } else if (ratio < 0) { 10616 ratio = 0; 10617 } 10618 10619 while (i--) { 10620 Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getPositionOnPath"])(rawPaths[i], ratio, !i && data.rotate, rawPaths[i]); 10621 } 10622 10623 while (pt) { 10624 pt.set(pt.t, pt.p, pt.path[pt.pp] + pt.u, pt.d, ratio); 10625 pt = pt._next; 10626 } 10627 10628 data.rotate && data.rSet(data.target, data.rProp, rawPaths[0].angle * (data.radians ? _DEG2RAD : 1) + data.rOffset + data.ru, data, ratio); 10629 }, 10630 getLength: function getLength(path) { 10631 return Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["cacheRawPathMeasurements"])(Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getRawPath"])(path)).totalLength; 10632 }, 10633 sliceRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["sliceRawPath"], 10634 getRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getRawPath"], 10635 pointsToSegment: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["pointsToSegment"], 10636 stringToRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"], 10637 rawPathToString: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"], 10638 transformRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"], 10639 getGlobalMatrix: _utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"], 10640 getPositionOnPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["getPositionOnPath"], 10641 cacheRawPathMeasurements: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["cacheRawPathMeasurements"], 10642 convertToPath: function convertToPath(targets, swap) { 10643 return _toArray(targets).map(function (target) { 10644 return Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["convertToPath"])(target, swap !== false); 10645 }); 10646 }, 10647 convertCoordinates: function convertCoordinates(fromElement, toElement, point) { 10648 var m = Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(toElement, true, true).multiply(Object(_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(fromElement)); 10649 return point ? m.apply(point) : m; 10650 }, 10651 getAlignMatrix: _getAlignMatrix, 10652 getRelativePosition: function getRelativePosition(fromElement, toElement, fromOrigin, toOrigin) { 10653 var m = _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin); 10654 10655 return { 10656 x: m.e, 10657 y: m.f 10658 }; 10659 }, 10660 arrayToRawPath: function arrayToRawPath(value, vars) { 10661 vars = vars || {}; 10662 10663 var segment = _populateSegmentFromArray(_populateSegmentFromArray([], value, vars.x || "x", 0), value, vars.y || "y", 1); 10664 10665 vars.relative && _relativize(segment); 10666 return [vars.type === "cubic" ? segment : Object(_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__["pointsToSegment"])(segment, vars.curviness)]; 10667 } 10668}; 10669_getGSAP() && gsap.registerPlugin(MotionPathPlugin); 10670 10671 10672/***/ }), 10673
vendor: 5,186 bytes, lines 10674-10850
10674/***/ "./node_modules/gsap/Physics2DPlugin.js": 10675/*!**********************************************!*\ 10676 !*** ./node_modules/gsap/Physics2DPlugin.js ***! 10677 \**********************************************/ 10678/*! exports provided: Physics2DPlugin, default */ 10679/***/ (function(module, __webpack_exports__, __webpack_require__) { 10680 10681"use strict"; 10682__webpack_require__.r(__webpack_exports__); 10683/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Physics2DPlugin", function() { return Physics2DPlugin; }); 10684/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return Physics2DPlugin; }); 10685/*! 10686 * Physics2DPlugin 3.6.0 10687 * https://greensock.com 10688 * 10689 * @license Copyright 2008-2021, GreenSock. All rights reserved. 10690 * Subject to the terms at https://greensock.com/standard-license or for 10691 * Club GreenSock members, the agreement issued with that membership. 10692 * @author: Jack Doyle, [email protected] 10693*/ 10694 10695/* eslint-disable */ 10696var gsap, 10697 _coreInitted, 10698 _getUnit, 10699 _DEG2RAD = Math.PI / 180, 10700 _getGSAP = function _getGSAP() { 10701 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 10702}, 10703 _round = function _round(value) { 10704 return Math.round(value * 10000) / 10000; 10705}, 10706 _bonusValidated = 1, 10707 //<name>Physics2DPlugin</name> 10708_initCore = function _initCore(core) { 10709 gsap = core || _getGSAP(); 10710 10711 if (!_coreInitted) { 10712 _getUnit = gsap.utils.getUnit; 10713 _coreInitted = 1; 10714 } 10715}; 10716 10717var PhysicsProp = function PhysicsProp(target, p, velocity, acceleration, stepsPerTimeUnit) { 10718 var cache = target._gsap, 10719 curVal = cache.get(target, p); 10720 this.p = p; 10721 this.set = cache.set(target, p); //setter 10722 10723 this.s = this.val = parseFloat(curVal); 10724 this.u = _getUnit(curVal) || 0; 10725 this.vel = velocity || 0; 10726 this.v = this.vel / stepsPerTimeUnit; 10727 10728 if (acceleration || acceleration === 0) { 10729 this.acc = acceleration; 10730 this.a = this.acc / (stepsPerTimeUnit * stepsPerTimeUnit); 10731 } else { 10732 this.acc = this.a = 0; 10733 } 10734}; 10735 10736var Physics2DPlugin = { 10737 version: "3.6.0", 10738 name: "physics2D", 10739 register: _initCore, 10740 init: function init(target, value, tween) { 10741 _coreInitted || _initCore(); 10742 var data = this, 10743 angle = +value.angle || 0, 10744 velocity = +value.velocity || 0, 10745 acceleration = +value.acceleration || 0, 10746 xProp = value.xProp || "x", 10747 yProp = value.yProp || "y", 10748 aAngle = value.accelerationAngle || value.accelerationAngle === 0 ? +value.accelerationAngle : angle; 10749 data.target = target; 10750 data.tween = tween; 10751 data.step = 0; 10752 data.sps = 30; //steps per second 10753 10754 if (value.gravity) { 10755 acceleration = +value.gravity; 10756 aAngle = 90; 10757 } 10758 10759 angle *= _DEG2RAD; 10760 aAngle *= _DEG2RAD; 10761 data.fr = 1 - (+value.friction || 0); 10762 10763 data._props.push(xProp, yProp); 10764 10765 data.xp = new PhysicsProp(target, xProp, Math.cos(angle) * velocity, Math.cos(aAngle) * acceleration, data.sps); 10766 data.yp = new PhysicsProp(target, yProp, Math.sin(angle) * velocity, Math.sin(aAngle) * acceleration, data.sps); 10767 data.skipX = data.skipY = 0; 10768 }, 10769 render: function render(ratio, data) { 10770 var xp = data.xp, 10771 yp = data.yp, 10772 tween = data.tween, 10773 target = data.target, 10774 step = data.step, 10775 sps = data.sps, 10776 fr = data.fr, 10777 skipX = data.skipX, 10778 skipY = data.skipY, 10779 time = tween._from ? tween._dur - tween._time : tween._time, 10780 x, 10781 y, 10782 tt, 10783 steps, 10784 remainder, 10785 i; 10786 10787 if (fr === 1) { 10788 tt = time * time * 0.5; 10789 x = xp.s + xp.vel * time + xp.acc * tt; 10790 y = yp.s + yp.vel * time + yp.acc * tt; 10791 } else { 10792 time *= sps; 10793 steps = i = (time | 0) - step; 10794 /* 10795 Note: rounding errors build up if we walk the calculations backward which we used to do like this to maximize performance: 10796 i = -i; 10797 while (i--) { 10798 xp.val -= xp.v; 10799 yp.val -= yp.v; 10800 xp.v /= fr; 10801 yp.v /= fr; 10802 xp.v -= xp.a; 10803 yp.v -= yp.a; 10804 } 10805 but now for the sake of accuracy (to ensure rewinding always goes back to EXACTLY the same spot), we force the calculations to go forward every time. So if the tween is going backward, we just start from the beginning and iterate. This is only necessary with friction. 10806 */ 10807 10808 if (i < 0) { 10809 xp.v = xp.vel / sps; 10810 yp.v = yp.vel / sps; 10811 xp.val = xp.s; 10812 yp.val = yp.s; 10813 data.step = 0; 10814 steps = i = time | 0; 10815 } 10816 10817 remainder = time % 1 * fr; 10818 10819 while (i--) { 10820 xp.v += xp.a; 10821 yp.v += yp.a; 10822 xp.v *= fr; 10823 yp.v *= fr; 10824 xp.val += xp.v; 10825 yp.val += yp.v; 10826 } 10827 10828 x = xp.val + xp.v * remainder; 10829 y = yp.val + yp.v * remainder; 10830 data.step += steps; 10831 } 10832 10833 skipX || xp.set(target, xp.p, _round(x) + xp.u); 10834 skipY || yp.set(target, yp.p, _round(y) + yp.u); 10835 }, 10836 kill: function kill(property) { 10837 if (this.xp.p === property) { 10838 this.skipX = 1; 10839 } 10840 10841 if (this.yp.p === property) { 10842 this.skipY = 1; 10843 } 10844 } 10845}; 10846_getGSAP() && gsap.registerPlugin(Physics2DPlugin); 10847 10848 10849/***/ }), 10850
vendor: 5,113 bytes, lines 10851-11027
10851/***/ "./node_modules/gsap/PhysicsPropsPlugin.js": 10852/*!*************************************************!*\ 10853 !*** ./node_modules/gsap/PhysicsPropsPlugin.js ***! 10854 \*************************************************/ 10855/*! exports provided: PhysicsPropsPlugin, default */ 10856/***/ (function(module, __webpack_exports__, __webpack_require__) { 10857 10858"use strict"; 10859__webpack_require__.r(__webpack_exports__); 10860/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PhysicsPropsPlugin", function() { return PhysicsPropsPlugin; }); 10861/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PhysicsPropsPlugin; }); 10862/*! 10863 * PhysicsPropsPlugin 3.6.0 10864 * https://greensock.com 10865 * 10866 * @license Copyright 2008-2021, GreenSock. All rights reserved. 10867 * Subject to the terms at https://greensock.com/standard-license or for 10868 * Club GreenSock members, the agreement issued with that membership. 10869 * @author: Jack Doyle, [email protected] 10870*/ 10871 10872/* eslint-disable */ 10873var gsap, 10874 _coreInitted, 10875 _getUnit, 10876 _getGSAP = function _getGSAP() { 10877 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 10878}, 10879 _round = function _round(value) { 10880 return Math.round(value * 10000) / 10000; 10881}, 10882 _bonusValidated = 1, 10883 //<name>PhysicsPropsPlugin</name> 10884_initCore = function _initCore(core) { 10885 gsap = core || _getGSAP(); 10886 10887 if (!_coreInitted) { 10888 _getUnit = gsap.utils.getUnit; 10889 _coreInitted = 1; 10890 } 10891}; 10892 10893var PhysicsProp = function PhysicsProp(target, p, velocity, acceleration, friction, stepsPerTimeUnit) { 10894 var cache = target._gsap, 10895 curVal = cache.get(target, p); 10896 this.p = p; 10897 this.set = cache.set(target, p); //setter 10898 10899 this.s = this.val = parseFloat(curVal); 10900 this.u = _getUnit(curVal) || 0; 10901 this.vel = velocity || 0; 10902 this.v = this.vel / stepsPerTimeUnit; 10903 10904 if (acceleration || acceleration === 0) { 10905 this.acc = acceleration; 10906 this.a = this.acc / (stepsPerTimeUnit * stepsPerTimeUnit); 10907 } else { 10908 this.acc = this.a = 0; 10909 } 10910 10911 this.fr = 1 - (friction || 0); 10912}; 10913 10914var PhysicsPropsPlugin = { 10915 version: "3.6.0", 10916 name: "physicsProps", 10917 register: _initCore, 10918 init: function init(target, value, tween) { 10919 _coreInitted || _initCore(); 10920 var data = this, 10921 p; 10922 data.target = target; 10923 data.tween = tween; 10924 data.step = 0; 10925 data.sps = 30; //steps per second 10926 10927 data.vProps = []; 10928 10929 for (p in value) { 10930 var _value$p = value[p], 10931 velocity = _value$p.velocity, 10932 acceleration = _value$p.acceleration, 10933 friction = _value$p.friction; 10934 10935 if (velocity || acceleration) { 10936 data.vProps.push(new PhysicsProp(target, p, velocity, acceleration, friction, data.sps)); 10937 10938 data._props.push(p); 10939 10940 friction && (data.hasFr = 1); 10941 } 10942 } 10943 }, 10944 render: function render(ratio, data) { 10945 var vProps = data.vProps, 10946 tween = data.tween, 10947 target = data.target, 10948 step = data.step, 10949 hasFr = data.hasFr, 10950 sps = data.sps, 10951 i = vProps.length, 10952 time = tween._from ? tween._dur - tween._time : tween._time, 10953 curProp, 10954 steps, 10955 remainder, 10956 j, 10957 tt; 10958 10959 if (hasFr) { 10960 time *= sps; 10961 steps = (time | 0) - step; 10962 /* 10963 Note: rounding errors build up if we walk the calculations backward which we used to do like this to maximize performance: 10964 while (i--) { 10965 curProp = vProps[i]; 10966 j = -steps; 10967 while (j--) { 10968 curProp.val -= curProp.v; 10969 curProp.v /= curProp.fr; 10970 curProp.v -= curProp.a; 10971 } 10972 curProp.set(target, curProp.p, _round(curProp.val + (curProp.v * remainder * curProp.fr)) + curProp.u); 10973 } 10974 but now for the sake of accuracy (to ensure rewinding always goes back to EXACTLY the same spot), we force the calculations to go forward every time. So if the tween is going backward, we just start from the beginning and iterate. This is only necessary with friction. 10975 */ 10976 10977 if (steps < 0) { 10978 while (i--) { 10979 curProp = vProps[i]; 10980 curProp.v = curProp.vel / sps; 10981 curProp.val = curProp.s; 10982 } 10983 10984 i = vProps.length; 10985 data.step = step = 0; 10986 steps = time | 0; 10987 } 10988 10989 remainder = time % 1; 10990 10991 while (i--) { 10992 curProp = vProps[i]; 10993 j = steps; 10994 10995 while (j--) { 10996 curProp.v += curProp.a; 10997 curProp.v *= curProp.fr; 10998 curProp.val += curProp.v; 10999 } 11000 11001 curProp.set(target, curProp.p, _round(curProp.val + curProp.v * remainder * curProp.fr) + curProp.u); 11002 } 11003 11004 data.step += steps; 11005 } else { 11006 tt = time * time * 0.5; 11007 11008 while (i--) { 11009 curProp = vProps[i]; 11010 curProp.set(target, curProp.p, _round(curProp.s + curProp.vel * time + curProp.acc * tt) + curProp.u); 11011 } 11012 } 11013 }, 11014 kill: function kill(property) { 11015 var vProps = this.vProps, 11016 i = vProps.length; 11017 11018 while (i--) { 11019 vProps[i].p === property && vProps.splice(i, 1); 11020 } 11021 } 11022}; 11023_getGSAP() && gsap.registerPlugin(PhysicsPropsPlugin); 11024 11025 11026/***/ }), 11027
vendor: 15,282 bytes, lines 11028-11505
11028/***/ "./node_modules/gsap/PixiPlugin.js": 11029/*!*****************************************!*\ 11030 !*** ./node_modules/gsap/PixiPlugin.js ***! 11031 \*****************************************/ 11032/*! exports provided: PixiPlugin, default */ 11033/***/ (function(module, __webpack_exports__, __webpack_require__) { 11034 11035"use strict"; 11036__webpack_require__.r(__webpack_exports__); 11037/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PixiPlugin", function() { return PixiPlugin; }); 11038/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PixiPlugin; }); 11039/*! 11040 * PixiPlugin 3.6.0 11041 * https://greensock.com 11042 * 11043 * @license Copyright 2008-2021, GreenSock. All rights reserved. 11044 * Subject to the terms at https://greensock.com/standard-license or for 11045 * Club GreenSock members, the agreement issued with that membership. 11046 * @author: Jack Doyle, [email protected] 11047*/ 11048 11049/* eslint-disable */ 11050var gsap, 11051 _win, 11052 _splitColor, 11053 _coreInitted, 11054 _PIXI, 11055 PropTween, 11056 _getSetter, 11057 _windowExists = function _windowExists() { 11058 return typeof window !== "undefined"; 11059}, 11060 _getGSAP = function _getGSAP() { 11061 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 11062}, 11063 _isFunction = function _isFunction(value) { 11064 return typeof value === "function"; 11065}, 11066 _warn = function _warn(message) { 11067 return console.warn(message); 11068}, 11069 _idMatrix = [1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0], 11070 _lumR = 0.212671, 11071 _lumG = 0.715160, 11072 _lumB = 0.072169, 11073 _applyMatrix = function _applyMatrix(m, m2) { 11074 var temp = [], 11075 i = 0, 11076 z = 0, 11077 y, 11078 x; 11079 11080 for (y = 0; y < 4; y++) { 11081 for (x = 0; x < 5; x++) { 11082 z = x === 4 ? m[i + 4] : 0; 11083 temp[i + x] = m[i] * m2[x] + m[i + 1] * m2[x + 5] + m[i + 2] * m2[x + 10] + m[i + 3] * m2[x + 15] + z; 11084 } 11085 11086 i += 5; 11087 } 11088 11089 return temp; 11090}, 11091 _setSaturation = function _setSaturation(m, n) { 11092 var inv = 1 - n, 11093 r = inv * _lumR, 11094 g = inv * _lumG, 11095 b = inv * _lumB; 11096 return _applyMatrix([r + n, g, b, 0, 0, r, g + n, b, 0, 0, r, g, b + n, 0, 0, 0, 0, 0, 1, 0], m); 11097}, 11098 _colorize = function _colorize(m, color, amount) { 11099 var c = _splitColor(color), 11100 r = c[0] / 255, 11101 g = c[1] / 255, 11102 b = c[2] / 255, 11103 inv = 1 - amount; 11104 11105 return _applyMatrix([inv + amount * r * _lumR, amount * r * _lumG, amount * r * _lumB, 0, 0, amount * g * _lumR, inv + amount * g * _lumG, amount * g * _lumB, 0, 0, amount * b * _lumR, amount * b * _lumG, inv + amount * b * _lumB, 0, 0, 0, 0, 0, 1, 0], m); 11106}, 11107 _setHue = function _setHue(m, n) { 11108 n *= Math.PI / 180; 11109 var c = Math.cos(n), 11110 s = Math.sin(n); 11111 return _applyMatrix([_lumR + c * (1 - _lumR) + s * -_lumR, _lumG + c * -_lumG + s * -_lumG, _lumB + c * -_lumB + s * (1 - _lumB), 0, 0, _lumR + c * -_lumR + s * 0.143, _lumG + c * (1 - _lumG) + s * 0.14, _lumB + c * -_lumB + s * -0.283, 0, 0, _lumR + c * -_lumR + s * -(1 - _lumR), _lumG + c * -_lumG + s * _lumG, _lumB + c * (1 - _lumB) + s * _lumB, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1], m); 11112}, 11113 _setContrast = function _setContrast(m, n) { 11114 return _applyMatrix([n, 0, 0, 0, 0.5 * (1 - n), 0, n, 0, 0, 0.5 * (1 - n), 0, 0, n, 0, 0.5 * (1 - n), 0, 0, 0, 1, 0], m); 11115}, 11116 _getFilter = function _getFilter(target, type) { 11117 var filterClass = _PIXI.filters[type], 11118 filters = target.filters || [], 11119 i = filters.length, 11120 filter; 11121 11122 if (!filterClass) { 11123 _warn(type + " not found. PixiPlugin.registerPIXI(PIXI)"); 11124 } 11125 11126 while (--i > -1) { 11127 if (filters[i] instanceof filterClass) { 11128 return filters[i]; 11129 } 11130 } 11131 11132 filter = new filterClass(); 11133 11134 if (type === "BlurFilter") { 11135 filter.blur = 0; 11136 } 11137 11138 filters.push(filter); 11139 target.filters = filters; 11140 return filter; 11141}, 11142 _addColorMatrixFilterCacheTween = function _addColorMatrixFilterCacheTween(p, plugin, cache, vars) { 11143 //we cache the ColorMatrixFilter components in a _gsColorMatrixFilter object attached to the target object so that it's easy to grab the current value at any time. 11144 plugin.add(cache, p, cache[p], vars[p]); 11145 11146 plugin._props.push(p); 11147}, 11148 _applyBrightnessToMatrix = function _applyBrightnessToMatrix(brightness, matrix) { 11149 var temp = new _PIXI.filters.ColorMatrixFilter(); 11150 temp.matrix = matrix; 11151 temp.brightness(brightness, true); 11152 return temp.matrix; 11153}, 11154 _copy = function _copy(obj) { 11155 var copy = {}, 11156 p; 11157 11158 for (p in obj) { 11159 copy[p] = obj[p]; 11160 } 11161 11162 return copy; 11163}, 11164 _CMFdefaults = { 11165 contrast: 1, 11166 saturation: 1, 11167 colorizeAmount: 0, 11168 colorize: "rgb(255,255,255)", 11169 hue: 0, 11170 brightness: 1 11171}, 11172 _parseColorMatrixFilter = function _parseColorMatrixFilter(target, v, pg) { 11173 var filter = _getFilter(target, "ColorMatrixFilter"), 11174 cache = target._gsColorMatrixFilter = target._gsColorMatrixFilter || _copy(_CMFdefaults), 11175 combine = v.combineCMF && !("colorMatrixFilter" in v && !v.colorMatrixFilter), 11176 i, 11177 matrix, 11178 startMatrix; 11179 11180 startMatrix = filter.matrix; 11181 11182 if (v.resolution) { 11183 filter.resolution = v.resolution; 11184 } 11185 11186 if (v.matrix && v.matrix.length === startMatrix.length) { 11187 matrix = v.matrix; 11188 11189 if (cache.contrast !== 1) { 11190 _addColorMatrixFilterCacheTween("contrast", pg, cache, _CMFdefaults); 11191 } 11192 11193 if (cache.hue) { 11194 _addColorMatrixFilterCacheTween("hue", pg, cache, _CMFdefaults); 11195 } 11196 11197 if (cache.brightness !== 1) { 11198 _addColorMatrixFilterCacheTween("brightness", pg, cache, _CMFdefaults); 11199 } 11200 11201 if (cache.colorizeAmount) { 11202 _addColorMatrixFilterCacheTween("colorize", pg, cache, _CMFdefaults); 11203 11204 _addColorMatrixFilterCacheTween("colorizeAmount", pg, cache, _CMFdefaults); 11205 } 11206 11207 if (cache.saturation !== 1) { 11208 _addColorMatrixFilterCacheTween("saturation", pg, cache, _CMFdefaults); 11209 } 11210 } else { 11211 matrix = _idMatrix.slice(); 11212 11213 if (v.contrast != null) { 11214 matrix = _setContrast(matrix, +v.contrast); 11215 11216 _addColorMatrixFilterCacheTween("contrast", pg, cache, v); 11217 } else if (cache.contrast !== 1) { 11218 if (combine) { 11219 matrix = _setContrast(matrix, cache.contrast); 11220 } else { 11221 _addColorMatrixFilterCacheTween("contrast", pg, cache, _CMFdefaults); 11222 } 11223 } 11224 11225 if (v.hue != null) { 11226 matrix = _setHue(matrix, +v.hue); 11227 11228 _addColorMatrixFilterCacheTween("hue", pg, cache, v); 11229 } else if (cache.hue) { 11230 if (combine) { 11231 matrix = _setHue(matrix, cache.hue); 11232 } else { 11233 _addColorMatrixFilterCacheTween("hue", pg, cache, _CMFdefaults); 11234 } 11235 } 11236 11237 if (v.brightness != null) { 11238 matrix = _applyBrightnessToMatrix(+v.brightness, matrix); 11239 11240 _addColorMatrixFilterCacheTween("brightness", pg, cache, v); 11241 } else if (cache.brightness !== 1) { 11242 if (combine) { 11243 matrix = _applyBrightnessToMatrix(cache.brightness, matrix); 11244 } else { 11245 _addColorMatrixFilterCacheTween("brightness", pg, cache, _CMFdefaults); 11246 } 11247 } 11248 11249 if (v.colorize != null) { 11250 v.colorizeAmount = "colorizeAmount" in v ? +v.colorizeAmount : 1; 11251 matrix = _colorize(matrix, v.colorize, v.colorizeAmount); 11252 11253 _addColorMatrixFilterCacheTween("colorize", pg, cache, v); 11254 11255 _addColorMatrixFilterCacheTween("colorizeAmount", pg, cache, v); 11256 } else if (cache.colorizeAmount) { 11257 if (combine) { 11258 matrix = _colorize(matrix, cache.colorize, cache.colorizeAmount); 11259 } else { 11260 _addColorMatrixFilterCacheTween("colorize", pg, cache, _CMFdefaults); 11261 11262 _addColorMatrixFilterCacheTween("colorizeAmount", pg, cache, _CMFdefaults); 11263 } 11264 } 11265 11266 if (v.saturation != null) { 11267 matrix = _setSaturation(matrix, +v.saturation); 11268 11269 _addColorMatrixFilterCacheTween("saturation", pg, cache, v); 11270 } else if (cache.saturation !== 1) { 11271 if (combine) { 11272 matrix = _setSaturation(matrix, cache.saturation); 11273 } else { 11274 _addColorMatrixFilterCacheTween("saturation", pg, cache, _CMFdefaults); 11275 } 11276 } 11277 } 11278 11279 i = matrix.length; 11280 11281 while (--i > -1) { 11282 if (matrix[i] !== startMatrix[i]) { 11283 pg.add(startMatrix, i, startMatrix[i], matrix[i], "colorMatrixFilter"); 11284 } 11285 } 11286 11287 pg._props.push("colorMatrixFilter"); 11288}, 11289 _renderColor = function _renderColor(ratio, _ref) { 11290 var t = _ref.t, 11291 p = _ref.p, 11292 color = _ref.color, 11293 set = _ref.set; 11294 set(t, p, color[0] << 16 | color[1] << 8 | color[2]); 11295}, 11296 _renderDirtyCache = function _renderDirtyCache(ratio, _ref2) { 11297 var g = _ref2.g; 11298 11299 if (g) { 11300 //in order for PixiJS to actually redraw GraphicsData, we've gotta increment the "dirty" and "clearDirty" values. If we don't do this, the values will be tween properly, but not rendered. 11301 g.dirty++; 11302 g.clearDirty++; 11303 } 11304}, 11305 _renderAutoAlpha = function _renderAutoAlpha(ratio, data) { 11306 data.t.visible = !!data.t.alpha; 11307}, 11308 _addColorTween = function _addColorTween(target, p, value, plugin) { 11309 var currentValue = target[p], 11310 startColor = _splitColor(_isFunction(currentValue) ? target[p.indexOf("set") || !_isFunction(target["get" + p.substr(3)]) ? p : "get" + p.substr(3)]() : currentValue), 11311 endColor = _splitColor(value); 11312 11313 plugin._pt = new PropTween(plugin._pt, target, p, 0, 0, _renderColor, { 11314 t: target, 11315 p: p, 11316 color: startColor, 11317 set: _getSetter(target, p) 11318 }); 11319 plugin.add(startColor, 0, startColor[0], endColor[0]); 11320 plugin.add(startColor, 1, startColor[1], endColor[1]); 11321 plugin.add(startColor, 2, startColor[2], endColor[2]); 11322}, 11323 _colorProps = { 11324 tint: 1, 11325 lineColor: 1, 11326 fillColor: 1 11327}, 11328 _xyContexts = "position,scale,skew,pivot,anchor,tilePosition,tileScale".split(","), 11329 _contexts = { 11330 x: "position", 11331 y: "position", 11332 tileX: "tilePosition", 11333 tileY: "tilePosition" 11334}, 11335 _colorMatrixFilterProps = { 11336 colorMatrixFilter: 1, 11337 saturation: 1, 11338 contrast: 1, 11339 hue: 1, 11340 colorize: 1, 11341 colorizeAmount: 1, 11342 brightness: 1, 11343 combineCMF: 1 11344}, 11345 _DEG2RAD = Math.PI / 180, 11346 _isString = function _isString(value) { 11347 return typeof value === "string"; 11348}, 11349 _degreesToRadians = function _degreesToRadians(value) { 11350 return _isString(value) && value.charAt(1) === "=" ? value.substr(0, 2) + parseFloat(value.substr(2)) * _DEG2RAD : value * _DEG2RAD; 11351}, 11352 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 11353 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 100000) / 100000, data); 11354}, 11355 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue, radians) { 11356 var cap = 360 * (radians ? _DEG2RAD : 1), 11357 isString = _isString(endValue), 11358 relative = isString && endValue.charAt(1) === "=" ? +(endValue.charAt(0) + "1") : 0, 11359 endNum = parseFloat(relative ? endValue.substr(2) : endValue) * (radians ? _DEG2RAD : 1), 11360 change = relative ? endNum * relative : endNum - startNum, 11361 finalValue = startNum + change, 11362 direction, 11363 pt; 11364 11365 if (isString) { 11366 direction = endValue.split("_")[1]; 11367 11368 if (direction === "short") { 11369 change %= cap; 11370 11371 if (change !== change % (cap / 2)) { 11372 change += change < 0 ? cap : -cap; 11373 } 11374 } 11375 11376 if (direction === "cw" && change < 0) { 11377 change = (change + cap * 1e10) % cap - ~~(change / cap) * cap; 11378 } else if (direction === "ccw" && change > 0) { 11379 change = (change - cap * 1e10) % cap - ~~(change / cap) * cap; 11380 } 11381 } 11382 11383 plugin._pt = pt = new PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 11384 pt.e = finalValue; 11385 return pt; 11386}, 11387 _initCore = function _initCore() { 11388 if (_windowExists()) { 11389 _win = window; 11390 gsap = _coreInitted = _getGSAP(); 11391 _PIXI = _PIXI || _win.PIXI; 11392 11393 _splitColor = function _splitColor(color) { 11394 return gsap.utils.splitColor((color + "").substr(0, 2) === "0x" ? "#" + color.substr(2) : color); 11395 }; // some colors in PIXI are reported as "0xFF4421" instead of "#FF4421". 11396 11397 } 11398}, 11399 i, 11400 p; //context setup... 11401 11402 11403for (i = 0; i < _xyContexts.length; i++) { 11404 p = _xyContexts[i]; 11405 _contexts[p + "X"] = p; 11406 _contexts[p + "Y"] = p; 11407} 11408 11409var PixiPlugin = { 11410 version: "3.6.0", 11411 name: "pixi", 11412 register: function register(core, Plugin, propTween) { 11413 gsap = core; 11414 PropTween = propTween; 11415 _getSetter = Plugin.getSetter; 11416 11417 _initCore(); 11418 }, 11419 registerPIXI: function registerPIXI(pixi) { 11420 _PIXI = pixi; 11421 }, 11422 init: function init(target, values, tween, index, targets) { 11423 if (!_PIXI) { 11424 _initCore(); 11425 } 11426 11427 if (!target instanceof _PIXI.DisplayObject) { 11428 return false; 11429 } 11430 11431 var isV4 = _PIXI.VERSION.charAt(0) === "4", 11432 context, 11433 axis, 11434 value, 11435 colorMatrix, 11436 filter, 11437 p, 11438 padding, 11439 i, 11440 data; 11441 11442 for (p in values) { 11443 context = _contexts[p]; 11444 value = values[p]; 11445 11446 if (context) { 11447 axis = ~p.charAt(p.length - 1).toLowerCase().indexOf("x") ? "x" : "y"; 11448 this.add(target[context], axis, target[context][axis], context === "skew" ? _degreesToRadians(value) : value); 11449 } else if (p === "scale" || p === "anchor" || p === "pivot" || p === "tileScale") { 11450 this.add(target[p], "x", target[p].x, value); 11451 this.add(target[p], "y", target[p].y, value); 11452 } else if (p === "rotation" || p === "angle") { 11453 //PIXI expects rotation in radians, but as a convenience we let folks define it in degrees and we do the conversion. 11454 _addRotationalPropTween(this, target, p, target[p], value, p === "rotation"); 11455 } else if (_colorMatrixFilterProps[p]) { 11456 if (!colorMatrix) { 11457 _parseColorMatrixFilter(target, values.colorMatrixFilter || values, this); 11458 11459 colorMatrix = true; 11460 } 11461 } else if (p === "blur" || p === "blurX" || p === "blurY" || p === "blurPadding") { 11462 filter = _getFilter(target, "BlurFilter"); 11463 this.add(filter, p, filter[p], value); 11464 11465 if (values.blurPadding !== 0) { 11466 padding = values.blurPadding || Math.max(filter[p], value) * 2; 11467 i = target.filters.length; 11468 11469 while (--i > -1) { 11470 target.filters[i].padding = Math.max(target.filters[i].padding, padding); //if we don't expand the padding on all the filters, it can look clipped. 11471 } 11472 } 11473 } else if (_colorProps[p]) { 11474 if ((p === "lineColor" || p === "fillColor") && target instanceof _PIXI.Graphics) { 11475 data = (target.geometry || target).graphicsData; //"geometry" was introduced in PIXI version 5 11476 11477 this._pt = new PropTween(this._pt, target, p, 0, 0, _renderDirtyCache, { 11478 g: target.geometry || target 11479 }); 11480 i = data.length; 11481 11482 while (--i > -1) { 11483 _addColorTween(isV4 ? data[i] : data[i][p.substr(0, 4) + "Style"], isV4 ? p : "color", value, this); 11484 } 11485 } else { 11486 _addColorTween(target, p, value, this); 11487 } 11488 } else if (p === "autoAlpha") { 11489 this._pt = new PropTween(this._pt, target, "visible", 0, 0, _renderAutoAlpha); 11490 this.add(target, "alpha", target.alpha, value); 11491 11492 this._props.push("alpha", "visible"); 11493 } else if (p !== "resolution") { 11494 this.add(target, p, "get", value); 11495 } 11496 11497 this._props.push(p); 11498 } 11499 } 11500}; 11501_getGSAP() && gsap.registerPlugin(PixiPlugin); 11502 11503 11504/***/ }), 11505
vendor: 10,006 bytes, lines 11506-11770
11506/***/ "./node_modules/gsap/ScrambleTextPlugin.js": 11507/*!*************************************************!*\ 11508 !*** ./node_modules/gsap/ScrambleTextPlugin.js ***! 11509 \*************************************************/ 11510/*! exports provided: ScrambleTextPlugin, default */ 11511/***/ (function(module, __webpack_exports__, __webpack_require__) { 11512 11513"use strict"; 11514__webpack_require__.r(__webpack_exports__); 11515/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScrambleTextPlugin", function() { return ScrambleTextPlugin; }); 11516/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ScrambleTextPlugin; }); 11517/* harmony import */ var _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/strings.js */ "./node_modules/gsap/utils/strings.js"); 11518/*! 11519 * ScrambleTextPlugin 3.6.0 11520 * https://greensock.com 11521 * 11522 * @license Copyright 2008-2021, GreenSock. All rights reserved. 11523 * Subject to the terms at https://greensock.com/standard-license or for 11524 * Club GreenSock members, the agreement issued with that membership. 11525 * @author: Jack Doyle, [email protected] 11526*/ 11527 11528/* eslint-disable */ 11529 11530 11531var CharSet = /*#__PURE__*/function () { 11532 function CharSet(chars) { 11533 this.chars = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(chars); 11534 this.sets = []; 11535 this.length = 50; 11536 11537 for (var i = 0; i < 20; i++) { 11538 this.sets[i] = _scrambleText(80, this.chars); //we create 20 strings that are 80 characters long, randomly chosen and pack them into an array. We then randomly choose the scrambled text from this array in order to greatly improve efficiency compared to creating new randomized text from scratch each and every time it's needed. This is a simple lookup whereas the other technique requires looping through as many times as there are characters needed, and calling Math.random() each time through the loop, building the string, etc. 11539 } 11540 } 11541 11542 var _proto = CharSet.prototype; 11543 11544 _proto.grow = function grow(newLength) { 11545 //if we encounter a tween that has more than 80 characters, we'll need to add to the character sets accordingly. Once it's cached, it'll only need to grow again if we exceed that new length. Again, this is an efficiency tactic. 11546 for (var i = 0; i < 20; i++) { 11547 this.sets[i] += _scrambleText(newLength - this.length, this.chars); 11548 } 11549 11550 this.length = newLength; 11551 }; 11552 11553 return CharSet; 11554}(); 11555 11556var gsap, 11557 _coreInitted, 11558 _getGSAP = function _getGSAP() { 11559 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 11560}, 11561 _bonusValidated = 1, 11562 //<name>ScrambleTextPlugin</name> 11563_spacesExp = /\s+/g, 11564 _scrambleText = function _scrambleText(length, chars) { 11565 var l = chars.length, 11566 s = ""; 11567 11568 while (--length > -1) { 11569 s += chars[~~(Math.random() * l)]; 11570 } 11571 11572 return s; 11573}, 11574 _upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 11575 _lower = _upper.toLowerCase(), 11576 _charsLookup = { 11577 upperCase: new CharSet(_upper), 11578 lowerCase: new CharSet(_lower), 11579 upperAndLowerCase: new CharSet(_upper + _lower) 11580}, 11581 _initCore = function _initCore() { 11582 _coreInitted = gsap = _getGSAP(); 11583}; 11584 11585var ScrambleTextPlugin = { 11586 version: "3.6.0", 11587 name: "scrambleText", 11588 register: function register(core, Plugin, propTween) { 11589 gsap = core; 11590 11591 _initCore(); 11592 }, 11593 init: function init(target, value, tween, index, targets) { 11594 if (!_coreInitted) { 11595 _initCore(); 11596 } 11597 11598 this.prop = "innerHTML" in target ? "innerHTML" : "textContent" in target ? "textContent" : 0; // SVG text in IE doesn't have innerHTML, but it does have textContent. 11599 11600 if (!this.prop) { 11601 return; 11602 } 11603 11604 this.target = target; 11605 11606 if (typeof value !== "object") { 11607 value = { 11608 text: value 11609 }; 11610 } 11611 11612 var text = value.text || value.value, 11613 trim = value.trim !== false, 11614 data = this, 11615 delim, 11616 maxLength, 11617 charset, 11618 splitByChars; 11619 data.delimiter = delim = value.delimiter || ""; 11620 data.original = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["getText"])(target).replace(_spacesExp, " ").split(" ").join(""), delim, trim); 11621 11622 if (text === "{original}" || text === true || text == null) { 11623 text = data.original.join(delim); 11624 } 11625 11626 data.text = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])((text || "").replace(_spacesExp, " "), delim, trim); 11627 data.hasClass = !!(value.newClass || value.oldClass); 11628 data.newClass = value.newClass; 11629 data.oldClass = value.oldClass; 11630 splitByChars = delim === ""; 11631 data.textHasEmoji = splitByChars && !!data.text.emoji; 11632 data.charsHaveEmoji = !!value.chars && !!Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(value.chars).emoji; 11633 data.length = splitByChars ? data.original.length : data.original.join(delim).length; 11634 data.lengthDif = (splitByChars ? data.text.length : data.text.join(delim).length) - data.length; 11635 data.fillChar = value.fillChar || value.chars && ~value.chars.indexOf(" ") ? " " : ""; 11636 data.charSet = charset = _charsLookup[value.chars || "upperCase"] || new CharSet(value.chars); 11637 data.speed = 0.05 / (value.speed || 1); 11638 data.prevScrambleTime = 0; 11639 data.setIndex = Math.random() * 20 | 0; 11640 maxLength = data.length + Math.max(data.lengthDif, 0); 11641 11642 if (maxLength > charset.length) { 11643 charset.grow(maxLength); 11644 } 11645 11646 data.chars = charset.sets[data.setIndex]; 11647 data.revealDelay = value.revealDelay || 0; 11648 data.tweenLength = value.tweenLength !== false; 11649 data.tween = tween; 11650 data.rightToLeft = !!value.rightToLeft; 11651 11652 data._props.push("scrambleText", "text"); 11653 11654 return _bonusValidated; 11655 }, 11656 render: function render(ratio, data) { 11657 var target = data.target, 11658 prop = data.prop, 11659 text = data.text, 11660 delimiter = data.delimiter, 11661 tween = data.tween, 11662 prevScrambleTime = data.prevScrambleTime, 11663 revealDelay = data.revealDelay, 11664 setIndex = data.setIndex, 11665 chars = data.chars, 11666 charSet = data.charSet, 11667 length = data.length, 11668 textHasEmoji = data.textHasEmoji, 11669 charsHaveEmoji = data.charsHaveEmoji, 11670 lengthDif = data.lengthDif, 11671 tweenLength = data.tweenLength, 11672 oldClass = data.oldClass, 11673 newClass = data.newClass, 11674 rightToLeft = data.rightToLeft, 11675 fillChar = data.fillChar, 11676 speed = data.speed, 11677 original = data.original, 11678 hasClass = data.hasClass, 11679 l = text.length, 11680 time = tween._time, 11681 timeDif = time - prevScrambleTime, 11682 i, 11683 i2, 11684 startText, 11685 endText, 11686 applyNew, 11687 applyOld, 11688 str, 11689 startClass, 11690 endClass; 11691 11692 if (revealDelay) { 11693 if (tween._from) { 11694 time = tween._dur - time; //invert the time for from() tweens 11695 } 11696 11697 ratio = time === 0 ? 0 : time < revealDelay ? 0.000001 : time === tween._dur ? 1 : tween._ease((time - revealDelay) / (tween._dur - revealDelay)); 11698 } 11699 11700 if (ratio < 0) { 11701 ratio = 0; 11702 } else if (ratio > 1) { 11703 ratio = 1; 11704 } 11705 11706 if (rightToLeft) { 11707 ratio = 1 - ratio; 11708 } 11709 11710 i = ~~(ratio * l + 0.5); 11711 11712 if (ratio) { 11713 if (timeDif > speed || timeDif < -speed) { 11714 data.setIndex = setIndex = (setIndex + (Math.random() * 19 | 0)) % 20; 11715 data.chars = charSet.sets[setIndex]; 11716 data.prevScrambleTime += timeDif; 11717 } 11718 11719 endText = chars; 11720 } else { 11721 endText = original.join(delimiter); 11722 } 11723 11724 if (rightToLeft) { 11725 if (ratio === 1 && (tween._from || tween.data === "isFromStart")) { 11726 //special case for from() tweens 11727 startText = ""; 11728 endText = original.join(delimiter); 11729 } else { 11730 str = text.slice(i).join(delimiter); 11731 11732 if (charsHaveEmoji) { 11733 startText = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(endText).slice(0, length + (tweenLength ? 1 - ratio * ratio * ratio : 1) * lengthDif - (textHasEmoji ? Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(str) : str).length + 0.5 | 0).join(""); 11734 } else { 11735 startText = endText.substr(0, length + (tweenLength ? 1 - ratio * ratio * ratio : 1) * lengthDif - (textHasEmoji ? Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(str) : str).length + 0.5 | 0); 11736 } 11737 11738 endText = str; 11739 } 11740 } else { 11741 startText = text.slice(0, i).join(delimiter); 11742 i2 = (textHasEmoji ? Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(startText) : startText).length; 11743 11744 if (charsHaveEmoji) { 11745 endText = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"])(endText).slice(i2, length + (tweenLength ? 1 - (ratio = 1 - ratio) * ratio * ratio * ratio : 1) * lengthDif + 0.5 | 0).join(""); 11746 } else { 11747 endText = endText.substr(i2, length + (tweenLength ? 1 - (ratio = 1 - ratio) * ratio * ratio * ratio : 1) * lengthDif - i2 + 0.5 | 0); 11748 } 11749 } 11750 11751 if (hasClass) { 11752 startClass = rightToLeft ? oldClass : newClass; 11753 endClass = rightToLeft ? newClass : oldClass; 11754 applyNew = startClass && i !== 0; 11755 applyOld = endClass && i !== l; 11756 str = (applyNew ? "<span class='" + startClass + "'>" : "") + startText + (applyNew ? "</span>" : "") + (applyOld ? "<span class='" + endClass + "'>" : "") + delimiter + endText + (applyOld ? "</span>" : ""); 11757 } else { 11758 str = startText + delimiter + endText; 11759 } 11760 11761 target[prop] = fillChar === " " && ~str.indexOf(" ") ? str.split(" ").join(" ") : str; 11762 } 11763}; 11764ScrambleTextPlugin.emojiSafeSplit = _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"]; 11765ScrambleTextPlugin.getText = _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["getText"]; 11766_getGSAP() && gsap.registerPlugin(ScrambleTextPlugin); 11767 11768 11769/***/ }), 11770
vendor: 8,277 bytes, lines 11771-12026
11771/***/ "./node_modules/gsap/ScrollToPlugin.js": 11772/*!*********************************************!*\ 11773 !*** ./node_modules/gsap/ScrollToPlugin.js ***! 11774 \*********************************************/ 11775/*! exports provided: ScrollToPlugin, default */ 11776/***/ (function(module, __webpack_exports__, __webpack_require__) { 11777 11778"use strict"; 11779__webpack_require__.r(__webpack_exports__); 11780/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScrollToPlugin", function() { return ScrollToPlugin; }); 11781/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ScrollToPlugin; }); 11782/*! 11783 * ScrollToPlugin 3.6.0 11784 * https://greensock.com 11785 * 11786 * @license Copyright 2008-2021, GreenSock. All rights reserved. 11787 * Subject to the terms at https://greensock.com/standard-license or for 11788 * Club GreenSock members, the agreement issued with that membership. 11789 * @author: Jack Doyle, [email protected] 11790*/ 11791 11792/* eslint-disable */ 11793var gsap, 11794 _coreInitted, 11795 _window, 11796 _docEl, 11797 _body, 11798 _toArray, 11799 _config, 11800 _windowExists = function _windowExists() { 11801 return typeof window !== "undefined"; 11802}, 11803 _getGSAP = function _getGSAP() { 11804 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 11805}, 11806 _isString = function _isString(value) { 11807 return typeof value === "string"; 11808}, 11809 _isFunction = function _isFunction(value) { 11810 return typeof value === "function"; 11811}, 11812 _max = function _max(element, axis) { 11813 var dim = axis === "x" ? "Width" : "Height", 11814 scroll = "scroll" + dim, 11815 client = "client" + dim; 11816 return element === _window || element === _docEl || element === _body ? Math.max(_docEl[scroll], _body[scroll]) - (_window["inner" + dim] || _docEl[client] || _body[client]) : element[scroll] - element["offset" + dim]; 11817}, 11818 _buildGetter = function _buildGetter(e, axis) { 11819 //pass in an element and an axis ("x" or "y") and it'll return a getter function for the scroll position of that element (like scrollTop or scrollLeft, although if the element is the window, it'll use the pageXOffset/pageYOffset or the documentElement's scrollTop/scrollLeft or document.body's. Basically this streamlines things and makes a very fast getter across browsers. 11820 var p = "scroll" + (axis === "x" ? "Left" : "Top"); 11821 11822 if (e === _window) { 11823 if (e.pageXOffset != null) { 11824 p = "page" + axis.toUpperCase() + "Offset"; 11825 } else { 11826 e = _docEl[p] != null ? _docEl : _body; 11827 } 11828 } 11829 11830 return function () { 11831 return e[p]; 11832 }; 11833}, 11834 _clean = function _clean(value, index, target, targets) { 11835 _isFunction(value) && (value = value(index, target, targets)); 11836 11837 if (typeof value !== "object") { 11838 return _isString(value) && value !== "max" && value.charAt(1) !== "=" ? { 11839 x: value, 11840 y: value 11841 } : { 11842 y: value 11843 }; //if we don't receive an object as the parameter, assume the user intends "y". 11844 } else if (value.nodeType) { 11845 return { 11846 y: value, 11847 x: value 11848 }; 11849 } else { 11850 var result = {}, 11851 p; 11852 11853 for (p in value) { 11854 p !== "onAutoKill" && (result[p] = _isFunction(value[p]) ? value[p](index, target, targets) : value[p]); 11855 } 11856 11857 return result; 11858 } 11859}, 11860 _getOffset = function _getOffset(element, container) { 11861 element = _toArray(element)[0]; 11862 11863 if (!element || !element.getBoundingClientRect) { 11864 return console.warn("scrollTo target doesn't exist. Using 0") || { 11865 x: 0, 11866 y: 0 11867 }; 11868 } 11869 11870 var rect = element.getBoundingClientRect(), 11871 isRoot = !container || container === _window || container === _body, 11872 cRect = isRoot ? { 11873 top: _docEl.clientTop - (_window.pageYOffset || _docEl.scrollTop || _body.scrollTop || 0), 11874 left: _docEl.clientLeft - (_window.pageXOffset || _docEl.scrollLeft || _body.scrollLeft || 0) 11875 } : container.getBoundingClientRect(), 11876 offsets = { 11877 x: rect.left - cRect.left, 11878 y: rect.top - cRect.top 11879 }; 11880 11881 if (!isRoot && container) { 11882 //only add the current scroll position if it's not the window/body. 11883 offsets.x += _buildGetter(container, "x")(); 11884 offsets.y += _buildGetter(container, "y")(); 11885 } 11886 11887 return offsets; 11888}, 11889 _parseVal = function _parseVal(value, target, axis, currentVal, offset) { 11890 return !isNaN(value) && typeof value !== "object" ? parseFloat(value) - offset : _isString(value) && value.charAt(1) === "=" ? parseFloat(value.substr(2)) * (value.charAt(0) === "-" ? -1 : 1) + currentVal - offset : value === "max" ? _max(target, axis) - offset : Math.min(_max(target, axis), _getOffset(value, target)[axis] - offset); 11891}, 11892 _initCore = function _initCore() { 11893 gsap = _getGSAP(); 11894 11895 if (_windowExists() && gsap && document.body) { 11896 _window = window; 11897 _body = document.body; 11898 _docEl = document.documentElement; 11899 _toArray = gsap.utils.toArray; 11900 gsap.config({ 11901 autoKillThreshold: 7 11902 }); 11903 _config = gsap.config(); 11904 _coreInitted = 1; 11905 } 11906}; 11907 11908var ScrollToPlugin = { 11909 version: "3.6.0", 11910 name: "scrollTo", 11911 rawVars: 1, 11912 register: function register(core) { 11913 gsap = core; 11914 11915 _initCore(); 11916 }, 11917 init: function init(target, value, tween, index, targets) { 11918 _coreInitted || _initCore(); 11919 var data = this; 11920 data.isWin = target === _window; 11921 data.target = target; 11922 data.tween = tween; 11923 value = _clean(value, index, target, targets); 11924 data.vars = value; 11925 data.autoKill = !!value.autoKill; 11926 data.getX = _buildGetter(target, "x"); 11927 data.getY = _buildGetter(target, "y"); 11928 data.x = data.xPrev = data.getX(); 11929 data.y = data.yPrev = data.getY(); 11930 11931 if (value.x != null) { 11932 data.add(data, "x", data.x, _parseVal(value.x, target, "x", data.x, value.offsetX || 0), index, targets, Math.round); 11933 11934 data._props.push("scrollTo_x"); 11935 } else { 11936 data.skipX = 1; 11937 } 11938 11939 if (value.y != null) { 11940 data.add(data, "y", data.y, _parseVal(value.y, target, "y", data.y, value.offsetY || 0), index, targets, Math.round); 11941 11942 data._props.push("scrollTo_y"); 11943 } else { 11944 data.skipY = 1; 11945 } 11946 }, 11947 render: function render(ratio, data) { 11948 var pt = data._pt, 11949 target = data.target, 11950 tween = data.tween, 11951 autoKill = data.autoKill, 11952 xPrev = data.xPrev, 11953 yPrev = data.yPrev, 11954 isWin = data.isWin, 11955 x, 11956 y, 11957 yDif, 11958 xDif, 11959 threshold; 11960 11961 while (pt) { 11962 pt.r(ratio, pt.d); 11963 pt = pt._next; 11964 } 11965 11966 x = isWin || !data.skipX ? data.getX() : xPrev; 11967 y = isWin || !data.skipY ? data.getY() : yPrev; 11968 yDif = y - yPrev; 11969 xDif = x - xPrev; 11970 threshold = _config.autoKillThreshold; 11971 11972 if (data.x < 0) { 11973 //can't scroll to a position less than 0! Might happen if someone uses a Back.easeOut or Elastic.easeOut when scrolling back to the top of the page (for example) 11974 data.x = 0; 11975 } 11976 11977 if (data.y < 0) { 11978 data.y = 0; 11979 } 11980 11981 if (autoKill) { 11982 //note: iOS has a bug that throws off the scroll by several pixels, so we need to check if it's within 7 pixels of the previous one that we set instead of just looking for an exact match. 11983 if (!data.skipX && (xDif > threshold || xDif < -threshold) && x < _max(target, "x")) { 11984 data.skipX = 1; //if the user scrolls separately, we should stop tweening! 11985 } 11986 11987 if (!data.skipY && (yDif > threshold || yDif < -threshold) && y < _max(target, "y")) { 11988 data.skipY = 1; //if the user scrolls separately, we should stop tweening! 11989 } 11990 11991 if (data.skipX && data.skipY) { 11992 tween.kill(); 11993 data.vars.onAutoKill && data.vars.onAutoKill.apply(tween, data.vars.onAutoKillParams || []); 11994 } 11995 } 11996 11997 if (isWin) { 11998 _window.scrollTo(!data.skipX ? data.x : x, !data.skipY ? data.y : y); 11999 } else { 12000 data.skipY || (target.scrollTop = data.y); 12001 data.skipX || (target.scrollLeft = data.x); 12002 } 12003 12004 data.xPrev = data.x; 12005 data.yPrev = data.y; 12006 }, 12007 kill: function kill(property) { 12008 var both = property === "scrollTo"; 12009 12010 if (both || property === "scrollTo_x") { 12011 this.skipX = 1; 12012 } 12013 12014 if (both || property === "scrollTo_y") { 12015 this.skipY = 1; 12016 } 12017 } 12018}; 12019ScrollToPlugin.max = _max; 12020ScrollToPlugin.getOffset = _getOffset; 12021ScrollToPlugin.buildGetter = _buildGetter; 12022_getGSAP() && gsap.registerPlugin(ScrollToPlugin); 12023 12024 12025/***/ }), 12026
vendor: 62,529 bytes, lines 12027-13706
12027/***/ "./node_modules/gsap/ScrollTrigger.js": 12028/*!********************************************!*\ 12029 !*** ./node_modules/gsap/ScrollTrigger.js ***! 12030 \********************************************/ 12031/*! exports provided: ScrollTrigger, default */ 12032/***/ (function(module, __webpack_exports__, __webpack_require__) { 12033 12034"use strict"; 12035__webpack_require__.r(__webpack_exports__); 12036/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ScrollTrigger", function() { return ScrollTrigger; }); 12037/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return ScrollTrigger; }); 12038/*! 12039 * ScrollTrigger 3.6.0 12040 * https://greensock.com 12041 * 12042 * @license Copyright 2008-2021, GreenSock. All rights reserved. 12043 * Subject to the terms at https://greensock.com/standard-license or for 12044 * Club GreenSock members, the agreement issued with that membership. 12045 * @author: Jack Doyle, [email protected] 12046*/ 12047 12048/* eslint-disable */ 12049var gsap, 12050 _coreInitted, 12051 _win, 12052 _doc, 12053 _docEl, 12054 _body, 12055 _root, 12056 _resizeDelay, 12057 _raf, 12058 _request, 12059 _toArray, 12060 _clamp, 12061 _time2, 12062 _syncInterval, 12063 _refreshing, 12064 _pointerIsDown, 12065 _transformProp, 12066 _i, 12067 _prevWidth, 12068 _prevHeight, 12069 _autoRefresh, 12070 _sort, 12071 _suppressOverwrites, 12072 _ignoreResize, 12073 _limitCallbacks, 12074 // if true, we'll only trigger callbacks if the active state toggles, so if you scroll immediately past both the start and end positions of a ScrollTrigger (thus inactive to inactive), neither its onEnter nor onLeave will be called. This is useful during startup. 12075_startup = 1, 12076 _proxies = [], 12077 _scrollers = [], 12078 _getTime = Date.now, 12079 _time1 = _getTime(), 12080 _lastScrollTime = 0, 12081 _enabled = 1, 12082 _passThrough = function _passThrough(v) { 12083 return v; 12084}, 12085 _windowExists = function _windowExists() { 12086 return typeof window !== "undefined"; 12087}, 12088 _getGSAP = function _getGSAP() { 12089 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 12090}, 12091 _isViewport = function _isViewport(e) { 12092 return !!~_root.indexOf(e); 12093}, 12094 _getProxyProp = function _getProxyProp(element, property) { 12095 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 12096}, 12097 _getScrollFunc = function _getScrollFunc(element, _ref) { 12098 var s = _ref.s, 12099 sc = _ref.sc; 12100 12101 var i = _scrollers.indexOf(element), 12102 offset = sc === _vertical.sc ? 1 : 2; 12103 12104 !~i && (i = _scrollers.push(element) - 1); 12105 return _scrollers[i + offset] || (_scrollers[i + offset] = _getProxyProp(element, s) || (_isViewport(element) ? sc : function (value) { 12106 return arguments.length ? element[s] = value : element[s]; 12107 })); 12108}, 12109 _getBoundsFunc = function _getBoundsFunc(element) { 12110 return _getProxyProp(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 12111 _winOffsets.width = _win.innerWidth; 12112 _winOffsets.height = _win.innerHeight; 12113 return _winOffsets; 12114 } : function () { 12115 return _getBounds(element); 12116 }); 12117}, 12118 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref2) { 12119 var d = _ref2.d, 12120 d2 = _ref2.d2, 12121 a = _ref2.a; 12122 return (a = _getProxyProp(scroller, "getBoundingClientRect")) ? function () { 12123 return a()[d]; 12124 } : function () { 12125 return (isViewport ? _win["inner" + d2] : scroller["client" + d2]) || 0; 12126 }; 12127}, 12128 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 12129 return !isViewport || ~_proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 12130 return _winOffsets; 12131 }; 12132}, 12133 _maxScroll = function _maxScroll(element, _ref3) { 12134 var s = _ref3.s, 12135 d2 = _ref3.d2, 12136 d = _ref3.d, 12137 a = _ref3.a; 12138 return (s = "scroll" + d2) && (a = _getProxyProp(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? Math.max(_docEl[s], _body[s]) - (_win["inner" + d2] || _docEl["client" + d2] || _body["client" + d2]) : element[s] - element["offset" + d2]; 12139}, 12140 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 12141 for (var i = 0; i < _autoRefresh.length; i += 3) { 12142 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 12143 } 12144}, 12145 _isString = function _isString(value) { 12146 return typeof value === "string"; 12147}, 12148 _isFunction = function _isFunction(value) { 12149 return typeof value === "function"; 12150}, 12151 _isNumber = function _isNumber(value) { 12152 return typeof value === "number"; 12153}, 12154 _isObject = function _isObject(value) { 12155 return typeof value === "object"; 12156}, 12157 _callIfFunc = function _callIfFunc(value) { 12158 return _isFunction(value) && value(); 12159}, 12160 _combineFunc = function _combineFunc(f1, f2) { 12161 return function () { 12162 var result1 = _callIfFunc(f1), 12163 result2 = _callIfFunc(f2); 12164 12165 return function () { 12166 _callIfFunc(result1); 12167 12168 _callIfFunc(result2); 12169 }; 12170 }; 12171}, 12172 _abs = Math.abs, 12173 _scrollLeft = "scrollLeft", 12174 _scrollTop = "scrollTop", 12175 _left = "left", 12176 _top = "top", 12177 _right = "right", 12178 _bottom = "bottom", 12179 _width = "width", 12180 _height = "height", 12181 _Right = "Right", 12182 _Left = "Left", 12183 _Top = "Top", 12184 _Bottom = "Bottom", 12185 _padding = "padding", 12186 _margin = "margin", 12187 _Width = "Width", 12188 _Height = "Height", 12189 _px = "px", 12190 _horizontal = { 12191 s: _scrollLeft, 12192 p: _left, 12193 p2: _Left, 12194 os: _right, 12195 os2: _Right, 12196 d: _width, 12197 d2: _Width, 12198 a: "x", 12199 sc: function sc(value) { 12200 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 12201 } 12202}, 12203 _vertical = { 12204 s: _scrollTop, 12205 p: _top, 12206 p2: _Top, 12207 os: _bottom, 12208 os2: _Bottom, 12209 d: _height, 12210 d2: _Height, 12211 a: "y", 12212 op: _horizontal, 12213 sc: function sc(value) { 12214 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 12215 } 12216}, 12217 _getComputedStyle = function _getComputedStyle(element) { 12218 return _win.getComputedStyle(element); 12219}, 12220 _makePositionable = function _makePositionable(element) { 12221 return element.style.position = _getComputedStyle(element).position === "absolute" ? "absolute" : "relative"; 12222}, 12223 // if the element already has position: absolute, leave that, otherwise make it position: relative 12224_setDefaults = function _setDefaults(obj, defaults) { 12225 for (var p in defaults) { 12226 p in obj || (obj[p] = defaults[p]); 12227 } 12228 12229 return obj; 12230}, 12231 //_isInViewport = element => (element = _getBounds(element)) && !(element.top > (_win.innerHeight || _docEl.clientHeight) || element.bottom < 0 || element.left > (_win.innerWidth || _docEl.clientWidth) || element.right < 0) && element, 12232_getBounds = function _getBounds(element, withoutTransforms) { 12233 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 12234 x: 0, 12235 y: 0, 12236 xPercent: 0, 12237 yPercent: 0, 12238 rotation: 0, 12239 rotationX: 0, 12240 rotationY: 0, 12241 scale: 1, 12242 skewX: 0, 12243 skewY: 0 12244 }).progress(1), 12245 bounds = element.getBoundingClientRect(); 12246 tween && tween.progress(0).kill(); 12247 return bounds; 12248}, 12249 _getSize = function _getSize(element, _ref4) { 12250 var d2 = _ref4.d2; 12251 return element["offset" + d2] || element["client" + d2] || 0; 12252}, 12253 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 12254 var a = [], 12255 labels = timeline.labels, 12256 duration = timeline.duration(), 12257 p; 12258 12259 for (p in labels) { 12260 a.push(labels[p] / duration); 12261 } 12262 12263 return a; 12264}, 12265 _getClosestLabel = function _getClosestLabel(animation) { 12266 return function (value) { 12267 return gsap.utils.snap(_getLabelRatioArray(animation), value); 12268 }; 12269}, 12270 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 12271 return function (value, st) { 12272 var a = _getLabelRatioArray(timeline), 12273 i; 12274 12275 a.sort(function (a, b) { 12276 return a - b; 12277 }); 12278 12279 if (st.direction > 0) { 12280 for (i = 0; i < a.length; i++) { 12281 if (a[i] >= value) { 12282 return a[i]; 12283 } 12284 } 12285 12286 return a.pop(); 12287 } else { 12288 i = a.length; 12289 12290 while (i--) { 12291 if (a[i] <= value) { 12292 return a[i]; 12293 } 12294 } 12295 } 12296 12297 return a[0]; 12298 }; 12299}, 12300 _multiListener = function _multiListener(func, element, types, callback) { 12301 return types.split(",").forEach(function (type) { 12302 return func(element, type, callback); 12303 }); 12304}, 12305 _addListener = function _addListener(element, type, func) { 12306 return element.addEventListener(type, func, { 12307 passive: true 12308 }); 12309}, 12310 _removeListener = function _removeListener(element, type, func) { 12311 return element.removeEventListener(type, func); 12312}, 12313 _markerDefaults = { 12314 startColor: "green", 12315 endColor: "red", 12316 indent: 0, 12317 fontSize: "16px", 12318 fontWeight: "normal" 12319}, 12320 _defaults = { 12321 toggleActions: "play", 12322 anticipatePin: 0 12323}, 12324 _keywords = { 12325 top: 0, 12326 left: 0, 12327 center: 0.5, 12328 bottom: 1, 12329 right: 1 12330}, 12331 _offsetToPx = function _offsetToPx(value, size) { 12332 if (_isString(value)) { 12333 var eqIndex = value.indexOf("="), 12334 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 12335 12336 if (~eqIndex) { 12337 value.indexOf("%") > eqIndex && (relative *= size / 100); 12338 value = value.substr(0, eqIndex - 1); 12339 } 12340 12341 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 12342 } 12343 12344 return value; 12345}, 12346 _createMarker = function _createMarker(type, name, container, direction, _ref5, offset, matchWidthEl) { 12347 var startColor = _ref5.startColor, 12348 endColor = _ref5.endColor, 12349 fontSize = _ref5.fontSize, 12350 indent = _ref5.indent, 12351 fontWeight = _ref5.fontWeight; 12352 12353 var e = _doc.createElement("div"), 12354 useFixedPosition = _isViewport(container) || _getProxyProp(container, "pinType") === "fixed", 12355 isScroller = type.indexOf("scroller") !== -1, 12356 parent = useFixedPosition ? _body : container, 12357 isStart = type.indexOf("start") !== -1, 12358 color = isStart ? startColor : endColor, 12359 css = "border-color:" + color + ";font-size:" + fontSize + ";color:" + color + ";font-weight:" + fontWeight + ";pointer-events:none;white-space:nowrap;font-family:sans-serif,Arial;z-index:1000;padding:4px 8px;border-width:0;border-style:solid;"; 12360 12361 css += "position:" + (isScroller && useFixedPosition ? "fixed;" : "absolute;"); 12362 (isScroller || !useFixedPosition) && (css += (direction === _vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 12363 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 12364 e._isStart = isStart; 12365 e.setAttribute("class", "gsap-marker-" + type); 12366 e.style.cssText = css; 12367 e.innerText = name || name === 0 ? type + "-" + name : type; 12368 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 12369 e._offset = e["offset" + direction.op.d2]; 12370 12371 _positionMarker(e, 0, direction, isStart); 12372 12373 return e; 12374}, 12375 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 12376 var vars = { 12377 display: "block" 12378 }, 12379 side = direction[flipped ? "os2" : "p2"], 12380 oppositeSide = direction[flipped ? "p2" : "os2"]; 12381 marker._isFlipped = flipped; 12382 vars[direction.a + "Percent"] = flipped ? -100 : 0; 12383 vars[direction.a] = flipped ? "1px" : 0; 12384 vars["border" + side + _Width] = 1; 12385 vars["border" + oppositeSide + _Width] = 0; 12386 vars[direction.p] = start + "px"; 12387 gsap.set(marker, vars); 12388}, 12389 _triggers = [], 12390 _ids = {}, 12391 _sync = function _sync() { 12392 return _request || (_request = _raf(_updateAll)); 12393}, 12394 _onScroll = function _onScroll() { 12395 if (!_request) { 12396 _request = _raf(_updateAll); 12397 _lastScrollTime || _dispatch("scrollStart"); 12398 _lastScrollTime = _getTime(); 12399 } 12400}, 12401 _onResize = function _onResize() { 12402 return !_refreshing && !_ignoreResize && !_doc.fullscreenElement && _resizeDelay.restart(true); 12403}, 12404 // ignore resizes triggered by refresh() 12405_listeners = {}, 12406 _emptyArray = [], 12407 _media = [], 12408 _creatingMedia, 12409 // when ScrollTrigger.matchMedia() is called, we record the current media key here (like "(min-width: 800px)") so that we can assign it to everything that's created during that call. Then we can revert just those when necessary. In the ScrollTrigger's init() call, the _creatingMedia is recorded as a "media" property on the instance. 12410_lastMediaTick, 12411 _onMediaChange = function _onMediaChange(e) { 12412 var tick = gsap.ticker.frame, 12413 matches = [], 12414 i = 0, 12415 index; 12416 12417 if (_lastMediaTick !== tick || _startup) { 12418 _revertAll(); 12419 12420 for (; i < _media.length; i += 4) { 12421 index = _win.matchMedia(_media[i]).matches; 12422 12423 if (index !== _media[i + 3]) { 12424 // note: some browsers fire the matchMedia event multiple times, like when going full screen, so we shouldn't call the function multiple times. Check to see if it's already matched. 12425 _media[i + 3] = index; 12426 index ? matches.push(i) : _revertAll(1, _media[i]) || _isFunction(_media[i + 2]) && _media[i + 2](); // Firefox doesn't update the "matches" property of the MediaQueryList object correctly - it only does so as it calls its change handler - so we must re-create a media query here to ensure it's accurate. 12427 } 12428 } 12429 12430 _revertRecorded(); // in case killing/reverting any of the animations actually added inline styles back. 12431 12432 12433 for (i = 0; i < matches.length; i++) { 12434 index = matches[i]; 12435 _creatingMedia = _media[index]; 12436 _media[index + 2] = _media[index + 1](e); 12437 } 12438 12439 _creatingMedia = 0; 12440 _coreInitted && _refreshAll(0, 1); 12441 _lastMediaTick = tick; 12442 12443 _dispatch("matchMedia"); 12444 } 12445}, 12446 _softRefresh = function _softRefresh() { 12447 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 12448}, 12449 _dispatch = function _dispatch(type) { 12450 return _listeners[type] && _listeners[type].map(function (f) { 12451 return f(); 12452 }) || _emptyArray; 12453}, 12454 _savedStyles = [], 12455 // when ScrollTrigger.saveStyles() is called, the inline styles are recorded in this Array in a sequential format like [element, cssText, gsCache, media]. This keeps it very memory-efficient and fast to iterate through. 12456_revertRecorded = function _revertRecorded(media) { 12457 for (var i = 0; i < _savedStyles.length; i += 4) { 12458 if (!media || _savedStyles[i + 3] === media) { 12459 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 12460 _savedStyles[i + 2].uncache = 1; 12461 } 12462 } 12463}, 12464 _revertAll = function _revertAll(kill, media) { 12465 var trigger; 12466 12467 for (_i = 0; _i < _triggers.length; _i++) { 12468 trigger = _triggers[_i]; 12469 12470 if (!media || trigger.media === media) { 12471 if (kill) { 12472 trigger.kill(1); 12473 } else { 12474 trigger.scroll.rec || (trigger.scroll.rec = trigger.scroll()); // record the scroll positions so that in each refresh() we can ensure that it doesn't shift. Remember, pinning can make things change around, especially if the same element is pinned multiple times. If one was already recorded, don't re-record because unpinning may have occurred and made it shorter. 12475 12476 trigger.revert(); 12477 } 12478 } 12479 } 12480 12481 _revertRecorded(media); 12482 12483 media || _dispatch("revert"); 12484}, 12485 _refreshAll = function _refreshAll(force, skipRevert) { 12486 if (_lastScrollTime && !force) { 12487 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 12488 12489 return; 12490 } 12491 12492 var refreshInits = _dispatch("refreshInit"); 12493 12494 _sort && ScrollTrigger.sort(); 12495 skipRevert || _revertAll(); 12496 12497 for (_i = 0; _i < _triggers.length; _i++) { 12498 _triggers[_i].refresh(); 12499 } 12500 12501 refreshInits.forEach(function (result) { 12502 return result && result.render && result.render(-1); 12503 }); // if the onRefreshInit() returns an animation (typically a gsap.set()), revert it. This makes it easy to put things in a certain spot before refreshing for measurement purposes, and then put things back. 12504 12505 _i = _triggers.length; 12506 12507 while (_i--) { 12508 _triggers[_i].scroll.rec = 0; 12509 } 12510 12511 _resizeDelay.pause(); 12512 12513 _dispatch("refresh"); 12514}, 12515 _lastScroll = 0, 12516 _direction = 1, 12517 _updateAll = function _updateAll() { 12518 var l = _triggers.length, 12519 time = _getTime(), 12520 recordVelocity = time - _time1 >= 50, 12521 scroll = l && _triggers[0].scroll(); 12522 12523 _direction = _lastScroll > scroll ? -1 : 1; 12524 _lastScroll = scroll; 12525 12526 if (recordVelocity) { 12527 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 12528 _lastScrollTime = 0; 12529 12530 _dispatch("scrollEnd"); 12531 } 12532 12533 _time2 = _time1; 12534 _time1 = time; 12535 } 12536 12537 if (_direction < 0) { 12538 _i = l; 12539 12540 while (_i--) { 12541 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 12542 } 12543 12544 _direction = 1; 12545 } else { 12546 for (_i = 0; _i < l; _i++) { 12547 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 12548 } 12549 } 12550 12551 _request = 0; 12552}, 12553 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex"], 12554 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 12555 _swapPinOut = function _swapPinOut(pin, spacer, state) { 12556 _setState(state); 12557 12558 if (pin.parentNode === spacer) { 12559 var parent = spacer.parentNode; 12560 12561 if (parent) { 12562 parent.insertBefore(pin, spacer); 12563 parent.removeChild(spacer); 12564 } 12565 } 12566}, 12567 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 12568 if (pin.parentNode !== spacer) { 12569 var i = _propNamesToCopy.length, 12570 spacerStyle = spacer.style, 12571 pinStyle = pin.style, 12572 p; 12573 12574 while (i--) { 12575 p = _propNamesToCopy[i]; 12576 spacerStyle[p] = cs[p]; 12577 } 12578 12579 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 12580 cs.display === "inline" && (spacerStyle.display = "inline-block"); 12581 pinStyle[_bottom] = pinStyle[_right] = "auto"; 12582 spacerStyle.overflow = "visible"; 12583 spacerStyle.boxSizing = "border-box"; 12584 spacerStyle[_width] = _getSize(pin, _horizontal) + _px; 12585 spacerStyle[_height] = _getSize(pin, _vertical) + _px; 12586 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 12587 12588 _setState(spacerState); 12589 12590 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 12591 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 12592 pinStyle[_padding] = cs[_padding]; 12593 pin.parentNode.insertBefore(spacer, pin); 12594 spacer.appendChild(pin); 12595 } 12596}, 12597 _capsExp = /([A-Z])/g, 12598 _setState = function _setState(state) { 12599 if (state) { 12600 var style = state.t.style, 12601 l = state.length, 12602 i = 0, 12603 p, 12604 value; 12605 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off 12606 12607 for (; i < l; i += 2) { 12608 value = state[i + 1]; 12609 p = state[i]; 12610 12611 if (value) { 12612 style[p] = value; 12613 } else if (style[p]) { 12614 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 12615 } 12616 } 12617 } 12618}, 12619 _getState = function _getState(element) { 12620 // returns an Array with alternating values like [property, value, property, value] and a "t" property pointing to the target (element). Makes it fast and cheap. 12621 var l = _stateProps.length, 12622 style = element.style, 12623 state = [], 12624 i = 0; 12625 12626 for (; i < l; i++) { 12627 state.push(_stateProps[i], style[_stateProps[i]]); 12628 } 12629 12630 state.t = element; 12631 return state; 12632}, 12633 _copyState = function _copyState(state, override, omitOffsets) { 12634 var result = [], 12635 l = state.length, 12636 i = omitOffsets ? 8 : 0, 12637 // skip top, left, right, bottom if omitOffsets is true 12638 p; 12639 12640 for (; i < l; i += 2) { 12641 p = state[i]; 12642 result.push(p, p in override ? override[p] : state[i + 1]); 12643 } 12644 12645 result.t = state.t; 12646 return result; 12647}, 12648 _winOffsets = { 12649 left: 0, 12650 top: 0 12651}, 12652 _parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax) { 12653 _isFunction(value) && (value = value(self)); 12654 12655 if (_isString(value) && value.substr(0, 3) === "max") { 12656 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 12657 } 12658 12659 if (!_isNumber(value)) { 12660 _isFunction(trigger) && (trigger = trigger(self)); 12661 12662 var element = _toArray(trigger)[0] || _body, 12663 bounds = _getBounds(element) || {}, 12664 offsets = value.split(" "), 12665 localOffset, 12666 globalOffset, 12667 display; 12668 12669 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 12670 // if display is "none", it won't report getBoundingClientRect() properly 12671 display = element.style.display; 12672 element.style.display = "block"; 12673 bounds = _getBounds(element); 12674 display ? element.style.display = display : element.style.removeProperty("display"); 12675 } 12676 12677 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 12678 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 12679 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 12680 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 12681 scrollerSize -= scrollerSize - globalOffset; // adjust for the marker 12682 } else if (markerScroller) { 12683 _positionMarker(markerScroller, scrollerSize, direction, true); 12684 } 12685 12686 if (marker) { 12687 var position = value + scrollerSize, 12688 isStart = marker._isStart; 12689 scrollerMax = "scroll" + direction.d2; 12690 12691 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[scrollerMax], _docEl[scrollerMax]) : marker.parentNode[scrollerMax]) <= position + 1); 12692 12693 if (useFixedPosition) { 12694 scrollerBounds = _getBounds(markerScroller); 12695 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 12696 } 12697 } 12698 12699 return Math.round(value); 12700}, 12701 _prefixExp = /(?:webkit|moz|length|cssText|inset)/i, 12702 _reparent = function _reparent(element, parent, top, left) { 12703 if (element.parentNode !== parent) { 12704 var style = element.style, 12705 p, 12706 cs; 12707 12708 if (parent === _body) { 12709 element._stOrig = style.cssText; // record original inline styles so we can revert them later 12710 12711 cs = _getComputedStyle(element); 12712 12713 for (p in cs) { 12714 // must copy all relevant styles to ensure that nothing changes visually when we reparent to the <body>. Skip the vendor prefixed ones. 12715 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 12716 style[p] = cs[p]; 12717 } 12718 } 12719 12720 style.top = top; 12721 style.left = left; 12722 } else { 12723 style.cssText = element._stOrig; 12724 } 12725 12726 gsap.core.getCache(element).uncache = 1; 12727 parent.appendChild(element); 12728 } 12729}, 12730 // returns a function that can be used to tween the scroll position in the direction provided, and when doing so it'll add a .tween property to the FUNCTION itself, and remove it when the tween completes or gets killed. This gives us a way to have multiple ScrollTriggers use a central function for any given scroller and see if there's a scroll tween running (which would affect if/how things get updated) 12731_getTweenCreator = function _getTweenCreator(scroller, direction) { 12732 var getScroll = _getScrollFunc(scroller, direction), 12733 prop = "_scroll" + direction.p2, 12734 // add a tweenable property to the scroller that's a getter/setter function, like _scrollTop or _scrollLeft. This way, if someone does gsap.killTweensOf(scroller) it'll kill the scroll tween. 12735 lastScroll1, 12736 lastScroll2, 12737 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 12738 var tween = getTween.tween, 12739 onComplete = vars.onComplete, 12740 modifiers = {}; 12741 tween && tween.kill(); 12742 lastScroll1 = Math.round(initialValue); 12743 vars[prop] = scrollTo; 12744 vars.modifiers = modifiers; 12745 12746 modifiers[prop] = function (value) { 12747 value = Math.round(getScroll()); // round because in some [very uncommon] Windows environments, it can get reported with decimals even though it was set without. 12748 12749 if (value !== lastScroll1 && value !== lastScroll2 && Math.abs(value - lastScroll1) > 2) { 12750 // if the user scrolls, kill the tween. iOS Safari intermittently misreports the scroll position, it may be the most recently-set one or the one before that! When Safari is zoomed (CMD-+), it often misreports as 1 pixel off too! So if we set the scroll position to 125, for example, it'll actually report it as 124. 12751 tween.kill(); 12752 getTween.tween = 0; 12753 } else { 12754 value = initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio; 12755 } 12756 12757 lastScroll2 = lastScroll1; 12758 return lastScroll1 = Math.round(value); 12759 }; 12760 12761 vars.onComplete = function () { 12762 getTween.tween = 0; 12763 onComplete && onComplete.call(tween); 12764 }; 12765 12766 tween = getTween.tween = gsap.to(scroller, vars); 12767 return tween; 12768 }; 12769 12770 scroller[prop] = getScroll; 12771 scroller.addEventListener("mousewheel", function () { 12772 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 12773 }); // Windows machines handle mousewheel scrolling in chunks (like "3 lines per scroll") meaning the typical strategy for cancelling the scroll isn't as sensitive. It's much more likely to match one of the previous 2 scroll event positions. So we kill any snapping as soon as there's a mousewheel event. 12774 12775 return getTween; 12776}; 12777 12778_horizontal.op = _vertical; 12779var ScrollTrigger = /*#__PURE__*/function () { 12780 function ScrollTrigger(vars, animation) { 12781 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 12782 this.init(vars, animation); 12783 } 12784 12785 var _proto = ScrollTrigger.prototype; 12786 12787 _proto.init = function init(vars, animation) { 12788 this.progress = this.start = 0; 12789 this.vars && this.kill(1); // in case it's being initted again 12790 12791 if (!_enabled) { 12792 this.update = this.refresh = this.kill = _passThrough; 12793 return; 12794 } 12795 12796 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 12797 trigger: vars 12798 } : vars, _defaults); 12799 12800 var direction = vars.horizontal ? _horizontal : _vertical, 12801 _vars = vars, 12802 onUpdate = _vars.onUpdate, 12803 toggleClass = _vars.toggleClass, 12804 id = _vars.id, 12805 onToggle = _vars.onToggle, 12806 onRefresh = _vars.onRefresh, 12807 scrub = _vars.scrub, 12808 trigger = _vars.trigger, 12809 pin = _vars.pin, 12810 pinSpacing = _vars.pinSpacing, 12811 invalidateOnRefresh = _vars.invalidateOnRefresh, 12812 anticipatePin = _vars.anticipatePin, 12813 onScrubComplete = _vars.onScrubComplete, 12814 onSnapComplete = _vars.onSnapComplete, 12815 once = _vars.once, 12816 snap = _vars.snap, 12817 pinReparent = _vars.pinReparent, 12818 isToggle = !scrub && scrub !== 0, 12819 scroller = _toArray(vars.scroller || _win)[0], 12820 scrollerCache = gsap.core.getCache(scroller), 12821 isViewport = _isViewport(scroller), 12822 useFixedPosition = "pinType" in vars ? vars.pinType === "fixed" : isViewport || _getProxyProp(scroller, "pinType") === "fixed", 12823 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 12824 toggleActions = isToggle && vars.toggleActions.split(" "), 12825 markers = "markers" in vars ? vars.markers : _defaults.markers, 12826 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 12827 self = this, 12828 onRefreshInit = vars.onRefreshInit && function () { 12829 return vars.onRefreshInit(self); 12830 }, 12831 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 12832 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 12833 tweenTo, 12834 pinCache, 12835 snapFunc, 12836 isReverted, 12837 scroll1, 12838 scroll2, 12839 start, 12840 end, 12841 markerStart, 12842 markerEnd, 12843 markerStartTrigger, 12844 markerEndTrigger, 12845 markerVars, 12846 change, 12847 pinOriginalState, 12848 pinActiveState, 12849 pinState, 12850 spacer, 12851 offset, 12852 pinGetter, 12853 pinSetter, 12854 pinStart, 12855 pinChange, 12856 spacingStart, 12857 spacerState, 12858 markerStartSetter, 12859 markerEndSetter, 12860 cs, 12861 snap1, 12862 snap2, 12863 scrubTween, 12864 scrubSmooth, 12865 snapDurClamp, 12866 snapDelayedCall, 12867 prevProgress, 12868 prevScroll, 12869 prevAnimProgress; 12870 12871 self.media = _creatingMedia; 12872 anticipatePin *= 45; 12873 12874 _triggers.push(self); 12875 12876 self.scroller = scroller; 12877 self.scroll = _getScrollFunc(scroller, direction); 12878 scroll1 = self.scroll(); 12879 self.vars = vars; 12880 animation = animation || vars.animation; 12881 "refreshPriority" in vars && (_sort = 1); 12882 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 12883 top: _getTweenCreator(scroller, _vertical), 12884 left: _getTweenCreator(scroller, _horizontal) 12885 }; 12886 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 12887 12888 if (animation) { 12889 animation.vars.lazy = false; 12890 animation._initted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.render(0, true, true); 12891 self.animation = animation.pause(); 12892 animation.scrollTrigger = self; 12893 scrubSmooth = _isNumber(scrub) && scrub; 12894 scrubSmooth && (scrubTween = gsap.to(animation, { 12895 ease: "power3", 12896 duration: scrubSmooth, 12897 onComplete: function onComplete() { 12898 return onScrubComplete && onScrubComplete(self); 12899 } 12900 })); 12901 snap1 = 0; 12902 id || (id = animation.vars.id); 12903 } 12904 12905 if (snap) { 12906 _isObject(snap) || (snap = { 12907 snapTo: snap 12908 }); 12909 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 12910 scrollBehavior: "auto" 12911 }); // smooth scrolling doesn't work with snap. 12912 12913 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : gsap.utils.snap(snap.snapTo); 12914 snapDurClamp = snap.duration || { 12915 min: 0.1, 12916 max: 2 12917 }; 12918 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 12919 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 12920 if (Math.abs(self.getVelocity()) < 10 && !_pointerIsDown) { 12921 var totalProgress = animation && !isToggle ? animation.totalProgress() : self.progress, 12922 velocity = (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 12923 change1 = _abs(velocity / 2) * velocity / 0.185, 12924 naturalEnd = totalProgress + change1, 12925 endValue = _clamp(0, 1, snapFunc(naturalEnd, self)), 12926 scroll = self.scroll(), 12927 endScroll = Math.round(start + endValue * change), 12928 tween = tweenTo.tween; 12929 12930 if (scroll <= end && scroll >= start && endScroll !== scroll) { 12931 if (tween && !tween._initted && tween.data <= Math.abs(endScroll - scroll)) { 12932 // there's an overlapping snap! So we must figure out which one is closer and let that tween live. 12933 return; 12934 } 12935 12936 tweenTo(endScroll, { 12937 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 12938 ease: snap.ease || "power3", 12939 data: Math.abs(endScroll - scroll), 12940 // record the distance so that if another snap tween occurs (conflict) we can prioritize the closest snap. 12941 onComplete: function onComplete() { 12942 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 12943 onSnapComplete && onSnapComplete(self); 12944 } 12945 }, scroll, change1 * change, endScroll - scroll - change1 * change); 12946 } 12947 } else if (self.isActive) { 12948 snapDelayedCall.restart(true); 12949 } 12950 }).pause(); 12951 } 12952 12953 id && (_ids[id] = self); 12954 trigger = self.trigger = _toArray(trigger || pin)[0]; 12955 pin = pin === true ? trigger : _toArray(pin)[0]; 12956 _isString(toggleClass) && (toggleClass = { 12957 targets: trigger, 12958 className: toggleClass 12959 }); 12960 12961 if (pin) { 12962 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); // if the parent is display: flex, don't apply pinSpacing by default. 12963 12964 self.pin = pin; 12965 vars.force3D !== false && gsap.set(pin, { 12966 force3D: true 12967 }); 12968 pinCache = gsap.core.getCache(pin); 12969 12970 if (!pinCache.spacer) { 12971 // record the spacer and pinOriginalState on the cache in case someone tries pinning the same element with MULTIPLE ScrollTriggers - we don't want to have multiple spacers or record the "original" pin state after it has already been affected by another ScrollTrigger. 12972 pinCache.spacer = spacer = _doc.createElement("div"); 12973 spacer.setAttribute("class", "pin-spacer" + (id ? " pin-spacer-" + id : "")); 12974 pinCache.pinState = pinOriginalState = _getState(pin); 12975 } else { 12976 pinOriginalState = pinCache.pinState; 12977 } 12978 12979 self.spacer = spacer = pinCache.spacer; 12980 cs = _getComputedStyle(pin); 12981 spacingStart = cs[pinSpacing + direction.os2]; 12982 pinGetter = gsap.getProperty(pin); 12983 pinSetter = gsap.quickSetter(pin, direction.a, _px); // pin.firstChild && !_maxScroll(pin, direction) && (pin.style.overflow = "hidden"); // protects from collapsing margins, but can have unintended consequences as demonstrated here: https://codepen.io/GreenSock/pen/1e42c7a73bfa409d2cf1e184e7a4248d so it was removed in favor of just telling people to set up their CSS to avoid the collapsing margins (overflow: hidden | auto is just one option. Another is border-top: 1px solid transparent). 12984 12985 _swapPinIn(pin, spacer, cs); 12986 12987 pinState = _getState(pin); 12988 } 12989 12990 if (markers) { 12991 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 12992 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 12993 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 12994 offset = markerStartTrigger["offset" + direction.op.d2]; 12995 markerStart = _createMarker("start", id, scroller, direction, markerVars, offset); 12996 markerEnd = _createMarker("end", id, scroller, direction, markerVars, offset); 12997 12998 if (!useFixedPosition) { 12999 _makePositionable(isViewport ? _body : scroller); 13000 13001 gsap.set([markerStartTrigger, markerEndTrigger], { 13002 force3D: true 13003 }); 13004 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 13005 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 13006 } 13007 } 13008 13009 self.revert = function (revert) { 13010 var r = revert !== false || !self.enabled, 13011 prevRefreshing = _refreshing; 13012 13013 if (r !== isReverted) { 13014 if (r) { 13015 prevScroll = Math.max(self.scroll(), self.scroll.rec || 0); // record the scroll so we can revert later (repositioning/pinning things can affect scroll position). In the static refresh() method, we first record all the scroll positions as a reference. 13016 13017 prevProgress = self.progress; 13018 prevAnimProgress = animation && animation.progress(); 13019 } 13020 13021 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 13022 return m.style.display = r ? "none" : "block"; 13023 }); 13024 r && (_refreshing = 1); 13025 self.update(r); // make sure the pin is back in its original position so that all the measurements are correct. 13026 13027 _refreshing = prevRefreshing; 13028 pin && (r ? _swapPinOut(pin, spacer, pinOriginalState) : (!pinReparent || !self.isActive) && _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState)); 13029 isReverted = r; 13030 } 13031 }; 13032 13033 self.refresh = function (soft) { 13034 if (_refreshing || !self.enabled) { 13035 return; 13036 } 13037 13038 if (pin && soft && _lastScrollTime) { 13039 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 13040 13041 return; 13042 } 13043 13044 _refreshing = 1; 13045 scrubTween && scrubTween.pause(); 13046 invalidateOnRefresh && animation && animation.progress(0).invalidate(); 13047 isReverted || self.revert(); 13048 13049 var size = getScrollerSize(), 13050 scrollerBounds = getScrollerOffsets(), 13051 max = _maxScroll(scroller, direction), 13052 offset = 0, 13053 otherPinOffset = 0, 13054 parsedEnd = vars.end, 13055 parsedEndTrigger = vars.endTrigger || trigger, 13056 parsedStart = vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 13057 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 13058 i = triggerIndex, 13059 cs, 13060 bounds, 13061 scroll, 13062 isVertical, 13063 override, 13064 curTrigger, 13065 curPin, 13066 oppositeScroll, 13067 initted; 13068 13069 while (i--) { 13070 // user might try to pin the same element more than once, so we must find any prior triggers with the same pin, revert them, and determine how long they're pinning so that we can offset things appropriately. Make sure we revert from last to first so that things "rewind" properly. 13071 curPin = _triggers[i].pin; 13072 curPin && (curPin === trigger || curPin === pin) && _triggers[i].revert(); 13073 } 13074 13075 start = _parsePosition(parsedStart, trigger, size, direction, self.scroll(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max) || (pin ? -0.001 : 0); 13076 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 13077 13078 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 13079 if (~parsedEnd.indexOf(" ")) { 13080 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 13081 } else { 13082 offset = _offsetToPx(parsedEnd.substr(2), size); 13083 parsedEnd = _isString(parsedStart) ? parsedStart : start + offset; // _parsePosition won't factor in the offset if the start is a number, so do it here. 13084 13085 parsedEndTrigger = trigger; 13086 } 13087 } 13088 13089 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, self.scroll() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max)) || -0.001; 13090 change = end - start || (start -= 0.01) && 0.001; 13091 offset = 0; 13092 i = triggerIndex; 13093 13094 while (i--) { 13095 curTrigger = _triggers[i]; 13096 curPin = curTrigger.pin; 13097 13098 if (curPin && curTrigger.start - curTrigger._pinPush < start) { 13099 cs = curTrigger.end - curTrigger.start; 13100 curPin === trigger && (offset += cs); 13101 curPin === pin && (otherPinOffset += cs); 13102 } 13103 } 13104 13105 start += offset; 13106 end += offset; 13107 self._pinPush = otherPinOffset; 13108 13109 if (markerStart && offset) { 13110 // offset the markers if necessary 13111 cs = {}; 13112 cs[direction.a] = "+=" + offset; 13113 gsap.set([markerStart, markerEnd], cs); 13114 } 13115 13116 if (pin) { 13117 cs = _getComputedStyle(pin); 13118 isVertical = direction === _vertical; 13119 scroll = self.scroll(); // recalculate because the triggers can affect the scroll 13120 13121 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 13122 !max && end > 1 && ((isViewport ? _body : scroller).style["overflow-" + direction.a] = "scroll"); // makes sure the scroller has a scrollbar, otherwise if something has width: 100%, for example, it would be too big (exclude the scrollbar). See https://greensock.com/forums/topic/25182-scrolltrigger-width-of-page-increase-where-markers-are-set-to-false/ 13123 13124 _swapPinIn(pin, spacer, cs); 13125 13126 pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms. 13127 13128 bounds = _getBounds(pin, true); 13129 oppositeScroll = useFixedPosition && _getScrollFunc(scroller, isVertical ? _horizontal : _vertical)(); 13130 13131 if (pinSpacing) { 13132 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 13133 spacerState.t = spacer; 13134 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 13135 i && spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding). 13136 13137 _setState(spacerState); 13138 13139 useFixedPosition && self.scroll(prevScroll); 13140 } 13141 13142 if (useFixedPosition) { 13143 override = { 13144 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 13145 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 13146 boxSizing: "border-box", 13147 position: "fixed" 13148 }; 13149 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 13150 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 13151 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 13152 override[_padding] = cs[_padding]; 13153 override[_padding + _Top] = cs[_padding + _Top]; 13154 override[_padding + _Right] = cs[_padding + _Right]; 13155 override[_padding + _Bottom] = cs[_padding + _Bottom]; 13156 override[_padding + _Left] = cs[_padding + _Left]; 13157 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 13158 } 13159 13160 if (animation) { 13161 // the animation might be affecting the transform, so we must jump to the end, check the value, and compensate accordingly. Otherwise, when it becomes unpinned, the pinSetter() will get set to a value that doesn't include whatever the animation did. 13162 initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock in starting values prematurely. 13163 13164 _suppressOverwrites(1); 13165 13166 animation.progress(1, true); 13167 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 13168 change !== pinChange && pinActiveState.splice(pinActiveState.length - 2, 2); // transform is the last property/value set in the state Array. Since the animation is controlling that, we should omit it. 13169 13170 animation.progress(0, true); 13171 initted || animation.invalidate(); 13172 13173 _suppressOverwrites(0); 13174 } else { 13175 pinChange = change; 13176 } 13177 } else if (trigger && self.scroll()) { 13178 // it may be INSIDE a pinned element, so walk up the tree and look for any elements with _pinOffset to compensate because anything with pinSpacing that's already scrolled would throw off the measurements in getBoundingClientRect() 13179 bounds = trigger.parentNode; 13180 13181 while (bounds && bounds !== _body) { 13182 if (bounds._pinOffset) { 13183 start -= bounds._pinOffset; 13184 end -= bounds._pinOffset; 13185 } 13186 13187 bounds = bounds.parentNode; 13188 } 13189 } 13190 13191 for (i = 0; i < triggerIndex; i++) { 13192 // make sure we revert from first to last to make sure things reach their end state properly 13193 curTrigger = _triggers[i].pin; 13194 curTrigger && (curTrigger === trigger || curTrigger === pin) && _triggers[i].revert(false); 13195 } 13196 13197 self.start = start; 13198 self.end = end; 13199 scroll1 = scroll2 = self.scroll(); // reset velocity 13200 13201 scroll1 < prevScroll && self.scroll(prevScroll); 13202 self.revert(false); 13203 _refreshing = 0; 13204 animation && isToggle && animation._initted && animation.progress(prevAnimProgress, true).render(animation.time(), true, true); // must force a re-render because if saveStyles() was used on the target(s), the styles could have been wiped out during the refresh(). 13205 13206 if (prevProgress !== self.progress) { 13207 // ensures that the direction is set properly (when refreshing, progress is set back to 0 initially, then back again to wherever it needs to be) and that callbacks are triggered. 13208 scrubTween && animation.totalProgress(prevProgress, true); // to avoid issues where animation callbacks like onStart aren't triggered. 13209 13210 self.progress = prevProgress; 13211 self.update(); 13212 } 13213 13214 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 13215 onRefresh && onRefresh(self); 13216 }; 13217 13218 self.getVelocity = function () { 13219 return (self.scroll() - scroll2) / (_getTime() - _time2) * 1000 || 0; 13220 }; 13221 13222 self.update = function (reset, recordVelocity) { 13223 var scroll = self.scroll(), 13224 p = reset ? 0 : (scroll - start) / change, 13225 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 13226 prevProgress = self.progress, 13227 isActive, 13228 wasActive, 13229 toggleState, 13230 action, 13231 stateChanged, 13232 toggled; 13233 13234 if (recordVelocity) { 13235 scroll2 = scroll1; 13236 scroll1 = scroll; 13237 13238 if (snap) { 13239 snap2 = snap1; 13240 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 13241 } 13242 } // anticipate the pinning a few ticks ahead of time based on velocity to avoid a visual glitch due to the fact that most browsers do scrolling on a separate thread (not synced with requestAnimationFrame). 13243 13244 13245 anticipatePin && !clipped && pin && !_refreshing && !_startup && _lastScrollTime && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin && (clipped = 0.0001); 13246 13247 if (clipped !== prevProgress && self.enabled) { 13248 isActive = self.isActive = !!clipped && clipped < 1; 13249 wasActive = !!prevProgress && prevProgress < 1; 13250 toggled = isActive !== wasActive; 13251 stateChanged = toggled || !!clipped !== !!prevProgress; // could go from start all the way to end, thus it didn't toggle but it did change state in a sense (may need to fire a callback) 13252 13253 self.direction = clipped > prevProgress ? 1 : -1; 13254 self.progress = clipped; 13255 13256 if (!isToggle) { 13257 if (scrubTween && !_refreshing && !_startup) { 13258 scrubTween.vars.totalProgress = clipped; 13259 scrubTween.invalidate().restart(); 13260 } else if (animation) { 13261 animation.totalProgress(clipped, !!_refreshing); 13262 } 13263 } 13264 13265 if (pin) { 13266 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 13267 13268 if (!useFixedPosition) { 13269 pinSetter(pinStart + pinChange * clipped); 13270 } else if (stateChanged) { 13271 action = !reset && clipped > prevProgress && end + 1 > scroll && scroll + 1 >= _maxScroll(scroller, direction); // if it's at the VERY end of the page, don't switch away from position: fixed because it's pointless and it could cause a brief flash when the user scrolls back up (when it gets pinned again) 13272 13273 if (pinReparent) { 13274 if (!reset && (isActive || action)) { 13275 var bounds = _getBounds(pin, true), 13276 _offset = scroll - start; 13277 13278 _reparent(pin, _body, bounds.top + (direction === _vertical ? _offset : 0) + _px, bounds.left + (direction === _vertical ? 0 : _offset) + _px); 13279 } else { 13280 _reparent(pin, spacer); 13281 } 13282 } 13283 13284 _setState(isActive || action ? pinActiveState : pinState); 13285 13286 pinChange !== change && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !action ? pinChange : 0)); 13287 } 13288 } 13289 13290 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 13291 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 13292 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 13293 }); // classes could affect positioning, so do it even if reset or refreshing is true. 13294 13295 onUpdate && !isToggle && !reset && onUpdate(self); 13296 13297 if (stateChanged && !_refreshing) { 13298 toggleState = clipped && !prevProgress ? 0 : clipped === 1 ? 1 : prevProgress === 1 ? 2 : 3; // 0 = enter, 1 = leave, 2 = enterBack, 3 = leaveBack (we prioritize the FIRST encounter, thus if you scroll really fast past the onEnter and onLeave in one tick, it'd prioritize onEnter. 13299 13300 if (isToggle) { 13301 action = !toggled && toggleActions[toggleState + 1] !== "none" && toggleActions[toggleState + 1] || toggleActions[toggleState]; // if it didn't toggle, that means it shot right past and since we prioritize the "enter" action, we should switch to the "leave" in this case (but only if one is defined) 13302 13303 if (animation && (action === "complete" || action === "reset" || action in animation)) { 13304 if (action === "complete") { 13305 animation.pause().totalProgress(1); 13306 } else if (action === "reset") { 13307 animation.restart(true).pause(); 13308 } else { 13309 animation[action](); 13310 } 13311 } 13312 13313 onUpdate && onUpdate(self); 13314 } 13315 13316 if (toggled || !_limitCallbacks) { 13317 // on startup, the page could be scrolled and we don't want to fire callbacks that didn't toggle. For example onEnter shouldn't fire if the ScrollTrigger isn't actually entered. 13318 onToggle && toggled && onToggle(self); 13319 callbacks[toggleState] && callbacks[toggleState](self); 13320 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn't be called again if once is true. 13321 13322 if (!toggled) { 13323 // it's possible to go completely past, like from before the start to after the end (or vice-versa) in which case BOTH callbacks should be fired in that order 13324 toggleState = clipped === 1 ? 1 : 3; 13325 callbacks[toggleState] && callbacks[toggleState](self); 13326 } 13327 } 13328 } else if (isToggle && onUpdate && !_refreshing) { 13329 onUpdate(self); 13330 } 13331 } // update absolutely-positioned markers (only if the scroller isn't the viewport) 13332 13333 13334 if (markerEndSetter) { 13335 markerStartSetter(scroll + (markerStartTrigger._isFlipped ? 1 : 0)); 13336 markerEndSetter(scroll); 13337 } 13338 }; 13339 13340 self.enable = function () { 13341 if (!self.enabled) { 13342 self.enabled = true; 13343 13344 _addListener(scroller, "resize", _onResize); 13345 13346 _addListener(scroller, "scroll", _onScroll); 13347 13348 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 13349 !animation || !animation.add ? self.refresh() : gsap.delayedCall(0.01, function () { 13350 return start || end || self.refresh(); 13351 }) && (change = 0.01) && (start = end = 0); // if the animation is a timeline, it may not have been populated yet, so it wouldn't render at the proper place on the first refresh(), thus we should schedule one for the next tick. 13352 } 13353 }; 13354 13355 self.disable = function (reset, allowAnimation) { 13356 if (self.enabled) { 13357 reset !== false && self.revert(); 13358 self.enabled = self.isActive = false; 13359 allowAnimation || scrubTween && scrubTween.pause(); 13360 prevScroll = 0; 13361 pinCache && (pinCache.uncache = 1); 13362 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 13363 13364 if (snapDelayedCall) { 13365 snapDelayedCall.pause(); 13366 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 13367 } 13368 13369 if (!isViewport) { 13370 var i = _triggers.length; 13371 13372 while (i--) { 13373 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 13374 return; //don't remove the listeners if there are still other triggers referencing it. 13375 } 13376 } 13377 13378 _removeListener(scroller, "resize", _onResize); 13379 13380 _removeListener(scroller, "scroll", _onScroll); 13381 } 13382 } 13383 }; 13384 13385 self.kill = function (revert, allowAnimation) { 13386 self.disable(revert, allowAnimation); 13387 id && delete _ids[id]; 13388 13389 var i = _triggers.indexOf(self); 13390 13391 _triggers.splice(i, 1); 13392 13393 i === _i && _direction > 0 && _i--; // if we're in the middle of a refresh() or update(), splicing would cause skips in the index, so adjust... 13394 13395 if (animation) { 13396 animation.scrollTrigger = null; 13397 revert && animation.render(-1); 13398 allowAnimation || animation.kill(); 13399 } 13400 13401 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 13402 return m.parentNode.removeChild(m); 13403 }); 13404 13405 if (pin) { 13406 pinCache && (pinCache.uncache = 1); 13407 i = 0; 13408 13409 _triggers.forEach(function (t) { 13410 return t.pin === pin && i++; 13411 }); 13412 13413 i || (pinCache.spacer = 0); // if there aren't any more ScrollTriggers with the same pin, remove the spacer, otherwise it could be contaminated with old/stale values if the user re-creates a ScrollTrigger for the same element. 13414 } 13415 }; 13416 13417 self.enable(); 13418 }; 13419 13420 ScrollTrigger.register = function register(core) { 13421 if (!_coreInitted) { 13422 gsap = core || _getGSAP(); 13423 13424 if (_windowExists() && window.document) { 13425 _win = window; 13426 _doc = document; 13427 _docEl = _doc.documentElement; 13428 _body = _doc.body; 13429 } 13430 13431 if (gsap) { 13432 _toArray = gsap.utils.toArray; 13433 _clamp = gsap.utils.clamp; 13434 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 13435 gsap.core.globals("ScrollTrigger", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don't have a "name" property. 13436 13437 if (_body) { 13438 _raf = _win.requestAnimationFrame || function (f) { 13439 return setTimeout(f, 16); 13440 }; 13441 13442 _addListener(_win, "mousewheel", _onScroll); 13443 13444 _root = [_win, _doc, _docEl, _body]; 13445 13446 _addListener(_doc, "scroll", _onScroll); // some browsers (like Chrome), the window stops dispatching scroll events on the window if you scroll really fast, but it's consistent on the document! 13447 13448 13449 var bodyStyle = _body.style, 13450 border = bodyStyle.borderTop, 13451 bounds; 13452 bodyStyle.borderTop = "1px solid #000"; // works around an issue where a margin of a child element could throw off the bounds of the _body, making it seem like there's a margin when there actually isn't. The border ensures that the bounds are accurate. 13453 13454 bounds = _getBounds(_body); 13455 _vertical.m = Math.round(bounds.top + _vertical.sc()) || 0; // accommodate the offset of the <body> caused by margins and/or padding 13456 13457 _horizontal.m = Math.round(bounds.left + _horizontal.sc()) || 0; 13458 border ? bodyStyle.borderTop = border : bodyStyle.removeProperty("border-top"); 13459 _syncInterval = setInterval(_sync, 200); 13460 gsap.delayedCall(0.5, function () { 13461 return _startup = 0; 13462 }); 13463 13464 _addListener(_doc, "touchcancel", _passThrough); // some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. 13465 13466 13467 _addListener(_body, "touchstart", _passThrough); //works around Safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 13468 13469 13470 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", function () { 13471 return _pointerIsDown = 1; 13472 }); 13473 13474 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", function () { 13475 return _pointerIsDown = 0; 13476 }); 13477 13478 _transformProp = gsap.utils.checkPrefix("transform"); 13479 13480 _stateProps.push(_transformProp); 13481 13482 _coreInitted = _getTime(); 13483 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 13484 _autoRefresh = [_doc, "visibilitychange", function () { 13485 var w = _win.innerWidth, 13486 h = _win.innerHeight; 13487 13488 if (_doc.hidden) { 13489 _prevWidth = w; 13490 _prevHeight = h; 13491 } else if (_prevWidth !== w || _prevHeight !== h) { 13492 _onResize(); 13493 } 13494 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", function () { 13495 return _lastScrollTime || _refreshAll(); 13496 }, _win, "resize", _onResize]; 13497 13498 _iterateAutoRefresh(_addListener); 13499 } 13500 } 13501 } 13502 13503 return _coreInitted; 13504 }; 13505 13506 ScrollTrigger.defaults = function defaults(config) { 13507 for (var p in config) { 13508 _defaults[p] = config[p]; 13509 } 13510 }; 13511 13512 ScrollTrigger.kill = function kill() { 13513 _enabled = 0; 13514 13515 _triggers.slice(0).forEach(function (trigger) { 13516 return trigger.kill(1); 13517 }); 13518 }; 13519 13520 ScrollTrigger.config = function config(vars) { 13521 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 13522 var ms = vars.syncInterval; 13523 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 13524 13525 if ("autoRefreshEvents" in vars) { 13526 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 13527 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 13528 } 13529 }; 13530 13531 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 13532 var t = _toArray(target)[0], 13533 i = _scrollers.indexOf(t), 13534 isViewport = _isViewport(t); 13535 13536 if (~i) { 13537 _scrollers.splice(i, isViewport ? 6 : 2); 13538 } 13539 13540 isViewport ? _proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _proxies.unshift(t, vars); 13541 }; 13542 13543 ScrollTrigger.matchMedia = function matchMedia(vars) { 13544 // _media is populated in the following order: mediaQueryString, onMatch, onUnmatch, isMatched. So if there are two media queries, the Array would have a length of 8 13545 var mq, p, i, func, result; 13546 13547 for (p in vars) { 13548 i = _media.indexOf(p); 13549 func = vars[p]; 13550 _creatingMedia = p; 13551 13552 if (p === "all") { 13553 func(); 13554 } else { 13555 mq = _win.matchMedia(p); 13556 13557 if (mq) { 13558 mq.matches && (result = func()); 13559 13560 if (~i) { 13561 _media[i + 1] = _combineFunc(_media[i + 1], func); 13562 _media[i + 2] = _combineFunc(_media[i + 2], result); 13563 } else { 13564 i = _media.length; 13565 13566 _media.push(p, func, result); 13567 13568 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 13569 } 13570 13571 _media[i + 3] = mq.matches; 13572 } 13573 } 13574 13575 _creatingMedia = 0; 13576 } 13577 13578 return _media; 13579 }; 13580 13581 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 13582 query || (_media.length = 0); 13583 query = _media.indexOf(query); 13584 query >= 0 && _media.splice(query, 4); 13585 }; 13586 13587 return ScrollTrigger; 13588}(); 13589ScrollTrigger.version = "3.6.0"; 13590 13591ScrollTrigger.saveStyles = function (targets) { 13592 return targets ? _toArray(targets).forEach(function (target) { 13593 if (target && target.style) { 13594 var i = _savedStyles.indexOf(target); 13595 13596 i >= 0 && _savedStyles.splice(i, 4); 13597 13598 _savedStyles.push(target, target.style.cssText, gsap.core.getCache(target), _creatingMedia); 13599 } 13600 }) : _savedStyles; 13601}; 13602 13603ScrollTrigger.revert = function (soft, media) { 13604 return _revertAll(!soft, media); 13605}; 13606 13607ScrollTrigger.create = function (vars, animation) { 13608 return new ScrollTrigger(vars, animation); 13609}; 13610 13611ScrollTrigger.refresh = function (safe) { 13612 return safe ? _onResize() : _refreshAll(true); 13613}; 13614 13615ScrollTrigger.update = _updateAll; 13616 13617ScrollTrigger.maxScroll = function (element, horizontal) { 13618 return _maxScroll(element, horizontal ? _horizontal : _vertical); 13619}; 13620 13621ScrollTrigger.getScrollFunc = function (element, horizontal) { 13622 return _getScrollFunc(_toArray(element)[0], horizontal ? _horizontal : _vertical); 13623}; 13624 13625ScrollTrigger.getById = function (id) { 13626 return _ids[id]; 13627}; 13628 13629ScrollTrigger.getAll = function () { 13630 return _triggers.slice(0); 13631}; 13632 13633ScrollTrigger.isScrolling = function () { 13634 return !!_lastScrollTime; 13635}; 13636 13637ScrollTrigger.addEventListener = function (type, callback) { 13638 var a = _listeners[type] || (_listeners[type] = []); 13639 ~a.indexOf(callback) || a.push(callback); 13640}; 13641 13642ScrollTrigger.removeEventListener = function (type, callback) { 13643 var a = _listeners[type], 13644 i = a && a.indexOf(callback); 13645 i >= 0 && a.splice(i, 1); 13646}; 13647 13648ScrollTrigger.batch = function (targets, vars) { 13649 var result = [], 13650 varsCopy = {}, 13651 interval = vars.interval || 0.016, 13652 batchMax = vars.batchMax || 1e9, 13653 proxyCallback = function proxyCallback(type, callback) { 13654 var elements = [], 13655 triggers = [], 13656 delay = gsap.delayedCall(interval, function () { 13657 callback(elements, triggers); 13658 elements = []; 13659 triggers = []; 13660 }).pause(); 13661 return function (self) { 13662 elements.length || delay.restart(true); 13663 elements.push(self.trigger); 13664 triggers.push(self); 13665 batchMax <= elements.length && delay.progress(1); 13666 }; 13667 }, 13668 p; 13669 13670 for (p in vars) { 13671 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 13672 } 13673 13674 if (_isFunction(batchMax)) { 13675 batchMax = batchMax(); 13676 13677 _addListener(ScrollTrigger, "refresh", function () { 13678 return batchMax = vars.batchMax(); 13679 }); 13680 } 13681 13682 _toArray(targets).forEach(function (target) { 13683 var config = {}; 13684 13685 for (p in varsCopy) { 13686 config[p] = varsCopy[p]; 13687 } 13688 13689 config.trigger = target; 13690 result.push(ScrollTrigger.create(config)); 13691 }); 13692 13693 return result; 13694}; 13695 13696ScrollTrigger.sort = function (func) { 13697 return _triggers.sort(func || function (a, b) { 13698 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 13699 }); 13700}; 13701 13702_getGSAP() && gsap.registerPlugin(ScrollTrigger); 13703 13704 13705/***/ }), 13706
vendor: 23,046 bytes, lines 13707-14317
13707/***/ "./node_modules/gsap/SplitText.js": 13708/*!****************************************!*\ 13709 !*** ./node_modules/gsap/SplitText.js ***! 13710 \****************************************/ 13711/*! exports provided: SplitText, default */ 13712/***/ (function(module, __webpack_exports__, __webpack_require__) { 13713 13714"use strict"; 13715__webpack_require__.r(__webpack_exports__); 13716/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SplitText", function() { return SplitText; }); 13717/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return SplitText; }); 13718/* harmony import */ var _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/strings.js */ "./node_modules/gsap/utils/strings.js"); 13719/*! 13720 * SplitText: 3.6.0 13721 * https://greensock.com 13722 * 13723 * @license Copyright 2008-2021, GreenSock. All rights reserved. 13724 * Subject to the terms at https://greensock.com/standard-license or for 13725 * Club GreenSock members, the agreement issued with that membership. 13726 * @author: Jack Doyle, [email protected] 13727*/ 13728 13729/* eslint-disable */ 13730 13731 13732var _doc, 13733 _win, 13734 _coreInitted, 13735 _stripExp = /(?:\r|\n|\t\t)/g, 13736 //find carriage returns, new line feeds and double-tabs. 13737_multipleSpacesExp = /(?:\s\s+)/g, 13738 _initCore = function _initCore() { 13739 _doc = document; 13740 _win = window; 13741 _coreInitted = 1; 13742}, 13743 _bonusValidated = 1, 13744 //<name>SplitText</name> 13745_getComputedStyle = function _getComputedStyle(element) { 13746 return _win.getComputedStyle(element); 13747}, 13748 _isArray = Array.isArray, 13749 _slice = [].slice, 13750 _toArray = function _toArray(value, leaveStrings) { 13751 //takes any value and returns an array. If it's a string (and leaveStrings isn't true), it'll use document.querySelectorAll() and convert that to an array. It'll also accept iterables like jQuery objects. 13752 var type; 13753 return _isArray(value) ? value : (type = typeof value) === "string" && !leaveStrings && value ? _slice.call(_doc.querySelectorAll(value), 0) : value && type === "object" && "length" in value ? _slice.call(value, 0) : value ? [value] : []; 13754}, 13755 _isAbsolute = function _isAbsolute(vars) { 13756 return vars.position === "absolute" || vars.absolute === true; 13757}, 13758 //some characters are combining marks (think diacritics/accents in European languages) which involve 2 or 4 characters that combine in the browser to form a single character. Pass in the remaining text and an array of the special characters to search for and if the text starts with one of those special characters, it'll spit back the number of characters to retain (often 2 or 4). Used in the specialChars features that was introduced in 0.6.0. 13759_findSpecialChars = function _findSpecialChars(text, chars) { 13760 var i = chars.length, 13761 s; 13762 13763 while (--i > -1) { 13764 s = chars[i]; 13765 13766 if (text.substr(0, s.length) === s) { 13767 return s.length; 13768 } 13769 } 13770}, 13771 _divStart = " style='position:relative;display:inline-block;'", 13772 _cssClassFunc = function _cssClassFunc(cssClass, tag) { 13773 if (cssClass === void 0) { 13774 cssClass = ""; 13775 } 13776 13777 var iterate = ~cssClass.indexOf("++"), 13778 num = 1; 13779 13780 if (iterate) { 13781 cssClass = cssClass.split("++").join(""); 13782 } 13783 13784 return function () { 13785 return "<" + tag + _divStart + (cssClass ? " class='" + cssClass + (iterate ? num++ : "") + "'>" : ">"); 13786 }; 13787}, 13788 _swapText = function _swapText(element, oldText, newText) { 13789 var type = element.nodeType; 13790 13791 if (type === 1 || type === 9 || type === 11) { 13792 for (element = element.firstChild; element; element = element.nextSibling) { 13793 _swapText(element, oldText, newText); 13794 } 13795 } else if (type === 3 || type === 4) { 13796 element.nodeValue = element.nodeValue.split(oldText).join(newText); 13797 } 13798}, 13799 _pushReversed = function _pushReversed(a, merge) { 13800 var i = merge.length; 13801 13802 while (--i > -1) { 13803 a.push(merge[i]); 13804 } 13805}, 13806 _isBeforeWordDelimiter = function _isBeforeWordDelimiter(e, root, wordDelimiter) { 13807 var next; 13808 13809 while (e && e !== root) { 13810 next = e._next || e.nextSibling; 13811 13812 if (next) { 13813 return next.textContent.charAt(0) === wordDelimiter; 13814 } 13815 13816 e = e.parentNode || e._parent; 13817 } 13818}, 13819 _deWordify = function _deWordify(e) { 13820 var children = _toArray(e.childNodes), 13821 l = children.length, 13822 i, 13823 child; 13824 13825 for (i = 0; i < l; i++) { 13826 child = children[i]; 13827 13828 if (child._isSplit) { 13829 _deWordify(child); 13830 } else { 13831 if (i && child.previousSibling && child.previousSibling.nodeType === 3) { 13832 child.previousSibling.nodeValue += child.nodeType === 3 ? child.nodeValue : child.firstChild.nodeValue; 13833 e.removeChild(child); 13834 } else if (child.nodeType !== 3) { 13835 e.insertBefore(child.firstChild, child); 13836 e.removeChild(child); 13837 } 13838 } 13839 } 13840}, 13841 _getStyleAsNumber = function _getStyleAsNumber(name, computedStyle) { 13842 return parseFloat(computedStyle[name]) || 0; 13843}, 13844 _setPositionsAfterSplit = function _setPositionsAfterSplit(element, vars, allChars, allWords, allLines, origWidth, origHeight) { 13845 var cs = _getComputedStyle(element), 13846 paddingLeft = _getStyleAsNumber("paddingLeft", cs), 13847 lineOffsetY = -999, 13848 borderTopAndBottom = _getStyleAsNumber("borderBottomWidth", cs) + _getStyleAsNumber("borderTopWidth", cs), 13849 borderLeftAndRight = _getStyleAsNumber("borderLeftWidth", cs) + _getStyleAsNumber("borderRightWidth", cs), 13850 padTopAndBottom = _getStyleAsNumber("paddingTop", cs) + _getStyleAsNumber("paddingBottom", cs), 13851 padLeftAndRight = _getStyleAsNumber("paddingLeft", cs) + _getStyleAsNumber("paddingRight", cs), 13852 lineThreshold = _getStyleAsNumber("fontSize", cs) * (vars.lineThreshold || 0.2), 13853 textAlign = cs.textAlign, 13854 charArray = [], 13855 wordArray = [], 13856 lineArray = [], 13857 wordDelimiter = vars.wordDelimiter || " ", 13858 tag = vars.tag ? vars.tag : vars.span ? "span" : "div", 13859 types = vars.type || vars.split || "chars,words,lines", 13860 lines = allLines && ~types.indexOf("lines") ? [] : null, 13861 words = ~types.indexOf("words"), 13862 chars = ~types.indexOf("chars"), 13863 absolute = _isAbsolute(vars), 13864 linesClass = vars.linesClass, 13865 iterateLine = ~(linesClass || "").indexOf("++"), 13866 spaceNodesToRemove = [], 13867 i, 13868 j, 13869 l, 13870 node, 13871 nodes, 13872 isChild, 13873 curLine, 13874 addWordSpaces, 13875 style, 13876 lineNode, 13877 lineWidth, 13878 offset; 13879 13880 if (iterateLine) { 13881 linesClass = linesClass.split("++").join(""); 13882 } //copy all the descendant nodes into an array (we can't use a regular nodeList because it's live and we may need to renest things) 13883 13884 13885 j = element.getElementsByTagName("*"); 13886 l = j.length; 13887 nodes = []; 13888 13889 for (i = 0; i < l; i++) { 13890 nodes[i] = j[i]; 13891 } //for absolute positioning, we need to record the x/y offsets and width/height for every <div>. And even if we're not positioning things absolutely, in order to accommodate lines, we must figure out where the y offset changes so that we can sense where the lines break, and we populate the lines array. 13892 13893 13894 if (lines || absolute) { 13895 for (i = 0; i < l; i++) { 13896 node = nodes[i]; 13897 isChild = node.parentNode === element; 13898 13899 if (isChild || absolute || chars && !words) { 13900 offset = node.offsetTop; 13901 13902 if (lines && isChild && Math.abs(offset - lineOffsetY) > lineThreshold && (node.nodeName !== "BR" || i === 0)) { 13903 //we found some rare occasions where a certain character like ‑ could cause the offsetTop to be off by 1 pixel, so we build in a threshold. 13904 curLine = []; 13905 lines.push(curLine); 13906 lineOffsetY = offset; 13907 } 13908 13909 if (absolute) { 13910 //record offset x and y, as well as width and height so that we can access them later for positioning. Grabbing them at once ensures we don't trigger a browser paint & we maximize performance. 13911 node._x = node.offsetLeft; 13912 node._y = offset; 13913 node._w = node.offsetWidth; 13914 node._h = node.offsetHeight; 13915 } 13916 13917 if (lines) { 13918 if (node._isSplit && isChild || !chars && isChild || words && isChild || !words && node.parentNode.parentNode === element && !node.parentNode._isSplit) { 13919 curLine.push(node); 13920 node._x -= paddingLeft; 13921 13922 if (_isBeforeWordDelimiter(node, element, wordDelimiter)) { 13923 node._wordEnd = true; 13924 } 13925 } 13926 13927 if (node.nodeName === "BR" && (node.nextSibling && node.nextSibling.nodeName === "BR" || i === 0)) { 13928 //two consecutive <br> tags signify a new [empty] line. Also, if the entire block of content STARTS with a <br>, add a line. 13929 lines.push([]); 13930 } 13931 } 13932 } 13933 } 13934 } 13935 13936 for (i = 0; i < l; i++) { 13937 node = nodes[i]; 13938 isChild = node.parentNode === element; 13939 13940 if (node.nodeName === "BR") { 13941 if (lines || absolute) { 13942 node.parentNode && node.parentNode.removeChild(node); 13943 nodes.splice(i--, 1); 13944 l--; 13945 } else if (!words) { 13946 element.appendChild(node); 13947 } 13948 13949 continue; 13950 } 13951 13952 if (absolute) { 13953 style = node.style; 13954 13955 if (!words && !isChild) { 13956 node._x += node.parentNode._x; 13957 node._y += node.parentNode._y; 13958 } 13959 13960 style.left = node._x + "px"; 13961 style.top = node._y + "px"; 13962 style.position = "absolute"; 13963 style.display = "block"; //if we don't set the width/height, things collapse in older versions of IE and the origin for transforms is thrown off in all browsers. 13964 13965 style.width = node._w + 1 + "px"; //IE is 1px short sometimes. Avoid wrapping 13966 13967 style.height = node._h + "px"; 13968 } 13969 13970 if (!words && chars) { 13971 //we always start out wrapping words in their own <div> so that line breaks happen correctly, but here we'll remove those <div> tags if necessary and re-nest the characters directly into the element rather than inside the word <div> 13972 if (node._isSplit) { 13973 node._next = j = node.nextSibling; 13974 node.parentNode.appendChild(node); //put it at the end to keep the order correct. 13975 13976 while (j && j.nodeType === 3 && j.textContent === " ") { 13977 // if there are nodes that are just a space right afterward, go ahead and append them to the end so they're not out of order. 13978 node._next = j.nextSibling; 13979 node.parentNode.appendChild(j); 13980 j = j.nextSibling; 13981 } 13982 } else if (node.parentNode._isSplit) { 13983 node._parent = node.parentNode; 13984 13985 if (!node.previousSibling && node.firstChild) { 13986 node.firstChild._isFirst = true; 13987 } 13988 13989 if (node.nextSibling && node.nextSibling.textContent === " " && !node.nextSibling.nextSibling) { 13990 //if the last node inside a nested element is just a space (like T<span>nested </span>), remove it otherwise it'll get placed in the wrong order. Don't remove it right away, though, because we need to sense when words/characters are before a space like _isBeforeWordDelimiter(). Removing it now would make that a false negative. 13991 spaceNodesToRemove.push(node.nextSibling); 13992 } 13993 13994 node._next = node.nextSibling && node.nextSibling._isFirst ? null : node.nextSibling; 13995 node.parentNode.removeChild(node); 13996 nodes.splice(i--, 1); 13997 l--; 13998 } else if (!isChild) { 13999 offset = !node.nextSibling && _isBeforeWordDelimiter(node.parentNode, element, wordDelimiter); //if this is the last letter in the word (and we're not breaking by lines and not positioning things absolutely), we need to add a space afterwards so that the characters don't just mash together 14000 14001 node.parentNode._parent && node.parentNode._parent.appendChild(node); 14002 offset && node.parentNode.appendChild(_doc.createTextNode(" ")); 14003 14004 if (tag === "span") { 14005 node.style.display = "inline"; //so that word breaks are honored properly. 14006 } 14007 14008 charArray.push(node); 14009 } 14010 } else if (node.parentNode._isSplit && !node._isSplit && node.innerHTML !== "") { 14011 wordArray.push(node); 14012 } else if (chars && !node._isSplit) { 14013 if (tag === "span") { 14014 node.style.display = "inline"; 14015 } 14016 14017 charArray.push(node); 14018 } 14019 } 14020 14021 i = spaceNodesToRemove.length; 14022 14023 while (--i > -1) { 14024 spaceNodesToRemove[i].parentNode.removeChild(spaceNodesToRemove[i]); 14025 } 14026 14027 if (lines) { 14028 //the next 7 lines just give us the line width in the most reliable way and figure out the left offset (if position isn't relative or absolute). We must set the width along with text-align to ensure everything works properly for various alignments. 14029 if (absolute) { 14030 lineNode = _doc.createElement(tag); 14031 element.appendChild(lineNode); 14032 lineWidth = lineNode.offsetWidth + "px"; 14033 offset = lineNode.offsetParent === element ? 0 : element.offsetLeft; 14034 element.removeChild(lineNode); 14035 } 14036 14037 style = element.style.cssText; 14038 element.style.cssText = "display:none;"; //to improve performance, set display:none on the element so that the browser doesn't have to worry about reflowing or rendering while we're renesting things. We'll revert the cssText later. 14039 //we can't use element.innerHTML = "" because that causes IE to literally delete all the nodes and their content even though we've stored them in an array! So we must loop through the children and remove them. 14040 14041 while (element.firstChild) { 14042 element.removeChild(element.firstChild); 14043 } 14044 14045 addWordSpaces = wordDelimiter === " " && (!absolute || !words && !chars); 14046 14047 for (i = 0; i < lines.length; i++) { 14048 curLine = lines[i]; 14049 lineNode = _doc.createElement(tag); 14050 lineNode.style.cssText = "display:block;text-align:" + textAlign + ";position:" + (absolute ? "absolute;" : "relative;"); 14051 14052 if (linesClass) { 14053 lineNode.className = linesClass + (iterateLine ? i + 1 : ""); 14054 } 14055 14056 lineArray.push(lineNode); 14057 l = curLine.length; 14058 14059 for (j = 0; j < l; j++) { 14060 if (curLine[j].nodeName !== "BR") { 14061 node = curLine[j]; 14062 lineNode.appendChild(node); 14063 addWordSpaces && node._wordEnd && lineNode.appendChild(_doc.createTextNode(" ")); 14064 14065 if (absolute) { 14066 if (j === 0) { 14067 lineNode.style.top = node._y + "px"; 14068 lineNode.style.left = paddingLeft + offset + "px"; 14069 } 14070 14071 node.style.top = "0px"; 14072 14073 if (offset) { 14074 node.style.left = node._x - offset + "px"; 14075 } 14076 } 14077 } 14078 } 14079 14080 if (l === 0) { 14081 //if there are no nodes in the line (typically meaning there were two consecutive <br> tags, just add a non-breaking space so that things display properly. 14082 lineNode.innerHTML = " "; 14083 } else if (!words && !chars) { 14084 _deWordify(lineNode); 14085 14086 _swapText(lineNode, String.fromCharCode(160), " "); 14087 } 14088 14089 if (absolute) { 14090 lineNode.style.width = lineWidth; 14091 lineNode.style.height = node._h + "px"; 14092 } 14093 14094 element.appendChild(lineNode); 14095 } 14096 14097 element.style.cssText = style; 14098 } //if everything shifts to being position:absolute, the container can collapse in terms of height or width, so fix that here. 14099 14100 14101 if (absolute) { 14102 if (origHeight > element.clientHeight) { 14103 element.style.height = origHeight - padTopAndBottom + "px"; 14104 14105 if (element.clientHeight < origHeight) { 14106 //IE8 and earlier use a different box model - we must include padding and borders 14107 element.style.height = origHeight + borderTopAndBottom + "px"; 14108 } 14109 } 14110 14111 if (origWidth > element.clientWidth) { 14112 element.style.width = origWidth - padLeftAndRight + "px"; 14113 14114 if (element.clientWidth < origWidth) { 14115 //IE8 and earlier use a different box model - we must include padding and borders 14116 element.style.width = origWidth + borderLeftAndRight + "px"; 14117 } 14118 } 14119 } 14120 14121 _pushReversed(allChars, charArray); 14122 14123 words && _pushReversed(allWords, wordArray); 14124 14125 _pushReversed(allLines, lineArray); 14126}, 14127 _splitRawText = function _splitRawText(element, vars, wordStart, charStart) { 14128 var tag = vars.tag ? vars.tag : vars.span ? "span" : "div", 14129 types = vars.type || vars.split || "chars,words,lines", 14130 //words = (types.indexOf("words") !== -1), 14131 chars = ~types.indexOf("chars"), 14132 absolute = _isAbsolute(vars), 14133 wordDelimiter = vars.wordDelimiter || " ", 14134 space = wordDelimiter !== " " ? "" : absolute ? "­ " : " ", 14135 wordEnd = "</" + tag + ">", 14136 wordIsOpen = 1, 14137 specialChars = vars.specialChars ? typeof vars.specialChars === "function" ? vars.specialChars : _findSpecialChars : null, 14138 //specialChars can be an array or a function. For performance reasons, we always set this local "specialChars" to a function to which we pass the remaining text and whatever the original vars.specialChars was so that if it's an array, it works with the _findSpecialChars() function. 14139 text, 14140 splitText, 14141 i, 14142 j, 14143 l, 14144 character, 14145 hasTagStart, 14146 testResult, 14147 container = _doc.createElement("div"), 14148 parent = element.parentNode; 14149 14150 parent.insertBefore(container, element); 14151 container.textContent = element.nodeValue; 14152 parent.removeChild(element); 14153 element = container; 14154 text = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["getText"])(element); 14155 hasTagStart = text.indexOf("<") !== -1; 14156 14157 if (vars.reduceWhiteSpace !== false) { 14158 text = text.replace(_multipleSpacesExp, " ").replace(_stripExp, ""); 14159 } 14160 14161 if (hasTagStart) { 14162 text = text.split("<").join("{{LT}}"); //we can't leave "<" in the string, or when we set the innerHTML, it can be interpreted as a node 14163 } 14164 14165 l = text.length; 14166 splitText = (text.charAt(0) === " " ? space : "") + wordStart(); 14167 14168 for (i = 0; i < l; i++) { 14169 character = text.charAt(i); 14170 14171 if (specialChars && (testResult = specialChars(text.substr(i), vars.specialChars))) { 14172 // look for any specialChars that were declared. Remember, they can be passed in like {specialChars:["à ¤®à ¥€", "à ¤ªà ¤¾", "à ¤¹à ¥ˆ"]} or a function could be defined instead. Either way, the function should return the number of characters that should be grouped together for this "character". 14173 character = text.substr(i, testResult || 1); 14174 splitText += chars && character !== " " ? charStart() + character + "</" + tag + ">" : character; 14175 i += testResult - 1; 14176 } else if (character === wordDelimiter && text.charAt(i - 1) !== wordDelimiter && i) { 14177 splitText += wordIsOpen ? wordEnd : ""; 14178 wordIsOpen = 0; 14179 14180 while (text.charAt(i + 1) === wordDelimiter) { 14181 //skip over empty spaces (to avoid making them words) 14182 splitText += space; 14183 i++; 14184 } 14185 14186 if (i === l - 1) { 14187 splitText += space; 14188 } else if (text.charAt(i + 1) !== ")") { 14189 splitText += space + wordStart(); 14190 wordIsOpen = 1; 14191 } 14192 } else if (character === "{" && text.substr(i, 6) === "{{LT}}") { 14193 splitText += chars ? charStart() + "{{LT}}" + "</" + tag + ">" : "{{LT}}"; 14194 i += 5; 14195 } else if (character.charCodeAt(0) >= 0xD800 && character.charCodeAt(0) <= 0xDBFF || text.charCodeAt(i + 1) >= 0xFE00 && text.charCodeAt(i + 1) <= 0xFE0F) { 14196 //special emoji characters use 2 or 4 unicode characters that we must keep together. 14197 j = ((text.substr(i, 12).split(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiExp"]) || [])[1] || "").length || 2; 14198 splitText += chars && character !== " " ? charStart() + text.substr(i, j) + "</" + tag + ">" : text.substr(i, j); 14199 i += j - 1; 14200 } else { 14201 splitText += chars && character !== " " ? charStart() + character + "</" + tag + ">" : character; 14202 } 14203 } 14204 14205 element.outerHTML = splitText + (wordIsOpen ? wordEnd : ""); 14206 hasTagStart && _swapText(parent, "{{LT}}", "<"); //note: don't perform this on "element" because that gets replaced with all new elements when we set element.outerHTML. 14207}, 14208 _split = function _split(element, vars, wordStart, charStart) { 14209 var children = _toArray(element.childNodes), 14210 l = children.length, 14211 absolute = _isAbsolute(vars), 14212 i, 14213 child; 14214 14215 if (element.nodeType !== 3 || l > 1) { 14216 vars.absolute = false; 14217 14218 for (i = 0; i < l; i++) { 14219 child = children[i]; 14220 child._next = child._isFirst = child._parent = child._wordEnd = null; 14221 14222 if (child.nodeType !== 3 || /\S+/.test(child.nodeValue)) { 14223 if (absolute && child.nodeType !== 3 && _getComputedStyle(child).display === "inline") { 14224 //if there's a child node that's display:inline, switch it to inline-block so that absolute positioning works properly (most browsers don't report offsetTop/offsetLeft properly inside a <span> for example) 14225 child.style.display = "inline-block"; 14226 child.style.position = "relative"; 14227 } 14228 14229 child._isSplit = true; 14230 14231 _split(child, vars, wordStart, charStart); //don't split lines on child elements 14232 14233 } 14234 } 14235 14236 vars.absolute = absolute; 14237 element._isSplit = true; 14238 return; 14239 } 14240 14241 _splitRawText(element, vars, wordStart, charStart); 14242}; 14243 14244var SplitText = /*#__PURE__*/function () { 14245 function SplitText(element, vars) { 14246 _coreInitted || _initCore(); 14247 this.elements = _toArray(element); 14248 this.chars = []; 14249 this.words = []; 14250 this.lines = []; 14251 this._originals = []; 14252 this.vars = vars || {}; 14253 _bonusValidated && this.split(vars); 14254 } 14255 14256 var _proto = SplitText.prototype; 14257 14258 _proto.split = function split(vars) { 14259 this.isSplit && this.revert(); 14260 this.vars = vars = vars || this.vars; 14261 this._originals.length = this.chars.length = this.words.length = this.lines.length = 0; 14262 14263 var i = this.elements.length, 14264 tag = vars.tag ? vars.tag : vars.span ? "span" : "div", 14265 wordStart = _cssClassFunc(vars.wordsClass, tag), 14266 charStart = _cssClassFunc(vars.charsClass, tag), 14267 origHeight, 14268 origWidth, 14269 e; //we split in reversed order so that if/when we position:absolute elements, they don't affect the position of the ones after them in the document flow (shifting them up as they're taken out of the document flow). 14270 14271 14272 while (--i > -1) { 14273 e = this.elements[i]; 14274 this._originals[i] = e.innerHTML; 14275 origHeight = e.clientHeight; 14276 origWidth = e.clientWidth; 14277 14278 _split(e, vars, wordStart, charStart); 14279 14280 _setPositionsAfterSplit(e, vars, this.chars, this.words, this.lines, origWidth, origHeight); 14281 } 14282 14283 this.chars.reverse(); 14284 this.words.reverse(); 14285 this.lines.reverse(); 14286 this.isSplit = true; 14287 return this; 14288 }; 14289 14290 _proto.revert = function revert() { 14291 var originals = this._originals; 14292 14293 if (!originals) { 14294 throw "revert() call wasn't scoped properly."; 14295 } 14296 14297 this.elements.forEach(function (e, i) { 14298 return e.innerHTML = originals[i]; 14299 }); 14300 this.chars = []; 14301 this.words = []; 14302 this.lines = []; 14303 this.isSplit = false; 14304 return this; 14305 }; 14306 14307 SplitText.create = function create(element, vars) { 14308 return new SplitText(element, vars); 14309 }; 14310 14311 return SplitText; 14312}(); 14313SplitText.version = "3.6.0"; 14314 14315 14316/***/ }), 14317
vendor: 5,208 bytes, lines 14318-14499
14318/***/ "./node_modules/gsap/TextPlugin.js": 14319/*!*****************************************!*\ 14320 !*** ./node_modules/gsap/TextPlugin.js ***! 14321 \*****************************************/ 14322/*! exports provided: TextPlugin, default */ 14323/***/ (function(module, __webpack_exports__, __webpack_require__) { 14324 14325"use strict"; 14326__webpack_require__.r(__webpack_exports__); 14327/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TextPlugin", function() { return TextPlugin; }); 14328/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return TextPlugin; }); 14329/* harmony import */ var _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/strings.js */ "./node_modules/gsap/utils/strings.js"); 14330/*! 14331 * TextPlugin 3.6.0 14332 * https://greensock.com 14333 * 14334 * @license Copyright 2008-2021, GreenSock. All rights reserved. 14335 * Subject to the terms at https://greensock.com/standard-license or for 14336 * Club GreenSock members, the agreement issued with that membership. 14337 * @author: Jack Doyle, [email protected] 14338*/ 14339 14340/* eslint-disable */ 14341 14342 14343var gsap, 14344 _tempDiv, 14345 _getGSAP = function _getGSAP() { 14346 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 14347}; 14348 14349var TextPlugin = { 14350 version: "3.6.0", 14351 name: "text", 14352 init: function init(target, value, tween) { 14353 var i = target.nodeName.toUpperCase(), 14354 data = this, 14355 _short, 14356 text, 14357 original, 14358 j, 14359 condensedText, 14360 condensedOriginal, 14361 aggregate, 14362 s; 14363 14364 data.svg = target.getBBox && (i === "TEXT" || i === "TSPAN"); 14365 14366 if (!("innerHTML" in target) && !data.svg) { 14367 return false; 14368 } 14369 14370 data.target = target; 14371 14372 if (typeof value !== "object") { 14373 value = { 14374 value: value 14375 }; 14376 } 14377 14378 if (!("value" in value)) { 14379 data.text = data.original = [""]; 14380 return; 14381 } 14382 14383 data.delimiter = value.delimiter || ""; 14384 original = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["splitInnerHTML"])(target, data.delimiter); 14385 14386 if (!_tempDiv) { 14387 _tempDiv = document.createElement("div"); 14388 } 14389 14390 _tempDiv.innerHTML = value.value; 14391 text = Object(_utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["splitInnerHTML"])(_tempDiv, data.delimiter); 14392 data.from = tween._from; 14393 14394 if (data.from) { 14395 i = original; 14396 original = text; 14397 text = i; 14398 } 14399 14400 data.hasClass = !!(value.newClass || value.oldClass); 14401 data.newClass = value.newClass; 14402 data.oldClass = value.oldClass; 14403 i = original.length - text.length; 14404 _short = i < 0 ? original : text; 14405 data.fillChar = value.fillChar || (value.padSpace ? " " : ""); 14406 14407 if (i < 0) { 14408 i = -i; 14409 } 14410 14411 while (--i > -1) { 14412 _short.push(data.fillChar); 14413 } 14414 14415 if (value.type === "diff") { 14416 j = 0; 14417 condensedText = []; 14418 condensedOriginal = []; 14419 aggregate = ""; 14420 14421 for (i = 0; i < text.length; i++) { 14422 s = text[i]; 14423 14424 if (s === original[i]) { 14425 aggregate += s; 14426 } else { 14427 condensedText[j] = aggregate + s; 14428 condensedOriginal[j++] = aggregate + original[i]; 14429 aggregate = ""; 14430 } 14431 } 14432 14433 text = condensedText; 14434 original = condensedOriginal; 14435 14436 if (aggregate) { 14437 text.push(aggregate); 14438 original.push(aggregate); 14439 } 14440 } 14441 14442 if (value.speed) { 14443 tween.duration(Math.min(0.05 / value.speed * _short.length, value.maxDuration || 9999)); 14444 } 14445 14446 this.original = original; 14447 this.text = text; 14448 14449 this._props.push("text"); 14450 }, 14451 render: function render(ratio, data) { 14452 if (ratio > 1) { 14453 ratio = 1; 14454 } else if (ratio < 0) { 14455 ratio = 0; 14456 } 14457 14458 if (data.from) { 14459 ratio = 1 - ratio; 14460 } 14461 14462 var text = data.text, 14463 hasClass = data.hasClass, 14464 newClass = data.newClass, 14465 oldClass = data.oldClass, 14466 delimiter = data.delimiter, 14467 target = data.target, 14468 fillChar = data.fillChar, 14469 original = data.original, 14470 l = text.length, 14471 i = ratio * l + 0.5 | 0, 14472 applyNew, 14473 applyOld, 14474 str; 14475 14476 if (hasClass) { 14477 applyNew = newClass && i; 14478 applyOld = oldClass && i !== l; 14479 str = (applyNew ? "<span class='" + newClass + "'>" : "") + text.slice(0, i).join(delimiter) + (applyNew ? "</span>" : "") + (applyOld ? "<span class='" + oldClass + "'>" : "") + delimiter + original.slice(i).join(delimiter) + (applyOld ? "</span>" : ""); 14480 } else { 14481 str = text.slice(0, i).join(delimiter) + delimiter + original.slice(i).join(delimiter); 14482 } 14483 14484 if (data.svg) { 14485 //SVG text elements don't have an "innerHTML" in Microsoft browsers. 14486 target.textContent = str; 14487 } else { 14488 target.innerHTML = fillChar === " " && ~str.indexOf(" ") ? str.split(" ").join(" ") : str; 14489 } 14490 } 14491}; 14492TextPlugin.splitInnerHTML = _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["splitInnerHTML"]; 14493TextPlugin.emojiSafeSplit = _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["emojiSafeSplit"]; 14494TextPlugin.getText = _utils_strings_js__WEBPACK_IMPORTED_MODULE_0__["getText"]; 14495_getGSAP() && gsap.registerPlugin(TextPlugin); 14496 14497 14498/***/ }), 14499
vendor: 16,171 bytes, lines 14500-14695
14500/***/ "./node_modules/gsap/all.js": 14501/*!**********************************!*\ 14502 !*** ./node_modules/gsap/all.js ***! 14503 \**********************************/ 14504/*! exports provided: gsap, default, CSSPlugin, TweenMax, TweenLite, TimelineMax, TimelineLite, Power0, Power1, Power2, Power3, Power4, Linear, Quad, Cubic, Quart, Quint, Strong, Elastic, Back, SteppedEase, Bounce, Sine, Expo, Circ, wrap, wrapYoyo, distribute, random, snap, normalize, getUnit, clamp, splitColor, toArray, mapRange, pipe, unitize, interpolate, shuffle, Draggable, CSSRulePlugin, EaselPlugin, SlowMo, ExpoScaleEase, RoughEase, EasePack, MotionPathPlugin, PixiPlugin, ScrollToPlugin, ScrollTrigger, TextPlugin, CustomEase, DrawSVGPlugin, Physics2DPlugin, PhysicsPropsPlugin, ScrambleTextPlugin, CustomBounce, CustomWiggle, Flip, GSDevTools, InertiaPlugin, VelocityTracker, MorphSVGPlugin, MotionPathHelper, SplitText */ 14505/***/ (function(module, __webpack_exports__, __webpack_require__) { 14506 14507"use strict"; 14508__webpack_require__.r(__webpack_exports__); 14509/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gsap", function() { return gsapWithCSS; }); 14510/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return gsapWithCSS; }); 14511/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TweenMax", function() { return TweenMaxWithCSS; }); 14512/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js"); 14513/* harmony import */ var _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CSSPlugin.js */ "./node_modules/gsap/CSSPlugin.js"); 14514/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CSSPlugin", function() { return _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__["default"]; }); 14515 14516/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TweenLite", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["TweenLite"]; }); 14517 14518/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TimelineMax", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["TimelineMax"]; }); 14519 14520/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TimelineLite", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["TimelineLite"]; }); 14521 14522/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Power0", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Power0"]; }); 14523 14524/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Power1", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Power1"]; }); 14525 14526/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Power2", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Power2"]; }); 14527 14528/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Power3", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Power3"]; }); 14529 14530/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Power4", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Power4"]; }); 14531 14532/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Linear", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Linear"]; }); 14533 14534/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quad", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Quad"]; }); 14535 14536/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Cubic", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Cubic"]; }); 14537 14538/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quart", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Quart"]; }); 14539 14540/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Quint", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Quint"]; }); 14541 14542/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Strong", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Strong"]; }); 14543 14544/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Elastic", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Elastic"]; }); 14545 14546/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Back", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Back"]; }); 14547 14548/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SteppedEase", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["SteppedEase"]; }); 14549 14550/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Bounce", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Bounce"]; }); 14551 14552/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Sine", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Sine"]; }); 14553 14554/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Expo", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Expo"]; }); 14555 14556/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Circ", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["Circ"]; }); 14557 14558/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "wrap", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["wrap"]; }); 14559 14560/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "wrapYoyo", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["wrapYoyo"]; }); 14561 14562/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distribute", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["distribute"]; }); 14563 14564/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "random", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["random"]; }); 14565 14566/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "snap", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["snap"]; }); 14567 14568/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "normalize", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["normalize"]; }); 14569 14570/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "getUnit", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["getUnit"]; }); 14571 14572/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "clamp", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["clamp"]; }); 14573 14574/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "splitColor", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["splitColor"]; }); 14575 14576/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["toArray"]; }); 14577 14578/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapRange", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["mapRange"]; }); 14579 14580/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["pipe"]; }); 14581 14582/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "unitize", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["unitize"]; }); 14583 14584/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "interpolate", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["interpolate"]; }); 14585 14586/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shuffle", function() { return _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["shuffle"]; }); 14587 14588/* harmony import */ var _Draggable_js__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./Draggable.js */ "./node_modules/gsap/Draggable.js"); 14589/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Draggable", function() { return _Draggable_js__WEBPACK_IMPORTED_MODULE_2__["Draggable"]; }); 14590 14591/* harmony import */ var _CSSRulePlugin_js__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./CSSRulePlugin.js */ "./node_modules/gsap/CSSRulePlugin.js"); 14592/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CSSRulePlugin", function() { return _CSSRulePlugin_js__WEBPACK_IMPORTED_MODULE_3__["CSSRulePlugin"]; }); 14593 14594/* harmony import */ var _EaselPlugin_js__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./EaselPlugin.js */ "./node_modules/gsap/EaselPlugin.js"); 14595/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EaselPlugin", function() { return _EaselPlugin_js__WEBPACK_IMPORTED_MODULE_4__["EaselPlugin"]; }); 14596 14597/* harmony import */ var _EasePack_js__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./EasePack.js */ "./node_modules/gsap/EasePack.js"); 14598/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SlowMo", function() { return _EasePack_js__WEBPACK_IMPORTED_MODULE_5__["SlowMo"]; }); 14599 14600/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ExpoScaleEase", function() { return _EasePack_js__WEBPACK_IMPORTED_MODULE_5__["ExpoScaleEase"]; }); 14601 14602/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "RoughEase", function() { return _EasePack_js__WEBPACK_IMPORTED_MODULE_5__["RoughEase"]; }); 14603 14604/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "EasePack", function() { return _EasePack_js__WEBPACK_IMPORTED_MODULE_5__["EasePack"]; }); 14605 14606/* harmony import */ var _MotionPathPlugin_js__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./MotionPathPlugin.js */ "./node_modules/gsap/MotionPathPlugin.js"); 14607/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotionPathPlugin", function() { return _MotionPathPlugin_js__WEBPACK_IMPORTED_MODULE_6__["MotionPathPlugin"]; }); 14608 14609/* harmony import */ var _PixiPlugin_js__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./PixiPlugin.js */ "./node_modules/gsap/PixiPlugin.js"); 14610/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PixiPlugin", function() { return _PixiPlugin_js__WEBPACK_IMPORTED_MODULE_7__["PixiPlugin"]; }); 14611 14612/* harmony import */ var _ScrollToPlugin_js__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./ScrollToPlugin.js */ "./node_modules/gsap/ScrollToPlugin.js"); 14613/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScrollToPlugin", function() { return _ScrollToPlugin_js__WEBPACK_IMPORTED_MODULE_8__["ScrollToPlugin"]; }); 14614 14615/* harmony import */ var _ScrollTrigger_js__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./ScrollTrigger.js */ "./node_modules/gsap/ScrollTrigger.js"); 14616/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScrollTrigger", function() { return _ScrollTrigger_js__WEBPACK_IMPORTED_MODULE_9__["ScrollTrigger"]; }); 14617 14618/* harmony import */ var _TextPlugin_js__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./TextPlugin.js */ "./node_modules/gsap/TextPlugin.js"); 14619/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "TextPlugin", function() { return _TextPlugin_js__WEBPACK_IMPORTED_MODULE_10__["TextPlugin"]; }); 14620 14621/* harmony import */ var _CustomEase_js__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./CustomEase.js */ "./node_modules/gsap/CustomEase.js"); 14622/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomEase", function() { return _CustomEase_js__WEBPACK_IMPORTED_MODULE_11__["CustomEase"]; }); 14623 14624/* harmony import */ var _DrawSVGPlugin_js__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./DrawSVGPlugin.js */ "./node_modules/gsap/DrawSVGPlugin.js"); 14625/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "DrawSVGPlugin", function() { return _DrawSVGPlugin_js__WEBPACK_IMPORTED_MODULE_12__["DrawSVGPlugin"]; }); 14626 14627/* harmony import */ var _Physics2DPlugin_js__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./Physics2DPlugin.js */ "./node_modules/gsap/Physics2DPlugin.js"); 14628/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Physics2DPlugin", function() { return _Physics2DPlugin_js__WEBPACK_IMPORTED_MODULE_13__["Physics2DPlugin"]; }); 14629 14630/* harmony import */ var _PhysicsPropsPlugin_js__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./PhysicsPropsPlugin.js */ "./node_modules/gsap/PhysicsPropsPlugin.js"); 14631/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "PhysicsPropsPlugin", function() { return _PhysicsPropsPlugin_js__WEBPACK_IMPORTED_MODULE_14__["PhysicsPropsPlugin"]; }); 14632 14633/* harmony import */ var _ScrambleTextPlugin_js__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! ./ScrambleTextPlugin.js */ "./node_modules/gsap/ScrambleTextPlugin.js"); 14634/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ScrambleTextPlugin", function() { return _ScrambleTextPlugin_js__WEBPACK_IMPORTED_MODULE_15__["ScrambleTextPlugin"]; }); 14635 14636/* harmony import */ var _CustomBounce_js__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! ./CustomBounce.js */ "./node_modules/gsap/CustomBounce.js"); 14637/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomBounce", function() { return _CustomBounce_js__WEBPACK_IMPORTED_MODULE_16__["CustomBounce"]; }); 14638 14639/* harmony import */ var _CustomWiggle_js__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./CustomWiggle.js */ "./node_modules/gsap/CustomWiggle.js"); 14640/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "CustomWiggle", function() { return _CustomWiggle_js__WEBPACK_IMPORTED_MODULE_17__["CustomWiggle"]; }); 14641 14642/* harmony import */ var _Flip_js__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(/*! ./Flip.js */ "./node_modules/gsap/Flip.js"); 14643/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "Flip", function() { return _Flip_js__WEBPACK_IMPORTED_MODULE_18__["Flip"]; }); 14644 14645/* harmony import */ var _GSDevTools_js__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(/*! ./GSDevTools.js */ "./node_modules/gsap/GSDevTools.js"); 14646/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "GSDevTools", function() { return _GSDevTools_js__WEBPACK_IMPORTED_MODULE_19__["GSDevTools"]; }); 14647 14648/* harmony import */ var _InertiaPlugin_js__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(/*! ./InertiaPlugin.js */ "./node_modules/gsap/InertiaPlugin.js"); 14649/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "InertiaPlugin", function() { return _InertiaPlugin_js__WEBPACK_IMPORTED_MODULE_20__["InertiaPlugin"]; }); 14650 14651/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "VelocityTracker", function() { return _InertiaPlugin_js__WEBPACK_IMPORTED_MODULE_20__["VelocityTracker"]; }); 14652 14653/* harmony import */ var _MorphSVGPlugin_js__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(/*! ./MorphSVGPlugin.js */ "./node_modules/gsap/MorphSVGPlugin.js"); 14654/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MorphSVGPlugin", function() { return _MorphSVGPlugin_js__WEBPACK_IMPORTED_MODULE_21__["MorphSVGPlugin"]; }); 14655 14656/* harmony import */ var _MotionPathHelper_js__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(/*! ./MotionPathHelper.js */ "./node_modules/gsap/MotionPathHelper.js"); 14657/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "MotionPathHelper", function() { return _MotionPathHelper_js__WEBPACK_IMPORTED_MODULE_22__["MotionPathHelper"]; }); 14658 14659/* harmony import */ var _SplitText_js__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(/*! ./SplitText.js */ "./node_modules/gsap/SplitText.js"); 14660/* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "SplitText", function() { return _SplitText_js__WEBPACK_IMPORTED_MODULE_23__["SplitText"]; }); 14661 14662 14663 14664var gsapWithCSS = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["default"].registerPlugin(_CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__["default"]) || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__["default"], // to protect from tree shaking 14665 TweenMaxWithCSS = gsapWithCSS.core.Tween; 14666 14667 14668 14669 14670 14671 14672 14673 14674 14675 14676 14677 14678 14679//BONUS EXPORTS 14680 14681 14682 14683 14684 14685 14686 14687 14688 14689 14690 14691 14692 14693 14694/***/ }), 14695
vendor: 151,129 bytes, lines 14696-18605
14696/***/ "./node_modules/gsap/gsap-core.js": 14697/*!****************************************!*\ 14698 !*** ./node_modules/gsap/gsap-core.js ***! 14699 \****************************************/ 14700/*! exports provided: GSCache, Animation, Timeline, Tween, PropTween, gsap, Power0, Power1, Power2, Power3, Power4, Linear, Quad, Cubic, Quart, Quint, Strong, Elastic, Back, SteppedEase, Bounce, Sine, Expo, Circ, TweenMax, TweenLite, TimelineMax, TimelineLite, default, wrap, wrapYoyo, distribute, random, snap, normalize, getUnit, clamp, splitColor, toArray, mapRange, pipe, unitize, interpolate, shuffle, _getProperty, _numExp, _numWithUnitExp, _isString, _isUndefined, _renderComplexString, _relExp, _setDefaults, _removeLinkedListItem, _forEachName, _sortPropTweensByPriority, _colorStringFilter, _replaceRandom, _checkPlugin, _plugins, _ticker, _config, _roundModifier, _round, _missingPlugin, _getSetter, _getCache */ 14701/***/ (function(module, __webpack_exports__, __webpack_require__) { 14702 14703"use strict"; 14704__webpack_require__.r(__webpack_exports__); 14705/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "GSCache", function() { return GSCache; }); 14706/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Animation", function() { return Animation; }); 14707/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Timeline", function() { return Timeline; }); 14708/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Tween", function() { return Tween; }); 14709/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PropTween", function() { return PropTween; }); 14710/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "gsap", function() { return gsap; }); 14711/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Power0", function() { return Power0; }); 14712/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Power1", function() { return Power1; }); 14713/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Power2", function() { return Power2; }); 14714/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Power3", function() { return Power3; }); 14715/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Power4", function() { return Power4; }); 14716/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Linear", function() { return Linear; }); 14717/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Quad", function() { return Quad; }); 14718/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Cubic", function() { return Cubic; }); 14719/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Quart", function() { return Quart; }); 14720/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Quint", function() { return Quint; }); 14721/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Strong", function() { return Strong; }); 14722/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Elastic", function() { return Elastic; }); 14723/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Back", function() { return Back; }); 14724/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SteppedEase", function() { return SteppedEase; }); 14725/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Bounce", function() { return Bounce; }); 14726/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Sine", function() { return Sine; }); 14727/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Expo", function() { return Expo; }); 14728/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Circ", function() { return Circ; }); 14729/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TweenMax", function() { return Tween; }); 14730/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TweenLite", function() { return Tween; }); 14731/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimelineMax", function() { return Timeline; }); 14732/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimelineLite", function() { return Timeline; }); 14733/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return gsap; }); 14734/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wrap", function() { return wrap; }); 14735/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "wrapYoyo", function() { return wrapYoyo; }); 14736/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distribute", function() { return distribute; }); 14737/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "random", function() { return random; }); 14738/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "snap", function() { return snap; }); 14739/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "normalize", function() { return normalize; }); 14740/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getUnit", function() { return getUnit; }); 14741/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "clamp", function() { return clamp; }); 14742/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "splitColor", function() { return splitColor; }); 14743/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); 14744/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mapRange", function() { return mapRange; }); 14745/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pipe", function() { return pipe; }); 14746/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unitize", function() { return unitize; }); 14747/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "interpolate", function() { return interpolate; }); 14748/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "shuffle", function() { return shuffle; }); 14749/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getProperty", function() { return _getProperty; }); 14750/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_numExp", function() { return _numExp; }); 14751/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_numWithUnitExp", function() { return _numWithUnitExp; }); 14752/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_isString", function() { return _isString; }); 14753/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_isUndefined", function() { return _isUndefined; }); 14754/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_renderComplexString", function() { return _renderComplexString; }); 14755/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_relExp", function() { return _relExp; }); 14756/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_setDefaults", function() { return _setDefaults; }); 14757/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_removeLinkedListItem", function() { return _removeLinkedListItem; }); 14758/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_forEachName", function() { return _forEachName; }); 14759/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_sortPropTweensByPriority", function() { return _sortPropTweensByPriority; }); 14760/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_colorStringFilter", function() { return _colorStringFilter; }); 14761/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_replaceRandom", function() { return _replaceRandom; }); 14762/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_checkPlugin", function() { return _checkPlugin; }); 14763/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_plugins", function() { return _plugins; }); 14764/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_ticker", function() { return _ticker; }); 14765/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_config", function() { return _config; }); 14766/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_roundModifier", function() { return _roundModifier; }); 14767/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_round", function() { return _round; }); 14768/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_missingPlugin", function() { return _missingPlugin; }); 14769/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getSetter", function() { return _getSetter; }); 14770/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getCache", function() { return _getCache; }); 14771function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 14772 14773function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } 14774 14775/*! 14776 * GSAP 3.6.0 14777 * https://greensock.com 14778 * 14779 * @license Copyright 2008-2021, GreenSock. All rights reserved. 14780 * Subject to the terms at https://greensock.com/standard-license or for 14781 * Club GreenSock members, the agreement issued with that membership. 14782 * @author: Jack Doyle, [email protected] 14783*/ 14784 14785/* eslint-disable */ 14786var _config = { 14787 autoSleep: 120, 14788 force3D: "auto", 14789 nullTargetWarn: 1, 14790 units: { 14791 lineHeight: "" 14792 } 14793}, 14794 _defaults = { 14795 duration: .5, 14796 overwrite: false, 14797 delay: 0 14798}, 14799 _suppressOverwrites, 14800 _bigNum = 1e8, 14801 _tinyNum = 1 / _bigNum, 14802 _2PI = Math.PI * 2, 14803 _HALF_PI = _2PI / 4, 14804 _gsID = 0, 14805 _sqrt = Math.sqrt, 14806 _cos = Math.cos, 14807 _sin = Math.sin, 14808 _isString = function _isString(value) { 14809 return typeof value === "string"; 14810}, 14811 _isFunction = function _isFunction(value) { 14812 return typeof value === "function"; 14813}, 14814 _isNumber = function _isNumber(value) { 14815 return typeof value === "number"; 14816}, 14817 _isUndefined = function _isUndefined(value) { 14818 return typeof value === "undefined"; 14819}, 14820 _isObject = function _isObject(value) { 14821 return typeof value === "object"; 14822}, 14823 _isNotFalse = function _isNotFalse(value) { 14824 return value !== false; 14825}, 14826 _windowExists = function _windowExists() { 14827 return typeof window !== "undefined"; 14828}, 14829 _isFuncOrString = function _isFuncOrString(value) { 14830 return _isFunction(value) || _isString(value); 14831}, 14832 _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {}, 14833 // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView(). 14834_isArray = Array.isArray, 14835 _strictNumExp = /(?:-?\.?\d|\.)+/gi, 14836 //only numbers (including negatives and decimals) but NOT relative values. 14837_numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g, 14838 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 14839_numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g, 14840 _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi, 14841 //duplicate so that while we're looping through matches from exec(), it doesn't contaminate the lastIndex of _numExp which we use to search for colors too. 14842_relExp = /[+-]=-?[.\d]+/, 14843 _delimitedValueExp = /[#\-+.]*\b[a-z\d-=+%.]+/gi, 14844 _unitExp = /[\d.+\-=]+(?:e[-+]\d*)*/i, 14845 _globalTimeline, 14846 _win, 14847 _coreInitted, 14848 _doc, 14849 _globals = {}, 14850 _installScope = {}, 14851 _coreReady, 14852 _install = function _install(scope) { 14853 return (_installScope = _merge(scope, _globals)) && gsap; 14854}, 14855 _missingPlugin = function _missingPlugin(property, value) { 14856 return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()"); 14857}, 14858 _warn = function _warn(message, suppress) { 14859 return !suppress && console.warn(message); 14860}, 14861 _addGlobal = function _addGlobal(name, obj) { 14862 return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals; 14863}, 14864 _emptyFunc = function _emptyFunc() { 14865 return 0; 14866}, 14867 _reservedProps = {}, 14868 _lazyTweens = [], 14869 _lazyLookup = {}, 14870 _lastRenderedFrame, 14871 _plugins = {}, 14872 _effects = {}, 14873 _nextGCFrame = 30, 14874 _harnessPlugins = [], 14875 _callbackNames = "", 14876 _harness = function _harness(targets) { 14877 var target = targets[0], 14878 harnessPlugin, 14879 i; 14880 _isObject(target) || _isFunction(target) || (targets = [targets]); 14881 14882 if (!(harnessPlugin = (target._gsap || {}).harness)) { 14883 // find the first target with a harness. We assume targets passed into an animation will be of similar type, meaning the same kind of harness can be used for them all (performance optimization) 14884 i = _harnessPlugins.length; 14885 14886 while (i-- && !_harnessPlugins[i].targetTest(target)) {} 14887 14888 harnessPlugin = _harnessPlugins[i]; 14889 } 14890 14891 i = targets.length; 14892 14893 while (i--) { 14894 targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1); 14895 } 14896 14897 return targets; 14898}, 14899 _getCache = function _getCache(target) { 14900 return target._gsap || _harness(toArray(target))[0]._gsap; 14901}, 14902 _getProperty = function _getProperty(target, property, v) { 14903 return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v; 14904}, 14905 _forEachName = function _forEachName(names, func) { 14906 return (names = names.split(",")).forEach(func) || names; 14907}, 14908 //split a comma-delimited list of names into an array, then run a forEach() function and return the split array (this is just a way to consolidate/shorten some code). 14909_round = function _round(value) { 14910 return Math.round(value * 100000) / 100000 || 0; 14911}, 14912 _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) { 14913 //searches one array to find matches for any of the items in the toFind array. As soon as one is found, it returns true. It does NOT return all the matches; it's simply a boolean search. 14914 var l = toFind.length, 14915 i = 0; 14916 14917 for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {} 14918 14919 return i < l; 14920}, 14921 _parseVars = function _parseVars(params, type, parent) { 14922 //reads the arguments passed to one of the key methods and figures out if the user is defining things with the OLD/legacy syntax where the duration is the 2nd parameter, and then it adjusts things accordingly and spits back the corrected vars object (with the duration added if necessary, as well as runBackwards or startAt or immediateRender). type 0 = to()/staggerTo(), 1 = from()/staggerFrom(), 2 = fromTo()/staggerFromTo() 14923 var isLegacy = _isNumber(params[1]), 14924 varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1), 14925 vars = params[varsIndex], 14926 irVars; 14927 14928 isLegacy && (vars.duration = params[1]); 14929 vars.parent = parent; 14930 14931 if (type) { 14932 irVars = vars; 14933 14934 while (parent && !("immediateRender" in irVars)) { 14935 // inheritance hasn't happened yet, but someone may have set a default in an ancestor timeline. We could do vars.immediateRender = _isNotFalse(_inheritDefaults(vars).immediateRender) but that'd exact a slight performance penalty because _inheritDefaults() also runs in the Tween constructor. We're paying a small kb price here to gain speed. 14936 irVars = parent.vars.defaults || {}; 14937 parent = _isNotFalse(parent.vars.inherit) && parent.parent; 14938 } 14939 14940 vars.immediateRender = _isNotFalse(irVars.immediateRender); 14941 type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // "from" vars 14942 } 14943 14944 return vars; 14945}, 14946 _lazyRender = function _lazyRender() { 14947 var l = _lazyTweens.length, 14948 a = _lazyTweens.slice(0), 14949 i, 14950 tween; 14951 14952 _lazyLookup = {}; 14953 _lazyTweens.length = 0; 14954 14955 for (i = 0; i < l; i++) { 14956 tween = a[i]; 14957 tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0); 14958 } 14959}, 14960 _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) { 14961 _lazyTweens.length && _lazyRender(); 14962 animation.render(time, suppressEvents, force); 14963 _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when someone calls seek() or time() or progress(), they expect an immediate render. 14964}, 14965 _numericIfPossible = function _numericIfPossible(value) { 14966 var n = parseFloat(value); 14967 return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value; 14968}, 14969 _passThrough = function _passThrough(p) { 14970 return p; 14971}, 14972 _setDefaults = function _setDefaults(obj, defaults) { 14973 for (var p in defaults) { 14974 p in obj || (obj[p] = defaults[p]); 14975 } 14976 14977 return obj; 14978}, 14979 _setKeyframeDefaults = function _setKeyframeDefaults(obj, defaults) { 14980 for (var p in defaults) { 14981 p in obj || p === "duration" || p === "ease" || (obj[p] = defaults[p]); 14982 } 14983}, 14984 _merge = function _merge(base, toMerge) { 14985 for (var p in toMerge) { 14986 base[p] = toMerge[p]; 14987 } 14988 14989 return base; 14990}, 14991 _mergeDeep = function _mergeDeep(base, toMerge) { 14992 for (var p in toMerge) { 14993 p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]); 14994 } 14995 14996 return base; 14997}, 14998 _copyExcluding = function _copyExcluding(obj, excluding) { 14999 var copy = {}, 15000 p; 15001 15002 for (p in obj) { 15003 p in excluding || (copy[p] = obj[p]); 15004 } 15005 15006 return copy; 15007}, 15008 _inheritDefaults = function _inheritDefaults(vars) { 15009 var parent = vars.parent || _globalTimeline, 15010 func = vars.keyframes ? _setKeyframeDefaults : _setDefaults; 15011 15012 if (_isNotFalse(vars.inherit)) { 15013 while (parent) { 15014 func(vars, parent.vars.defaults); 15015 parent = parent.parent || parent._dp; 15016 } 15017 } 15018 15019 return vars; 15020}, 15021 _arraysMatch = function _arraysMatch(a1, a2) { 15022 var i = a1.length, 15023 match = i === a2.length; 15024 15025 while (match && i-- && a1[i] === a2[i]) {} 15026 15027 return i < 0; 15028}, 15029 _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) { 15030 if (firstProp === void 0) { 15031 firstProp = "_first"; 15032 } 15033 15034 if (lastProp === void 0) { 15035 lastProp = "_last"; 15036 } 15037 15038 var prev = parent[lastProp], 15039 t; 15040 15041 if (sortBy) { 15042 t = child[sortBy]; 15043 15044 while (prev && prev[sortBy] > t) { 15045 prev = prev._prev; 15046 } 15047 } 15048 15049 if (prev) { 15050 child._next = prev._next; 15051 prev._next = child; 15052 } else { 15053 child._next = parent[firstProp]; 15054 parent[firstProp] = child; 15055 } 15056 15057 if (child._next) { 15058 child._next._prev = child; 15059 } else { 15060 parent[lastProp] = child; 15061 } 15062 15063 child._prev = prev; 15064 child.parent = child._dp = parent; 15065 return child; 15066}, 15067 _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) { 15068 if (firstProp === void 0) { 15069 firstProp = "_first"; 15070 } 15071 15072 if (lastProp === void 0) { 15073 lastProp = "_last"; 15074 } 15075 15076 var prev = child._prev, 15077 next = child._next; 15078 15079 if (prev) { 15080 prev._next = next; 15081 } else if (parent[firstProp] === child) { 15082 parent[firstProp] = next; 15083 } 15084 15085 if (next) { 15086 next._prev = prev; 15087 } else if (parent[lastProp] === child) { 15088 parent[lastProp] = prev; 15089 } 15090 15091 child._next = child._prev = child.parent = null; // don't delete the _dp just so we can revert if necessary. But parent should be null to indicate the item isn't in a linked list. 15092}, 15093 _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) { 15094 child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove(child); 15095 child._act = 0; 15096}, 15097 _uncache = function _uncache(animation, child) { 15098 if (animation && (!child || child._end > animation._dur || child._start < 0)) { 15099 // performance optimization: if a child animation is passed in we should only uncache if that child EXTENDS the animation (its end time is beyond the end) 15100 var a = animation; 15101 15102 while (a) { 15103 a._dirty = 1; 15104 a = a.parent; 15105 } 15106 } 15107 15108 return animation; 15109}, 15110 _recacheAncestors = function _recacheAncestors(animation) { 15111 var parent = animation.parent; 15112 15113 while (parent && parent.parent) { 15114 //sometimes we must force a re-sort of all children and update the duration/totalDuration of all ancestor timelines immediately in case, for example, in the middle of a render loop, one tween alters another tween's timeScale which shoves its startTime before 0, forcing the parent timeline to shift around and shiftChildren() which could affect that next tween's render (startTime). Doesn't matter for the root timeline though. 15115 parent._dirty = 1; 15116 parent.totalDuration(); 15117 parent = parent.parent; 15118 } 15119 15120 return animation; 15121}, 15122 _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) { 15123 return !animation || animation._ts && _hasNoPausedAncestors(animation.parent); 15124}, 15125 _elapsedCycleDuration = function _elapsedCycleDuration(animation) { 15126 return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0; 15127}, 15128 // feed in the totalTime and cycleDuration and it'll return the cycle (iteration minus 1) and if the playhead is exactly at the very END, it will NOT bump up to the next cycle. 15129_animationCycle = function _animationCycle(tTime, cycleDuration) { 15130 var whole = Math.floor(tTime /= cycleDuration); 15131 return tTime && whole === tTime ? whole - 1 : whole; 15132}, 15133 _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) { 15134 return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur); 15135}, 15136 _setEnd = function _setEnd(animation) { 15137 return animation._end = _round(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0)); 15138}, 15139 _alignPlayhead = function _alignPlayhead(animation, totalTime) { 15140 // adjusts the animation's _start and _end according to the provided totalTime (only if the parent's smoothChildTiming is true and the animation isn't paused). It doesn't do any rendering or forcing things back into parent timelines, etc. - that's what totalTime() is for. 15141 var parent = animation._dp; 15142 15143 if (parent && parent.smoothChildTiming && animation._ts) { 15144 animation._start = _round(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts)); 15145 15146 _setEnd(animation); 15147 15148 parent._dirty || _uncache(parent, animation); //for performance improvement. If the parent's cache is already dirty, it already took care of marking the ancestors as dirty too, so skip the function call here. 15149 } 15150 15151 return animation; 15152}, 15153 15154/* 15155_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => { 15156 let cycleDuration = duration + repeatDelay, 15157 time = _round(clampedTotalTime % cycleDuration); 15158 if (time > duration) { 15159 time = duration; 15160 } 15161 return (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time; 15162}, 15163*/ 15164_postAddChecks = function _postAddChecks(timeline, child) { 15165 var t; 15166 15167 if (child._time || child._initted && !child._dur) { 15168 //in case, for example, the _start is moved on a tween that has already rendered. Imagine it's at its end state, then the startTime is moved WAY later (after the end of this timeline), it should render at its beginning. 15169 t = _parentToChildTotalTime(timeline.rawTime(), child); 15170 15171 if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) { 15172 child.render(t, true); 15173 } 15174 } //if the timeline has already ended but the inserted tween/timeline extends the duration, we should enable this timeline again so that it renders properly. We should also align the playhead with the parent timeline's when appropriate. 15175 15176 15177 if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) { 15178 //in case any of the ancestors had completed but should now be enabled... 15179 if (timeline._dur < timeline.duration()) { 15180 t = timeline; 15181 15182 while (t._dp) { 15183 t.rawTime() >= 0 && t.totalTime(t._tTime); //moves the timeline (shifts its startTime) if necessary, and also enables it. If it's currently zero, though, it may not be scheduled to render until later so there's no need to force it to align with the current playhead position. Only move to catch up with the playhead. 15184 15185 t = t._dp; 15186 } 15187 } 15188 15189 timeline._zTime = -_tinyNum; // helps ensure that the next render() will be forced (crossingStart = true in render()), even if the duration hasn't changed (we're adding a child which would need to get rendered). Definitely an edge case. Note: we MUST do this AFTER the loop above where the totalTime() might trigger a render() because this _addToTimeline() method gets called from the Animation constructor, BEFORE tweens even record their targets, etc. so we wouldn't want things to get triggered in the wrong order. 15190 } 15191}, 15192 _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) { 15193 child.parent && _removeFromParent(child); 15194 child._start = _round(position + child._delay); 15195 child._end = _round(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0)); 15196 15197 _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0); 15198 15199 timeline._recent = child; 15200 skipChecks || _postAddChecks(timeline, child); 15201 return timeline; 15202}, 15203 _scrollTrigger = function _scrollTrigger(animation, trigger) { 15204 return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation); 15205}, 15206 _attemptInitTween = function _attemptInitTween(tween, totalTime, force, suppressEvents) { 15207 _initTween(tween, totalTime); 15208 15209 if (!tween._initted) { 15210 return 1; 15211 } 15212 15213 if (!force && tween._pt && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) { 15214 _lazyTweens.push(tween); 15215 15216 tween._lazy = [totalTime, suppressEvents]; 15217 return 1; 15218 } 15219}, 15220 _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) { 15221 var parent = _ref.parent; 15222 return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent)); 15223}, 15224 // check parent's _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn't force the ratio back to 0 15225_renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) { 15226 var prevRatio = tween.ratio, 15227 ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) || (tween._ts < 0 || tween._dp._ts < 0) && tween.data !== "isFromStart" && tween.data !== "isStart") ? 0 : 1, 15228 // if the tween or its parent is reversed and the totalTime is 0, we should go to a ratio of 0. 15229 repeatDelay = tween._rDelay, 15230 tTime = 0, 15231 pt, 15232 iteration, 15233 prevIteration; 15234 15235 if (repeatDelay && tween._repeat) { 15236 // in case there's a zero-duration tween that has a repeat with a repeatDelay 15237 tTime = _clamp(0, tween._tDur, totalTime); 15238 iteration = _animationCycle(tTime, repeatDelay); 15239 prevIteration = _animationCycle(tween._tTime, repeatDelay); 15240 tween._yoyo && iteration & 1 && (ratio = 1 - ratio); 15241 15242 if (iteration !== prevIteration) { 15243 prevRatio = 1 - ratio; 15244 tween.vars.repeatRefresh && tween._initted && tween.invalidate(); 15245 } 15246 } 15247 15248 if (ratio !== prevRatio || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) { 15249 if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents)) { 15250 // if we render the very beginning (time == 0) of a fromTo(), we must force the render (normal tweens wouldn't need to render at a time of 0 when the prevTime was also 0). This is also mandatory to make sure overwriting kicks in immediately. 15251 return; 15252 } 15253 15254 prevIteration = tween._zTime; 15255 tween._zTime = totalTime || (suppressEvents ? _tinyNum : 0); // when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration tween, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. 15256 15257 suppressEvents || (suppressEvents = totalTime && !prevIteration); // if it was rendered previously at exactly 0 (_zTime) and now the playhead is moving away, DON'T fire callbacks otherwise they'll seem like duplicates. 15258 15259 tween.ratio = ratio; 15260 tween._from && (ratio = 1 - ratio); 15261 tween._time = 0; 15262 tween._tTime = tTime; 15263 suppressEvents || _callback(tween, "onStart"); 15264 pt = tween._pt; 15265 15266 while (pt) { 15267 pt.r(ratio, pt.d); 15268 pt = pt._next; 15269 } 15270 15271 tween._startAt && totalTime < 0 && tween._startAt.render(totalTime, true, true); 15272 tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate"); 15273 tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat"); 15274 15275 if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) { 15276 ratio && _removeFromParent(tween, 1); 15277 15278 if (!suppressEvents) { 15279 _callback(tween, ratio ? "onComplete" : "onReverseComplete", true); 15280 15281 tween._prom && tween._prom(); 15282 } 15283 } 15284 } else if (!tween._zTime) { 15285 tween._zTime = totalTime; 15286 } 15287}, 15288 _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) { 15289 var child; 15290 15291 if (time > prevTime) { 15292 child = animation._first; 15293 15294 while (child && child._start <= time) { 15295 if (!child._dur && child.data === "isPause" && child._start > prevTime) { 15296 return child; 15297 } 15298 15299 child = child._next; 15300 } 15301 } else { 15302 child = animation._last; 15303 15304 while (child && child._start >= time) { 15305 if (!child._dur && child.data === "isPause" && child._start < prevTime) { 15306 return child; 15307 } 15308 15309 child = child._prev; 15310 } 15311 } 15312}, 15313 _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) { 15314 var repeat = animation._repeat, 15315 dur = _round(duration) || 0, 15316 totalProgress = animation._tTime / animation._tDur; 15317 totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur); 15318 animation._dur = dur; 15319 animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _round(dur * (repeat + 1) + animation._rDelay * repeat); 15320 totalProgress && !leavePlayhead ? _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress) : animation.parent && _setEnd(animation); 15321 skipUncache || _uncache(animation.parent, animation); 15322 return animation; 15323}, 15324 _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) { 15325 return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur); 15326}, 15327 _zeroPosition = { 15328 _start: 0, 15329 endTime: _emptyFunc 15330}, 15331 _parsePosition = function _parsePosition(animation, position) { 15332 var labels = animation.labels, 15333 recent = animation._recent || _zeroPosition, 15334 clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur, 15335 //in case there's a child that infinitely repeats, users almost never intend for the insertion point of a new child to be based on a SUPER long value like that so we clip it and assume the most recently-added child's endTime should be used instead. 15336 i, 15337 offset; 15338 15339 if (_isString(position) && (isNaN(position) || position in labels)) { 15340 //if the string is a number like "1", check to see if there's a label with that name, otherwise interpret it as a number (absolute value). 15341 i = position.charAt(0); 15342 15343 if (i === "<" || i === ">") { 15344 return (i === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0); 15345 } 15346 15347 i = position.indexOf("="); 15348 15349 if (i < 0) { 15350 position in labels || (labels[position] = clippedDuration); 15351 return labels[position]; 15352 } 15353 15354 offset = +(position.charAt(i - 1) + position.substr(i + 1)); 15355 return i > 1 ? _parsePosition(animation, position.substr(0, i - 1)) + offset : clippedDuration + offset; 15356 } 15357 15358 return position == null ? clippedDuration : +position; 15359}, 15360 _conditionalReturn = function _conditionalReturn(value, func) { 15361 return value || value === 0 ? func(value) : func; 15362}, 15363 _clamp = function _clamp(min, max, value) { 15364 return value < min ? min : value > max ? max : value; 15365}, 15366 getUnit = function getUnit(value) { 15367 if (typeof value !== "string") { 15368 return ""; 15369 } 15370 15371 var v = _unitExp.exec(value); 15372 15373 return v ? value.substr(v.index + v[0].length) : ""; 15374}, 15375 // note: protect against padded numbers as strings, like "100.100". That shouldn't return "00" as the unit. If it's numeric, return no unit. 15376clamp = function clamp(min, max, value) { 15377 return _conditionalReturn(value, function (v) { 15378 return _clamp(min, max, v); 15379 }); 15380}, 15381 _slice = [].slice, 15382 _isArrayLike = function _isArrayLike(value, nonEmpty) { 15383 return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win; 15384}, 15385 _flatten = function _flatten(ar, leaveStrings, accumulator) { 15386 if (accumulator === void 0) { 15387 accumulator = []; 15388 } 15389 15390 return ar.forEach(function (value) { 15391 var _accumulator; 15392 15393 return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value); 15394 }) || accumulator; 15395}, 15396 //takes any value and returns an array. If it's a string (and leaveStrings isn't true), it'll use document.querySelectorAll() and convert that to an array. It'll also accept iterables like jQuery objects. 15397toArray = function toArray(value, leaveStrings) { 15398 return _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call(_doc.querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : []; 15399}, 15400 shuffle = function shuffle(a) { 15401 return a.sort(function () { 15402 return .5 - Math.random(); 15403 }); 15404}, 15405 // alternative that's a bit faster and more reliably diverse but bigger: for (let j, v, i = a.length; i; j = Math.floor(Math.random() * i), v = a[--i], a[i] = a[j], a[j] = v); return a; 15406//for distributing values across an array. Can accept a number, a function or (most commonly) a function which can contain the following properties: {base, amount, from, ease, grid, axis, length, each}. Returns a function that expects the following parameters: index, target, array. Recognizes the following 15407distribute = function distribute(v) { 15408 if (_isFunction(v)) { 15409 return v; 15410 } 15411 15412 var vars = _isObject(v) ? v : { 15413 each: v 15414 }, 15415 //n:1 is just to indicate v was a number; we leverage that later to set v according to the length we get. If a number is passed in, we treat it like the old stagger value where 0.1, for example, would mean that things would be distributed with 0.1 between each element in the array rather than a total "amount" that's chunked out among them all. 15416 ease = _parseEase(vars.ease), 15417 from = vars.from || 0, 15418 base = parseFloat(vars.base) || 0, 15419 cache = {}, 15420 isDecimal = from > 0 && from < 1, 15421 ratios = isNaN(from) || isDecimal, 15422 axis = vars.axis, 15423 ratioX = from, 15424 ratioY = from; 15425 15426 if (_isString(from)) { 15427 ratioX = ratioY = { 15428 center: .5, 15429 edges: .5, 15430 end: 1 15431 }[from] || 0; 15432 } else if (!isDecimal && ratios) { 15433 ratioX = from[0]; 15434 ratioY = from[1]; 15435 } 15436 15437 return function (i, target, a) { 15438 var l = (a || vars).length, 15439 distances = cache[l], 15440 originX, 15441 originY, 15442 x, 15443 y, 15444 d, 15445 j, 15446 max, 15447 min, 15448 wrapAt; 15449 15450 if (!distances) { 15451 wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1]; 15452 15453 if (!wrapAt) { 15454 max = -_bigNum; 15455 15456 while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {} 15457 15458 wrapAt--; 15459 } 15460 15461 distances = cache[l] = []; 15462 originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt; 15463 originY = ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0; 15464 max = 0; 15465 min = _bigNum; 15466 15467 for (j = 0; j < l; j++) { 15468 x = j % wrapAt - originX; 15469 y = originY - (j / wrapAt | 0); 15470 distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x); 15471 d > max && (max = d); 15472 d < min && (min = d); 15473 } 15474 15475 from === "random" && shuffle(distances); 15476 distances.max = max - min; 15477 distances.min = min; 15478 distances.v = l = (parseFloat(vars.amount) || parseFloat(vars.each) * (wrapAt > l ? l - 1 : !axis ? Math.max(wrapAt, l / wrapAt) : axis === "y" ? l / wrapAt : wrapAt) || 0) * (from === "edges" ? -1 : 1); 15479 distances.b = l < 0 ? base - l : base; 15480 distances.u = getUnit(vars.amount || vars.each) || 0; //unit 15481 15482 ease = ease && l < 0 ? _invertEase(ease) : ease; 15483 } 15484 15485 l = (distances[i] - distances.min) / distances.max || 0; 15486 return _round(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors 15487 }; 15488}, 15489 _roundModifier = function _roundModifier(v) { 15490 //pass in 0.1 get a function that'll round to the nearest tenth, or 5 to round to the closest 5, or 0.001 to the closest 1000th, etc. 15491 var p = v < 1 ? Math.pow(10, (v + "").length - 2) : 1; //to avoid floating point math errors (like 24 * 0.1 == 2.4000000000000004), we chop off at a specific number of decimal places (much faster than toFixed() 15492 15493 return function (raw) { 15494 var n = Math.round(parseFloat(raw) / v) * v * p; 15495 return (n - n % 1) / p + (_isNumber(raw) ? 0 : getUnit(raw)); // n - n % 1 replaces Math.floor() in order to handle negative values properly. For example, Math.floor(-150.00000000000003) is 151! 15496 }; 15497}, 15498 snap = function snap(snapTo, value) { 15499 var isArray = _isArray(snapTo), 15500 radius, 15501 is2D; 15502 15503 if (!isArray && _isObject(snapTo)) { 15504 radius = isArray = snapTo.radius || _bigNum; 15505 15506 if (snapTo.values) { 15507 snapTo = toArray(snapTo.values); 15508 15509 if (is2D = !_isNumber(snapTo[0])) { 15510 radius *= radius; //performance optimization so we don't have to Math.sqrt() in the loop. 15511 } 15512 } else { 15513 snapTo = _roundModifier(snapTo.increment); 15514 } 15515 } 15516 15517 return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) { 15518 is2D = snapTo(raw); 15519 return Math.abs(is2D - raw) <= radius ? is2D : raw; 15520 } : function (raw) { 15521 var x = parseFloat(is2D ? raw.x : raw), 15522 y = parseFloat(is2D ? raw.y : 0), 15523 min = _bigNum, 15524 closest = 0, 15525 i = snapTo.length, 15526 dx, 15527 dy; 15528 15529 while (i--) { 15530 if (is2D) { 15531 dx = snapTo[i].x - x; 15532 dy = snapTo[i].y - y; 15533 dx = dx * dx + dy * dy; 15534 } else { 15535 dx = Math.abs(snapTo[i] - x); 15536 } 15537 15538 if (dx < min) { 15539 min = dx; 15540 closest = i; 15541 } 15542 } 15543 15544 closest = !radius || min <= radius ? snapTo[closest] : raw; 15545 return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw); 15546 }); 15547}, 15548 random = function random(min, max, roundingIncrement, returnFunction) { 15549 return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () { 15550 return _isArray(min) ? min[~~(Math.random() * min.length)] : (roundingIncrement = roundingIncrement || 1e-5) && (returnFunction = roundingIncrement < 1 ? Math.pow(10, (roundingIncrement + "").length - 2) : 1) && Math.floor(Math.round((min - roundingIncrement / 2 + Math.random() * (max - min + roundingIncrement * .99)) / roundingIncrement) * roundingIncrement * returnFunction) / returnFunction; 15551 }); 15552}, 15553 pipe = function pipe() { 15554 for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) { 15555 functions[_key] = arguments[_key]; 15556 } 15557 15558 return function (value) { 15559 return functions.reduce(function (v, f) { 15560 return f(v); 15561 }, value); 15562 }; 15563}, 15564 unitize = function unitize(func, unit) { 15565 return function (value) { 15566 return func(parseFloat(value)) + (unit || getUnit(value)); 15567 }; 15568}, 15569 normalize = function normalize(min, max, value) { 15570 return mapRange(min, max, 0, 1, value); 15571}, 15572 _wrapArray = function _wrapArray(a, wrapper, value) { 15573 return _conditionalReturn(value, function (index) { 15574 return a[~~wrapper(index)]; 15575 }); 15576}, 15577 wrap = function wrap(min, max, value) { 15578 // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug causes problems (unrelated to GSAP). 15579 var range = max - min; 15580 return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) { 15581 return (range + (value - min) % range) % range + min; 15582 }); 15583}, 15584 wrapYoyo = function wrapYoyo(min, max, value) { 15585 var range = max - min, 15586 total = range * 2; 15587 return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) { 15588 value = (total + (value - min) % total) % total || 0; 15589 return min + (value > range ? total - value : value); 15590 }); 15591}, 15592 _replaceRandom = function _replaceRandom(value) { 15593 //replaces all occurrences of random(...) in a string with the calculated random value. can be a range like random(-100, 100, 5) or an array like random([0, 100, 500]) 15594 var prev = 0, 15595 s = "", 15596 i, 15597 nums, 15598 end, 15599 isArray; 15600 15601 while (~(i = value.indexOf("random(", prev))) { 15602 end = value.indexOf(")", i); 15603 isArray = value.charAt(i + 7) === "["; 15604 nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp); 15605 s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5); 15606 prev = end + 1; 15607 } 15608 15609 return s + value.substr(prev, value.length - prev); 15610}, 15611 mapRange = function mapRange(inMin, inMax, outMin, outMax, value) { 15612 var inRange = inMax - inMin, 15613 outRange = outMax - outMin; 15614 return _conditionalReturn(value, function (value) { 15615 return outMin + ((value - inMin) / inRange * outRange || 0); 15616 }); 15617}, 15618 interpolate = function interpolate(start, end, progress, mutate) { 15619 var func = isNaN(start + end) ? 0 : function (p) { 15620 return (1 - p) * start + p * end; 15621 }; 15622 15623 if (!func) { 15624 var isString = _isString(start), 15625 master = {}, 15626 p, 15627 i, 15628 interpolators, 15629 l, 15630 il; 15631 15632 progress === true && (mutate = 1) && (progress = null); 15633 15634 if (isString) { 15635 start = { 15636 p: start 15637 }; 15638 end = { 15639 p: end 15640 }; 15641 } else if (_isArray(start) && !_isArray(end)) { 15642 interpolators = []; 15643 l = start.length; 15644 il = l - 2; 15645 15646 for (i = 1; i < l; i++) { 15647 interpolators.push(interpolate(start[i - 1], start[i])); //build the interpolators up front as a performance optimization so that when the function is called many times, it can just reuse them. 15648 } 15649 15650 l--; 15651 15652 func = function func(p) { 15653 p *= l; 15654 var i = Math.min(il, ~~p); 15655 return interpolators[i](p - i); 15656 }; 15657 15658 progress = end; 15659 } else if (!mutate) { 15660 start = _merge(_isArray(start) ? [] : {}, start); 15661 } 15662 15663 if (!interpolators) { 15664 for (p in end) { 15665 _addPropTween.call(master, start, p, "get", end[p]); 15666 } 15667 15668 func = function func(p) { 15669 return _renderPropTweens(p, master) || (isString ? start.p : start); 15670 }; 15671 } 15672 } 15673 15674 return _conditionalReturn(progress, func); 15675}, 15676 _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) { 15677 //used for nextLabel() and previousLabel() 15678 var labels = timeline.labels, 15679 min = _bigNum, 15680 p, 15681 distance, 15682 label; 15683 15684 for (p in labels) { 15685 distance = labels[p] - fromTime; 15686 15687 if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) { 15688 label = p; 15689 min = distance; 15690 } 15691 } 15692 15693 return label; 15694}, 15695 _callback = function _callback(animation, type, executeLazyFirst) { 15696 var v = animation.vars, 15697 callback = v[type], 15698 params, 15699 scope; 15700 15701 if (!callback) { 15702 return; 15703 } 15704 15705 params = v[type + "Params"]; 15706 scope = v.callbackScope || animation; 15707 executeLazyFirst && _lazyTweens.length && _lazyRender(); //in case rendering caused any tweens to lazy-init, we should render them because typically when a timeline finishes, users expect things to have rendered fully. Imagine an onUpdate on a timeline that reports/checks tweened values. 15708 15709 return params ? callback.apply(scope, params) : callback.call(scope); 15710}, 15711 _interrupt = function _interrupt(animation) { 15712 _removeFromParent(animation); 15713 15714 animation.progress() < 1 && _callback(animation, "onInterrupt"); 15715 return animation; 15716}, 15717 _quickTween, 15718 _createPlugin = function _createPlugin(config) { 15719 config = !config.name && config["default"] || config; //UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}. 15720 15721 var name = config.name, 15722 isFunc = _isFunction(config), 15723 Plugin = name && !isFunc && config.init ? function () { 15724 this._props = []; 15725 } : config, 15726 //in case someone passes in an object that's not a plugin, like CustomEase 15727 instanceDefaults = { 15728 init: _emptyFunc, 15729 render: _renderPropTweens, 15730 add: _addPropTween, 15731 kill: _killPropTweensOf, 15732 modifier: _addPluginModifier, 15733 rawVars: 0 15734 }, 15735 statics = { 15736 targetTest: 0, 15737 get: 0, 15738 getSetter: _getSetter, 15739 aliases: {}, 15740 register: 0 15741 }; 15742 15743 _wake(); 15744 15745 if (config !== Plugin) { 15746 if (_plugins[name]) { 15747 return; 15748 } 15749 15750 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods 15751 15752 15753 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods 15754 15755 15756 _plugins[Plugin.prop = name] = Plugin; 15757 15758 if (config.targetTest) { 15759 _harnessPlugins.push(Plugin); 15760 15761 _reservedProps[name] = 1; 15762 } 15763 15764 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; //for the global name. "motionPath" should become MotionPathPlugin 15765 } 15766 15767 _addGlobal(name, Plugin); 15768 15769 config.register && config.register(gsap, Plugin, PropTween); 15770}, 15771 15772/* 15773 * -------------------------------------------------------------------------------------- 15774 * COLORS 15775 * -------------------------------------------------------------------------------------- 15776 */ 15777_255 = 255, 15778 _colorLookup = { 15779 aqua: [0, _255, _255], 15780 lime: [0, _255, 0], 15781 silver: [192, 192, 192], 15782 black: [0, 0, 0], 15783 maroon: [128, 0, 0], 15784 teal: [0, 128, 128], 15785 blue: [0, 0, _255], 15786 navy: [0, 0, 128], 15787 white: [_255, _255, _255], 15788 olive: [128, 128, 0], 15789 yellow: [_255, _255, 0], 15790 orange: [_255, 165, 0], 15791 gray: [128, 128, 128], 15792 purple: [128, 0, 128], 15793 green: [0, 128, 0], 15794 red: [_255, 0, 0], 15795 pink: [_255, 192, 203], 15796 cyan: [0, _255, _255], 15797 transparent: [_255, _255, _255, 0] 15798}, 15799 _hue = function _hue(h, m1, m2) { 15800 h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; 15801 return (h * 6 < 1 ? m1 + (m2 - m1) * h * 6 : h < .5 ? m2 : h * 3 < 2 ? m1 + (m2 - m1) * (2 / 3 - h) * 6 : m1) * _255 + .5 | 0; 15802}, 15803 splitColor = function splitColor(v, toHSL, forceAlpha) { 15804 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 15805 r, 15806 g, 15807 b, 15808 h, 15809 s, 15810 l, 15811 max, 15812 min, 15813 d, 15814 wasHSL; 15815 15816 if (!a) { 15817 if (v.substr(-1) === ",") { 15818 //sometimes a trailing comma is included and we should chop it off (typically from a comma-delimited list of values like a textShadow:"2px 2px 2px blue, 5px 5px 5px rgb(255,0,0)" - in this example "blue," has a trailing comma. We could strip it out inside parseComplex() but we'd need to do it to the beginning and ending values plus it wouldn't provide protection from other potential scenarios like if the user passes in a similar value. 15819 v = v.substr(0, v.length - 1); 15820 } 15821 15822 if (_colorLookup[v]) { 15823 a = _colorLookup[v]; 15824 } else if (v.charAt(0) === "#") { 15825 if (v.length < 6) { 15826 //for shorthand like #9F0 or #9F0F (could have alpha) 15827 r = v.charAt(1); 15828 g = v.charAt(2); 15829 b = v.charAt(3); 15830 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 15831 } 15832 15833 if (v.length === 9) { 15834 // hex with alpha, like #fd5e53ff 15835 a = parseInt(v.substr(1, 6), 16); 15836 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 15837 } 15838 15839 v = parseInt(v.substr(1), 16); 15840 a = [v >> 16, v >> 8 & _255, v & _255]; 15841 } else if (v.substr(0, 3) === "hsl") { 15842 a = wasHSL = v.match(_strictNumExp); 15843 15844 if (!toHSL) { 15845 h = +a[0] % 360 / 360; 15846 s = +a[1] / 100; 15847 l = +a[2] / 100; 15848 g = l <= .5 ? l * (s + 1) : l + s - l * s; 15849 r = l * 2 - g; 15850 a.length > 3 && (a[3] *= 1); //cast as number 15851 15852 a[0] = _hue(h + 1 / 3, r, g); 15853 a[1] = _hue(h, r, g); 15854 a[2] = _hue(h - 1 / 3, r, g); 15855 } else if (~v.indexOf("=")) { 15856 //if relative values are found, just return the raw strings with the relative prefixes in place. 15857 a = v.match(_numExp); 15858 forceAlpha && a.length < 4 && (a[3] = 1); 15859 return a; 15860 } 15861 } else { 15862 a = v.match(_strictNumExp) || _colorLookup.transparent; 15863 } 15864 15865 a = a.map(Number); 15866 } 15867 15868 if (toHSL && !wasHSL) { 15869 r = a[0] / _255; 15870 g = a[1] / _255; 15871 b = a[2] / _255; 15872 max = Math.max(r, g, b); 15873 min = Math.min(r, g, b); 15874 l = (max + min) / 2; 15875 15876 if (max === min) { 15877 h = s = 0; 15878 } else { 15879 d = max - min; 15880 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 15881 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 15882 h *= 60; 15883 } 15884 15885 a[0] = ~~(h + .5); 15886 a[1] = ~~(s * 100 + .5); 15887 a[2] = ~~(l * 100 + .5); 15888 } 15889 15890 forceAlpha && a.length < 4 && (a[3] = 1); 15891 return a; 15892}, 15893 _colorOrderData = function _colorOrderData(v) { 15894 // strips out the colors from the string, finds all the numeric slots (with units) and returns an array of those. The Array also has a "c" property which is an Array of the index values where the colors belong. This is to help work around issues where there's a mis-matched order of color/numeric data like drop-shadow(#f00 0px 1px 2px) and drop-shadow(0x 1px 2px #f00). This is basically a helper function used in _formatColors() 15895 var values = [], 15896 c = [], 15897 i = -1; 15898 v.split(_colorExp).forEach(function (v) { 15899 var a = v.match(_numWithUnitExp) || []; 15900 values.push.apply(values, a); 15901 c.push(i += a.length + 1); 15902 }); 15903 values.c = c; 15904 return values; 15905}, 15906 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 15907 var result = "", 15908 colors = (s + result).match(_colorExp), 15909 type = toHSL ? "hsla(" : "rgba(", 15910 i = 0, 15911 c, 15912 shell, 15913 d, 15914 l; 15915 15916 if (!colors) { 15917 return s; 15918 } 15919 15920 colors = colors.map(function (color) { 15921 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 15922 }); 15923 15924 if (orderMatchData) { 15925 d = _colorOrderData(s); 15926 c = orderMatchData.c; 15927 15928 if (c.join(result) !== d.c.join(result)) { 15929 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 15930 l = shell.length - 1; 15931 15932 for (; i < l; i++) { 15933 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 15934 } 15935 } 15936 } 15937 15938 if (!shell) { 15939 shell = s.split(_colorExp); 15940 l = shell.length - 1; 15941 15942 for (; i < l; i++) { 15943 result += shell[i] + colors[i]; 15944 } 15945 } 15946 15947 return result + shell[l]; 15948}, 15949 _colorExp = function () { 15950 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 15951 //we'll dynamically build this Regular Expression to conserve file size. After building it, it will be able to find rgb(), rgba(), # (hexadecimal), and named color values like red, blue, purple, etc., 15952 p; 15953 15954 for (p in _colorLookup) { 15955 s += "|" + p + "\\b"; 15956 } 15957 15958 return new RegExp(s + ")", "gi"); 15959}(), 15960 _hslExp = /hsl[a]?\(/, 15961 _colorStringFilter = function _colorStringFilter(a) { 15962 var combined = a.join(" "), 15963 toHSL; 15964 _colorExp.lastIndex = 0; 15965 15966 if (_colorExp.test(combined)) { 15967 toHSL = _hslExp.test(combined); 15968 a[1] = _formatColors(a[1], toHSL); 15969 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value. 15970 15971 return true; 15972 } 15973}, 15974 15975/* 15976 * -------------------------------------------------------------------------------------- 15977 * TICKER 15978 * -------------------------------------------------------------------------------------- 15979 */ 15980_tickerActive, 15981 _ticker = function () { 15982 var _getTime = Date.now, 15983 _lagThreshold = 500, 15984 _adjustedLag = 33, 15985 _startTime = _getTime(), 15986 _lastUpdate = _startTime, 15987 _gap = 1000 / 240, 15988 _nextTime = _gap, 15989 _listeners = [], 15990 _id, 15991 _req, 15992 _raf, 15993 _self, 15994 _delta, 15995 _i, 15996 _tick = function _tick(v) { 15997 var elapsed = _getTime() - _lastUpdate, 15998 manual = v === true, 15999 overlap, 16000 dispatch, 16001 time, 16002 frame; 16003 16004 elapsed > _lagThreshold && (_startTime += elapsed - _adjustedLag); 16005 _lastUpdate += elapsed; 16006 time = _lastUpdate - _startTime; 16007 overlap = time - _nextTime; 16008 16009 if (overlap > 0 || manual) { 16010 frame = ++_self.frame; 16011 _delta = time - _self.time * 1000; 16012 _self.time = time = time / 1000; 16013 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 16014 dispatch = 1; 16015 } 16016 16017 manual || (_id = _req(_tick)); //make sure the request is made before we dispatch the "tick" event so that timing is maintained. Otherwise, if processing the "tick" requires a bunch of time (like 15ms) and we're using a setTimeout() that's based on 16.7ms, it'd technically take 31.7ms between frames otherwise. 16018 16019 if (dispatch) { 16020 for (_i = 0; _i < _listeners.length; _i++) { 16021 // use _i and check _listeners.length instead of a variable because a listener could get removed during the loop, and if that happens to an element less than the current index, it'd throw things off in the loop. 16022 _listeners[_i](time, _delta, frame, v); 16023 } 16024 } 16025 }; 16026 16027 _self = { 16028 time: 0, 16029 frame: 0, 16030 tick: function tick() { 16031 _tick(true); 16032 }, 16033 deltaRatio: function deltaRatio(fps) { 16034 return _delta / (1000 / (fps || 60)); 16035 }, 16036 wake: function wake() { 16037 if (_coreReady) { 16038 if (!_coreInitted && _windowExists()) { 16039 _win = _coreInitted = window; 16040 _doc = _win.document || {}; 16041 _globals.gsap = gsap; 16042 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 16043 16044 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 16045 16046 _raf = _win.requestAnimationFrame; 16047 } 16048 16049 _id && _self.sleep(); 16050 16051 _req = _raf || function (f) { 16052 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 16053 }; 16054 16055 _tickerActive = 1; 16056 16057 _tick(2); 16058 } 16059 }, 16060 sleep: function sleep() { 16061 (_raf ? _win.cancelAnimationFrame : clearTimeout)(_id); 16062 _tickerActive = 0; 16063 _req = _emptyFunc; 16064 }, 16065 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 16066 _lagThreshold = threshold || 1 / _tinyNum; //zero should be interpreted as basically unlimited 16067 16068 _adjustedLag = Math.min(adjustedLag, _lagThreshold, 0); 16069 }, 16070 fps: function fps(_fps) { 16071 _gap = 1000 / (_fps || 240); 16072 _nextTime = _self.time * 1000 + _gap; 16073 }, 16074 add: function add(callback) { 16075 _listeners.indexOf(callback) < 0 && _listeners.push(callback); 16076 16077 _wake(); 16078 }, 16079 remove: function remove(callback) { 16080 var i; 16081 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 16082 }, 16083 _listeners: _listeners 16084 }; 16085 return _self; 16086}(), 16087 _wake = function _wake() { 16088 return !_tickerActive && _ticker.wake(); 16089}, 16090 //also ensures the core classes are initialized. 16091 16092/* 16093* ------------------------------------------------- 16094* EASING 16095* ------------------------------------------------- 16096*/ 16097_easeMap = {}, 16098 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 16099 _quotesExp = /["']/g, 16100 _parseObjectInString = function _parseObjectInString(value) { 16101 //takes a string like "{wiggles:10, type:anticipate})" and turns it into a real object. Notice it ends in ")" and includes the {} wrappers. This is because we only use this function for parsing ease configs and prioritized optimization rather than reusability. 16102 var obj = {}, 16103 split = value.substr(1, value.length - 3).split(":"), 16104 key = split[0], 16105 i = 1, 16106 l = split.length, 16107 index, 16108 val, 16109 parsedVal; 16110 16111 for (; i < l; i++) { 16112 val = split[i]; 16113 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 16114 parsedVal = val.substr(0, index); 16115 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 16116 key = val.substr(index + 1).trim(); 16117 } 16118 16119 return obj; 16120}, 16121 _valueInParentheses = function _valueInParentheses(value) { 16122 var open = value.indexOf("(") + 1, 16123 close = value.indexOf(")"), 16124 nested = value.indexOf("(", open); 16125 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 16126}, 16127 _configEaseFromString = function _configEaseFromString(name) { 16128 //name can be a string like "elastic.out(1,0.5)", and pass in _easeMap as obj and it'll parse it out and call the actual function like _easeMap.Elastic.easeOut.config(1,0.5). It will also parse custom ease strings as long as CustomEase is loaded and registered (internally as _easeMap._CE). 16129 var split = (name + "").split("("), 16130 ease = _easeMap[split[0]]; 16131 return ease && split.length > 1 && ease.config ? ease.config.apply(null, ~name.indexOf("{") ? [_parseObjectInString(split[1])] : _valueInParentheses(name).split(",").map(_numericIfPossible)) : _easeMap._CE && _customEaseExp.test(name) ? _easeMap._CE("", name) : ease; 16132}, 16133 _invertEase = function _invertEase(ease) { 16134 return function (p) { 16135 return 1 - ease(1 - p); 16136 }; 16137}, 16138 // allow yoyoEase to be set in children and have those affected when the parent/ancestor timeline yoyos. 16139_propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 16140 var child = timeline._first, 16141 ease; 16142 16143 while (child) { 16144 if (child instanceof Timeline) { 16145 _propagateYoyoEase(child, isYoyo); 16146 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 16147 if (child.timeline) { 16148 _propagateYoyoEase(child.timeline, isYoyo); 16149 } else { 16150 ease = child._ease; 16151 child._ease = child._yEase; 16152 child._yEase = ease; 16153 child._yoyo = isYoyo; 16154 } 16155 } 16156 16157 child = child._next; 16158 } 16159}, 16160 _parseEase = function _parseEase(ease, defaultEase) { 16161 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 16162}, 16163 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 16164 if (easeOut === void 0) { 16165 easeOut = function easeOut(p) { 16166 return 1 - easeIn(1 - p); 16167 }; 16168 } 16169 16170 if (easeInOut === void 0) { 16171 easeInOut = function easeInOut(p) { 16172 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 16173 }; 16174 } 16175 16176 var ease = { 16177 easeIn: easeIn, 16178 easeOut: easeOut, 16179 easeInOut: easeInOut 16180 }, 16181 lowercaseName; 16182 16183 _forEachName(names, function (name) { 16184 _easeMap[name] = _globals[name] = ease; 16185 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 16186 16187 for (var p in ease) { 16188 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 16189 } 16190 }); 16191 16192 return ease; 16193}, 16194 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 16195 return function (p) { 16196 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 16197 }; 16198}, 16199 _configElastic = function _configElastic(type, amplitude, period) { 16200 var p1 = amplitude >= 1 ? amplitude : 1, 16201 //note: if amplitude is < 1, we simply adjust the period for a more natural feel. Otherwise the math doesn't work right and the curve starts at 1. 16202 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 16203 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 16204 easeOut = function easeOut(p) { 16205 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 16206 }, 16207 ease = type === "out" ? easeOut : type === "in" ? function (p) { 16208 return 1 - easeOut(1 - p); 16209 } : _easeInOutFromOut(easeOut); 16210 16211 p2 = _2PI / p2; //precalculate to optimize 16212 16213 ease.config = function (amplitude, period) { 16214 return _configElastic(type, amplitude, period); 16215 }; 16216 16217 return ease; 16218}, 16219 _configBack = function _configBack(type, overshoot) { 16220 if (overshoot === void 0) { 16221 overshoot = 1.70158; 16222 } 16223 16224 var easeOut = function easeOut(p) { 16225 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 16226 }, 16227 ease = type === "out" ? easeOut : type === "in" ? function (p) { 16228 return 1 - easeOut(1 - p); 16229 } : _easeInOutFromOut(easeOut); 16230 16231 ease.config = function (overshoot) { 16232 return _configBack(type, overshoot); 16233 }; 16234 16235 return ease; 16236}; // a cheaper (kb and cpu) but more mild way to get a parameterized weighted ease by feeding in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear. 16237// _weightedEase = ratio => { 16238// let y = 0.5 + ratio / 2; 16239// return p => (2 * (1 - p) * p * y + p * p); 16240// }, 16241// a stronger (but more expensive kb/cpu) parameterized weighted ease that lets you feed in a value between -1 (easeIn) and 1 (easeOut) where 0 is linear. 16242// _weightedEaseStrong = ratio => { 16243// ratio = .5 + ratio / 2; 16244// let o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio), 16245// b = ratio - o, 16246// c = ratio + o; 16247// return p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p; 16248// }; 16249 16250 16251_forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 16252 var power = i < 5 ? i + 1 : i; 16253 16254 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 16255 return Math.pow(p, power); 16256 } : function (p) { 16257 return p; 16258 }, function (p) { 16259 return 1 - Math.pow(1 - p, power); 16260 }, function (p) { 16261 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 16262 }); 16263}); 16264 16265_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 16266 16267_insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 16268 16269(function (n, c) { 16270 var n1 = 1 / c, 16271 n2 = 2 * n1, 16272 n3 = 2.5 * n1, 16273 easeOut = function easeOut(p) { 16274 return p < n1 ? n * p * p : p < n2 ? n * Math.pow(p - 1.5 / c, 2) + .75 : p < n3 ? n * (p -= 2.25 / c) * p + .9375 : n * Math.pow(p - 2.625 / c, 2) + .984375; 16275 }; 16276 16277 _insertEase("Bounce", function (p) { 16278 return 1 - easeOut(1 - p); 16279 }, easeOut); 16280})(7.5625, 2.75); 16281 16282_insertEase("Expo", function (p) { 16283 return p ? Math.pow(2, 10 * (p - 1)) : 0; 16284}); 16285 16286_insertEase("Circ", function (p) { 16287 return -(_sqrt(1 - p * p) - 1); 16288}); 16289 16290_insertEase("Sine", function (p) { 16291 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 16292}); 16293 16294_insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 16295 16296_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 16297 config: function config(steps, immediateStart) { 16298 if (steps === void 0) { 16299 steps = 1; 16300 } 16301 16302 var p1 = 1 / steps, 16303 p2 = steps + (immediateStart ? 0 : 1), 16304 p3 = immediateStart ? 1 : 0, 16305 max = 1 - _tinyNum; 16306 return function (p) { 16307 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 16308 }; 16309 } 16310}; 16311_defaults.ease = _easeMap["quad.out"]; 16312 16313_forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 16314 return _callbackNames += name + "," + name + "Params,"; 16315}); 16316/* 16317 * -------------------------------------------------------------------------------------- 16318 * CACHE 16319 * -------------------------------------------------------------------------------------- 16320 */ 16321 16322 16323var GSCache = function GSCache(target, harness) { 16324 this.id = _gsID++; 16325 target._gsap = this; 16326 this.target = target; 16327 this.harness = harness; 16328 this.get = harness ? harness.get : _getProperty; 16329 this.set = harness ? harness.getSetter : _getSetter; 16330}; 16331/* 16332 * -------------------------------------------------------------------------------------- 16333 * ANIMATION 16334 * -------------------------------------------------------------------------------------- 16335 */ 16336 16337var Animation = /*#__PURE__*/function () { 16338 function Animation(vars, time) { 16339 var parent = vars.parent || _globalTimeline; 16340 this.vars = vars; 16341 this._delay = +vars.delay || 0; 16342 16343 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 16344 // TODO: repeat: Infinity on a timeline's children must flag that timeline internally and affect its totalDuration, otherwise it'll stop in the negative direction when reaching the start. 16345 this._rDelay = vars.repeatDelay || 0; 16346 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 16347 } 16348 16349 this._ts = 1; 16350 16351 _setDuration(this, +vars.duration, 1, 1); 16352 16353 this.data = vars.data; 16354 _tickerActive || _ticker.wake(); 16355 parent && _addToTimeline(parent, this, time || time === 0 ? time : parent._time, 1); 16356 vars.reversed && this.reverse(); 16357 vars.paused && this.paused(true); 16358 } 16359 16360 var _proto = Animation.prototype; 16361 16362 _proto.delay = function delay(value) { 16363 if (value || value === 0) { 16364 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 16365 this._delay = value; 16366 return this; 16367 } 16368 16369 return this._delay; 16370 }; 16371 16372 _proto.duration = function duration(value) { 16373 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 16374 }; 16375 16376 _proto.totalDuration = function totalDuration(value) { 16377 if (!arguments.length) { 16378 return this._tDur; 16379 } 16380 16381 this._dirty = 0; 16382 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 16383 }; 16384 16385 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 16386 _wake(); 16387 16388 if (!arguments.length) { 16389 return this._tTime; 16390 } 16391 16392 var parent = this._dp; 16393 16394 if (parent && parent.smoothChildTiming && this._ts) { 16395 _alignPlayhead(this, _totalTime); 16396 16397 !parent._dp || parent.parent || _postAddChecks(parent, this); // edge case: if this is a child of a timeline that already completed, for example, we must re-activate the parent. 16398 //in case any of the ancestor timelines had completed but should now be enabled, we should reset their totalTime() which will also ensure that they're lined up properly and enabled. Skip for animations that are on the root (wasteful). Example: a TimelineLite.exportRoot() is performed when there's a paused tween on the root, the export will not complete until that tween is unpaused, but imagine a child gets restarted later, after all [unpaused] tweens have completed. The start of that child would get pushed out, but one of the ancestors may have completed. 16399 16400 while (parent.parent) { 16401 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 16402 parent.totalTime(parent._tTime, true); 16403 } 16404 16405 parent = parent.parent; 16406 } 16407 16408 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 16409 //if the animation doesn't have a parent, put it back into its last parent (recorded as _dp for exactly cases like this). Limit to parents with autoRemoveChildren (like globalTimeline) so that if the user manually removes an animation from a timeline and then alters its playhead, it doesn't get added back in. 16410 _addToTimeline(this._dp, this, this._start - this._delay); 16411 } 16412 } 16413 16414 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 16415 // check for _ptLookup on a Tween instance to ensure it has actually finished being instantiated, otherwise if this.reverse() gets called in the Animation constructor, it could trigger a render() here even though the _targets weren't populated, thus when _init() is called there won't be any PropTweens (it'll act like the tween is non-functional) 16416 this._ts || (this._pTime = _totalTime); // otherwise, if an animation is paused, then the playhead is moved back to zero, then resumed, it'd revert back to the original time at the pause 16417 //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it's worth the performance hit) 16418 // this._lock = 1; 16419 16420 _lazySafeRender(this, _totalTime, suppressEvents); // this._lock = 0; 16421 //} 16422 16423 } 16424 16425 return this; 16426 }; 16427 16428 _proto.time = function time(value, suppressEvents) { 16429 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % this._dur || (value ? this._dur : 0), suppressEvents) : this._time; // note: if the modulus results in 0, the playhead could be exactly at the end or the beginning, and we always defer to the END with a non-zero value, otherwise if you set the time() to the very end (duration()), it would render at the START! 16430 }; 16431 16432 _proto.totalProgress = function totalProgress(value, suppressEvents) { 16433 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.ratio; 16434 }; 16435 16436 _proto.progress = function progress(value, suppressEvents) { 16437 return arguments.length ? this.totalTime(this.duration() * (this._yoyo && !(this.iteration() & 1) ? 1 - value : value) + _elapsedCycleDuration(this), suppressEvents) : this.duration() ? Math.min(1, this._time / this._dur) : this.ratio; 16438 }; 16439 16440 _proto.iteration = function iteration(value, suppressEvents) { 16441 var cycleDuration = this.duration() + this._rDelay; 16442 16443 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 16444 } // potential future addition: 16445 // isPlayingBackwards() { 16446 // let animation = this, 16447 // orientation = 1; // 1 = forward, -1 = backward 16448 // while (animation) { 16449 // orientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1; 16450 // animation = animation.parent; 16451 // } 16452 // return orientation < 0; 16453 // } 16454 ; 16455 16456 _proto.timeScale = function timeScale(value) { 16457 if (!arguments.length) { 16458 return this._rts === -_tinyNum ? 0 : this._rts; // recorded timeScale. Special case: if someone calls reverse() on an animation with timeScale of 0, we assign it -_tinyNum to remember it's reversed. 16459 } 16460 16461 if (this._rts === value) { 16462 return this; 16463 } 16464 16465 var tTime = this.parent && this._ts ? _parentToChildTotalTime(this.parent._time, this) : this._tTime; // make sure to do the parentToChildTotalTime() BEFORE setting the new _ts because the old one must be used in that calculation. 16466 // prioritize rendering where the parent's playhead lines up instead of this._tTime because there could be a tween that's animating another tween's timeScale in the same rendering loop (same parent), thus if the timeScale tween renders first, it would alter _start BEFORE _tTime was set on that tick (in the rendering loop), effectively freezing it until the timeScale tween finishes. 16467 16468 this._rts = +value || 0; 16469 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused. 16470 16471 return _recacheAncestors(this.totalTime(_clamp(-this._delay, this._tDur, tTime), true)); 16472 }; 16473 16474 _proto.paused = function paused(value) { 16475 if (!arguments.length) { 16476 return this._ps; 16477 } 16478 16479 if (this._ps !== value) { 16480 this._ps = value; 16481 16482 if (value) { 16483 this._pTime = this._tTime || Math.max(-this._delay, this.rawTime()); // if the pause occurs during the delay phase, make sure that's factored in when resuming. 16484 16485 this._ts = this._act = 0; // _ts is the functional timeScale, so a paused tween would effectively have a timeScale of 0. We record the "real" timeScale as _rts (recorded time scale) 16486 } else { 16487 _wake(); 16488 16489 this._ts = this._rts; //only defer to _pTime (pauseTime) if tTime is zero. Remember, someone could pause() an animation, then scrub the playhead and resume(). If the parent doesn't have smoothChildTiming, we render at the rawTime() because the startTime won't get updated. 16490 16491 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && (this._tTime -= _tinyNum) && Math.abs(this._zTime) !== _tinyNum); // edge case: animation.progress(1).pause().play() wouldn't render again because the playhead is already at the end, but the call to totalTime() below will add it back to its parent...and not remove it again (since removing only happens upon rendering at a new time). Offsetting the _tTime slightly is done simply to cause the final render in totalTime() that'll pop it off its timeline (if autoRemoveChildren is true, of course). Check to make sure _zTime isn't -_tinyNum to avoid an edge case where the playhead is pushed to the end but INSIDE a tween/callback, the timeline itself is paused thus halting rendering and leaving a few unrendered. When resuming, it wouldn't render those otherwise. 16492 } 16493 } 16494 16495 return this; 16496 }; 16497 16498 _proto.startTime = function startTime(value) { 16499 if (arguments.length) { 16500 this._start = value; 16501 var parent = this.parent || this._dp; 16502 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 16503 return this; 16504 } 16505 16506 return this._start; 16507 }; 16508 16509 _proto.endTime = function endTime(includeRepeats) { 16510 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts); 16511 }; 16512 16513 _proto.rawTime = function rawTime(wrapRepeats) { 16514 var parent = this.parent || this._dp; // _dp = detatched parent 16515 16516 return !parent ? this._tTime : wrapRepeats && (!this._ts || this._repeat && this._time && this.totalProgress() < 1) ? this._tTime % (this._dur + this._rDelay) : !this._ts ? this._tTime : _parentToChildTotalTime(parent.rawTime(wrapRepeats), this); 16517 }; 16518 16519 _proto.globalTime = function globalTime(rawTime) { 16520 var animation = this, 16521 time = arguments.length ? rawTime : animation.rawTime(); 16522 16523 while (animation) { 16524 time = animation._start + time / (animation._ts || 1); 16525 animation = animation._dp; 16526 } 16527 16528 return time; 16529 }; 16530 16531 _proto.repeat = function repeat(value) { 16532 if (arguments.length) { 16533 this._repeat = value === Infinity ? -2 : value; 16534 return _onUpdateTotalDuration(this); 16535 } 16536 16537 return this._repeat === -2 ? Infinity : this._repeat; 16538 }; 16539 16540 _proto.repeatDelay = function repeatDelay(value) { 16541 if (arguments.length) { 16542 this._rDelay = value; 16543 return _onUpdateTotalDuration(this); 16544 } 16545 16546 return this._rDelay; 16547 }; 16548 16549 _proto.yoyo = function yoyo(value) { 16550 if (arguments.length) { 16551 this._yoyo = value; 16552 return this; 16553 } 16554 16555 return this._yoyo; 16556 }; 16557 16558 _proto.seek = function seek(position, suppressEvents) { 16559 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 16560 }; 16561 16562 _proto.restart = function restart(includeDelay, suppressEvents) { 16563 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 16564 }; 16565 16566 _proto.play = function play(from, suppressEvents) { 16567 from != null && this.seek(from, suppressEvents); 16568 return this.reversed(false).paused(false); 16569 }; 16570 16571 _proto.reverse = function reverse(from, suppressEvents) { 16572 from != null && this.seek(from || this.totalDuration(), suppressEvents); 16573 return this.reversed(true).paused(false); 16574 }; 16575 16576 _proto.pause = function pause(atTime, suppressEvents) { 16577 atTime != null && this.seek(atTime, suppressEvents); 16578 return this.paused(true); 16579 }; 16580 16581 _proto.resume = function resume() { 16582 return this.paused(false); 16583 }; 16584 16585 _proto.reversed = function reversed(value) { 16586 if (arguments.length) { 16587 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum. 16588 16589 return this; 16590 } 16591 16592 return this._rts < 0; 16593 }; 16594 16595 _proto.invalidate = function invalidate() { 16596 this._initted = this._act = 0; 16597 this._zTime = -_tinyNum; 16598 return this; 16599 }; 16600 16601 _proto.isActive = function isActive() { 16602 var parent = this.parent || this._dp, 16603 start = this._start, 16604 rawTime; 16605 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 16606 }; 16607 16608 _proto.eventCallback = function eventCallback(type, callback, params) { 16609 var vars = this.vars; 16610 16611 if (arguments.length > 1) { 16612 if (!callback) { 16613 delete vars[type]; 16614 } else { 16615 vars[type] = callback; 16616 params && (vars[type + "Params"] = params); 16617 type === "onUpdate" && (this._onUpdate = callback); 16618 } 16619 16620 return this; 16621 } 16622 16623 return vars[type]; 16624 }; 16625 16626 _proto.then = function then(onFulfilled) { 16627 var self = this; 16628 return new Promise(function (resolve) { 16629 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 16630 _resolve = function _resolve() { 16631 var _then = self.then; 16632 self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322) 16633 16634 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 16635 resolve(f); 16636 self.then = _then; 16637 }; 16638 16639 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 16640 _resolve(); 16641 } else { 16642 self._prom = _resolve; 16643 } 16644 }); 16645 }; 16646 16647 _proto.kill = function kill() { 16648 _interrupt(this); 16649 }; 16650 16651 return Animation; 16652}(); 16653 16654_setDefaults(Animation.prototype, { 16655 _time: 0, 16656 _start: 0, 16657 _end: 0, 16658 _tTime: 0, 16659 _tDur: 0, 16660 _dirty: 0, 16661 _repeat: 0, 16662 _yoyo: false, 16663 parent: null, 16664 _initted: false, 16665 _rDelay: 0, 16666 _ts: 1, 16667 _dp: 0, 16668 ratio: 0, 16669 _zTime: -_tinyNum, 16670 _prom: 0, 16671 _ps: false, 16672 _rts: 1 16673}); 16674/* 16675 * ------------------------------------------------- 16676 * TIMELINE 16677 * ------------------------------------------------- 16678 */ 16679 16680 16681var Timeline = /*#__PURE__*/function (_Animation) { 16682 _inheritsLoose(Timeline, _Animation); 16683 16684 function Timeline(vars, time) { 16685 var _this; 16686 16687 if (vars === void 0) { 16688 vars = {}; 16689 } 16690 16691 _this = _Animation.call(this, vars, time) || this; 16692 _this.labels = {}; 16693 _this.smoothChildTiming = !!vars.smoothChildTiming; 16694 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 16695 _this._sort = _isNotFalse(vars.sortChildren); 16696 _this.parent && _postAddChecks(_this.parent, _assertThisInitialized(_this)); 16697 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 16698 return _this; 16699 } 16700 16701 var _proto2 = Timeline.prototype; 16702 16703 _proto2.to = function to(targets, vars, position) { 16704 new Tween(targets, _parseVars(arguments, 0, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 16705 return this; 16706 }; 16707 16708 _proto2.from = function from(targets, vars, position) { 16709 new Tween(targets, _parseVars(arguments, 1, this), _parsePosition(this, _isNumber(vars) ? arguments[3] : position)); 16710 return this; 16711 }; 16712 16713 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 16714 new Tween(targets, _parseVars(arguments, 2, this), _parsePosition(this, _isNumber(fromVars) ? arguments[4] : position)); 16715 return this; 16716 }; 16717 16718 _proto2.set = function set(targets, vars, position) { 16719 vars.duration = 0; 16720 vars.parent = this; 16721 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 16722 vars.immediateRender = !!vars.immediateRender; 16723 new Tween(targets, vars, _parsePosition(this, position), 1); 16724 return this; 16725 }; 16726 16727 _proto2.call = function call(callback, params, position) { 16728 return _addToTimeline(this, Tween.delayedCall(0, callback, params), _parsePosition(this, position)); 16729 } //ONLY for backward compatibility! Maybe delete? 16730 ; 16731 16732 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 16733 vars.duration = duration; 16734 vars.stagger = vars.stagger || stagger; 16735 vars.onComplete = onCompleteAll; 16736 vars.onCompleteParams = onCompleteAllParams; 16737 vars.parent = this; 16738 new Tween(targets, vars, _parsePosition(this, position)); 16739 return this; 16740 }; 16741 16742 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 16743 vars.runBackwards = 1; 16744 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 16745 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 16746 }; 16747 16748 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 16749 toVars.startAt = fromVars; 16750 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 16751 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 16752 }; 16753 16754 _proto2.render = function render(totalTime, suppressEvents, force) { 16755 var prevTime = this._time, 16756 tDur = this._dirty ? this.totalDuration() : this._tDur, 16757 dur = this._dur, 16758 tTime = this !== _globalTimeline && totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 16759 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 16760 time, 16761 child, 16762 next, 16763 iteration, 16764 cycleDuration, 16765 prevPaused, 16766 pauseTween, 16767 timeScale, 16768 prevStart, 16769 prevIteration, 16770 yoyo, 16771 isYoyo; 16772 16773 if (tTime !== this._tTime || force || crossingStart) { 16774 if (prevTime !== this._time && dur) { 16775 //if totalDuration() finds a child with a negative startTime and smoothChildTiming is true, things get shifted around internally so we need to adjust the time accordingly. For example, if a tween starts at -30 we must shift EVERYTHING forward 30 seconds and move this timeline's startTime backward by 30 seconds so that things align with the playhead (no jump). 16776 tTime += this._time - prevTime; 16777 totalTime += this._time - prevTime; 16778 } 16779 16780 time = tTime; 16781 prevStart = this._start; 16782 timeScale = this._ts; 16783 prevPaused = !timeScale; 16784 16785 if (crossingStart) { 16786 dur || (prevTime = this._zTime); //when the playhead arrives at EXACTLY time 0 (right on top) of a zero-duration timeline, we need to discern if events are suppressed so that when the playhead moves again (next time), it'll trigger the callback. If events are NOT suppressed, obviously the callback would be triggered in this render. Basically, the callback should fire either when the playhead ARRIVES or LEAVES this exact spot, not both. Imagine doing a timeline.seek(0) and there's a callback that sits at 0. Since events are suppressed on that seek() by default, nothing will fire, but when the playhead moves off of that position, the callback should fire. This behavior is what people intuitively expect. 16787 16788 (totalTime || !suppressEvents) && (this._zTime = totalTime); 16789 } 16790 16791 if (this._repeat) { 16792 //adjust the time for repeats and yoyos 16793 yoyo = this._yoyo; 16794 cycleDuration = dur + this._rDelay; 16795 16796 if (this._repeat < -1 && totalTime < 0) { 16797 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 16798 } 16799 16800 time = _round(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 16801 16802 if (tTime === tDur) { 16803 // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't) 16804 iteration = this._repeat; 16805 time = dur; 16806 } else { 16807 iteration = ~~(tTime / cycleDuration); 16808 16809 if (iteration && iteration === tTime / cycleDuration) { 16810 time = dur; 16811 iteration--; 16812 } 16813 16814 time > dur && (time = dur); 16815 } 16816 16817 prevIteration = _animationCycle(this._tTime, cycleDuration); 16818 !prevTime && this._tTime && prevIteration !== iteration && (prevIteration = iteration); // edge case - if someone does addPause() at the very beginning of a repeating timeline, that pause is technically at the same spot as the end which causes this._time to get set to 0 when the totalTime would normally place the playhead at the end. See https://greensock.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 16819 16820 if (yoyo && iteration & 1) { 16821 time = dur - time; 16822 isYoyo = 1; 16823 } 16824 /* 16825 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 16826 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which 16827 would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 16828 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 16829 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 16830 ensure that zero-duration tweens at the very beginning or end of the Timeline work. 16831 */ 16832 16833 16834 if (iteration !== prevIteration && !this._lock) { 16835 var rewinding = yoyo && prevIteration & 1, 16836 doesWrap = rewinding === (yoyo && iteration & 1); 16837 iteration < prevIteration && (rewinding = !rewinding); 16838 prevTime = rewinding ? 0 : dur; 16839 this._lock = 1; 16840 this.render(prevTime || (isYoyo ? 0 : _round(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 16841 !suppressEvents && this.parent && _callback(this, "onRepeat"); 16842 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 16843 16844 if (prevTime !== this._time || prevPaused !== !this._ts) { 16845 return this; 16846 } 16847 16848 dur = this._dur; // in case the duration changed in the onRepeat 16849 16850 tDur = this._tDur; 16851 16852 if (doesWrap) { 16853 this._lock = 2; 16854 prevTime = rewinding ? dur : -0.0001; 16855 this.render(prevTime, true); 16856 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 16857 } 16858 16859 this._lock = 0; 16860 16861 if (!this._ts && !prevPaused) { 16862 return this; 16863 } //in order for yoyoEase to work properly when there's a stagger, we must swap out the ease in each sub-tween. 16864 16865 16866 _propagateYoyoEase(this, isYoyo); 16867 } 16868 } 16869 16870 if (this._hasPause && !this._forcing && this._lock < 2) { 16871 pauseTween = _findNextPauseTween(this, _round(prevTime), _round(time)); 16872 16873 if (pauseTween) { 16874 tTime -= time - (time = pauseTween._start); 16875 } 16876 } 16877 16878 this._tTime = tTime; 16879 this._time = time; 16880 this._act = !timeScale; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick. 16881 16882 if (!this._initted) { 16883 this._onUpdate = this.vars.onUpdate; 16884 this._initted = 1; 16885 this._zTime = totalTime; 16886 prevTime = 0; // upon init, the playhead should always go forward; someone could invalidate() a completed timeline and then if they restart(), that would make child tweens render in reverse order which could lock in the wrong starting values if they build on each other, like tl.to(obj, {x: 100}).to(obj, {x: 0}). 16887 } 16888 16889 !prevTime && (time || !dur && totalTime >= 0) && !suppressEvents && _callback(this, "onStart"); 16890 16891 if (time >= prevTime && totalTime >= 0) { 16892 child = this._first; 16893 16894 while (child) { 16895 next = child._next; 16896 16897 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 16898 if (child.parent !== this) { 16899 // an extreme edge case - the child's render could do something like kill() the "next" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe. 16900 return this.render(totalTime, suppressEvents, force); 16901 } 16902 16903 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 16904 16905 if (time !== this._time || !this._ts && !prevPaused) { 16906 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 16907 pauseTween = 0; 16908 next && (tTime += this._zTime = -_tinyNum); // it didn't finish rendering, so flag zTime as negative so that so that the next time render() is called it'll be forced (to render any remaining children) 16909 16910 break; 16911 } 16912 } 16913 16914 child = next; 16915 } 16916 } else { 16917 child = this._last; 16918 var adjustedTime = totalTime < 0 ? totalTime : time; //when the playhead goes backward beyond the start of this timeline, we must pass that information down to the child animations so that zero-duration tweens know whether to render their starting or ending values. 16919 16920 while (child) { 16921 next = child._prev; 16922 16923 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 16924 if (child.parent !== this) { 16925 // an extreme edge case - the child's render could do something like kill() the "next" one in the linked list, or reparent it. In that case we must re-initiate the whole render to be safe. 16926 return this.render(totalTime, suppressEvents, force); 16927 } 16928 16929 child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force); 16930 16931 if (time !== this._time || !this._ts && !prevPaused) { 16932 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 16933 pauseTween = 0; 16934 next && (tTime += this._zTime = adjustedTime ? -_tinyNum : _tinyNum); // it didn't finish rendering, so adjust zTime so that so that the next time render() is called it'll be forced (to render any remaining children) 16935 16936 break; 16937 } 16938 } 16939 16940 child = next; 16941 } 16942 } 16943 16944 if (pauseTween && !suppressEvents) { 16945 this.pause(); 16946 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 16947 16948 if (this._ts) { 16949 //the callback resumed playback! So since we may have held back the playhead due to where the pause is positioned, go ahead and jump to where it's SUPPOSED to be (if no pause happened). 16950 this._start = prevStart; //if the pause was at an earlier time and the user resumed in the callback, it could reposition the timeline (changing its startTime), throwing things off slightly, so we make sure the _start doesn't shift. 16951 16952 _setEnd(this); 16953 16954 return this.render(totalTime, suppressEvents, force); 16955 } 16956 } 16957 16958 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 16959 if (tTime === tDur && tDur >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 16960 (totalTime || !dur) && (tTime === tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative. 16961 16962 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 16963 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 16964 16965 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 16966 } 16967 } 16968 } 16969 16970 return this; 16971 }; 16972 16973 _proto2.add = function add(child, position) { 16974 var _this2 = this; 16975 16976 _isNumber(position) || (position = _parsePosition(this, position)); 16977 16978 if (!(child instanceof Animation)) { 16979 if (_isArray(child)) { 16980 child.forEach(function (obj) { 16981 return _this2.add(obj, position); 16982 }); 16983 return this; 16984 } 16985 16986 if (_isString(child)) { 16987 return this.addLabel(child, position); 16988 } 16989 16990 if (_isFunction(child)) { 16991 child = Tween.delayedCall(0, child); 16992 } else { 16993 return this; 16994 } 16995 } 16996 16997 return this !== child ? _addToTimeline(this, child, position) : this; //don't allow a timeline to be added to itself as a child! 16998 }; 16999 17000 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 17001 if (nested === void 0) { 17002 nested = true; 17003 } 17004 17005 if (tweens === void 0) { 17006 tweens = true; 17007 } 17008 17009 if (timelines === void 0) { 17010 timelines = true; 17011 } 17012 17013 if (ignoreBeforeTime === void 0) { 17014 ignoreBeforeTime = -_bigNum; 17015 } 17016 17017 var a = [], 17018 child = this._first; 17019 17020 while (child) { 17021 if (child._start >= ignoreBeforeTime) { 17022 if (child instanceof Tween) { 17023 tweens && a.push(child); 17024 } else { 17025 timelines && a.push(child); 17026 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 17027 } 17028 } 17029 17030 child = child._next; 17031 } 17032 17033 return a; 17034 }; 17035 17036 _proto2.getById = function getById(id) { 17037 var animations = this.getChildren(1, 1, 1), 17038 i = animations.length; 17039 17040 while (i--) { 17041 if (animations[i].vars.id === id) { 17042 return animations[i]; 17043 } 17044 } 17045 }; 17046 17047 _proto2.remove = function remove(child) { 17048 if (_isString(child)) { 17049 return this.removeLabel(child); 17050 } 17051 17052 if (_isFunction(child)) { 17053 return this.killTweensOf(child); 17054 } 17055 17056 _removeLinkedListItem(this, child); 17057 17058 if (child === this._recent) { 17059 this._recent = this._last; 17060 } 17061 17062 return _uncache(this); 17063 }; 17064 17065 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 17066 if (!arguments.length) { 17067 return this._tTime; 17068 } 17069 17070 this._forcing = 1; 17071 17072 if (!this._dp && this._ts) { 17073 //special case for the global timeline (or any other that has no parent or detached parent). 17074 this._start = _round(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 17075 } 17076 17077 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 17078 17079 this._forcing = 0; 17080 return this; 17081 }; 17082 17083 _proto2.addLabel = function addLabel(label, position) { 17084 this.labels[label] = _parsePosition(this, position); 17085 return this; 17086 }; 17087 17088 _proto2.removeLabel = function removeLabel(label) { 17089 delete this.labels[label]; 17090 return this; 17091 }; 17092 17093 _proto2.addPause = function addPause(position, callback, params) { 17094 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 17095 t.data = "isPause"; 17096 this._hasPause = 1; 17097 return _addToTimeline(this, t, _parsePosition(this, position)); 17098 }; 17099 17100 _proto2.removePause = function removePause(position) { 17101 var child = this._first; 17102 position = _parsePosition(this, position); 17103 17104 while (child) { 17105 if (child._start === position && child.data === "isPause") { 17106 _removeFromParent(child); 17107 } 17108 17109 child = child._next; 17110 } 17111 }; 17112 17113 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 17114 var tweens = this.getTweensOf(targets, onlyActive), 17115 i = tweens.length; 17116 17117 while (i--) { 17118 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 17119 } 17120 17121 return this; 17122 }; 17123 17124 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 17125 var a = [], 17126 parsedTargets = toArray(targets), 17127 child = this._first, 17128 isGlobalTime = _isNumber(onlyActive), 17129 // a number is interpreted as a global time. If the animation spans 17130 children; 17131 17132 while (child) { 17133 if (child instanceof Tween) { 17134 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 17135 // note: if this is for overwriting, it should only be for tweens that aren't paused and are initted. 17136 a.push(child); 17137 } 17138 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 17139 a.push.apply(a, children); 17140 } 17141 17142 child = child._next; 17143 } 17144 17145 return a; 17146 } // potential future feature - targets() on timelines 17147 // targets() { 17148 // let result = []; 17149 // this.getChildren(true, true, false).forEach(t => result.push(...t.targets())); 17150 // return result; 17151 // } 17152 ; 17153 17154 _proto2.tweenTo = function tweenTo(position, vars) { 17155 vars = vars || {}; 17156 17157 var tl = this, 17158 endTime = _parsePosition(tl, position), 17159 _vars = vars, 17160 startAt = _vars.startAt, 17161 _onStart = _vars.onStart, 17162 onStartParams = _vars.onStartParams, 17163 immediateRender = _vars.immediateRender, 17164 tween = Tween.to(tl, _setDefaults({ 17165 ease: "none", 17166 lazy: false, 17167 immediateRender: false, 17168 time: endTime, 17169 overwrite: "auto", 17170 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 17171 onStart: function onStart() { 17172 tl.pause(); 17173 var duration = vars.duration || Math.abs((endTime - tl._time) / tl.timeScale()); 17174 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 17175 _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don't want to overwrite it. 17176 } 17177 }, vars)); 17178 17179 return immediateRender ? tween.render(0) : tween; 17180 }; 17181 17182 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 17183 return this.tweenTo(toPosition, _setDefaults({ 17184 startAt: { 17185 time: _parsePosition(this, fromPosition) 17186 } 17187 }, vars)); 17188 }; 17189 17190 _proto2.recent = function recent() { 17191 return this._recent; 17192 }; 17193 17194 _proto2.nextLabel = function nextLabel(afterTime) { 17195 if (afterTime === void 0) { 17196 afterTime = this._time; 17197 } 17198 17199 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 17200 }; 17201 17202 _proto2.previousLabel = function previousLabel(beforeTime) { 17203 if (beforeTime === void 0) { 17204 beforeTime = this._time; 17205 } 17206 17207 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 17208 }; 17209 17210 _proto2.currentLabel = function currentLabel(value) { 17211 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 17212 }; 17213 17214 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 17215 if (ignoreBeforeTime === void 0) { 17216 ignoreBeforeTime = 0; 17217 } 17218 17219 var child = this._first, 17220 labels = this.labels, 17221 p; 17222 17223 while (child) { 17224 if (child._start >= ignoreBeforeTime) { 17225 child._start += amount; 17226 child._end += amount; 17227 } 17228 17229 child = child._next; 17230 } 17231 17232 if (adjustLabels) { 17233 for (p in labels) { 17234 if (labels[p] >= ignoreBeforeTime) { 17235 labels[p] += amount; 17236 } 17237 } 17238 } 17239 17240 return _uncache(this); 17241 }; 17242 17243 _proto2.invalidate = function invalidate() { 17244 var child = this._first; 17245 this._lock = 0; 17246 17247 while (child) { 17248 child.invalidate(); 17249 child = child._next; 17250 } 17251 17252 return _Animation.prototype.invalidate.call(this); 17253 }; 17254 17255 _proto2.clear = function clear(includeLabels) { 17256 if (includeLabels === void 0) { 17257 includeLabels = true; 17258 } 17259 17260 var child = this._first, 17261 next; 17262 17263 while (child) { 17264 next = child._next; 17265 this.remove(child); 17266 child = next; 17267 } 17268 17269 this._dp && (this._time = this._tTime = this._pTime = 0); 17270 includeLabels && (this.labels = {}); 17271 return _uncache(this); 17272 }; 17273 17274 _proto2.totalDuration = function totalDuration(value) { 17275 var max = 0, 17276 self = this, 17277 child = self._last, 17278 prevStart = _bigNum, 17279 prev, 17280 start, 17281 parent; 17282 17283 if (arguments.length) { 17284 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 17285 } 17286 17287 if (self._dirty) { 17288 parent = self.parent; 17289 17290 while (child) { 17291 prev = child._prev; //record it here in case the tween changes position in the sequence... 17292 17293 child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation's cache is clean before analyzing it. 17294 17295 start = child._start; 17296 17297 if (start > prevStart && self._sort && child._ts && !self._lock) { 17298 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 17299 self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(). 17300 17301 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 17302 } else { 17303 prevStart = start; 17304 } 17305 17306 if (start < 0 && child._ts) { 17307 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 17308 max -= start; 17309 17310 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 17311 self._start += start / self._ts; 17312 self._time -= start; 17313 self._tTime -= start; 17314 } 17315 17316 self.shiftChildren(-start, false, -1e999); 17317 prevStart = 0; 17318 } 17319 17320 child._end > max && child._ts && (max = child._end); 17321 child = prev; 17322 } 17323 17324 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 17325 17326 self._dirty = 0; 17327 } 17328 17329 return self._tDur; 17330 }; 17331 17332 Timeline.updateRoot = function updateRoot(time) { 17333 if (_globalTimeline._ts) { 17334 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 17335 17336 _lastRenderedFrame = _ticker.frame; 17337 } 17338 17339 if (_ticker.frame >= _nextGCFrame) { 17340 _nextGCFrame += _config.autoSleep || 120; 17341 var child = _globalTimeline._first; 17342 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 17343 while (child && !child._ts) { 17344 child = child._next; 17345 } 17346 17347 child || _ticker.sleep(); 17348 } 17349 } 17350 }; 17351 17352 return Timeline; 17353}(Animation); 17354 17355_setDefaults(Timeline.prototype, { 17356 _lock: 0, 17357 _hasPause: 0, 17358 _forcing: 0 17359}); 17360 17361var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 17362 //note: we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 17363 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 17364 index = 0, 17365 matchIndex = 0, 17366 result, 17367 startNums, 17368 color, 17369 endNum, 17370 chunk, 17371 startNum, 17372 hasRandom, 17373 a; 17374 pt.b = start; 17375 pt.e = end; 17376 start += ""; //ensure values are strings 17377 17378 end += ""; 17379 17380 if (hasRandom = ~end.indexOf("random(")) { 17381 end = _replaceRandom(end); 17382 } 17383 17384 if (stringFilter) { 17385 a = [start, end]; 17386 stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 17387 17388 start = a[0]; 17389 end = a[1]; 17390 } 17391 17392 startNums = start.match(_complexStringNumExp) || []; 17393 17394 while (result = _complexStringNumExp.exec(end)) { 17395 endNum = result[0]; 17396 chunk = end.substring(index, result.index); 17397 17398 if (color) { 17399 color = (color + 1) % 5; 17400 } else if (chunk.substr(-5) === "rgba(") { 17401 color = 1; 17402 } 17403 17404 if (endNum !== startNums[matchIndex++]) { 17405 startNum = parseFloat(startNums[matchIndex - 1]) || 0; //these nested PropTweens are handled in a special way - we'll never actually call a render or setter method on them. We'll just loop through them in the parent complex string PropTween's render method. 17406 17407 pt._pt = { 17408 _next: pt._pt, 17409 p: chunk || matchIndex === 1 ? chunk : ",", 17410 //note: SVG spec allows omission of comma/space when a negative sign is wedged between two numbers, like 2.5-5.3 instead of 2.5,-5.3 but when tweening, the negative value may switch to positive, so we insert the comma just in case. 17411 s: startNum, 17412 c: endNum.charAt(1) === "=" ? parseFloat(endNum.substr(2)) * (endNum.charAt(0) === "-" ? -1 : 1) : parseFloat(endNum) - startNum, 17413 m: color && color < 4 ? Math.round : 0 17414 }; 17415 index = _complexStringNumExp.lastIndex; 17416 } 17417 } 17418 17419 pt.c = index < end.length ? end.substring(index, end.length) : ""; //we use the "c" of the PropTween to store the final part of the string (after the last number) 17420 17421 pt.fp = funcParam; 17422 17423 if (_relExp.test(end) || hasRandom) { 17424 pt.e = 0; //if the end string contains relative values or dynamic random(...) values, delete the end it so that on the final render we don't actually set it to the string with += or -= characters (forces it to use the calculated value). 17425 } 17426 17427 this._pt = pt; //start the linked list with this new PropTween. Remember, we call _addComplexStringPropTween.call(tweenInstance...) to ensure that it's scoped properly. We may call it from within a plugin too, thus "this" would refer to the plugin. 17428 17429 return pt; 17430}, 17431 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam) { 17432 _isFunction(end) && (end = end(index || 0, target, targets)); 17433 var currentValue = target[prop], 17434 parsedStart = start !== "get" ? start : !_isFunction(currentValue) ? currentValue : funcParam ? target[prop.indexOf("set") || !_isFunction(target["get" + prop.substr(3)]) ? prop : "get" + prop.substr(3)](funcParam) : target[prop](), 17435 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 17436 pt; 17437 17438 if (_isString(end)) { 17439 if (~end.indexOf("random(")) { 17440 end = _replaceRandom(end); 17441 } 17442 17443 if (end.charAt(1) === "=") { 17444 end = parseFloat(parsedStart) + parseFloat(end.substr(2)) * (end.charAt(0) === "-" ? -1 : 1) + (getUnit(parsedStart) || 0); 17445 } 17446 } 17447 17448 if (parsedStart !== end) { 17449 if (!isNaN(parsedStart * end)) { 17450 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 17451 funcParam && (pt.fp = funcParam); 17452 modifier && pt.modifier(modifier, this, target); 17453 return this._pt = pt; 17454 } 17455 17456 !currentValue && !(prop in target) && _missingPlugin(prop, end); 17457 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 17458 } 17459}, 17460 //creates a copy of the vars object and processes any function-based values (putting the resulting values directly into the copy) as well as strings with "random()" in them. It does NOT process relative values. 17461_processVars = function _processVars(vars, index, target, targets, tween) { 17462 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 17463 17464 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 17465 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 17466 } 17467 17468 var copy = {}, 17469 p; 17470 17471 for (p in vars) { 17472 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 17473 } 17474 17475 return copy; 17476}, 17477 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 17478 var plugin, pt, ptLookup, i; 17479 17480 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 17481 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 17482 17483 if (tween !== _quickTween) { 17484 ptLookup = tween._ptLookup[tween._targets.indexOf(target)]; //note: we can't use tween._ptLookup[index] because for staggered tweens, the index from the fullTargets array won't match what it is in each individual tween that spawns from the stagger. 17485 17486 i = plugin._props.length; 17487 17488 while (i--) { 17489 ptLookup[plugin._props[i]] = pt; 17490 } 17491 } 17492 } 17493 17494 return plugin; 17495}, 17496 _overwritingTween, 17497 //store a reference temporarily so we can avoid overwriting itself. 17498_initTween = function _initTween(tween, time) { 17499 var vars = tween.vars, 17500 ease = vars.ease, 17501 startAt = vars.startAt, 17502 immediateRender = vars.immediateRender, 17503 lazy = vars.lazy, 17504 onUpdate = vars.onUpdate, 17505 onUpdateParams = vars.onUpdateParams, 17506 callbackScope = vars.callbackScope, 17507 runBackwards = vars.runBackwards, 17508 yoyoEase = vars.yoyoEase, 17509 keyframes = vars.keyframes, 17510 autoRevert = vars.autoRevert, 17511 dur = tween._dur, 17512 prevStartAt = tween._startAt, 17513 targets = tween._targets, 17514 parent = tween.parent, 17515 fullTargets = parent && parent.data === "nested" ? parent.parent._targets : targets, 17516 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 17517 tl = tween.timeline, 17518 cleanVars, 17519 i, 17520 p, 17521 pt, 17522 target, 17523 hasPriority, 17524 gsData, 17525 harness, 17526 plugin, 17527 ptLookup, 17528 index, 17529 harnessVars, 17530 overwritten; 17531 tl && (!keyframes || !ease) && (ease = "none"); 17532 tween._ease = _parseEase(ease, _defaults.ease); 17533 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 17534 17535 if (yoyoEase && tween._yoyo && !tween._repeat) { 17536 //there must have been a parent timeline with yoyo:true that is currently in its yoyo phase, so flip the eases. 17537 yoyoEase = tween._yEase; 17538 tween._yEase = tween._ease; 17539 tween._ease = yoyoEase; 17540 } 17541 17542 if (!tl) { 17543 //if there's an internal timeline, skip all the parsing because we passed that task down the chain. 17544 harness = targets[0] ? _getCache(targets[0]).harness : 0; 17545 harnessVars = harness && vars[harness.prop]; //someone may need to specify CSS-specific values AND non-CSS values, like if the element has an "x" property plus it's a standard DOM element. We allow people to distinguish by wrapping plugin-specific stuff in a css:{} object for example. 17546 17547 cleanVars = _copyExcluding(vars, _reservedProps); 17548 prevStartAt && prevStartAt.render(-1, true).kill(); 17549 17550 if (startAt) { 17551 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 17552 data: "isStart", 17553 overwrite: false, 17554 parent: parent, 17555 immediateRender: true, 17556 lazy: _isNotFalse(lazy), 17557 startAt: null, 17558 delay: 0, 17559 onUpdate: onUpdate, 17560 onUpdateParams: onUpdateParams, 17561 callbackScope: callbackScope, 17562 stagger: 0 17563 }, startAt))); //copy the properties/values into a new object to avoid collisions, like var to = {x:0}, from = {x:500}; timeline.fromTo(e, from, to).fromTo(e, to, from); 17564 17565 17566 if (immediateRender) { 17567 if (time > 0) { 17568 autoRevert || (tween._startAt = 0); //tweens that render immediately (like most from() and fromTo() tweens) shouldn't revert when their parent timeline's playhead goes backward past the startTime because the initial render could have happened anytime and it shouldn't be directly correlated to this tween's startTime. Imagine setting up a complex animation where the beginning states of various objects are rendered immediately but the tween doesn't happen for quite some time - if we revert to the starting values as soon as the playhead goes backward past the tween's startTime, it will throw things off visually. Reversion should only happen in Timeline instances where immediateRender was false or when autoRevert is explicitly set to true. 17569 } else if (dur && !(time < 0 && prevStartAt)) { 17570 time && (tween._zTime = time); 17571 return; //we skip initialization here so that overwriting doesn't occur until the tween actually begins. Otherwise, if you create several immediateRender:true tweens of the same target/properties to drop into a Timeline, the last one created would overwrite the first ones because they didn't get placed into the timeline yet before the first render occurs and kicks in overwriting. 17572 } 17573 } 17574 } else if (runBackwards && dur) { 17575 //from() tweens must be handled uniquely: their beginning values must be rendered but we don't want overwriting to occur yet (when time is still 0). Wait until the tween actually begins before doing all the routines like overwriting. At that time, we should render at the END of the tween to ensure that things initialize correctly (remember, from() tweens go backwards) 17576 if (prevStartAt) { 17577 !autoRevert && (tween._startAt = 0); 17578 } else { 17579 time && (immediateRender = false); //in rare cases (like if a from() tween runs and then is invalidate()-ed), immediateRender could be true but the initial forced-render gets skipped, so there's no need to force the render in this context when the _time is greater than 0 17580 17581 p = _setDefaults({ 17582 overwrite: false, 17583 data: "isFromStart", 17584 //we tag the tween with as "isFromStart" so that if [inside a plugin] we need to only do something at the very END of a tween, we have a way of identifying this tween as merely the one that's setting the beginning values for a "from()" tween. For example, clearProps in CSSPlugin should only get applied at the very END of a tween and without this tag, from(...{height:100, clearProps:"height", delay:1}) would wipe the height at the beginning of the tween and after 1 second, it'd kick back in. 17585 lazy: immediateRender && _isNotFalse(lazy), 17586 immediateRender: immediateRender, 17587 //zero-duration tweens render immediately by default, but if we're not specifically instructed to render this tween immediately, we should skip this and merely _init() to record the starting values (rendering them immediately would push them to completion which is wasteful in that case - we'd have to render(-1) immediately after) 17588 stagger: 0, 17589 parent: parent //ensures that nested tweens that had a stagger are handled properly, like gsap.from(".class", {y:gsap.utils.wrap([-100,100])}) 17590 17591 }, cleanVars); 17592 harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}}) 17593 17594 _removeFromParent(tween._startAt = Tween.set(targets, p)); 17595 17596 if (!immediateRender) { 17597 _initTween(tween._startAt, _tinyNum); //ensures that the initial values are recorded 17598 17599 } else if (!time) { 17600 return; 17601 } 17602 } 17603 } 17604 17605 tween._pt = 0; 17606 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 17607 17608 for (i = 0; i < targets.length; i++) { 17609 target = targets[i]; 17610 gsData = target._gsap || _harness(targets)[i]._gsap; 17611 tween._ptLookup[i] = ptLookup = {}; 17612 _lazyLookup[gsData.id] && _lazyTweens.length && _lazyRender(); //if other tweens of the same target have recently initted but haven't rendered yet, we've got to force the render so that the starting values are correct (imagine populating a timeline with a bunch of sequential tweens and then jumping to the end) 17613 17614 index = fullTargets === targets ? i : fullTargets.indexOf(target); 17615 17616 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 17617 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 17618 17619 plugin._props.forEach(function (name) { 17620 ptLookup[name] = pt; 17621 }); 17622 17623 plugin.priority && (hasPriority = 1); 17624 } 17625 17626 if (!harness || harnessVars) { 17627 for (p in cleanVars) { 17628 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 17629 plugin.priority && (hasPriority = 1); 17630 } else { 17631 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 17632 } 17633 } 17634 } 17635 17636 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 17637 17638 if (autoOverwrite && tween._pt) { 17639 _overwritingTween = tween; 17640 17641 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(0)); //Also make sure the overwriting doesn't overwrite THIS tween!!! 17642 17643 17644 overwritten = !tween.parent; 17645 _overwritingTween = 0; 17646 } 17647 17648 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 17649 } 17650 17651 hasPriority && _sortPropTweensByPriority(tween); 17652 tween._onInit && tween._onInit(tween); //plugins like RoundProps must wait until ALL of the PropTweens are instantiated. In the plugin's init() function, it sets the _onInit on the tween instance. May not be pretty/intuitive, but it's fast and keeps file size down. 17653 } 17654 17655 tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens. 17656 17657 tween._onUpdate = onUpdate; 17658 tween._initted = (!tween._op || tween._pt) && !overwritten; // if overwrittenProps resulted in the entire tween being killed, do NOT flag it as initted or else it may render for one tick. 17659}, 17660 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 17661 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 17662 propertyAliases = harness && harness.aliases, 17663 copy, 17664 p, 17665 i, 17666 aliases; 17667 17668 if (!propertyAliases) { 17669 return vars; 17670 } 17671 17672 copy = _merge({}, vars); 17673 17674 for (p in propertyAliases) { 17675 if (p in copy) { 17676 aliases = propertyAliases[p].split(","); 17677 i = aliases.length; 17678 17679 while (i--) { 17680 copy[aliases[i]] = copy[p]; 17681 } 17682 } 17683 } 17684 17685 return copy; 17686}, 17687 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 17688 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 17689}, 17690 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase", 17691 _staggerPropsToSkip = (_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger").split(","); 17692/* 17693 * -------------------------------------------------------------------------------------- 17694 * TWEEN 17695 * -------------------------------------------------------------------------------------- 17696 */ 17697 17698 17699var Tween = /*#__PURE__*/function (_Animation2) { 17700 _inheritsLoose(Tween, _Animation2); 17701 17702 function Tween(targets, vars, time, skipInherit) { 17703 var _this3; 17704 17705 if (typeof vars === "number") { 17706 time.duration = vars; 17707 vars = time; 17708 time = null; 17709 } 17710 17711 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars), time) || this; 17712 var _this3$vars = _this3.vars, 17713 duration = _this3$vars.duration, 17714 delay = _this3$vars.delay, 17715 immediateRender = _this3$vars.immediateRender, 17716 stagger = _this3$vars.stagger, 17717 overwrite = _this3$vars.overwrite, 17718 keyframes = _this3$vars.keyframes, 17719 defaults = _this3$vars.defaults, 17720 scrollTrigger = _this3$vars.scrollTrigger, 17721 yoyoEase = _this3$vars.yoyoEase, 17722 parent = _this3.parent, 17723 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 17724 tl, 17725 i, 17726 copy, 17727 l, 17728 p, 17729 curTarget, 17730 staggerFunc, 17731 staggerVarsToMerge; 17732 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://greensock.com", !_config.nullTargetWarn) || []; 17733 _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property 17734 17735 _this3._overwrite = overwrite; 17736 17737 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 17738 vars = _this3.vars; 17739 tl = _this3.timeline = new Timeline({ 17740 data: "nested", 17741 defaults: defaults || {} 17742 }); 17743 tl.kill(); 17744 tl.parent = tl._dp = _assertThisInitialized(_this3); 17745 tl._start = 0; 17746 17747 if (keyframes) { 17748 _setDefaults(tl.vars.defaults, { 17749 ease: "none" 17750 }); 17751 17752 keyframes.forEach(function (frame) { 17753 return tl.to(parsedTargets, frame, ">"); 17754 }); 17755 } else { 17756 l = parsedTargets.length; 17757 staggerFunc = stagger ? distribute(stagger) : _emptyFunc; 17758 17759 if (_isObject(stagger)) { 17760 //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween. 17761 for (p in stagger) { 17762 if (~_staggerTweenProps.indexOf(p)) { 17763 staggerVarsToMerge || (staggerVarsToMerge = {}); 17764 staggerVarsToMerge[p] = stagger[p]; 17765 } 17766 } 17767 } 17768 17769 for (i = 0; i < l; i++) { 17770 copy = {}; 17771 17772 for (p in vars) { 17773 if (_staggerPropsToSkip.indexOf(p) < 0) { 17774 copy[p] = vars[p]; 17775 } 17776 } 17777 17778 copy.stagger = 0; 17779 yoyoEase && (copy.yoyoEase = yoyoEase); 17780 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 17781 curTarget = parsedTargets[i]; //don't just copy duration or delay because if they're a string or function, we'd end up in an infinite loop because _isFuncOrString() would evaluate as true in the child tweens, entering this loop, etc. So we parse the value straight from vars and default to 0. 17782 17783 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 17784 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 17785 17786 if (!stagger && l === 1 && copy.delay) { 17787 // if someone does delay:"random(1, 5)", repeat:-1, for example, the delay shouldn't be inside the repeat. 17788 _this3._delay = delay = copy.delay; 17789 _this3._start += delay; 17790 copy.delay = 0; 17791 } 17792 17793 tl.to(curTarget, copy, staggerFunc(i, curTarget, parsedTargets)); 17794 } 17795 17796 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline's duration is 0, we don't need a timeline internally! 17797 } 17798 17799 duration || _this3.duration(duration = tl.duration()); 17800 } else { 17801 _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain) 17802 } 17803 17804 if (overwrite === true && !_suppressOverwrites) { 17805 _overwritingTween = _assertThisInitialized(_this3); 17806 17807 _globalTimeline.killTweensOf(parsedTargets); 17808 17809 _overwritingTween = 0; 17810 } 17811 17812 parent && _postAddChecks(parent, _assertThisInitialized(_this3)); 17813 17814 if (immediateRender || !duration && !keyframes && _this3._start === _round(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 17815 _this3._tTime = -_tinyNum; //forces a render without having to set the render() "force" parameter to true because we want to allow lazying by default (using the "force" parameter always forces an immediate full render) 17816 17817 _this3.render(Math.max(0, -delay)); //in case delay is negative 17818 17819 } 17820 17821 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 17822 return _this3; 17823 } 17824 17825 var _proto3 = Tween.prototype; 17826 17827 _proto3.render = function render(totalTime, suppressEvents, force) { 17828 var prevTime = this._time, 17829 tDur = this._tDur, 17830 dur = this._dur, 17831 tTime = totalTime > tDur - _tinyNum && totalTime >= 0 ? tDur : totalTime < _tinyNum ? 0 : totalTime, 17832 time, 17833 pt, 17834 iteration, 17835 cycleDuration, 17836 prevIteration, 17837 isYoyo, 17838 ratio, 17839 timeline, 17840 yoyoEase; 17841 17842 if (!dur) { 17843 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 17844 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== totalTime < 0) { 17845 //this senses if we're crossing over the start time, in which case we must record _zTime and force the render, but we do it in this lengthy conditional way for performance reasons (usually we can skip the calculations): this._initted && (this._zTime < 0) !== (totalTime < 0) 17846 time = tTime; 17847 timeline = this.timeline; 17848 17849 if (this._repeat) { 17850 //adjust the time for repeats and yoyos 17851 cycleDuration = dur + this._rDelay; 17852 17853 if (this._repeat < -1 && totalTime < 0) { 17854 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 17855 } 17856 17857 time = _round(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 17858 17859 if (tTime === tDur) { 17860 // the tDur === tTime is for edge cases where there's a lengthy decimal on the duration and it may reach the very end but the time is rendered as not-quite-there (remember, tDur is rounded to 4 decimals whereas dur isn't) 17861 iteration = this._repeat; 17862 time = dur; 17863 } else { 17864 iteration = ~~(tTime / cycleDuration); 17865 17866 if (iteration && iteration === tTime / cycleDuration) { 17867 time = dur; 17868 iteration--; 17869 } 17870 17871 time > dur && (time = dur); 17872 } 17873 17874 isYoyo = this._yoyo && iteration & 1; 17875 17876 if (isYoyo) { 17877 yoyoEase = this._yEase; 17878 time = dur - time; 17879 } 17880 17881 prevIteration = _animationCycle(this._tTime, cycleDuration); 17882 17883 if (time === prevTime && !force && this._initted) { 17884 //could be during the repeatDelay part. No need to render and fire callbacks. 17885 return this; 17886 } 17887 17888 if (iteration !== prevIteration) { 17889 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); //repeatRefresh functionality 17890 17891 if (this.vars.repeatRefresh && !isYoyo && !this._lock) { 17892 this._lock = force = 1; //force, otherwise if lazy is true, the _attemptInitTween() will return and we'll jump out and get caught bouncing on each tick. 17893 17894 this.render(_round(cycleDuration * iteration), true).invalidate()._lock = 0; 17895 } 17896 } 17897 } 17898 17899 if (!this._initted) { 17900 if (_attemptInitTween(this, totalTime < 0 ? totalTime : time, force, suppressEvents)) { 17901 this._tTime = 0; // in constructor if immediateRender is true, we set _tTime to -_tinyNum to have the playhead cross the starting point but we can't leave _tTime as a negative number. 17902 17903 return this; 17904 } 17905 17906 if (dur !== this._dur) { 17907 // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should. 17908 return this.render(totalTime, suppressEvents, force); 17909 } 17910 } 17911 17912 this._tTime = tTime; 17913 this._time = time; 17914 17915 if (!this._act && this._ts) { 17916 this._act = 1; //as long as it's not paused, force it to be active so that if the user renders independent of the parent timeline, it'll be forced to re-render on the next tick. 17917 17918 this._lazy = 0; 17919 } 17920 17921 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 17922 17923 if (this._from) { 17924 this.ratio = ratio = 1 - ratio; 17925 } 17926 17927 time && !prevTime && !suppressEvents && _callback(this, "onStart"); 17928 pt = this._pt; 17929 17930 while (pt) { 17931 pt.r(ratio, pt.d); 17932 pt = pt._next; 17933 } 17934 17935 timeline && timeline.render(totalTime < 0 ? totalTime : !time && isYoyo ? -_tinyNum : timeline._dur * ratio, suppressEvents, force) || this._startAt && (this._zTime = totalTime); 17936 17937 if (this._onUpdate && !suppressEvents) { 17938 totalTime < 0 && this._startAt && this._startAt.render(totalTime, true, force); //note: for performance reasons, we tuck this conditional logic inside less traveled areas (most tweens don't have an onUpdate). We'd just have it at the end before the onComplete, but the values should be updated before any onUpdate is called, so we ALSO put it here and then if it's not called, we do so later near the onComplete. 17939 17940 _callback(this, "onUpdate"); 17941 } 17942 17943 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 17944 17945 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 17946 totalTime < 0 && this._startAt && !this._onUpdate && this._startAt.render(totalTime, true, true); 17947 (totalTime || !dur) && (tTime === this._tDur && this._ts > 0 || !tTime && this._ts < 0) && _removeFromParent(this, 1); // don't remove if we're rendering at exactly a time of 0, as there could be autoRevert values that should get set on the next tick (if the playhead goes backward beyond the startTime, negative totalTime). Don't remove if the timeline is reversed and the playhead isn't at 0, otherwise tl.progress(1).reverse() won't work. Only remove if the playhead is at the end and timeScale is positive, or if the playhead is at 0 and the timeScale is negative. 17948 17949 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime)) { 17950 // if prevTime and tTime are zero, we shouldn't fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play(); 17951 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 17952 17953 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 17954 } 17955 } 17956 } 17957 17958 return this; 17959 }; 17960 17961 _proto3.targets = function targets() { 17962 return this._targets; 17963 }; 17964 17965 _proto3.invalidate = function invalidate() { 17966 this._pt = this._op = this._startAt = this._onUpdate = this._lazy = this.ratio = 0; 17967 this._ptLookup = []; 17968 this.timeline && this.timeline.invalidate(); 17969 return _Animation2.prototype.invalidate.call(this); 17970 }; 17971 17972 _proto3.kill = function kill(targets, vars) { 17973 if (vars === void 0) { 17974 vars = "all"; 17975 } 17976 17977 if (!targets && (!vars || vars === "all")) { 17978 this._lazy = this._pt = 0; 17979 return this.parent ? _interrupt(this) : this; 17980 } 17981 17982 if (this.timeline) { 17983 var tDur = this.timeline.totalDuration(); 17984 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt. 17985 17986 this.parent && tDur !== this.timeline.totalDuration() && _setDuration(this, this._dur * this.timeline._tDur / tDur, 0, 1); // if a nested tween is killed that changes the duration, it should affect this tween's duration. We must use the ratio, though, because sometimes the internal timeline is stretched like for keyframes where they don't all add up to whatever the parent tween's duration was set to. 17987 17988 return this; 17989 } 17990 17991 var parsedTargets = this._targets, 17992 killingTargets = targets ? toArray(targets) : parsedTargets, 17993 propTweenLookup = this._ptLookup, 17994 firstPT = this._pt, 17995 overwrittenProps, 17996 curLookup, 17997 curOverwriteProps, 17998 props, 17999 p, 18000 pt, 18001 i; 18002 18003 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 18004 vars === "all" && (this._pt = 0); 18005 return _interrupt(this); 18006 } 18007 18008 overwrittenProps = this._op = this._op || []; 18009 18010 if (vars !== "all") { 18011 //so people can pass in a comma-delimited list of property names 18012 if (_isString(vars)) { 18013 p = {}; 18014 18015 _forEachName(vars, function (name) { 18016 return p[name] = 1; 18017 }); 18018 18019 vars = p; 18020 } 18021 18022 vars = _addAliasesToVars(parsedTargets, vars); 18023 } 18024 18025 i = parsedTargets.length; 18026 18027 while (i--) { 18028 if (~killingTargets.indexOf(parsedTargets[i])) { 18029 curLookup = propTweenLookup[i]; 18030 18031 if (vars === "all") { 18032 overwrittenProps[i] = vars; 18033 props = curLookup; 18034 curOverwriteProps = {}; 18035 } else { 18036 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 18037 props = vars; 18038 } 18039 18040 for (p in props) { 18041 pt = curLookup && curLookup[p]; 18042 18043 if (pt) { 18044 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 18045 _removeLinkedListItem(this, pt, "_pt"); 18046 } 18047 18048 delete curLookup[p]; 18049 } 18050 18051 if (curOverwriteProps !== "all") { 18052 curOverwriteProps[p] = 1; 18053 } 18054 } 18055 } 18056 } 18057 18058 this._initted && !this._pt && firstPT && _interrupt(this); //if all tweening properties are killed, kill the tween. Without this line, if there's a tween with multiple targets and then you killTweensOf() each target individually, the tween would technically still remain active and fire its onComplete even though there aren't any more properties tweening. 18059 18060 return this; 18061 }; 18062 18063 Tween.to = function to(targets, vars) { 18064 return new Tween(targets, vars, arguments[2]); 18065 }; 18066 18067 Tween.from = function from(targets, vars) { 18068 return new Tween(targets, _parseVars(arguments, 1)); 18069 }; 18070 18071 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 18072 return new Tween(callback, 0, { 18073 immediateRender: false, 18074 lazy: false, 18075 overwrite: false, 18076 delay: delay, 18077 onComplete: callback, 18078 onReverseComplete: callback, 18079 onCompleteParams: params, 18080 onReverseCompleteParams: params, 18081 callbackScope: scope 18082 }); 18083 }; 18084 18085 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 18086 return new Tween(targets, _parseVars(arguments, 2)); 18087 }; 18088 18089 Tween.set = function set(targets, vars) { 18090 vars.duration = 0; 18091 vars.repeatDelay || (vars.repeat = 0); 18092 return new Tween(targets, vars); 18093 }; 18094 18095 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 18096 return _globalTimeline.killTweensOf(targets, props, onlyActive); 18097 }; 18098 18099 return Tween; 18100}(Animation); 18101 18102_setDefaults(Tween.prototype, { 18103 _targets: [], 18104 _lazy: 0, 18105 _startAt: 0, 18106 _op: 0, 18107 _onInit: 0 18108}); //add the pertinent timeline methods to Tween instances so that users can chain conveniently and create a timeline automatically. (removed due to concerns that it'd ultimately add to more confusion especially for beginners) 18109// _forEachName("to,from,fromTo,set,call,add,addLabel,addPause", name => { 18110// Tween.prototype[name] = function() { 18111// let tl = new Timeline(); 18112// return _addToTimeline(tl, this)[name].apply(tl, toArray(arguments)); 18113// } 18114// }); 18115//for backward compatibility. Leverage the timeline calls. 18116 18117 18118_forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 18119 Tween[name] = function () { 18120 var tl = new Timeline(), 18121 params = _slice.call(arguments, 0); 18122 18123 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 18124 return tl[name].apply(tl, params); 18125 }; 18126}); 18127/* 18128 * -------------------------------------------------------------------------------------- 18129 * PROPTWEEN 18130 * -------------------------------------------------------------------------------------- 18131 */ 18132 18133 18134var _setterPlain = function _setterPlain(target, property, value) { 18135 return target[property] = value; 18136}, 18137 _setterFunc = function _setterFunc(target, property, value) { 18138 return target[property](value); 18139}, 18140 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 18141 return target[property](data.fp, value); 18142}, 18143 _setterAttribute = function _setterAttribute(target, property, value) { 18144 return target.setAttribute(property, value); 18145}, 18146 _getSetter = function _getSetter(target, property) { 18147 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 18148}, 18149 _renderPlain = function _renderPlain(ratio, data) { 18150 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000, data); 18151}, 18152 _renderBoolean = function _renderBoolean(ratio, data) { 18153 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 18154}, 18155 _renderComplexString = function _renderComplexString(ratio, data) { 18156 var pt = data._pt, 18157 s = ""; 18158 18159 if (!ratio && data.b) { 18160 //b = beginning string 18161 s = data.b; 18162 } else if (ratio === 1 && data.e) { 18163 //e = ending string 18164 s = data.e; 18165 } else { 18166 while (pt) { 18167 s = pt.p + (pt.m ? pt.m(pt.s + pt.c * ratio) : Math.round((pt.s + pt.c * ratio) * 10000) / 10000) + s; //we use the "p" property for the text inbetween (like a suffix). And in the context of a complex string, the modifier (m) is typically just Math.round(), like for RGB colors. 18168 18169 pt = pt._next; 18170 } 18171 18172 s += data.c; //we use the "c" of the PropTween to store the final chunk of non-numeric text. 18173 } 18174 18175 data.set(data.t, data.p, s, data); 18176}, 18177 _renderPropTweens = function _renderPropTweens(ratio, data) { 18178 var pt = data._pt; 18179 18180 while (pt) { 18181 pt.r(ratio, pt.d); 18182 pt = pt._next; 18183 } 18184}, 18185 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 18186 var pt = this._pt, 18187 next; 18188 18189 while (pt) { 18190 next = pt._next; 18191 pt.p === property && pt.modifier(modifier, tween, target); 18192 pt = next; 18193 } 18194}, 18195 _killPropTweensOf = function _killPropTweensOf(property) { 18196 var pt = this._pt, 18197 hasNonDependentRemaining, 18198 next; 18199 18200 while (pt) { 18201 next = pt._next; 18202 18203 if (pt.p === property && !pt.op || pt.op === property) { 18204 _removeLinkedListItem(this, pt, "_pt"); 18205 } else if (!pt.dep) { 18206 hasNonDependentRemaining = 1; 18207 } 18208 18209 pt = next; 18210 } 18211 18212 return !hasNonDependentRemaining; 18213}, 18214 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 18215 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 18216}, 18217 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 18218 var pt = parent._pt, 18219 next, 18220 pt2, 18221 first, 18222 last; //sorts the PropTween linked list in order of priority because some plugins need to do their work after ALL of the PropTweens were created (like RoundPropsPlugin and ModifiersPlugin) 18223 18224 while (pt) { 18225 next = pt._next; 18226 pt2 = first; 18227 18228 while (pt2 && pt2.pr > pt.pr) { 18229 pt2 = pt2._next; 18230 } 18231 18232 if (pt._prev = pt2 ? pt2._prev : last) { 18233 pt._prev._next = pt; 18234 } else { 18235 first = pt; 18236 } 18237 18238 if (pt._next = pt2) { 18239 pt2._prev = pt; 18240 } else { 18241 last = pt; 18242 } 18243 18244 pt = next; 18245 } 18246 18247 parent._pt = first; 18248}; //PropTween key: t = target, p = prop, r = renderer, d = data, s = start, c = change, op = overwriteProperty (ONLY populated when it's different than p), pr = priority, _next/_prev for the linked list siblings, set = setter, m = modifier, mSet = modifierSetter (the original setter, before a modifier was added) 18249 18250 18251var PropTween = /*#__PURE__*/function () { 18252 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 18253 this.t = target; 18254 this.s = start; 18255 this.c = change; 18256 this.p = prop; 18257 this.r = renderer || _renderPlain; 18258 this.d = data || this; 18259 this.set = setter || _setterPlain; 18260 this.pr = priority || 0; 18261 this._next = next; 18262 18263 if (next) { 18264 next._prev = this; 18265 } 18266 } 18267 18268 var _proto4 = PropTween.prototype; 18269 18270 _proto4.modifier = function modifier(func, tween, target) { 18271 this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier) 18272 18273 this.set = _setterWithModifier; 18274 this.m = func; 18275 this.mt = target; //modifier target 18276 18277 this.tween = tween; 18278 }; 18279 18280 return PropTween; 18281}(); //Initialization tasks 18282 18283_forEachName(_callbackNames + "parent,duration,ease,delay,overwrite,runBackwards,startAt,yoyo,immediateRender,repeat,repeatDelay,data,paused,reversed,lazy,callbackScope,stringFilter,id,yoyoEase,stagger,inherit,repeatRefresh,keyframes,autoRevert,scrollTrigger", function (name) { 18284 return _reservedProps[name] = 1; 18285}); 18286 18287_globals.TweenMax = _globals.TweenLite = Tween; 18288_globals.TimelineLite = _globals.TimelineMax = Timeline; 18289_globalTimeline = new Timeline({ 18290 sortChildren: false, 18291 defaults: _defaults, 18292 autoRemoveChildren: true, 18293 id: "root", 18294 smoothChildTiming: true 18295}); 18296_config.stringFilter = _colorStringFilter; 18297/* 18298 * -------------------------------------------------------------------------------------- 18299 * GSAP 18300 * -------------------------------------------------------------------------------------- 18301 */ 18302 18303var _gsap = { 18304 registerPlugin: function registerPlugin() { 18305 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 18306 args[_key2] = arguments[_key2]; 18307 } 18308 18309 args.forEach(function (config) { 18310 return _createPlugin(config); 18311 }); 18312 }, 18313 timeline: function timeline(vars) { 18314 return new Timeline(vars); 18315 }, 18316 getTweensOf: function getTweensOf(targets, onlyActive) { 18317 return _globalTimeline.getTweensOf(targets, onlyActive); 18318 }, 18319 getProperty: function getProperty(target, property, unit, uncache) { 18320 _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in 18321 18322 var getter = _getCache(target || {}).get, 18323 format = unit ? _passThrough : _numericIfPossible; 18324 18325 unit === "native" && (unit = ""); 18326 return !target ? target : !property ? function (property, unit, uncache) { 18327 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 18328 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 18329 }, 18330 quickSetter: function quickSetter(target, property, unit) { 18331 target = toArray(target); 18332 18333 if (target.length > 1) { 18334 var setters = target.map(function (t) { 18335 return gsap.quickSetter(t, property, unit); 18336 }), 18337 l = setters.length; 18338 return function (value) { 18339 var i = l; 18340 18341 while (i--) { 18342 setters[i](value); 18343 } 18344 }; 18345 } 18346 18347 target = target[0] || {}; 18348 18349 var Plugin = _plugins[property], 18350 cache = _getCache(target), 18351 p = cache.harness && (cache.harness.aliases || {})[property] || property, 18352 // in case it's an alias, like "rotate" for "rotation". 18353 setter = Plugin ? function (value) { 18354 var p = new Plugin(); 18355 _quickTween._pt = 0; 18356 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 18357 p.render(1, p); 18358 _quickTween._pt && _renderPropTweens(1, _quickTween); 18359 } : cache.set(target, p); 18360 18361 return Plugin ? setter : function (value) { 18362 return setter(target, p, unit ? value + unit : value, cache, 1); 18363 }; 18364 }, 18365 isTweening: function isTweening(targets) { 18366 return _globalTimeline.getTweensOf(targets, true).length > 0; 18367 }, 18368 defaults: function defaults(value) { 18369 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 18370 return _mergeDeep(_defaults, value || {}); 18371 }, 18372 config: function config(value) { 18373 return _mergeDeep(_config, value || {}); 18374 }, 18375 registerEffect: function registerEffect(_ref2) { 18376 var name = _ref2.name, 18377 effect = _ref2.effect, 18378 plugins = _ref2.plugins, 18379 defaults = _ref2.defaults, 18380 extendTimeline = _ref2.extendTimeline; 18381 (plugins || "").split(",").forEach(function (pluginName) { 18382 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 18383 }); 18384 18385 _effects[name] = function (targets, vars, tl) { 18386 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 18387 }; 18388 18389 if (extendTimeline) { 18390 Timeline.prototype[name] = function (targets, vars, position) { 18391 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 18392 }; 18393 } 18394 }, 18395 registerEase: function registerEase(name, ease) { 18396 _easeMap[name] = _parseEase(ease); 18397 }, 18398 parseEase: function parseEase(ease, defaultEase) { 18399 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 18400 }, 18401 getById: function getById(id) { 18402 return _globalTimeline.getById(id); 18403 }, 18404 exportRoot: function exportRoot(vars, includeDelayedCalls) { 18405 if (vars === void 0) { 18406 vars = {}; 18407 } 18408 18409 var tl = new Timeline(vars), 18410 child, 18411 next; 18412 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 18413 18414 _globalTimeline.remove(tl); 18415 18416 tl._dp = 0; //otherwise it'll get re-activated when adding children and be re-introduced into _globalTimeline's linked list (then added to itself). 18417 18418 tl._time = tl._tTime = _globalTimeline._time; 18419 child = _globalTimeline._first; 18420 18421 while (child) { 18422 next = child._next; 18423 18424 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 18425 _addToTimeline(tl, child, child._start - child._delay); 18426 } 18427 18428 child = next; 18429 } 18430 18431 _addToTimeline(_globalTimeline, tl, 0); 18432 18433 return tl; 18434 }, 18435 utils: { 18436 wrap: wrap, 18437 wrapYoyo: wrapYoyo, 18438 distribute: distribute, 18439 random: random, 18440 snap: snap, 18441 normalize: normalize, 18442 getUnit: getUnit, 18443 clamp: clamp, 18444 splitColor: splitColor, 18445 toArray: toArray, 18446 mapRange: mapRange, 18447 pipe: pipe, 18448 unitize: unitize, 18449 interpolate: interpolate, 18450 shuffle: shuffle 18451 }, 18452 install: _install, 18453 effects: _effects, 18454 ticker: _ticker, 18455 updateRoot: Timeline.updateRoot, 18456 plugins: _plugins, 18457 globalTimeline: _globalTimeline, 18458 core: { 18459 PropTween: PropTween, 18460 globals: _addGlobal, 18461 Tween: Tween, 18462 Timeline: Timeline, 18463 Animation: Animation, 18464 getCache: _getCache, 18465 _removeLinkedListItem: _removeLinkedListItem, 18466 suppressOverwrites: function suppressOverwrites(value) { 18467 return _suppressOverwrites = value; 18468 } 18469 } 18470}; 18471 18472_forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 18473 return _gsap[name] = Tween[name]; 18474}); 18475 18476_ticker.add(Timeline.updateRoot); 18477 18478_quickTween = _gsap.to({}, { 18479 duration: 0 18480}); // ---- EXTRA PLUGINS -------------------------------------------------------- 18481 18482var _getPluginPropTween = function _getPluginPropTween(plugin, prop) { 18483 var pt = plugin._pt; 18484 18485 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 18486 pt = pt._next; 18487 } 18488 18489 return pt; 18490}, 18491 _addModifiers = function _addModifiers(tween, modifiers) { 18492 var targets = tween._targets, 18493 p, 18494 i, 18495 pt; 18496 18497 for (p in modifiers) { 18498 i = targets.length; 18499 18500 while (i--) { 18501 pt = tween._ptLookup[i][p]; 18502 18503 if (pt && (pt = pt.d)) { 18504 if (pt._pt) { 18505 // is a plugin 18506 pt = _getPluginPropTween(pt, p); 18507 } 18508 18509 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 18510 } 18511 } 18512 } 18513}, 18514 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 18515 return { 18516 name: name, 18517 rawVars: 1, 18518 //don't pre-process function-based values or "random()" strings. 18519 init: function init(target, vars, tween) { 18520 tween._onInit = function (tween) { 18521 var temp, p; 18522 18523 if (_isString(vars)) { 18524 temp = {}; 18525 18526 _forEachName(vars, function (name) { 18527 return temp[name] = 1; 18528 }); //if the user passes in a comma-delimited list of property names to roundProps, like "x,y", we round to whole numbers. 18529 18530 18531 vars = temp; 18532 } 18533 18534 if (modifier) { 18535 temp = {}; 18536 18537 for (p in vars) { 18538 temp[p] = modifier(vars[p]); 18539 } 18540 18541 vars = temp; 18542 } 18543 18544 _addModifiers(tween, vars); 18545 }; 18546 } 18547 }; 18548}; //register core plugins 18549 18550 18551var gsap = _gsap.registerPlugin({ 18552 name: "attr", 18553 init: function init(target, vars, tween, index, targets) { 18554 var p, pt; 18555 18556 for (p in vars) { 18557 pt = this.add(target, "setAttribute", (target.getAttribute(p) || 0) + "", vars[p], index, targets, 0, 0, p); 18558 pt && (pt.op = p); 18559 18560 this._props.push(p); 18561 } 18562 } 18563}, { 18564 name: "endArray", 18565 init: function init(target, value) { 18566 var i = value.length; 18567 18568 while (i--) { 18569 this.add(target, i, target[i] || 0, value[i]); 18570 } 18571 } 18572}, _buildModifierPlugin("roundProps", _roundModifier), _buildModifierPlugin("modifiers"), _buildModifierPlugin("snap", snap)) || _gsap; //to prevent the core plugins from being dropped via aggressive tree shaking, we must include them in the variable declaration in this way. 18573 18574Tween.version = Timeline.version = gsap.version = "3.6.0"; 18575_coreReady = 1; 18576 18577if (_windowExists()) { 18578 _wake(); 18579} 18580 18581var Power0 = _easeMap.Power0, 18582 Power1 = _easeMap.Power1, 18583 Power2 = _easeMap.Power2, 18584 Power3 = _easeMap.Power3, 18585 Power4 = _easeMap.Power4, 18586 Linear = _easeMap.Linear, 18587 Quad = _easeMap.Quad, 18588 Cubic = _easeMap.Cubic, 18589 Quart = _easeMap.Quart, 18590 Quint = _easeMap.Quint, 18591 Strong = _easeMap.Strong, 18592 Elastic = _easeMap.Elastic, 18593 Back = _easeMap.Back, 18594 SteppedEase = _easeMap.SteppedEase, 18595 Bounce = _easeMap.Bounce, 18596 Sine = _easeMap.Sine, 18597 Expo = _easeMap.Expo, 18598 Circ = _easeMap.Circ; 18599 18600 //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it. 18601 18602 18603 18604/***/ }), 18605
vendor: 54,701 bytes, lines 18606-20409
18606/***/ "./node_modules/gsap/utils/PathEditor.js": 18607/*!***********************************************!*\ 18608 !*** ./node_modules/gsap/utils/PathEditor.js ***! 18609 \***********************************************/ 18610/*! exports provided: PathEditor, default */ 18611/***/ (function(module, __webpack_exports__, __webpack_require__) { 18612 18613"use strict"; 18614__webpack_require__.r(__webpack_exports__); 18615/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PathEditor", function() { return PathEditor; }); 18616/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return PathEditor; }); 18617/* harmony import */ var _paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./paths.js */ "./node_modules/gsap/utils/paths.js"); 18618/* harmony import */ var _matrix_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./matrix.js */ "./node_modules/gsap/utils/matrix.js"); 18619/*! 18620 * PathEditor 3.6.0 18621 * https://greensock.com 18622 * 18623 * Copyright 2008-2021, GreenSock. All rights reserved. 18624 * Subject to the terms at https://greensock.com/standard-license or for 18625 * Club GreenSock members, the agreement issued with that membership. 18626 * @author: Jack Doyle, [email protected] 18627*/ 18628 18629/* eslint-disable */ 18630 18631 18632 18633var _numbersExp = /(?:(-)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 18634 _doc, 18635 _supportsPointer, 18636 _win, 18637 _body, 18638 _selectionColor = "#4e7fff", 18639 _minimumMovement = 1, 18640 _DEG2RAD = Math.PI / 180, 18641 _getTime = Date.now || function () { 18642 return new Date().getTime(); 18643}, 18644 _lastInteraction = 0, 18645 _isPressed = 0, 18646 _emptyFunc = function _emptyFunc() { 18647 return false; 18648}, 18649 _interacted = function _interacted() { 18650 return _lastInteraction = _getTime(); 18651}, 18652 _CTRL, 18653 _ALT, 18654 _SHIFT, 18655 _CMD, 18656 _recentlyAddedAnchor, 18657 _editingAxis = {}, 18658 //stores the x/y of the most recently-selected anchor point's x and y axis. We tap into this for snapping horizontally and vertically. 18659_history = [], 18660 _point = {}, 18661 //reuse to minimize memory and maximize performance (mostly for snapping) 18662_temp = [], 18663 //reuse this in places like getNormalizedSVG() to conserve memory 18664_comma = ",", 18665 _selectedPaths = [], 18666 _preventDefault = function _preventDefault(event) { 18667 if (event.preventDefault) { 18668 event.preventDefault(); 18669 18670 if (event.preventManipulation) { 18671 event.preventManipulation(); //for some Microsoft browsers 18672 } 18673 } 18674}, 18675 _createElement = function _createElement(type) { 18676 return _doc.createElementNS ? _doc.createElementNS("http://www.w3.org/1999/xhtml", type) : _doc.createElement(type); 18677}, 18678 _createSVG = function _createSVG(type, container, attributes) { 18679 var element = _doc.createElementNS("http://www.w3.org/2000/svg", type), 18680 reg = /([a-z])([A-Z])/g, 18681 p; 18682 18683 attributes = attributes || {}; 18684 attributes["class"] = attributes["class"] || "path-editor"; 18685 18686 for (p in attributes) { 18687 if (element.style[p] !== undefined) { 18688 element.style[p] = attributes[p]; 18689 } else { 18690 element.setAttributeNS(null, p.replace(reg, "$1-$2").toLowerCase(), attributes[p]); 18691 } 18692 } 18693 18694 container.appendChild(element); 18695 return element; 18696}, 18697 _identityMatrixObject = { 18698 matrix: new _matrix_js__WEBPACK_IMPORTED_MODULE_1__["Matrix2D"]() 18699}, 18700 _getConsolidatedMatrix = function _getConsolidatedMatrix(target) { 18701 return (target.transform && target.transform.baseVal.consolidate() || _identityMatrixObject).matrix; 18702}, 18703 _getConcatenatedTransforms = function _getConcatenatedTransforms(target) { 18704 var m = _getConsolidatedMatrix(target), 18705 owner = target.ownerSVGElement; 18706 18707 while ((target = target.parentNode) && target.ownerSVGElement === owner) { 18708 m.multiply(_getConsolidatedMatrix(target)); 18709 } 18710 18711 return "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + m.e + "," + m.f + ")"; 18712}, 18713 _addHistory = function _addHistory(pathEditor) { 18714 var selectedIndexes = [], 18715 a = pathEditor._selectedAnchors, 18716 i; 18717 18718 for (i = 0; i < a.length; i++) { 18719 selectedIndexes[i] = a[i].i; 18720 } 18721 18722 _history.unshift({ 18723 path: pathEditor, 18724 d: pathEditor.path.getAttribute("d"), 18725 transform: pathEditor.path.getAttribute("transform") || "", 18726 selectedIndexes: selectedIndexes 18727 }); 18728 18729 if (_history.length > 30) { 18730 _history.length = 30; 18731 } 18732}, 18733 _round = function _round(value) { 18734 return ~~(value * 1000 + (value < 0 ? -.5 : .5)) / 1000; 18735}, 18736 _getSquarePathData = function _getSquarePathData(size) { 18737 size = _round(size); 18738 return ["M-" + size, -size, size, -size, size, size, -size, size + "z"].join(_comma); 18739}, 18740 _getCirclePathData = function _getCirclePathData(size) { 18741 var circ = 0.552284749831, 18742 rcirc = _round(size * circ); 18743 18744 size = _round(size); 18745 return "M" + size + ",0C" + [size, rcirc, rcirc, size, 0, size, -rcirc, size, -size, rcirc, -size, 0, -size, -rcirc, -rcirc, -size, 0, -size, rcirc, -size, size, -rcirc, size, 0].join(_comma) + "z"; 18746}, 18747 _checkDeselect = function _checkDeselect(e) { 18748 if (!e.target._gsSelection && !_isPressed && _getTime() - _lastInteraction > 100) { 18749 var i = _selectedPaths.length; 18750 18751 while (--i > -1) { 18752 _selectedPaths[i].deselect(); 18753 } 18754 18755 _selectedPaths.length = 0; 18756 } 18757}, 18758 _tempDiv, 18759 _touchEventLookup, 18760 _isMultiTouching = 0, 18761 _addListener = function _addListener(element, type, func, capture) { 18762 if (element.addEventListener) { 18763 var touchType = _touchEventLookup[type]; 18764 capture = capture || { 18765 passive: false 18766 }; 18767 element.addEventListener(touchType || type, func, capture); 18768 18769 if (touchType && type !== touchType && touchType.substr(0, 7) !== "pointer") { 18770 //some browsers actually support both, so must we. But pointer events cover all. 18771 element.addEventListener(type, func, capture); 18772 } 18773 } else if (element.attachEvent) { 18774 element.attachEvent("on" + type, func); 18775 } 18776}, 18777 _removeListener = function _removeListener(element, type, func) { 18778 if (element.removeEventListener) { 18779 var touchType = _touchEventLookup[type]; 18780 element.removeEventListener(touchType || type, func); 18781 18782 if (touchType && type !== touchType && touchType.substr(0, 7) !== "pointer") { 18783 element.removeEventListener(type, func); 18784 } 18785 } else if (element.detachEvent) { 18786 element.detachEvent("on" + type, func); 18787 } 18788}, 18789 _hasTouchID = function _hasTouchID(list, ID) { 18790 var i = list.length; 18791 18792 while (--i > -1) { 18793 if (list[i].identifier === ID) { 18794 return true; 18795 } 18796 } 18797 18798 return false; 18799}, 18800 _onMultiTouchDocumentEnd = function _onMultiTouchDocumentEnd(e) { 18801 _isMultiTouching = e.touches && _dragCount < e.touches.length; 18802 18803 _removeListener(e.target, "touchend", _onMultiTouchDocumentEnd); 18804}, 18805 _onMultiTouchDocument = function _onMultiTouchDocument(e) { 18806 _isMultiTouching = e.touches && _dragCount < e.touches.length; 18807 18808 _addListener(e.target, "touchend", _onMultiTouchDocumentEnd); 18809}, 18810 _bind = function _bind(func, scope) { 18811 return function (e) { 18812 return func.call(scope, e); 18813 }; 18814}, 18815 _callback = function _callback(type, self, param) { 18816 var callback = self.vars[type]; 18817 18818 if (callback) { 18819 callback.call(self.vars.callbackScope || self, param || self); 18820 } 18821 18822 return self; 18823}, 18824 _copyElement, 18825 _resetSelection = function _resetSelection() { 18826 _copyElement.style.display = "block"; 18827 18828 _copyElement.select(); 18829 18830 _copyElement.style.display = "none"; 18831}, 18832 _coreInitted, 18833 _initCore = function _initCore() { 18834 _doc = document; 18835 _win = window; 18836 _body = _doc.body; 18837 _tempDiv = _createElement("div"); 18838 _copyElement = _createElement("textarea"); 18839 _copyElement.style.display = "none"; 18840 _body && _body.appendChild(_copyElement); 18841 18842 _touchEventLookup = function (types) { 18843 //we create an object that makes it easy to translate touch event types into their "pointer" counterparts if we're in a browser that uses those instead. Like IE10 uses "MSPointerDown" instead of "touchstart", for example. 18844 var standard = types.split(","), 18845 converted = (_tempDiv.onpointerdown !== undefined ? "pointerdown,pointermove,pointerup,pointercancel" : _tempDiv.onmspointerdown !== undefined ? "MSPointerDown,MSPointerMove,MSPointerUp,MSPointerCancel" : types).split(","), 18846 obj = {}, 18847 i = 4; 18848 18849 while (--i > -1) { 18850 obj[standard[i]] = converted[i]; 18851 obj[converted[i]] = standard[i]; 18852 } 18853 18854 return obj; 18855 }("touchstart,touchmove,touchend,touchcancel"); 18856 18857 SVGElement.prototype.getTransformToElement = SVGElement.prototype.getTransformToElement || function (e) { 18858 //adds Chrome support 18859 return e.getScreenCTM().inverse().multiply(this.getScreenCTM()); 18860 }; 18861 18862 _doc.addEventListener("keydown", function (e) { 18863 var key = e.keyCode || e.which, 18864 keyString = e.key || key, 18865 i, 18866 state, 18867 a, 18868 path; 18869 18870 if (keyString === "Shift" || key === 16) { 18871 _SHIFT = true; 18872 } else if (keyString === "Control" || key === 17) { 18873 _CTRL = true; 18874 } else if (keyString === "Meta" || key === 91) { 18875 _CMD = true; 18876 } else if (keyString === "Alt" || key === 18) { 18877 _ALT = true; 18878 i = _selectedPaths.length; 18879 18880 while (--i > -1) { 18881 _selectedPaths[i]._onPressAlt(); 18882 } 18883 } else if ((keyString === "z" || key === 90) && (_CTRL || _CMD) && _history.length > 1) { 18884 //UNDO 18885 _history.shift(); 18886 18887 state = _history[0]; 18888 18889 if (state) { 18890 path = state.path; 18891 path.path.setAttribute("d", state.d); 18892 path.path.setAttribute("transform", state.transform); 18893 path.init(); 18894 a = path._anchors; 18895 18896 for (i = 0; i < a.length; i++) { 18897 if (state.selectedIndexes.indexOf(a[i].i) !== -1) { 18898 path._selectedAnchors.push(a[i]); 18899 } 18900 } 18901 18902 path._updateAnchors(); 18903 18904 path.update(); 18905 18906 if (path.vars.onUndo) { 18907 path.vars.onUndo.call(path); 18908 } 18909 } 18910 } else if (keyString === "Delete" || keyString === "Backspace" || key === 8 || key === 46 || key === 63272 || key === "d" && (_CTRL || _CMD)) { 18911 //DELETE 18912 i = _selectedPaths.length; 18913 18914 while (--i > -1) { 18915 _selectedPaths[i]._deleteSelectedAnchors(); 18916 } 18917 } else if ((keyString === "a" || key === 65) && (_CMD || _CTRL)) { 18918 //SELECT ALL 18919 i = _selectedPaths.length; 18920 18921 while (--i > -1) { 18922 _selectedPaths[i].select(true); 18923 } 18924 } 18925 }, true); 18926 18927 _doc.addEventListener("keyup", function (e) { 18928 var key = e.key || e.keyCode || e.which; 18929 18930 if (key === "Shift" || key === 16) { 18931 _SHIFT = false; 18932 } else if (key === "Control" || key === 17) { 18933 _CTRL = false; 18934 } else if (key === "Meta" || key === 91) { 18935 _CMD = false; 18936 } else if (key === "Alt" || key === 18) { 18937 _ALT = false; 18938 var i = _selectedPaths.length; 18939 18940 while (--i > -1) { 18941 _selectedPaths[i]._onReleaseAlt(); 18942 } 18943 } 18944 }, true); 18945 18946 _supportsPointer = !!_win.PointerEvent; 18947 18948 _addListener(_doc, "mouseup", _checkDeselect); 18949 18950 _addListener(_doc, "touchend", _checkDeselect); 18951 18952 _addListener(_doc, "touchcancel", _emptyFunc); //some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. Very strange indeed. 18953 18954 18955 _addListener(_win, "touchmove", _emptyFunc); //works around Safari bugs that still allow the page to scroll even when we preventDefault() on the touchmove event. 18956 18957 18958 _body && _body.addEventListener("touchstart", _emptyFunc); //works around Safari bug: https://greensock.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 18959 18960 _coreInitted = 1; 18961}, 18962 _onPress = function _onPress(e) { 18963 var self = this, 18964 ctm = Object(_matrix_js__WEBPACK_IMPORTED_MODULE_1__["getGlobalMatrix"])(self.target.parentNode, true), 18965 //previously used self.target.parentNode.getScreenCTM().inverse() but there's a major bug in Firefox that prevents it from working properly when there's an ancestor with a transform applied, so we bootstrapped our own solution that seems ot work great across all browsers. 18966 touchEventTarget, 18967 temp; 18968 this._matrix = this.target.transform.baseVal.getItem(0).matrix; 18969 this._ctm = ctm; 18970 18971 if (_touchEventLookup[e.type]) { 18972 //note: on iOS, BOTH touchmove and mousemove are dispatched, but the mousemove has pageY and pageX of 0 which would mess up the calculations and needlessly hurt performance. 18973 touchEventTarget = e.type.indexOf("touch") !== -1 ? e.currentTarget || e.target : _doc; //pointer-based touches (for Microsoft browsers) don't remain locked to the original target like other browsers, so we must use the document instead. The event type would be "MSPointerDown" or "pointerdown". 18974 18975 _addListener(touchEventTarget, "touchend", self._onRelease); 18976 18977 _addListener(touchEventTarget, "touchmove", self._onMove); 18978 18979 _addListener(touchEventTarget, "touchcancel", self._onRelease); 18980 18981 _addListener(_doc, "touchstart", _onMultiTouchDocument); 18982 18983 _addListener(_win, "touchforcechange", _preventDefault); //otherwise iOS will scroll when dragging. 18984 18985 } else { 18986 touchEventTarget = null; 18987 18988 _addListener(_doc, "mousemove", self._onMove); //attach these to the document instead of the box itself so that if the user's mouse moves too quickly (and off of the box), things still work. 18989 18990 } 18991 18992 if (!_supportsPointer) { 18993 _addListener(_doc, "mouseup", self._onRelease); 18994 } 18995 18996 _preventDefault(e); 18997 18998 _resetSelection(); // when a PathEditor is in an iframe in an environment like codepen, this helps avoid situations where the DELETE key won't actually work because the parent frame is intercepting the event. 18999 19000 19001 if (e.changedTouches) { 19002 //touch events store the data slightly differently 19003 e = self.touch = e.changedTouches[0]; 19004 self.touchID = e.identifier; 19005 } else if (e.pointerId) { 19006 self.touchID = e.pointerId; //for some Microsoft browsers 19007 } else { 19008 self.touch = self.touchID = null; 19009 } 19010 19011 self._startPointerY = self.pointerY = e.pageY; //record the starting x and y so that we can calculate the movement from the original in _onMouseMove 19012 19013 self._startPointerX = self.pointerX = e.pageX; 19014 self._startElementX = self._matrix.e; 19015 self._startElementY = self._matrix.f; 19016 19017 if (this._ctm.a === 1 && this._ctm.b === 0 && this._ctm.c === 0 && this._ctm.d === 1) { 19018 this._ctm = null; 19019 } else { 19020 temp = self._startPointerX * this._ctm.a + self._startPointerY * this._ctm.c + this._ctm.e; 19021 self._startPointerY = self._startPointerX * this._ctm.b + self._startPointerY * this._ctm.d + this._ctm.f; 19022 self._startPointerX = temp; 19023 } 19024 19025 self.isPressed = _isPressed = true; 19026 self.touchEventTarget = touchEventTarget; 19027 19028 if (self.vars.onPress) { 19029 self.vars.onPress.call(self.vars.callbackScope || self, self.pointerEvent); 19030 } 19031}, 19032 _onMove = function _onMove(e) { 19033 var self = this, 19034 originalEvent = e, 19035 touches, 19036 i; 19037 19038 if (!self._enabled || _isMultiTouching || !self.isPressed || !e) { 19039 return; 19040 } 19041 19042 self.pointerEvent = e; 19043 touches = e.changedTouches; 19044 19045 if (touches) { 19046 //touch events store the data slightly differently 19047 e = touches[0]; 19048 19049 if (e !== self.touch && e.identifier !== self.touchID) { 19050 //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) 19051 i = touches.length; 19052 19053 while (--i > -1 && (e = touches[i]).identifier !== self.touchID) {} 19054 19055 if (i < 0) { 19056 return; 19057 } 19058 } 19059 } else if (e.pointerId && self.touchID && e.pointerId !== self.touchID) { 19060 //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch) 19061 return; 19062 } 19063 19064 _preventDefault(originalEvent); 19065 19066 self.setPointerPosition(e.pageX, e.pageY); 19067 19068 if (self.vars.onDrag) { 19069 self.vars.onDrag.call(self.vars.callbackScope || self, self.pointerEvent); 19070 } 19071}, 19072 _onRelease = function _onRelease(e, force) { 19073 var self = this; 19074 19075 if (!self._enabled || !self.isPressed || e && self.touchID != null && !force && (e.pointerId && e.pointerId !== self.touchID || e.changedTouches && !_hasTouchID(e.changedTouches, self.touchID))) { 19076 //for some Microsoft browsers, we must attach the listener to the doc rather than the trigger so that when the finger moves outside the bounds of the trigger, things still work. So if the event we're receiving has a pointerId that doesn't match the touchID, ignore it (for multi-touch) 19077 return; 19078 } 19079 19080 _interacted(); 19081 19082 self.isPressed = _isPressed = false; //TODO: if we want to accommodate multi-touch, we'd need to introduce a counter to track how many touches there are and only toggle this when they're all off. 19083 19084 var originalEvent = e, 19085 wasDragging = self.isDragging, 19086 touchEventTarget = self.touchEventTarget, 19087 touches, 19088 i; 19089 19090 if (touchEventTarget) { 19091 _removeListener(touchEventTarget, "touchend", self._onRelease); 19092 19093 _removeListener(touchEventTarget, "touchmove", self._onMove); 19094 19095 _removeListener(touchEventTarget, "touchcancel", self._onRelease); 19096 19097 _removeListener(_doc, "touchstart", _onMultiTouchDocument); 19098 } else { 19099 _removeListener(_doc, "mousemove", self._onMove); 19100 } 19101 19102 if (!_supportsPointer) { 19103 _removeListener(_doc, "mouseup", self._onRelease); 19104 19105 if (e && e.target) { 19106 _removeListener(e.target, "mouseup", self._onRelease); 19107 } 19108 } 19109 19110 if (wasDragging) { 19111 self.isDragging = false; 19112 } else if (self.vars.onClick) { 19113 self.vars.onClick.call(self.vars.callbackScope || self, originalEvent); 19114 } 19115 19116 if (e) { 19117 touches = e.changedTouches; 19118 19119 if (touches) { 19120 //touch events store the data slightly differently 19121 e = touches[0]; 19122 19123 if (e !== self.touch && e.identifier !== self.touchID) { 19124 //Usually changedTouches[0] will be what we're looking for, but in case it's not, look through the rest of the array...(and Android browsers don't reuse the event like iOS) 19125 i = touches.length; 19126 19127 while (--i > -1 && (e = touches[i]).identifier !== self.touchID) {} 19128 19129 if (i < 0) { 19130 return; 19131 } 19132 } 19133 } 19134 19135 self.pointerEvent = originalEvent; 19136 self.pointerX = e.pageX; 19137 self.pointerY = e.pageY; 19138 } 19139 19140 if (originalEvent && !wasDragging && self.vars.onDragRelease) { 19141 self.vars.onDragRelease.call(self, self.pointerEvent); 19142 } else { 19143 if (originalEvent) { 19144 _preventDefault(originalEvent); 19145 } 19146 19147 if (self.vars.onRelease) { 19148 self.vars.onRelease.call(self.vars.callbackScope || self, self.pointerEvent); 19149 } 19150 } 19151 19152 if (wasDragging && self.vars.onDragEnd) { 19153 self.vars.onDragEnd.call(self.vars.callbackScope || self, self.pointerEvent); 19154 } 19155 19156 return true; 19157}, 19158 _createSegmentAnchors = function _createSegmentAnchors(rawPath, j, editor, vars) { 19159 var segment = rawPath[j], 19160 l = segment.length, 19161 a = [], 19162 i; 19163 19164 for (i = 0; i < l; i += 6) { 19165 a.push(new Anchor(editor, rawPath, j, i, vars)); 19166 } 19167 19168 return a; 19169}, 19170 _getLength = function _getLength(segment, i, i2) { 19171 //i is the starting index, and it'll return the length to the next x/y pair. So if you're looking for the length to handle1, you'd feed in the index of the handle control point x whereas if you're looking for the length to handle2, i would be the x of the anchor. 19172 var x = segment[i2] - segment[i], 19173 y = segment[i2 + 1] - segment[i + 1]; 19174 return Math.sqrt(x * x + y * y); 19175}; 19176 19177var DraggableSVG = /*#__PURE__*/function () { 19178 function DraggableSVG(target, vars) { 19179 this.target = typeof target === "string" ? _doc.querySelectorAll(target)[0] : target; 19180 this.vars = vars || {}; 19181 this._onPress = _bind(_onPress, this); 19182 this._onMove = _bind(_onMove, this); 19183 this._onRelease = _bind(_onRelease, this); 19184 this.target.setAttribute("transform", (this.target.getAttribute("transform") || "") + " translate(0,0)"); 19185 this._matrix = _getConsolidatedMatrix(this.target); 19186 this.x = this._matrix.e; 19187 this.y = this._matrix.f; 19188 this.snap = vars.snap; 19189 19190 if (!isNaN(vars.maxX) || !isNaN(vars.minX)) { 19191 this._bounds = 1; 19192 this.maxX = +vars.maxX; 19193 this.minX = +vars.minX; 19194 } else { 19195 this._bounds = 0; 19196 } 19197 19198 this.enabled(true); 19199 } 19200 19201 var _proto = DraggableSVG.prototype; 19202 19203 _proto.setPointerPosition = function setPointerPosition(pointerX, pointerY) { 19204 var rnd = 1000, 19205 xChange, 19206 yChange, 19207 x, 19208 y, 19209 temp; 19210 this.pointerX = pointerX; 19211 this.pointerY = pointerY; 19212 19213 if (this._ctm) { 19214 temp = pointerX * this._ctm.a + pointerY * this._ctm.c + this._ctm.e; 19215 pointerY = pointerX * this._ctm.b + pointerY * this._ctm.d + this._ctm.f; 19216 pointerX = temp; 19217 } 19218 19219 yChange = pointerY - this._startPointerY; 19220 xChange = pointerX - this._startPointerX; 19221 19222 if (yChange < _minimumMovement && yChange > -_minimumMovement) { 19223 yChange = 0; 19224 } 19225 19226 if (xChange < _minimumMovement && xChange > -_minimumMovement) { 19227 xChange = 0; 19228 } 19229 19230 x = ((this._startElementX + xChange) * rnd | 0) / rnd; 19231 y = ((this._startElementY + yChange) * rnd | 0) / rnd; 19232 19233 if (this.snap && !_SHIFT) { 19234 _point.x = x; 19235 _point.y = y; 19236 this.snap.call(this, _point); 19237 x = _point.x; 19238 y = _point.y; 19239 } 19240 19241 if (this.x !== x || this.y !== y) { 19242 this._matrix.f = this.y = y; 19243 this._matrix.e = this.x = x; 19244 19245 if (!this.isDragging && this.isPressed) { 19246 this.isDragging = true; 19247 19248 _callback("onDragStart", this, this.pointerEvent); 19249 } 19250 } 19251 }; 19252 19253 _proto.enabled = function enabled(_enabled) { 19254 if (!arguments.length) { 19255 return this._enabled; 19256 } 19257 19258 var dragging; 19259 this._enabled = _enabled; 19260 19261 if (_enabled) { 19262 if (!_supportsPointer) { 19263 _addListener(this.target, "mousedown", this._onPress); 19264 } 19265 19266 _addListener(this.target, "touchstart", this._onPress); 19267 19268 _addListener(this.target, "click", this._onClick, true); //note: used to pass true for capture but it prevented click-to-play-video functionality in Firefox. 19269 19270 } else { 19271 dragging = this.isDragging; 19272 19273 _removeListener(this.target, "mousedown", this._onPress); 19274 19275 _removeListener(this.target, "touchstart", this._onPress); 19276 19277 _removeListener(_win, "touchforcechange", _preventDefault); 19278 19279 _removeListener(this.target, "click", this._onClick); 19280 19281 if (this.touchEventTarget) { 19282 _removeListener(this.touchEventTarget, "touchcancel", this._onRelease); 19283 19284 _removeListener(this.touchEventTarget, "touchend", this._onRelease); 19285 19286 _removeListener(this.touchEventTarget, "touchmove", this._onMove); 19287 } 19288 19289 _removeListener(_doc, "mouseup", this._onRelease); 19290 19291 _removeListener(_doc, "mousemove", this._onMove); 19292 19293 this.isDragging = this.isPressed = false; 19294 19295 if (dragging) { 19296 _callback("onDragEnd", this, this.pointerEvent); 19297 } 19298 } 19299 19300 return this; 19301 }; 19302 19303 _proto.endDrag = function endDrag(e) { 19304 this._onRelease(e); 19305 }; 19306 19307 return DraggableSVG; 19308}(); 19309 19310var Anchor = /*#__PURE__*/function () { 19311 function Anchor(editor, rawPath, j, i, vars) { 19312 this.editor = editor; 19313 this.element = _createSVG("path", editor._selection, { 19314 fill: _selectionColor, 19315 stroke: _selectionColor, 19316 strokeWidth: 2, 19317 vectorEffect: "non-scaling-stroke" 19318 }); 19319 this.update(rawPath, j, i); 19320 this.element._gsSelection = true; 19321 this.vars = vars || {}; 19322 this._draggable = new DraggableSVG(this.element, { 19323 callbackScope: this, 19324 onDrag: this.onDrag, 19325 snap: this.vars.snap, 19326 onPress: this.onPress, 19327 onRelease: this.onRelease, 19328 onClick: this.onClick, 19329 onDragEnd: this.onDragEnd 19330 }); 19331 } 19332 19333 var _proto2 = Anchor.prototype; 19334 19335 _proto2.onPress = function onPress() { 19336 _callback("onPress", this); 19337 }; 19338 19339 _proto2.onClick = function onClick() { 19340 _callback("onClick", this); 19341 }; 19342 19343 _proto2.onDrag = function onDrag() { 19344 var s = this.segment; 19345 this.vars.onDrag.call(this.vars.callbackScope || this, this, this._draggable.x - s[this.i], this._draggable.y - s[this.i + 1]); 19346 }; 19347 19348 _proto2.onDragEnd = function onDragEnd() { 19349 _callback("onDragEnd", this); 19350 }; 19351 19352 _proto2.onRelease = function onRelease() { 19353 _callback("onRelease", this); 19354 }; 19355 19356 _proto2.update = function update(rawPath, j, i) { 19357 if (rawPath) { 19358 this.rawPath = rawPath; 19359 } 19360 19361 if (arguments.length <= 1) { 19362 j = this.j; 19363 i = this.i; 19364 } else { 19365 this.j = j; 19366 this.i = i; 19367 } 19368 19369 var prevSmooth = this.smooth, 19370 segment = this.rawPath[j]; 19371 this.segment = segment; 19372 this.smooth = i && i < segment.length - 2 && Math.abs(Math.atan2(segment[i + 1] - segment[i - 1], segment[i] - segment[i - 2]) - Math.atan2(segment[i + 3] - segment[i + 1], segment[i + 2] - segment[i])) < 0.09 ? 2 : 0; //0: corner, 1: smooth but not mirrored, 2: smooth and mirrored. 19373 19374 if (this.smooth !== prevSmooth) { 19375 this.element.setAttribute("d", this.smooth ? this.editor._circleHandle : this.editor._squareHandle); 19376 } 19377 19378 this.element.setAttribute("transform", "translate(" + segment[i] + "," + segment[i + 1] + ")"); 19379 }; 19380 19381 return Anchor; 19382}(); 19383 19384var PathEditor = /*#__PURE__*/function () { 19385 function PathEditor(target, vars) { 19386 vars = vars || {}; 19387 19388 if (!_coreInitted) { 19389 _initCore(); 19390 } 19391 19392 this.vars = vars; 19393 this.path = typeof target === "string" ? _doc.querySelectorAll(target)[0] : target; 19394 this._g = _createSVG("g", this.path.ownerSVGElement, { 19395 "class": "path-editor-g path-editor" 19396 }); 19397 this._selectionHittest = _createSVG("path", this._g, { 19398 stroke: "transparent", 19399 strokeWidth: 16, 19400 fill: "none", 19401 vectorEffect: "non-scaling-stroke" 19402 }); 19403 this._selection = vars._selection || _createSVG("g", this._g, { 19404 "class": "path-editor-selection path-editor" 19405 }); 19406 this._selectionPath = _createSVG("path", this._selection, { 19407 stroke: _selectionColor, 19408 strokeWidth: 2, 19409 fill: "none", 19410 vectorEffect: "non-scaling-stroke" 19411 }); 19412 this._selectedAnchors = []; 19413 this._line1 = _createSVG("polyline", this._selection, { 19414 stroke: _selectionColor, 19415 strokeWidth: 2, 19416 vectorEffect: "non-scaling-stroke" 19417 }); 19418 this._line2 = _createSVG("polyline", this._selection, { 19419 stroke: _selectionColor, 19420 strokeWidth: 2, 19421 vectorEffect: "non-scaling-stroke" 19422 }); 19423 this._line1.style.pointerEvents = this._line2.style.pointerEvents = this._selectionPath.style.pointerEvents = "none"; 19424 this._enabled = true; 19425 var ctm = this.path.parentNode.getScreenCTM().inverse(), 19426 size = (ctm.a + ctm.d) / 2 * (vars.handleSize || 5); 19427 this._squareHandle = _getSquarePathData(size); 19428 this._circleHandle = _getCirclePathData(size * 1.15); 19429 this._handle1 = _createSVG("path", this._selection, { 19430 d: this._squareHandle, 19431 fill: _selectionColor, 19432 stroke: "transparent", 19433 strokeWidth: 6 19434 }); 19435 this._handle2 = _createSVG("path", this._selection, { 19436 d: this._squareHandle, 19437 fill: _selectionColor, 19438 stroke: "transparent", 19439 strokeWidth: 6 19440 }); 19441 this._handle1._draggable = new DraggableSVG(this._handle1, { 19442 onDrag: this._onDragHandle1, 19443 callbackScope: this, 19444 onPress: this._onPressHandle1, 19445 onRelease: this._onReleaseHandle, 19446 onClick: this._onClickHandle1, 19447 snap: vars.handleSnap 19448 }); 19449 this._handle2._draggable = new DraggableSVG(this._handle2, { 19450 onDrag: this._onDragHandle2, 19451 callbackScope: this, 19452 onPress: this._onPressHandle2, 19453 onRelease: this._onReleaseHandle, 19454 onClick: this._onClickHandle2, 19455 snap: vars.handleSnap 19456 }); 19457 this._handle1.style.visibility = this._handle2.style.visibility = "hidden"; 19458 var selectionItems = [this._handle1, this._handle2, this._line1, this._line2, this._selection, this._selectionPath, this._selectionHittest], 19459 i = selectionItems.length; 19460 19461 while (--i > -1) { 19462 selectionItems[i]._gsSelection = true; //just a flag we can check in the _checkDeselect() method to detect clicks on things that are selection-related. 19463 } 19464 19465 if (vars.draggable !== false) { 19466 this._draggable = new DraggableSVG(this._selectionHittest, { 19467 callbackScope: this, 19468 onPress: this.select, 19469 onRelease: this._onRelease, 19470 onDrag: this._onDragPath, 19471 onDragEnd: this._saveState, 19472 maxX: this.vars.maxX, 19473 minX: this.vars.minX 19474 }); 19475 } 19476 19477 this.init(); 19478 this._selection.style.visibility = vars.selected === false ? "hidden" : "visible"; 19479 19480 if (vars.selected !== false) { 19481 this.path._gsSelection = true; 19482 19483 _selectedPaths.push(this); 19484 } 19485 19486 this._saveState(); 19487 19488 if (!_supportsPointer) { 19489 _addListener(this._selectionHittest, "mousedown", _bind(this._onClickSelectionPath, this)); 19490 19491 _addListener(this._selectionHittest, "mouseup", _bind(this._onRelease, this)); 19492 } 19493 19494 _addListener(this._selectionHittest, "touchstart", _bind(this._onClickSelectionPath, this)); 19495 19496 _addListener(this._selectionHittest, "touchend", _bind(this._onRelease, this)); 19497 } 19498 19499 var _proto3 = PathEditor.prototype; 19500 19501 _proto3._onRelease = function _onRelease(e) { 19502 var anchor = this._editingAnchor; 19503 19504 if (anchor) { 19505 _editingAxis.x = anchor.segment[anchor.i]; 19506 _editingAxis.y = anchor.segment[anchor.i + 1]; 19507 } 19508 19509 _removeListener(_win, "touchforcechange", _preventDefault); //otherwise iOS will scroll when dragging. 19510 19511 19512 _callback("onRelease", this, e); 19513 }; 19514 19515 _proto3.init = function init() { 19516 var pathData = this.path.getAttribute("d"), 19517 rawPath = Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(pathData), 19518 transform = this.path.getAttribute("transform") || "translate(0,0)", 19519 createAnchors = !this._rawPath || rawPath.totalPoints !== this._rawPath.totalPoints || rawPath.length !== this._rawPath.length, 19520 anchorVars = { 19521 callbackScope: this, 19522 snap: this.vars.anchorSnap, 19523 onDrag: this._onDragAnchor, 19524 onPress: this._onPressAnchor, 19525 onRelease: this._onRelease, 19526 onClick: this._onClickAnchor, 19527 onDragEnd: this._onDragEndAnchor, 19528 maxX: this.vars.maxX, 19529 minX: this.vars.minX 19530 }, 19531 l, 19532 i; 19533 19534 if (createAnchors && this._anchors && this._anchors.length) { 19535 for (i = 0; i < this._anchors.length; i++) { 19536 this._anchors[i].element.parentNode.removeChild(this._anchors[i].element); 19537 19538 this._anchors[i]._draggable.enabled(false); 19539 } 19540 19541 this._selectedAnchors.length = 0; 19542 } 19543 19544 this._rawPath = rawPath; 19545 19546 if (createAnchors) { 19547 this._anchors = _createSegmentAnchors(rawPath, 0, this, anchorVars); 19548 l = rawPath.length; 19549 19550 if (l > 1) { 19551 for (i = 1; i < l; i++) { 19552 this._anchors = this._anchors.concat(_createSegmentAnchors(rawPath, i, this, anchorVars)); 19553 } 19554 } 19555 } else { 19556 i = this._anchors.length; 19557 19558 while (--i > -1) { 19559 this._anchors[i].update(rawPath); 19560 } 19561 } 19562 19563 this._selection.appendChild(this._handle1); //for stacking order (handles should always be on top) 19564 19565 19566 this._selection.appendChild(this._handle2); // this._selectedAnchors.length = 0; 19567 19568 19569 this._selectionPath.setAttribute("d", pathData); 19570 19571 this._selectionHittest.setAttribute("d", pathData); 19572 19573 this._g.setAttribute("transform", _getConcatenatedTransforms(this.path.parentNode) || "translate(0,0)"); 19574 19575 this._selection.setAttribute("transform", transform); 19576 19577 this._selectionHittest.setAttribute("transform", transform); 19578 19579 this._updateAnchors(); 19580 19581 return this; 19582 }; 19583 19584 _proto3._saveState = function _saveState() { 19585 _addHistory(this); 19586 }; 19587 19588 _proto3._onClickSelectionPath = function _onClickSelectionPath(e) { 19589 if (this._selection.style.visibility === "hidden") { 19590 this.select(); 19591 } else if (_ALT || e && e.altKey) { 19592 var anchorVars = { 19593 callbackScope: this, 19594 snap: this.vars.anchorSnap, 19595 onDrag: this._onDragAnchor, 19596 onPress: this._onPressAnchor, 19597 onRelease: this._onRelease, 19598 onClick: this._onClickAnchor, 19599 onDragEnd: this._onDragEndAnchor, 19600 maxX: this.vars.maxX, 19601 minX: this.vars.minX 19602 }, 19603 ctm = this._selection.getScreenCTM().inverse(), 19604 newIndex, 19605 _i, 19606 anchor, 19607 x, 19608 y, 19609 closestData; 19610 19611 if (this._draggable) { 19612 this._draggable._onRelease(e); //otherwise, ALT-click/dragging on a path would create a new anchor AND drag the entire path. 19613 19614 } 19615 19616 if (ctm) { 19617 x = e.clientX * ctm.a + e.clientY * ctm.c + ctm.e; 19618 y = e.clientX * ctm.b + e.clientY * ctm.d + ctm.f; 19619 } //DEBUG: _createSVG("circle", this._selection, {fill:"red", r:5, cx:x, cy:y}); 19620 19621 19622 closestData = Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["getClosestData"])(this._rawPath, x, y); 19623 Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["subdivideSegment"])(this._rawPath[closestData.j], closestData.i, closestData.t); 19624 newIndex = closestData.i + 6; 19625 19626 for (_i = 0; _i < this._anchors.length; _i++) { 19627 if (this._anchors[_i].i >= newIndex) { 19628 this._anchors[_i].i += 6; 19629 } 19630 } 19631 19632 anchor = new Anchor(this, this._rawPath, closestData.j, newIndex, anchorVars); 19633 19634 this._selection.appendChild(this._handle1); //for stacking order (handles should always be on top) 19635 19636 19637 this._selection.appendChild(this._handle2); 19638 19639 anchor._draggable._onPress(e); 19640 19641 _recentlyAddedAnchor = anchor; 19642 19643 this._anchors.push(anchor); 19644 19645 this._selectedAnchors.length = 0; 19646 19647 this._selectedAnchors.push(anchor); 19648 19649 this._updateAnchors(); 19650 19651 this.update(); 19652 19653 this._saveState(); 19654 } 19655 19656 _resetSelection(); 19657 19658 _addListener(_win, "touchforcechange", _preventDefault); //otherwise iOS will scroll when dragging. 19659 19660 19661 _callback("onPress", this); 19662 }; 19663 19664 _proto3._onClickHandle1 = function _onClickHandle1() { 19665 var anchor = this._editingAnchor, 19666 i = anchor.i, 19667 s = anchor.segment; 19668 19669 if (_ALT && Math.abs(s[i] - s[i - 2]) < 5 && Math.abs(s[i + 1] - s[i - 1]) < 5) { 19670 this._onClickAnchor(anchor); 19671 } 19672 }; 19673 19674 _proto3._onClickHandle2 = function _onClickHandle2() { 19675 var anchor = this._editingAnchor, 19676 i = anchor.i, 19677 s = anchor.segment; 19678 19679 if (_ALT && Math.abs(s[i] - s[i + 2]) < 5 && Math.abs(s[i + 1] - s[i + 3]) < 5) { 19680 this._onClickAnchor(anchor); 19681 } 19682 }; 19683 19684 _proto3._onDragEndAnchor = function _onDragEndAnchor(e) { 19685 _recentlyAddedAnchor = null; 19686 19687 this._saveState(); 19688 }; 19689 19690 _proto3.isSelected = function isSelected() { 19691 return this._selectedAnchors.length > 0; 19692 }; 19693 19694 _proto3.select = function select(allAnchors) { 19695 this._selection.style.visibility = "visible"; 19696 this._editingAnchor = null; 19697 this.path._gsSelection = true; 19698 19699 if (allAnchors === true) { 19700 var _i2 = this._anchors.length; 19701 19702 while (--_i2 > -1) { 19703 this._selectedAnchors[_i2] = this._anchors[_i2]; 19704 } 19705 } 19706 19707 if (_selectedPaths.indexOf(this) === -1) { 19708 _selectedPaths.push(this); 19709 } 19710 19711 this._updateAnchors(); 19712 19713 return this; 19714 }; 19715 19716 _proto3.deselect = function deselect() { 19717 this._selection.style.visibility = "hidden"; 19718 this._selectedAnchors.length = 0; 19719 this._editingAnchor = null; 19720 this.path._gsSelection = false; 19721 19722 _selectedPaths.splice(_selectedPaths.indexOf(this), 1); 19723 19724 this._updateAnchors(); 19725 19726 return this; 19727 }; 19728 19729 _proto3._onDragPath = function _onDragPath(e) { 19730 var transform = this._selectionHittest.getAttribute("transform") || "translate(0,0)"; 19731 19732 this._selection.setAttribute("transform", transform); 19733 19734 this.path.setAttribute("transform", transform); 19735 }; 19736 19737 _proto3._onPressAnchor = function _onPressAnchor(anchor) { 19738 if (this._selectedAnchors.indexOf(anchor) === -1) { 19739 //if it isn't already selected... 19740 if (!_SHIFT) { 19741 this._selectedAnchors.length = 0; 19742 } 19743 19744 this._selectedAnchors.push(anchor); 19745 } else if (_SHIFT) { 19746 this._selectedAnchors.splice(this._selectedAnchors.indexOf(anchor), 1); 19747 19748 anchor._draggable.endDrag(); 19749 } 19750 19751 _editingAxis.x = anchor.segment[anchor.i]; 19752 _editingAxis.y = anchor.segment[anchor.i + 1]; 19753 19754 this._updateAnchors(); 19755 19756 _callback("onPress", this); 19757 }; 19758 19759 _proto3._deleteSelectedAnchors = function _deleteSelectedAnchors() { 19760 var anchors = this._selectedAnchors, 19761 i = anchors.length, 19762 anchor, 19763 index, 19764 j; 19765 19766 while (--i > -1) { 19767 anchor = anchors[i]; 19768 anchor.element.parentNode.removeChild(anchor.element); 19769 19770 anchor._draggable.enabled(false); 19771 19772 index = anchor.i; 19773 19774 if (!index) { 19775 //first 19776 anchor.segment.splice(index, 6); 19777 } else if (index < anchor.segment.length - 2) { 19778 anchor.segment.splice(index - 2, 6); 19779 } else { 19780 //last 19781 anchor.segment.splice(index - 4, 6); 19782 } 19783 19784 anchors.splice(i, 1); 19785 19786 this._anchors.splice(this._anchors.indexOf(anchor), 1); 19787 19788 for (j = 0; j < this._anchors.length; j++) { 19789 if (this._anchors[j].i >= index) { 19790 this._anchors[j].i -= 6; 19791 } 19792 } 19793 } 19794 19795 this._updateAnchors(); 19796 19797 this.update(); 19798 19799 this._saveState(); 19800 19801 if (this.vars.onDeleteAnchor) { 19802 this.vars.onDeleteAnchor.call(this.vars.callbackScope || this); 19803 } 19804 }; 19805 19806 _proto3._onClickAnchor = function _onClickAnchor(anchor) { 19807 var i = anchor.i, 19808 segment = anchor.segment, 19809 rnd = 1000, 19810 isEnd = !i || i >= segment.length - 2, 19811 angle1, 19812 angle2, 19813 length1, 19814 length2, 19815 sin, 19816 cos; 19817 19818 if (_ALT && _recentlyAddedAnchor !== anchor && this._editingAnchor) { 19819 anchor.smooth = !anchor.smooth; 19820 19821 if (isEnd) { 19822 //the very ends can't be "smooth" 19823 anchor.smooth = false; 19824 } 19825 19826 anchor.element.setAttribute("d", anchor.smooth ? this._circleHandle : this._squareHandle); 19827 19828 if (anchor.smooth && !isEnd) { 19829 angle1 = Math.atan2(segment[i + 1] - segment[i - 1], segment[i] - segment[i - 2]); 19830 angle2 = Math.atan2(segment[i + 3] - segment[i + 1], segment[i + 2] - segment[i]); 19831 angle1 = (angle1 + angle2) / 2; 19832 length1 = _getLength(segment, i - 2, i); 19833 length2 = _getLength(segment, i, i + 2); 19834 19835 if (length1 < 0.2) { 19836 length1 = _getLength(segment, i, i - 6) / 4; 19837 angle1 = angle2 || Math.atan2(segment[i + 7] - segment[i - 5], segment[i + 6] - segment[i - 6]); 19838 } 19839 19840 if (length2 < 0.2) { 19841 length2 = _getLength(segment, i, i + 6) / 4; 19842 angle2 = angle1 || Math.atan2(segment[i + 7] - segment[i - 5], segment[i + 6] - segment[i - 6]); 19843 } 19844 19845 sin = Math.sin(angle1); 19846 cos = Math.cos(angle1); 19847 19848 if (Math.abs(angle2 - angle1) < Math.PI / 2) { 19849 sin = -sin; 19850 cos = -cos; 19851 } 19852 19853 segment[i - 2] = ((segment[i] + cos * length1) * rnd | 0) / rnd; 19854 segment[i - 1] = ((segment[i + 1] + sin * length1) * rnd | 0) / rnd; 19855 segment[i + 2] = ((segment[i] - cos * length2) * rnd | 0) / rnd; 19856 segment[i + 3] = ((segment[i + 1] - sin * length2) * rnd | 0) / rnd; 19857 19858 this._updateAnchors(); 19859 19860 this.update(); 19861 19862 this._saveState(); 19863 } else if (!anchor.smooth && !isEnd) { 19864 if (i) { 19865 segment[i - 2] = segment[i]; 19866 segment[i - 1] = segment[i + 1]; 19867 } 19868 19869 if (i < segment.length - 2) { 19870 segment[i + 2] = segment[i]; 19871 segment[i + 3] = segment[i + 1]; 19872 } 19873 19874 this._updateAnchors(); 19875 19876 this.update(); 19877 19878 this._saveState(); 19879 } 19880 } else if (!_SHIFT) { 19881 this._selectedAnchors.length = 0; 19882 19883 this._selectedAnchors.push(anchor); 19884 } 19885 19886 _recentlyAddedAnchor = null; 19887 19888 this._updateAnchors(); 19889 }; 19890 19891 _proto3._updateAnchors = function _updateAnchors() { 19892 var anchor = this._selectedAnchors.length === 1 ? this._selectedAnchors[0] : null, 19893 segment = anchor ? anchor.segment : null, 19894 i, 19895 x, 19896 y; 19897 this._editingAnchor = anchor; 19898 19899 for (i = 0; i < this._anchors.length; i++) { 19900 this._anchors[i].element.style.fill = this._selectedAnchors.indexOf(this._anchors[i]) !== -1 ? _selectionColor : "white"; //this._anchors[i].element.setAttribute("fill", (this._selectedAnchors.indexOf(this._anchors[i]) !== -1) ? _selectionColor : "white"); 19901 } 19902 19903 if (anchor) { 19904 this._handle1.setAttribute("d", anchor.smooth ? this._circleHandle : this._squareHandle); 19905 19906 this._handle2.setAttribute("d", anchor.smooth ? this._circleHandle : this._squareHandle); 19907 } 19908 19909 i = anchor ? anchor.i : 0; 19910 19911 if (anchor && i) { 19912 x = segment[i - 2]; 19913 y = segment[i - 1]; //TODO: if they equal the anchor coordinates, just hide it. 19914 19915 this._handle1.style.visibility = this._line1.style.visibility = !_ALT && x === segment[i] && y === segment[i + 1] ? "hidden" : "visible"; 19916 19917 this._handle1.setAttribute("transform", "translate(" + x + _comma + y + ")"); 19918 19919 this._line1.setAttribute("points", x + _comma + y + _comma + segment[i] + _comma + segment[i + 1]); 19920 } else { 19921 this._handle1.style.visibility = this._line1.style.visibility = "hidden"; 19922 } 19923 19924 if (anchor && i < segment.length - 2) { 19925 x = segment[i + 2]; 19926 y = segment[i + 3]; 19927 this._handle2.style.visibility = this._line2.style.visibility = !_ALT && x === segment[i] && y === segment[i + 1] ? "hidden" : "visible"; 19928 19929 this._handle2.setAttribute("transform", "translate(" + x + _comma + y + ")"); 19930 19931 this._line2.setAttribute("points", segment[i] + _comma + segment[i + 1] + _comma + x + _comma + y); 19932 } else { 19933 this._handle2.style.visibility = this._line2.style.visibility = "hidden"; 19934 } 19935 }; 19936 19937 _proto3._onPressAlt = function _onPressAlt() { 19938 var anchor = this._editingAnchor; 19939 19940 if (anchor) { 19941 if (anchor.i) { 19942 this._handle1.style.visibility = this._line1.style.visibility = "visible"; 19943 } 19944 19945 if (anchor.i < anchor.segment.length - 2) { 19946 this._handle2.style.visibility = this._line2.style.visibility = "visible"; 19947 } 19948 } 19949 }; 19950 19951 _proto3._onReleaseAlt = function _onReleaseAlt() { 19952 var anchor = this._editingAnchor, 19953 s, 19954 i; 19955 19956 if (anchor) { 19957 s = anchor.segment; 19958 i = anchor.i; 19959 19960 if (s[i] === s[i - 2] && s[i + 1] === s[i - 1]) { 19961 this._handle1.style.visibility = this._line1.style.visibility = "hidden"; 19962 } 19963 19964 if (s[i] === s[i + 2] && s[i + 1] === s[i + 3]) { 19965 this._handle2.style.visibility = this._line2.style.visibility = "hidden"; 19966 } 19967 } 19968 }; 19969 19970 _proto3._onPressHandle1 = function _onPressHandle1() { 19971 if (this._editingAnchor.smooth) { 19972 this._oppositeHandleLength = _getLength(this._editingAnchor.segment, this._editingAnchor.i, this._editingAnchor.i + 2); 19973 } 19974 19975 _callback("onPress", this); 19976 }; 19977 19978 _proto3._onPressHandle2 = function _onPressHandle2() { 19979 if (this._editingAnchor.smooth) { 19980 this._oppositeHandleLength = _getLength(this._editingAnchor.segment, this._editingAnchor.i - 2, this._editingAnchor.i); 19981 } 19982 19983 _callback("onPress", this); 19984 }; 19985 19986 _proto3._onReleaseHandle = function _onReleaseHandle(e) { 19987 this._onRelease(e); 19988 19989 this._saveState(); 19990 }; 19991 19992 _proto3._onDragHandle1 = function _onDragHandle1() { 19993 var anchor = this._editingAnchor, 19994 s = anchor.segment, 19995 i = anchor.i, 19996 rnd = 1000, 19997 x = this._handle1._draggable.x, 19998 y = this._handle1._draggable.y, 19999 angle; 20000 s[i - 2] = x = (x * rnd | 0) / rnd; 20001 s[i - 1] = y = (y * rnd | 0) / rnd; 20002 20003 if (anchor.smooth) { 20004 if (_ALT) { 20005 anchor.smooth = false; 20006 anchor.element.setAttribute("d", this._squareHandle); 20007 20008 this._handle1.setAttribute("d", this._squareHandle); 20009 20010 this._handle2.setAttribute("d", this._squareHandle); 20011 } else { 20012 angle = Math.atan2(s[i + 1] - y, s[i] - x); 20013 x = this._oppositeHandleLength * Math.cos(angle); 20014 y = this._oppositeHandleLength * Math.sin(angle); 20015 s[i + 2] = ((s[i] + x) * rnd | 0) / rnd; 20016 s[i + 3] = ((s[i + 1] + y) * rnd | 0) / rnd; 20017 } 20018 } 20019 20020 this.update(); 20021 }; 20022 20023 _proto3._onDragHandle2 = function _onDragHandle2() { 20024 var anchor = this._editingAnchor, 20025 s = anchor.segment, 20026 i = anchor.i, 20027 rnd = 1000, 20028 x = this._handle2._draggable.x, 20029 y = this._handle2._draggable.y, 20030 angle; 20031 s[i + 2] = x = (x * rnd | 0) / rnd; 20032 s[i + 3] = y = (y * rnd | 0) / rnd; 20033 20034 if (anchor.smooth) { 20035 if (_ALT) { 20036 anchor.smooth = false; 20037 anchor.element.setAttribute("d", this._squareHandle); 20038 20039 this._handle1.setAttribute("d", this._squareHandle); 20040 20041 this._handle2.setAttribute("d", this._squareHandle); 20042 } else { 20043 angle = Math.atan2(s[i + 1] - y, s[i] - x); 20044 x = this._oppositeHandleLength * Math.cos(angle); 20045 y = this._oppositeHandleLength * Math.sin(angle); 20046 s[i - 2] = ((s[i] + x) * rnd | 0) / rnd; 20047 s[i - 1] = ((s[i + 1] + y) * rnd | 0) / rnd; 20048 } 20049 } 20050 20051 this.update(); 20052 }; 20053 20054 _proto3._onDragAnchor = function _onDragAnchor(anchor, changeX, changeY) { 20055 var anchors = this._selectedAnchors, 20056 l = anchors.length, 20057 rnd = 1000, 20058 i, 20059 j, 20060 s, 20061 a; 20062 20063 for (j = 0; j < l; j++) { 20064 a = anchors[j]; 20065 i = a.i; 20066 s = a.segment; 20067 20068 if (i) { 20069 s[i - 2] = ((s[i - 2] + changeX) * rnd | 0) / rnd; 20070 s[i - 1] = ((s[i - 1] + changeY) * rnd | 0) / rnd; 20071 } 20072 20073 s[i] = ((s[i] + changeX) * rnd | 0) / rnd; 20074 s[i + 1] = ((s[i + 1] + changeY) * rnd | 0) / rnd; 20075 20076 if (i < s.length - 2) { 20077 s[i + 2] = ((s[i + 2] + changeX) * rnd | 0) / rnd; 20078 s[i + 3] = ((s[i + 3] + changeY) * rnd | 0) / rnd; 20079 } 20080 20081 if (a !== anchor) { 20082 a.element.setAttribute("transform", "translate(" + s[i] + _comma + s[i + 1] + ")"); 20083 } 20084 } 20085 20086 this.update(); 20087 }; 20088 20089 _proto3.enabled = function enabled(_enabled2) { 20090 if (!arguments.length) { 20091 return this._enabled; 20092 } 20093 20094 var i = this._anchors.length; 20095 20096 while (--i > -1) { 20097 this._anchors[i]._draggable.enabled(_enabled2); 20098 } 20099 20100 this._enabled = _enabled2; 20101 20102 this._handle1._draggable.enabled(_enabled2); 20103 20104 this._handle2._draggable.enabled(_enabled2); 20105 20106 if (this._draggable) { 20107 this._draggable.enabled(_enabled2); 20108 } 20109 20110 if (!_enabled2) { 20111 this.deselect(); 20112 this.path.ownerSVGElement.removeChild(this._selectionHittest); 20113 this.path.ownerSVGElement.removeChild(this._selection); 20114 } else if (!this._selection.parentNode) { 20115 this.path.ownerSVGElement.appendChild(this._selectionHittest); 20116 this.path.ownerSVGElement.appendChild(this._selection); 20117 this.init(); 20118 20119 this._saveState(); 20120 } 20121 20122 this._updateAnchors(); 20123 20124 return this.update(); 20125 }; 20126 20127 _proto3.update = function update(readPath) { 20128 var d = "", 20129 anchor = this._editingAnchor, 20130 i, 20131 s, 20132 x, 20133 y; 20134 20135 if (readPath) { 20136 this.init(); 20137 } 20138 20139 if (anchor) { 20140 i = anchor.i; 20141 s = anchor.segment; 20142 20143 if (i) { 20144 x = s[i - 2]; 20145 y = s[i - 1]; 20146 20147 this._handle1.setAttribute("transform", "translate(" + x + _comma + y + ")"); 20148 20149 this._line1.setAttribute("points", x + _comma + y + _comma + s[i] + _comma + s[i + 1]); 20150 } 20151 20152 if (i < s.length - 2) { 20153 x = s[i + 2]; 20154 y = s[i + 3]; 20155 20156 this._handle2.setAttribute("transform", "translate(" + x + _comma + y + ")"); 20157 20158 this._line2.setAttribute("points", s[i] + _comma + s[i + 1] + _comma + x + _comma + y); 20159 } 20160 } 20161 20162 if (readPath) { 20163 d = this.path.getAttribute("d"); 20164 } else { 20165 for (i = 0; i < this._rawPath.length; i++) { 20166 s = this._rawPath[i]; 20167 20168 if (s.length > 7) { 20169 d += "M" + s[0] + _comma + s[1] + "C" + s.slice(2).join(_comma); 20170 } 20171 } 20172 20173 this.path.setAttribute("d", d); 20174 20175 this._selectionPath.setAttribute("d", d); 20176 20177 this._selectionHittest.setAttribute("d", d); 20178 } 20179 20180 if (this.vars.onUpdate && this._enabled) { 20181 _callback("onUpdate", this, d); 20182 } 20183 20184 return this; 20185 }; 20186 20187 _proto3.getRawPath = function getRawPath(applyTransforms, offsetX, offsetY) { 20188 if (applyTransforms) { 20189 var m = _getConsolidatedMatrix(this.path); 20190 20191 return Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["copyRawPath"])(this._rawPath), 1, 0, 0, 1, m.e + (offsetX || 0), m.f + (offsetY || 0)); 20192 } 20193 20194 return this._rawPath; 20195 }; 20196 20197 _proto3.getString = function getString(applyTransforms, offsetX, offsetY) { 20198 if (applyTransforms) { 20199 var m = _getConsolidatedMatrix(this.path); 20200 20201 return Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["rawPathToString"])(Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["transformRawPath"])(Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["copyRawPath"])(this._rawPath), 1, 0, 0, 1, m.e + (offsetX || 0), m.f + (offsetY || 0))); 20202 } 20203 20204 return this.path.getAttribute("d"); 20205 }; 20206 20207 _proto3.getNormalizedSVG = function getNormalizedSVG(height, originY, shorten, onEaseError) { 20208 var s = this._rawPath[0], 20209 tx = s[0] * -1, 20210 ty = originY === 0 ? 0 : -(originY || s[1]), 20211 l = s.length, 20212 sx = 1 / (s[l - 2] + tx), 20213 sy = -height || s[l - 1] + ty, 20214 rnd = 1000, 20215 points, 20216 i, 20217 x1, 20218 y1, 20219 x2, 20220 y2; 20221 _temp.length = 0; 20222 20223 if (sy) { 20224 //typically y ends at 1 (so that the end values are reached) 20225 sy = 1 / sy; 20226 } else { 20227 //in case the ease returns to its beginning value, scale everything proportionally 20228 sy = -sx; 20229 } 20230 20231 sx *= rnd; 20232 sy *= rnd; 20233 20234 for (i = 0; i < l; i += 2) { 20235 _temp[i] = ((s[i] + tx) * sx | 0) / rnd; 20236 _temp[i + 1] = ((s[i + 1] + ty) * sy | 0) / rnd; 20237 } 20238 20239 if (onEaseError) { 20240 points = []; 20241 l = _temp.length; 20242 20243 for (i = 2; i < l; i += 6) { 20244 x1 = _temp[i - 2]; 20245 y1 = _temp[i - 1]; 20246 x2 = _temp[i + 4]; 20247 y2 = _temp[i + 5]; 20248 points.push(x1, y1, x2, y2); 20249 Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["bezierToPoints"])(x1, y1, _temp[i], _temp[i + 1], _temp[i + 2], _temp[i + 3], x2, y2, 0.001, points, points.length - 2); 20250 } 20251 20252 x1 = points[0]; 20253 l = points.length; 20254 20255 for (i = 2; i < l; i += 2) { 20256 x2 = points[i]; 20257 20258 if (x2 < x1 || x2 > 1 || x2 < 0) { 20259 onEaseError(); 20260 break; 20261 } 20262 20263 x1 = x2; 20264 } 20265 } 20266 20267 if (shorten && l === 8 && _temp[0] === 0 && _temp[1] === 0 && _temp[l - 2] === 1 && _temp[l - 1] === 1) { 20268 return _temp.slice(2, 6).join(","); 20269 } 20270 20271 _temp[2] = "C" + _temp[2]; 20272 return "M" + _temp.join(","); 20273 }; 20274 20275 return PathEditor; 20276}(); 20277PathEditor.simplifyPoints = _paths_js__WEBPACK_IMPORTED_MODULE_0__["simplifyPoints"]; 20278PathEditor.pointsToSegment = _paths_js__WEBPACK_IMPORTED_MODULE_0__["pointsToSegment"]; 20279 20280PathEditor.simplifySVG = function (data, vars) { 20281 //takes a <path> element or data string and simplifies it according to whatever tolerance you set (default:1, the bigger the number the more variance there can be). vars: {tolerance:1, cornerThreshold:degrees, curved:true} 20282 var element, points, i, x1, x2, y1, y2, bezier, precision, tolerance, l, cornerThreshold; 20283 vars = vars || {}; 20284 tolerance = vars.tolerance || 1; 20285 precision = vars.precision || 1 / tolerance; 20286 cornerThreshold = (vars.cornerThreshold === undefined ? 18 : +vars.cornerThreshold) * _DEG2RAD; 20287 20288 if (typeof data !== "string") { 20289 //element 20290 element = data; 20291 data = element.getAttribute("d"); 20292 } 20293 20294 if (data.charAt(0) === "#" || data.charAt(0) === ".") { 20295 //selector text 20296 element = _doc.querySelector(data); 20297 20298 if (element) { 20299 data = element.getAttribute("d"); 20300 } 20301 } 20302 20303 points = vars.curved === false && !/[achqstvz]/ig.test(data) ? data.match(_numbersExp) : Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["stringToRawPath"])(data)[0]; 20304 20305 if (vars.curved !== false) { 20306 bezier = points; 20307 points = []; 20308 l = bezier.length; 20309 20310 for (i = 2; i < l; i += 6) { 20311 x1 = +bezier[i - 2]; 20312 y1 = +bezier[i - 1]; 20313 x2 = +bezier[i + 4]; 20314 y2 = +bezier[i + 5]; 20315 points.push(_round(x1), _round(y1), _round(x2), _round(y2)); 20316 Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["bezierToPoints"])(x1, y1, +bezier[i], +bezier[i + 1], +bezier[i + 2], +bezier[i + 3], x2, y2, 1 / (precision * 200000), points, points.length - 2); 20317 } 20318 20319 points = Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["pointsToSegment"])(Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["simplifyPoints"])(points, tolerance), vars.curviness, cornerThreshold); 20320 points[2] = "C" + points[2]; 20321 } else { 20322 points = Object(_paths_js__WEBPACK_IMPORTED_MODULE_0__["simplifyPoints"])(points, tolerance); 20323 } 20324 20325 data = "M" + points.join(","); 20326 20327 if (element) { 20328 element.setAttribute("d", data); 20329 } 20330 20331 return data; 20332}; 20333 20334PathEditor.create = function (target, vars) { 20335 return new PathEditor(target, vars); 20336}; 20337 20338PathEditor.editingAxis = _editingAxis; 20339 20340PathEditor.getSnapFunction = function (vars) { 20341 //{gridSize, radius, x, y, width, height} 20342 var r = vars.radius || 2, 20343 big = 1e20, 20344 minX = vars.x || vars.x === 0 ? vars.x : vars.width ? 0 : -big, 20345 minY = vars.y || vars.y === 0 ? vars.y : vars.height ? 0 : -big, 20346 maxX = minX + (vars.width || big * big), 20347 maxY = minY + (vars.height || big * big), 20348 containX = vars.containX !== false, 20349 containY = vars.containY !== false, 20350 axis = vars.axis, 20351 grid = vars.gridSize; 20352 r *= r; 20353 return function (p) { 20354 var x = p.x, 20355 y = p.y, 20356 gridX, 20357 gridY, 20358 dx, 20359 dy; 20360 20361 if (containX && x < minX || (dx = x - minX) * dx < r) { 20362 x = minX; 20363 } else if (containX && x > maxX || (dx = maxX - x) * dx < r) { 20364 x = maxX; 20365 } 20366 20367 if (containY && y < minY || (dy = y - minY) * dy < r) { 20368 y = minY; 20369 } else if (containY && y > maxY || (dy = maxY - y) * dy < r) { 20370 y = maxY; 20371 } 20372 20373 if (axis) { 20374 dx = x - axis.x; 20375 dy = y - axis.y; 20376 20377 if (dx * dx < r) { 20378 x = axis.x; 20379 } 20380 20381 if (dy * dy < r) { 20382 y = axis.y; 20383 } 20384 } 20385 20386 if (grid) { 20387 gridX = minX + Math.round((x - minX) / grid) * grid; //closest grid slot on x-axis 20388 20389 dx = gridX - x; 20390 gridY = minY + Math.round((y - minY) / grid) * grid; //closest grid slot on y-axis 20391 20392 dy = gridY - y; 20393 20394 if (dx * dx + dy * dy < r) { 20395 x = gridX; 20396 y = gridY; 20397 } 20398 } 20399 20400 p.x = x; 20401 p.y = y; 20402 }; 20403}; 20404 20405PathEditor.version = "3.6.0"; 20406 20407 20408/***/ }), 20409
vendor: 7,225 bytes, lines 20410-20676
20410/***/ "./node_modules/gsap/utils/VelocityTracker.js": 20411/*!****************************************************!*\ 20412 !*** ./node_modules/gsap/utils/VelocityTracker.js ***! 20413 \****************************************************/ 20414/*! exports provided: VelocityTracker, default */ 20415/***/ (function(module, __webpack_exports__, __webpack_require__) { 20416 20417"use strict"; 20418__webpack_require__.r(__webpack_exports__); 20419/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VelocityTracker", function() { return VelocityTracker; }); 20420/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "default", function() { return VelocityTracker; }); 20421/*! 20422 * VelocityTracker: 3.6.0 20423 * https://greensock.com 20424 * 20425 * Copyright 2008-2021, GreenSock. All rights reserved. 20426 * Subject to the terms at https://greensock.com/standard-license or for 20427 * Club GreenSock members, the agreement issued with that membership. 20428 * @author: Jack Doyle, [email protected] 20429*/ 20430 20431/* eslint-disable */ 20432var gsap, 20433 _coreInitted, 20434 _toArray, 20435 _getUnit, 20436 _first, 20437 _ticker, 20438 _time1, 20439 _time2, 20440 _getCache, 20441 _getGSAP = function _getGSAP() { 20442 return gsap || typeof window !== "undefined" && (gsap = window.gsap); 20443}, 20444 _lookup = {}, 20445 _round = function _round(value) { 20446 return Math.round(value * 10000) / 10000; 20447}, 20448 _getID = function _getID(target) { 20449 return _getCache(target).id; 20450}, 20451 _getByTarget = function _getByTarget(target) { 20452 return _lookup[_getID(typeof target === "string" ? _toArray(target)[0] : target)]; 20453}, 20454 _onTick = function _onTick(time) { 20455 var pt = _first, 20456 val; //if the frame rate is too high, we won't be able to track the velocity as well, so only update the values about 20 times per second 20457 20458 if (time - _time1 >= 0.05) { 20459 _time2 = _time1; 20460 _time1 = time; 20461 20462 while (pt) { 20463 val = pt.g(pt.t, pt.p); 20464 20465 if (val !== pt.v1 || time - pt.t1 > 0.2) { 20466 //use a threshold of 0.2 seconds for zeroing-out velocity. If we only use 0.05 and things update slightly slower, like some Android devices dispatch "touchmove" events sluggishly so 2 or 3 ticks of the gsap.ticker may elapse inbetween, thus it may appear like the object is not moving but it actually is but it's not updating as frequently. A threshold of 0.2 seconds seems to be a good balance. We want to update things frequently (0.05 seconds) when they're moving so that we can respond to fast motions accurately, but we want to be more resistant to go back to a zero velocity. 20467 pt.v2 = pt.v1; 20468 pt.v1 = val; 20469 pt.t2 = pt.t1; 20470 pt.t1 = time; 20471 } 20472 20473 pt = pt._next; 20474 } 20475 } 20476}, 20477 _types = { 20478 deg: 360, 20479 rad: Math.PI * 2 20480}, 20481 _initCore = function _initCore() { 20482 gsap = _getGSAP(); 20483 20484 if (gsap) { 20485 _toArray = gsap.utils.toArray; 20486 _getUnit = gsap.utils.getUnit; 20487 _getCache = gsap.core.getCache; 20488 _ticker = gsap.ticker; 20489 _coreInitted = 1; 20490 } 20491}; 20492 20493var PropTracker = function PropTracker(target, property, type, next) { 20494 this.t = target; 20495 this.p = property; 20496 this.g = target._gsap.get; 20497 this.rCap = _types[type || _getUnit(this.g(target, property))]; //rotational cap (for degrees, "deg", it's 360 and for radians, "rad", it's Math.PI * 2) 20498 20499 this.v1 = this.v2 = 0; 20500 this.t1 = this.t2 = _ticker.time; 20501 20502 if (next) { 20503 this._next = next; 20504 next._prev = this; 20505 } 20506}; 20507 20508var VelocityTracker = /*#__PURE__*/function () { 20509 function VelocityTracker(target, property) { 20510 if (!_coreInitted) { 20511 _initCore(); 20512 } 20513 20514 this.target = _toArray(target)[0]; 20515 _lookup[_getID(this.target)] = this; 20516 this._props = {}; 20517 property && this.add(property); 20518 } 20519 20520 VelocityTracker.register = function register(core) { 20521 gsap = core; 20522 20523 _initCore(); 20524 }; 20525 20526 var _proto = VelocityTracker.prototype; 20527 20528 _proto.get = function get(property, skipRecentTick) { 20529 var pt = this._props[property] || console.warn("Not tracking " + property + " velocity."), 20530 val, 20531 dif, 20532 rotationCap; 20533 val = parseFloat(skipRecentTick ? pt.v1 : pt.g(pt.t, pt.p)); 20534 dif = val - parseFloat(pt.v2); 20535 rotationCap = pt.rCap; 20536 20537 if (rotationCap) { 20538 //rotational values need special interpretation so that if, for example, they go from 179 to -178 degrees it is interpreted as a change of 3 instead of -357. 20539 dif = dif % rotationCap; 20540 20541 if (dif !== dif % (rotationCap / 2)) { 20542 dif = dif < 0 ? dif + rotationCap : dif - rotationCap; 20543 } 20544 } 20545 20546 return _round(dif / ((skipRecentTick ? pt.t1 : _ticker.time) - pt.t2)); 20547 }; 20548 20549 _proto.getAll = function getAll() { 20550 var result = {}, 20551 props = this._props, 20552 p; 20553 20554 for (p in props) { 20555 result[p] = this.get(p); 20556 } 20557 20558 return result; 20559 }; 20560 20561 _proto.isTracking = function isTracking(property) { 20562 return property in this._props; 20563 }; 20564 20565 _proto.add = function add(property, type) { 20566 if (!(property in this._props)) { 20567 if (!_first) { 20568 _ticker.add(_onTick); 20569 20570 _time1 = _time2 = _ticker.time; 20571 } 20572 20573 _first = this._props[property] = new PropTracker(this.target, property, type, _first); 20574 } 20575 }; 20576 20577 _proto.remove = function remove(property) { 20578 var pt = this._props[property], 20579 prev, 20580 next; 20581 20582 if (pt) { 20583 prev = pt._prev; 20584 next = pt._next; 20585 20586 if (prev) { 20587 prev._next = next; 20588 } 20589 20590 if (next) { 20591 next._prev = prev; 20592 } else if (_first === pt) { 20593 _ticker.remove(_onTick); 20594 20595 _first = 0; 20596 } 20597 20598 delete this._props[property]; 20599 } 20600 }; 20601 20602 _proto.kill = function kill(shallow) { 20603 for (var p in this._props) { 20604 this.remove(p); 20605 } 20606 20607 if (!shallow) { 20608 delete _lookup[_getID(this.target)]; 20609 } 20610 }; 20611 20612 VelocityTracker.track = function track(targets, properties, types) { 20613 if (!_coreInitted) { 20614 _initCore(); 20615 } 20616 20617 var result = [], 20618 targs = _toArray(targets), 20619 a = properties.split(","), 20620 t = (types || "").split(","), 20621 i = targs.length, 20622 tracker, 20623 j; 20624 20625 while (i--) { 20626 tracker = _getByTarget(targs[i]) || new VelocityTracker(targs[i]); 20627 j = a.length; 20628 20629 while (j--) { 20630 tracker.add(a[j], t[j] || t[0]); 20631 } 20632 20633 result.push(tracker); 20634 } 20635 20636 return result; 20637 }; 20638 20639 VelocityTracker.untrack = function untrack(targets, properties) { 20640 var props = (properties || "").split(","); 20641 20642 _toArray(targets).forEach(function (target) { 20643 var tracker = _getByTarget(target); 20644 20645 if (tracker) { 20646 if (!props.length) { 20647 tracker.kill(1); 20648 } else { 20649 props.forEach(function (p) { 20650 return tracker.remove(p); 20651 }); 20652 } 20653 } 20654 }); 20655 }; 20656 20657 VelocityTracker.isTracking = function isTracking(target, property) { 20658 var tracker = _getByTarget(target); 20659 20660 return tracker && tracker.isTracking(property); 20661 }; 20662 20663 VelocityTracker.getVelocity = function getVelocity(target, property) { 20664 var tracker = _getByTarget(target); 20665 20666 return !tracker || !tracker.isTracking(property) ? console.warn("Not tracking velocity of " + property) : tracker.get(property); 20667 }; 20668 20669 return VelocityTracker; 20670}(); 20671VelocityTracker.getByTarget = _getByTarget; 20672_getGSAP() && gsap.registerPlugin(VelocityTracker); 20673 20674 20675/***/ }), 20676
vendor: 14,635 bytes, lines 20677-21090
20677/***/ "./node_modules/gsap/utils/matrix.js": 20678/*!*******************************************!*\ 20679 !*** ./node_modules/gsap/utils/matrix.js ***! 20680 \*******************************************/ 20681/*! exports provided: Matrix2D, getGlobalMatrix, _getDocScrollTop, _getDocScrollLeft, _setDoc */ 20682/***/ (function(module, __webpack_exports__, __webpack_require__) { 20683 20684"use strict"; 20685__webpack_require__.r(__webpack_exports__); 20686/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Matrix2D", function() { return Matrix2D; }); 20687/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getGlobalMatrix", function() { return getGlobalMatrix; }); 20688/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getDocScrollTop", function() { return _getDocScrollTop; }); 20689/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_getDocScrollLeft", function() { return _getDocScrollLeft; }); 20690/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "_setDoc", function() { return _setDoc; }); 20691/*! 20692 * matrix 3.6.0 20693 * https://greensock.com 20694 * 20695 * Copyright 2008-2021, GreenSock. All rights reserved. 20696 * Subject to the terms at https://greensock.com/standard-license or for 20697 * Club GreenSock members, the agreement issued with that membership. 20698 * @author: Jack Doyle, [email protected] 20699*/ 20700 20701/* eslint-disable */ 20702var _doc, 20703 _win, 20704 _docElement, 20705 _body, 20706 _divContainer, 20707 _svgContainer, 20708 _identityMatrix, 20709 _transformProp = "transform", 20710 _transformOriginProp = _transformProp + "Origin", 20711 _hasOffsetBug, 20712 _setDoc = function _setDoc(element) { 20713 var doc = element.ownerDocument || element; 20714 20715 if (!(_transformProp in element.style) && "msTransform" in element.style) { 20716 //to improve compatibility with old Microsoft browsers 20717 _transformProp = "msTransform"; 20718 _transformOriginProp = _transformProp + "Origin"; 20719 } 20720 20721 while (doc.parentNode && (doc = doc.parentNode)) {} 20722 20723 _win = window; 20724 _identityMatrix = new Matrix2D(); 20725 20726 if (doc) { 20727 _doc = doc; 20728 _docElement = doc.documentElement; 20729 _body = doc.body; // now test for the offset reporting bug. Use feature detection instead of browser sniffing to make things more bulletproof and future-proof. Hopefully Safari will fix their bug soon but it's 2020 and it's still not fixed. 20730 20731 var d1 = doc.createElement("div"), 20732 d2 = doc.createElement("div"); 20733 20734 _body.appendChild(d1); 20735 20736 d1.appendChild(d2); 20737 d1.style.position = "static"; 20738 d1.style[_transformProp] = "translate3d(0,0,1px)"; 20739 _hasOffsetBug = d2.offsetParent !== d1; 20740 20741 _body.removeChild(d1); 20742 } 20743 20744 return doc; 20745}, 20746 _forceNonZeroScale = function _forceNonZeroScale(e) { 20747 // walks up the element's ancestors and finds any that had their scale set to 0 via GSAP, and changes them to 0.0001 to ensure that measurements work. Firefox has a bug that causes it to incorrectly report getBoundingClientRect() when scale is 0. 20748 var a, cache; 20749 20750 while (e && e !== _body) { 20751 cache = e._gsap; 20752 cache && cache.uncache && cache.get(e, "x"); // force re-parsing of transforms if necessary 20753 20754 if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) { 20755 cache.scaleX = cache.scaleY = 1e-4; 20756 cache.renderTransform(1, cache); 20757 a ? a.push(cache) : a = [cache]; 20758 } 20759 20760 e = e.parentNode; 20761 } 20762 20763 return a; 20764}, 20765 // possible future addition: pass an element to _forceDisplay() and it'll walk up all its ancestors and make sure anything with display: none is set to display: block, and if there's no parentNode, it'll add it to the body. It returns an Array that you can then feed to _revertDisplay() to have it revert all the changes it made. 20766// _forceDisplay = e => { 20767// let a = [], 20768// parent; 20769// while (e && e !== _body) { 20770// parent = e.parentNode; 20771// (_win.getComputedStyle(e).display === "none" || !parent) && a.push(e, e.style.display, parent) && (e.style.display = "block"); 20772// parent || _body.appendChild(e); 20773// e = parent; 20774// } 20775// return a; 20776// }, 20777// _revertDisplay = a => { 20778// for (let i = 0; i < a.length; i+=3) { 20779// a[i+1] ? (a[i].style.display = a[i+1]) : a[i].style.removeProperty("display"); 20780// a[i+2] || a[i].parentNode.removeChild(a[i]); 20781// } 20782// }, 20783_svgTemps = [], 20784 //we create 3 elements for SVG, and 3 for other DOM elements and cache them for performance reasons. They get nested in _divContainer and _svgContainer so that just one element is added to the DOM on each successive attempt. Again, performance is key. 20785_divTemps = [], 20786 _getDocScrollTop = function _getDocScrollTop() { 20787 return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0; 20788}, 20789 _getDocScrollLeft = function _getDocScrollLeft() { 20790 return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0; 20791}, 20792 _svgOwner = function _svgOwner(element) { 20793 return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null); 20794}, 20795 _isFixed = function _isFixed(element) { 20796 if (_win.getComputedStyle(element).position === "fixed") { 20797 return true; 20798 } 20799 20800 element = element.parentNode; 20801 20802 if (element && element.nodeType === 1) { 20803 // avoid document fragments which will throw an error. 20804 return _isFixed(element); 20805 } 20806}, 20807 _createSibling = function _createSibling(element, i) { 20808 if (element.parentNode && (_doc || _setDoc(element))) { 20809 var svg = _svgOwner(element), 20810 ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml", 20811 type = svg ? i ? "rect" : "g" : "div", 20812 x = i !== 2 ? 0 : 100, 20813 y = i === 3 ? 100 : 0, 20814 css = "position:absolute;display:block;pointer-events:none;margin:0;padding:0;", 20815 e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type); 20816 20817 if (i) { 20818 if (!svg) { 20819 if (!_divContainer) { 20820 _divContainer = _createSibling(element); 20821 _divContainer.style.cssText = css; 20822 } 20823 20824 e.style.cssText = css + "width:0.1px;height:0.1px;top:" + y + "px;left:" + x + "px"; 20825 20826 _divContainer.appendChild(e); 20827 } else { 20828 _svgContainer || (_svgContainer = _createSibling(element)); 20829 e.setAttribute("width", 0.01); 20830 e.setAttribute("height", 0.01); 20831 e.setAttribute("transform", "translate(" + x + "," + y + ")"); 20832 20833 _svgContainer.appendChild(e); 20834 } 20835 } 20836 20837 return e; 20838 } 20839 20840 throw "Need document and parent."; 20841}, 20842 _consolidate = function _consolidate(m) { 20843 // replaces SVGTransformList.consolidate() because a bug in Firefox causes it to break pointer events. See https://greensock.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800 20844 var c = new Matrix2D(), 20845 i = 0; 20846 20847 for (; i < m.numberOfItems; i++) { 20848 c.multiply(m.getItem(i).matrix); 20849 } 20850 20851 return c; 20852}, 20853 _placeSiblings = function _placeSiblings(element, adjustGOffset) { 20854 var svg = _svgOwner(element), 20855 isRootSVG = element === svg, 20856 siblings = svg ? _svgTemps : _divTemps, 20857 parent = element.parentNode, 20858 container, 20859 m, 20860 b, 20861 x, 20862 y, 20863 cs; 20864 20865 if (element === _win) { 20866 return element; 20867 } 20868 20869 siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3)); 20870 container = svg ? _svgContainer : _divContainer; 20871 20872 if (svg) { 20873 b = isRootSVG ? { 20874 x: 0, 20875 y: 0 20876 } : element.getBBox(); 20877 m = element.transform ? element.transform.baseVal : {}; // IE11 doesn't follow the spec. 20878 20879 if (m.numberOfItems) { 20880 m = m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix; // don't call m.consolidate().matrix because a bug in Firefox makes pointer events not work when consolidate() is called on the same tick as getBoundingClientRect()! See https://greensock.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800 20881 20882 x = m.a * b.x + m.c * b.y; 20883 y = m.b * b.x + m.d * b.y; 20884 } else { 20885 m = _identityMatrix; 20886 x = b.x; 20887 y = b.y; 20888 } 20889 20890 if (adjustGOffset && element.tagName.toLowerCase() === "g") { 20891 x = y = 0; 20892 } 20893 20894 container.setAttribute("transform", "matrix(" + m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")"); 20895 (isRootSVG ? svg : parent).appendChild(container); 20896 } else { 20897 x = y = 0; 20898 20899 if (_hasOffsetBug) { 20900 // some browsers (like Safari) have a bug that causes them to misreport offset values. When an ancestor element has a transform applied, it's supposed to treat it as if it's position: relative (new context). Safari botches this, so we need to find the closest ancestor (between the element and its offsetParent) that has a transform applied and if one is found, grab its offsetTop/Left and subtract them to compensate. 20901 m = element.offsetParent; 20902 b = element; 20903 20904 while (b && (b = b.parentNode) && b !== m && b.parentNode) { 20905 if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) { 20906 x = b.offsetLeft; 20907 y = b.offsetTop; 20908 b = 0; 20909 } 20910 } 20911 } 20912 20913 cs = _win.getComputedStyle(element); 20914 20915 if (cs.position !== "absolute") { 20916 m = element.offsetParent; 20917 20918 while (parent !== m) { 20919 // if there's an ancestor element between the element and its offsetParent that's scrolled, we must factor that in. 20920 x += parent.scrollLeft || 0; 20921 y += parent.scrollTop || 0; 20922 parent = parent.parentNode; 20923 } 20924 } 20925 20926 b = container.style; 20927 b.top = element.offsetTop - y + "px"; 20928 b.left = element.offsetLeft - x + "px"; 20929 b[_transformProp] = cs[_transformProp]; 20930 b[_transformOriginProp] = cs[_transformOriginProp]; // b.border = m.border; 20931 // b.borderLeftStyle = m.borderLeftStyle; 20932 // b.borderTopStyle = m.borderTopStyle; 20933 // b.borderLeftWidth = m.borderLeftWidth; 20934 // b.borderTopWidth = m.borderTopWidth; 20935 20936 b.position = cs.position === "fixed" ? "fixed" : "absolute"; 20937 element.parentNode.appendChild(container); 20938 } 20939 20940 return container; 20941}, 20942 _setMatrix = function _setMatrix(m, a, b, c, d, e, f) { 20943 m.a = a; 20944 m.b = b; 20945 m.c = c; 20946 m.d = d; 20947 m.e = e; 20948 m.f = f; 20949 return m; 20950}; 20951 20952var Matrix2D = /*#__PURE__*/function () { 20953 function Matrix2D(a, b, c, d, e, f) { 20954 if (a === void 0) { 20955 a = 1; 20956 } 20957 20958 if (b === void 0) { 20959 b = 0; 20960 } 20961 20962 if (c === void 0) { 20963 c = 0; 20964 } 20965 20966 if (d === void 0) { 20967 d = 1; 20968 } 20969 20970 if (e === void 0) { 20971 e = 0; 20972 } 20973 20974 if (f === void 0) { 20975 f = 0; 20976 } 20977 20978 _setMatrix(this, a, b, c, d, e, f); 20979 } 20980 20981 var _proto = Matrix2D.prototype; 20982 20983 _proto.inverse = function inverse() { 20984 var a = this.a, 20985 b = this.b, 20986 c = this.c, 20987 d = this.d, 20988 e = this.e, 20989 f = this.f, 20990 determinant = a * d - b * c || 1e-10; 20991 return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant); 20992 }; 20993 20994 _proto.multiply = function multiply(matrix) { 20995 var a = this.a, 20996 b = this.b, 20997 c = this.c, 20998 d = this.d, 20999 e = this.e, 21000 f = this.f, 21001 a2 = matrix.a, 21002 b2 = matrix.c, 21003 c2 = matrix.b, 21004 d2 = matrix.d, 21005 e2 = matrix.e, 21006 f2 = matrix.f; 21007 return _setMatrix(this, a2 * a + c2 * c, a2 * b + c2 * d, b2 * a + d2 * c, b2 * b + d2 * d, e + e2 * a + f2 * c, f + e2 * b + f2 * d); 21008 }; 21009 21010 _proto.clone = function clone() { 21011 return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f); 21012 }; 21013 21014 _proto.equals = function equals(matrix) { 21015 var a = this.a, 21016 b = this.b, 21017 c = this.c, 21018 d = this.d, 21019 e = this.e, 21020 f = this.f; 21021 return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f; 21022 }; 21023 21024 _proto.apply = function apply(point, decoratee) { 21025 if (decoratee === void 0) { 21026 decoratee = {}; 21027 } 21028 21029 var x = point.x, 21030 y = point.y, 21031 a = this.a, 21032 b = this.b, 21033 c = this.c, 21034 d = this.d, 21035 e = this.e, 21036 f = this.f; 21037 decoratee.x = x * a + y * c + e || 0; 21038 decoratee.y = x * b + y * d + f || 0; 21039 return decoratee; 21040 }; 21041 21042 return Matrix2D; 21043}(); // Feed in an element and it'll return a 2D matrix (optionally inverted) so that you can translate between coordinate spaces. 21044// Inverting lets you translate a global point into a local coordinate space. No inverting lets you go the other way. 21045// We needed this to work around various browser bugs, like Firefox doesn't accurately report getScreenCTM() when there 21046// are transforms applied to ancestor elements. 21047// The matrix math to convert any x/y coordinate is as follows, which is wrapped in a convenient apply() method of Matrix2D above: 21048// tx = m.a * x + m.c * y + m.e 21049// ty = m.b * x + m.d * y + m.f 21050 21051function getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) { 21052 // adjustGOffset is typically used only when grabbing an element's PARENT's global matrix, and it ignores the x/y offset of any SVG <g> elements because they behave in a special way. 21053 if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) { 21054 return new Matrix2D(); 21055 } 21056 21057 var zeroScales = _forceNonZeroScale(element), 21058 svg = _svgOwner(element), 21059 temps = svg ? _svgTemps : _divTemps, 21060 container = _placeSiblings(element, adjustGOffset), 21061 b1 = temps[0].getBoundingClientRect(), 21062 b2 = temps[1].getBoundingClientRect(), 21063 b3 = temps[2].getBoundingClientRect(), 21064 parent = container.parentNode, 21065 isFixed = !includeScrollInFixed && _isFixed(element), 21066 m = new Matrix2D((b2.left - b1.left) / 100, (b2.top - b1.top) / 100, (b3.left - b1.left) / 100, (b3.top - b1.top) / 100, b1.left + (isFixed ? 0 : _getDocScrollLeft()), b1.top + (isFixed ? 0 : _getDocScrollTop())); 21067 21068 parent.removeChild(container); 21069 21070 if (zeroScales) { 21071 b1 = zeroScales.length; 21072 21073 while (b1--) { 21074 b2 = zeroScales[b1]; 21075 b2.scaleX = b2.scaleY = 0; 21076 b2.renderTransform(1, b2); 21077 } 21078 } 21079 21080 return inverse ? m.inverse() : m; 21081} 21082 // export function getMatrix(element) { 21083// _doc || _setDoc(element); 21084// let m = (_win.getComputedStyle(element)[_transformProp] + "").substr(7).match(/[-.]*\d+[.e\-+]*\d*[e\-\+]*\d*/g), 21085// is2D = m && m.length === 6; 21086// return !m || m.length < 6 ? new Matrix2D() : new Matrix2D(+m[0], +m[1], +m[is2D ? 2 : 4], +m[is2D ? 3 : 5], +m[is2D ? 4 : 12], +m[is2D ? 5 : 13]); 21087// } 21088 21089/***/ }), 21090
vendor: 50,181 bytes, lines 21091-22598
21091/***/ "./node_modules/gsap/utils/paths.js": 21092/*!******************************************!*\ 21093 !*** ./node_modules/gsap/utils/paths.js ***! 21094 \******************************************/ 21095/*! exports provided: getRawPath, copyRawPath, reverseSegment, convertToPath, getRotationAtProgress, sliceRawPath, cacheRawPathMeasurements, subdivideSegment, getPositionOnPath, transformRawPath, stringToRawPath, bezierToPoints, flatPointsToSegment, pointsToSegment, simplifyPoints, getClosestData, subdivideSegmentNear, rawPathToString */ 21096/***/ (function(module, __webpack_exports__, __webpack_require__) { 21097 21098"use strict"; 21099__webpack_require__.r(__webpack_exports__); 21100/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getRawPath", function() { return getRawPath; }); 21101/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "copyRawPath", function() { return copyRawPath; }); 21102/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reverseSegment", function() { return reverseSegment; }); 21103/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "convertToPath", function() { return convertToPath; }); 21104/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getRotationAtProgress", function() { return getRotationAtProgress; }); 21105/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "sliceRawPath", function() { return sliceRawPath; }); 21106/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "cacheRawPathMeasurements", function() { return cacheRawPathMeasurements; }); 21107/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subdivideSegment", function() { return subdivideSegment; }); 21108/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getPositionOnPath", function() { return getPositionOnPath; }); 21109/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "transformRawPath", function() { return transformRawPath; }); 21110/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "stringToRawPath", function() { return stringToRawPath; }); 21111/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "bezierToPoints", function() { return bezierToPoints; }); 21112/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "flatPointsToSegment", function() { return flatPointsToSegment; }); 21113/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "pointsToSegment", function() { return pointsToSegment; }); 21114/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "simplifyPoints", function() { return simplifyPoints; }); 21115/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getClosestData", function() { return getClosestData; }); 21116/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subdivideSegmentNear", function() { return subdivideSegmentNear; }); 21117/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "rawPathToString", function() { return rawPathToString; }); 21118/*! 21119 * paths 3.6.0 21120 * https://greensock.com 21121 * 21122 * Copyright 2008-2021, GreenSock. All rights reserved. 21123 * Subject to the terms at https://greensock.com/standard-license or for 21124 * Club GreenSock members, the agreement issued with that membership. 21125 * @author: Jack Doyle, [email protected] 21126*/ 21127 21128/* eslint-disable */ 21129var _svgPathExp = /[achlmqstvz]|(-?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 21130 _numbersExp = /(?:(-)?\d*\.?\d*(?:e[\-+]?\d+)?)[0-9]/ig, 21131 _scientific = /[\+\-]?\d*\.?\d+e[\+\-]?\d+/ig, 21132 _selectorExp = /(^[#\.][a-z]|[a-y][a-z])/i, 21133 _DEG2RAD = Math.PI / 180, 21134 _RAD2DEG = 180 / Math.PI, 21135 _sin = Math.sin, 21136 _cos = Math.cos, 21137 _abs = Math.abs, 21138 _sqrt = Math.sqrt, 21139 _atan2 = Math.atan2, 21140 _largeNum = 1e8, 21141 _isString = function _isString(value) { 21142 return typeof value === "string"; 21143}, 21144 _isNumber = function _isNumber(value) { 21145 return typeof value === "number"; 21146}, 21147 _isUndefined = function _isUndefined(value) { 21148 return typeof value === "undefined"; 21149}, 21150 _temp = {}, 21151 _temp2 = {}, 21152 _roundingNum = 1e5, 21153 _wrapProgress = function _wrapProgress(progress) { 21154 return Math.round((progress + _largeNum) % 1 * _roundingNum) / _roundingNum || (progress < 0 ? 0 : 1); 21155}, 21156 //if progress lands on 1, the % will make it 0 which is why we || 1, but not if it's negative because it makes more sense for motion to end at 0 in that case. 21157_round = function _round(value) { 21158 return Math.round(value * _roundingNum) / _roundingNum || 0; 21159}, 21160 _roundPrecise = function _roundPrecise(value) { 21161 return Math.round(value * 1e10) / 1e10 || 0; 21162}, 21163 _splitSegment = function _splitSegment(rawPath, segIndex, i, t) { 21164 var segment = rawPath[segIndex], 21165 shift = t === 1 ? 6 : subdivideSegment(segment, i, t); 21166 21167 if (shift && shift + i + 2 < segment.length) { 21168 rawPath.splice(segIndex, 0, segment.slice(0, i + shift + 2)); 21169 segment.splice(0, i + shift); 21170 return 1; 21171 } 21172}, 21173 _reverseRawPath = function _reverseRawPath(rawPath, skipOuter) { 21174 var i = rawPath.length; 21175 skipOuter || rawPath.reverse(); 21176 21177 while (i--) { 21178 rawPath[i].reversed || reverseSegment(rawPath[i]); 21179 } 21180}, 21181 _copyMetaData = function _copyMetaData(source, copy) { 21182 copy.totalLength = source.totalLength; 21183 21184 if (source.samples) { 21185 //segment 21186 copy.samples = source.samples.slice(0); 21187 copy.lookup = source.lookup.slice(0); 21188 copy.minLength = source.minLength; 21189 copy.resolution = source.resolution; 21190 } else if (source.totalPoints) { 21191 //rawPath 21192 copy.totalPoints = source.totalPoints; 21193 } 21194 21195 return copy; 21196}, 21197 //pushes a new segment into a rawPath, but if its starting values match the ending values of the last segment, it'll merge it into that same segment (to reduce the number of segments) 21198_appendOrMerge = function _appendOrMerge(rawPath, segment) { 21199 var index = rawPath.length, 21200 prevSeg = rawPath[index - 1] || [], 21201 l = prevSeg.length; 21202 21203 if (index && segment[0] === prevSeg[l - 2] && segment[1] === prevSeg[l - 1]) { 21204 segment = prevSeg.concat(segment.slice(2)); 21205 index--; 21206 } 21207 21208 rawPath[index] = segment; 21209}, 21210 _bestDistance; 21211/* TERMINOLOGY 21212 - RawPath - an array of arrays, one for each Segment. A single RawPath could have multiple "M" commands, defining Segments (paths aren't always connected). 21213 - Segment - an array containing a sequence of Cubic Bezier coordinates in alternating x, y, x, y format. Starting anchor, then control point 1, control point 2, and ending anchor, then the next control point 1, control point 2, anchor, etc. Uses less memory than an array with a bunch of {x, y} points. 21214 - Bezier - a single cubic Bezier with a starting anchor, two control points, and an ending anchor. 21215 - the variable "t" is typically the position along an individual Bezier path (time) and it's NOT linear, meaning it could accelerate/decelerate based on the control points whereas the "p" or "progress" value is linearly mapped to the whole path, so it shouldn't really accelerate/decelerate based on control points. So a progress of 0.2 would be almost exactly 20% along the path. "t" is ONLY in an individual Bezier piece. 21216 */ 21217//accepts basic selector text, a path instance, a RawPath instance, or a Segment and returns a RawPath (makes it easy to homogenize things). If an element or selector text is passed in, it'll also cache the value so that if it's queried again, it'll just take the path data from there instead of parsing it all over again (as long as the path data itself hasn't changed - it'll check). 21218 21219 21220function getRawPath(value) { 21221 value = _isString(value) && _selectorExp.test(value) ? document.querySelector(value) || value : value; 21222 var e = value.getAttribute ? value : 0, 21223 rawPath; 21224 21225 if (e && (value = value.getAttribute("d"))) { 21226 //implements caching 21227 if (!e._gsPath) { 21228 e._gsPath = {}; 21229 } 21230 21231 rawPath = e._gsPath[value]; 21232 return rawPath && !rawPath._dirty ? rawPath : e._gsPath[value] = stringToRawPath(value); 21233 } 21234 21235 return !value ? console.warn("Expecting a <path> element or an SVG path data string") : _isString(value) ? stringToRawPath(value) : _isNumber(value[0]) ? [value] : value; 21236} //copies a RawPath WITHOUT the length meta data (for speed) 21237 21238function copyRawPath(rawPath) { 21239 var a = [], 21240 i = 0; 21241 21242 for (; i < rawPath.length; i++) { 21243 a[i] = _copyMetaData(rawPath[i], rawPath[i].slice(0)); 21244 } 21245 21246 return _copyMetaData(rawPath, a); 21247} 21248function reverseSegment(segment) { 21249 var i = 0, 21250 y; 21251 segment.reverse(); //this will invert the order y, x, y, x so we must flip it back. 21252 21253 for (; i < segment.length; i += 2) { 21254 y = segment[i]; 21255 segment[i] = segment[i + 1]; 21256 segment[i + 1] = y; 21257 } 21258 21259 segment.reversed = !segment.reversed; 21260} 21261 21262var _createPath = function _createPath(e, ignore) { 21263 var path = document.createElementNS("http://www.w3.org/2000/svg", "path"), 21264 attr = [].slice.call(e.attributes), 21265 i = attr.length, 21266 name; 21267 ignore = "," + ignore + ","; 21268 21269 while (--i > -1) { 21270 name = attr[i].nodeName.toLowerCase(); //in Microsoft Edge, if you don't set the attribute with a lowercase name, it doesn't render correctly! Super weird. 21271 21272 if (ignore.indexOf("," + name + ",") < 0) { 21273 path.setAttributeNS(null, name, attr[i].nodeValue); 21274 } 21275 } 21276 21277 return path; 21278}, 21279 _typeAttrs = { 21280 rect: "rx,ry,x,y,width,height", 21281 circle: "r,cx,cy", 21282 ellipse: "rx,ry,cx,cy", 21283 line: "x1,x2,y1,y2" 21284}, 21285 _attrToObj = function _attrToObj(e, attrs) { 21286 var props = attrs ? attrs.split(",") : [], 21287 obj = {}, 21288 i = props.length; 21289 21290 while (--i > -1) { 21291 obj[props[i]] = +e.getAttribute(props[i]) || 0; 21292 } 21293 21294 return obj; 21295}; //converts an SVG shape like <circle>, <rect>, <polygon>, <polyline>, <ellipse>, etc. to a <path>, swapping it in and copying the attributes to match. 21296 21297 21298function convertToPath(element, swap) { 21299 var type = element.tagName.toLowerCase(), 21300 circ = 0.552284749831, 21301 data, 21302 x, 21303 y, 21304 r, 21305 ry, 21306 path, 21307 rcirc, 21308 rycirc, 21309 points, 21310 w, 21311 h, 21312 x2, 21313 x3, 21314 x4, 21315 x5, 21316 x6, 21317 y2, 21318 y3, 21319 y4, 21320 y5, 21321 y6, 21322 attr; 21323 21324 if (type === "path" || !element.getBBox) { 21325 return element; 21326 } 21327 21328 path = _createPath(element, "x,y,width,height,cx,cy,rx,ry,r,x1,x2,y1,y2,points"); 21329 attr = _attrToObj(element, _typeAttrs[type]); 21330 21331 if (type === "rect") { 21332 r = attr.rx; 21333 ry = attr.ry || r; 21334 x = attr.x; 21335 y = attr.y; 21336 w = attr.width - r * 2; 21337 h = attr.height - ry * 2; 21338 21339 if (r || ry) { 21340 //if there are rounded corners, render cubic beziers 21341 x2 = x + r * (1 - circ); 21342 x3 = x + r; 21343 x4 = x3 + w; 21344 x5 = x4 + r * circ; 21345 x6 = x4 + r; 21346 y2 = y + ry * (1 - circ); 21347 y3 = y + ry; 21348 y4 = y3 + h; 21349 y5 = y4 + ry * circ; 21350 y6 = y4 + ry; 21351 data = "M" + x6 + "," + y3 + " V" + y4 + " C" + [x6, y5, x5, y6, x4, y6, x4 - (x4 - x3) / 3, y6, x3 + (x4 - x3) / 3, y6, x3, y6, x2, y6, x, y5, x, y4, x, y4 - (y4 - y3) / 3, x, y3 + (y4 - y3) / 3, x, y3, x, y2, x2, y, x3, y, x3 + (x4 - x3) / 3, y, x4 - (x4 - x3) / 3, y, x4, y, x5, y, x6, y2, x6, y3].join(",") + "z"; 21352 } else { 21353 data = "M" + (x + w) + "," + y + " v" + h + " h" + -w + " v" + -h + " h" + w + "z"; 21354 } 21355 } else if (type === "circle" || type === "ellipse") { 21356 if (type === "circle") { 21357 r = ry = attr.r; 21358 rycirc = r * circ; 21359 } else { 21360 r = attr.rx; 21361 ry = attr.ry; 21362 rycirc = ry * circ; 21363 } 21364 21365 x = attr.cx; 21366 y = attr.cy; 21367 rcirc = r * circ; 21368 data = "M" + (x + r) + "," + y + " C" + [x + r, y + rycirc, x + rcirc, y + ry, x, y + ry, x - rcirc, y + ry, x - r, y + rycirc, x - r, y, x - r, y - rycirc, x - rcirc, y - ry, x, y - ry, x + rcirc, y - ry, x + r, y - rycirc, x + r, y].join(",") + "z"; 21369 } else if (type === "line") { 21370 data = "M" + attr.x1 + "," + attr.y1 + " L" + attr.x2 + "," + attr.y2; //previously, we just converted to "Mx,y Lx,y" but Safari has bugs that cause that not to render properly when using a stroke-dasharray that's not fully visible! Using a cubic bezier fixes that issue. 21371 } else if (type === "polyline" || type === "polygon") { 21372 points = (element.getAttribute("points") + "").match(_numbersExp) || []; 21373 x = points.shift(); 21374 y = points.shift(); 21375 data = "M" + x + "," + y + " L" + points.join(","); 21376 21377 if (type === "polygon") { 21378 data += "," + x + "," + y + "z"; 21379 } 21380 } 21381 21382 path.setAttribute("d", rawPathToString(path._gsRawPath = stringToRawPath(data))); 21383 21384 if (swap && element.parentNode) { 21385 element.parentNode.insertBefore(path, element); 21386 element.parentNode.removeChild(element); 21387 } 21388 21389 return path; 21390} //returns the rotation (in degrees) at a particular progress on a rawPath (the slope of the tangent) 21391 21392function getRotationAtProgress(rawPath, progress) { 21393 var d = getProgressData(rawPath, progress >= 1 ? 1 - 1e-9 : progress ? progress : 1e-9); 21394 return getRotationAtBezierT(d.segment, d.i, d.t); 21395} 21396 21397function getRotationAtBezierT(segment, i, t) { 21398 var a = segment[i], 21399 b = segment[i + 2], 21400 c = segment[i + 4], 21401 x; 21402 a += (b - a) * t; 21403 b += (c - b) * t; 21404 a += (b - a) * t; 21405 x = b + (c + (segment[i + 6] - c) * t - b) * t - a; 21406 a = segment[i + 1]; 21407 b = segment[i + 3]; 21408 c = segment[i + 5]; 21409 a += (b - a) * t; 21410 b += (c - b) * t; 21411 a += (b - a) * t; 21412 return _round(_atan2(b + (c + (segment[i + 7] - c) * t - b) * t - a, x) * _RAD2DEG); 21413} 21414 21415function sliceRawPath(rawPath, start, end) { 21416 end = _isUndefined(end) ? 1 : _roundPrecise(end) || 0; // we must round to avoid issues like 4.15 / 8 = 0.8300000000000001 instead of 0.83 or 2.8 / 5 = 0.5599999999999999 instead of 0.56 and if someone is doing a loop like start: 2.8 / 0.5, end: 2.8 / 0.5 + 1. 21417 21418 start = _roundPrecise(start) || 0; 21419 var loops = Math.max(0, ~~(_abs(end - start) - 1e-8)), 21420 path = copyRawPath(rawPath); 21421 21422 if (start > end) { 21423 start = 1 - start; 21424 end = 1 - end; 21425 21426 _reverseRawPath(path); 21427 21428 path.totalLength = 0; 21429 } 21430 21431 if (start < 0 || end < 0) { 21432 var offset = Math.abs(~~Math.min(start, end)) + 1; 21433 start += offset; 21434 end += offset; 21435 } 21436 21437 path.totalLength || cacheRawPathMeasurements(path); 21438 var wrap = end > 1, 21439 s = getProgressData(path, start, _temp, true), 21440 e = getProgressData(path, end, _temp2), 21441 eSeg = e.segment, 21442 sSeg = s.segment, 21443 eSegIndex = e.segIndex, 21444 sSegIndex = s.segIndex, 21445 ei = e.i, 21446 si = s.i, 21447 sameSegment = sSegIndex === eSegIndex, 21448 sameBezier = ei === si && sameSegment, 21449 wrapsBehind, 21450 sShift, 21451 eShift, 21452 i, 21453 copy, 21454 totalSegments, 21455 l, 21456 j; 21457 21458 if (wrap || loops) { 21459 wrapsBehind = eSegIndex < sSegIndex || sameSegment && ei < si || sameBezier && e.t < s.t; 21460 21461 if (_splitSegment(path, sSegIndex, si, s.t)) { 21462 sSegIndex++; 21463 21464 if (!wrapsBehind) { 21465 eSegIndex++; 21466 21467 if (sameBezier) { 21468 e.t = (e.t - s.t) / (1 - s.t); 21469 ei = 0; 21470 } else if (sameSegment) { 21471 ei -= si; 21472 } 21473 } 21474 } 21475 21476 if (1 - (end - start) < 1e-5) { 21477 eSegIndex = sSegIndex - 1; 21478 } else if (!e.t && eSegIndex) { 21479 eSegIndex--; 21480 } else if (_splitSegment(path, eSegIndex, ei, e.t) && wrapsBehind) { 21481 sSegIndex++; 21482 } 21483 21484 if (s.t === 1) { 21485 sSegIndex = (sSegIndex + 1) % path.length; 21486 } 21487 21488 copy = []; 21489 totalSegments = path.length; 21490 l = 1 + totalSegments * loops; 21491 j = sSegIndex; 21492 l += (totalSegments - sSegIndex + eSegIndex) % totalSegments; 21493 21494 for (i = 0; i < l; i++) { 21495 _appendOrMerge(copy, path[j++ % totalSegments]); 21496 } 21497 21498 path = copy; 21499 } else { 21500 eShift = e.t === 1 ? 6 : subdivideSegment(eSeg, ei, e.t); 21501 21502 if (start !== end) { 21503 sShift = subdivideSegment(sSeg, si, sameBezier ? s.t / e.t : s.t); 21504 sameSegment && (eShift += sShift); 21505 eSeg.splice(ei + eShift + 2); 21506 (sShift || si) && sSeg.splice(0, si + sShift); 21507 i = path.length; 21508 21509 while (i--) { 21510 //chop off any extra segments 21511 (i < sSegIndex || i > eSegIndex) && path.splice(i, 1); 21512 } 21513 } else { 21514 eSeg.angle = getRotationAtBezierT(eSeg, ei + eShift, 0); //record the value before we chop because it'll be impossible to determine the angle after its length is 0! 21515 21516 ei += eShift; 21517 s = eSeg[ei]; 21518 e = eSeg[ei + 1]; 21519 eSeg.length = eSeg.totalLength = 0; 21520 eSeg.totalPoints = path.totalPoints = 8; 21521 eSeg.push(s, e, s, e, s, e, s, e); 21522 } 21523 } 21524 21525 path.totalLength = 0; 21526 return path; 21527} //measures a Segment according to its resolution (so if segment.resolution is 6, for example, it'll take 6 samples equally across each Bezier) and create/populate a "samples" Array that has the length up to each of those sample points (always increasing from the start) as well as a "lookup" array that's broken up according to the smallest distance between 2 samples. This gives us a very fast way of looking up a progress position rather than looping through all the points/Beziers. You can optionally have it only measure a subset, starting at startIndex and going for a specific number of beziers (remember, there are 3 x/y pairs each, for a total of 6 elements for each Bezier). It will also populate a "totalLength" property, but that's not generally super accurate because by default it'll only take 6 samples per Bezier. But for performance reasons, it's perfectly adequate for measuring progress values along the path. If you need a more accurate totalLength, either increase the resolution or use the more advanced bezierToPoints() method which keeps adding points until they don't deviate by more than a certain precision value. 21528 21529function measureSegment(segment, startIndex, bezierQty) { 21530 startIndex = startIndex || 0; 21531 21532 if (!segment.samples) { 21533 segment.samples = []; 21534 segment.lookup = []; 21535 } 21536 21537 var resolution = ~~segment.resolution || 12, 21538 inc = 1 / resolution, 21539 endIndex = bezierQty ? startIndex + bezierQty * 6 + 1 : segment.length, 21540 x1 = segment[startIndex], 21541 y1 = segment[startIndex + 1], 21542 samplesIndex = startIndex ? startIndex / 6 * resolution : 0, 21543 samples = segment.samples, 21544 lookup = segment.lookup, 21545 min = (startIndex ? segment.minLength : _largeNum) || _largeNum, 21546 prevLength = samples[samplesIndex + bezierQty * resolution - 1], 21547 length = startIndex ? samples[samplesIndex - 1] : 0, 21548 i, 21549 j, 21550 x4, 21551 x3, 21552 x2, 21553 xd, 21554 xd1, 21555 y4, 21556 y3, 21557 y2, 21558 yd, 21559 yd1, 21560 inv, 21561 t, 21562 lengthIndex, 21563 l, 21564 segLength; 21565 samples.length = lookup.length = 0; 21566 21567 for (j = startIndex + 2; j < endIndex; j += 6) { 21568 x4 = segment[j + 4] - x1; 21569 x3 = segment[j + 2] - x1; 21570 x2 = segment[j] - x1; 21571 y4 = segment[j + 5] - y1; 21572 y3 = segment[j + 3] - y1; 21573 y2 = segment[j + 1] - y1; 21574 xd = xd1 = yd = yd1 = 0; 21575 21576 if (_abs(x4) < 1e-5 && _abs(y4) < 1e-5 && _abs(x2) + _abs(y2) < 1e-5) { 21577 //dump points that are sufficiently close (basically right on top of each other, making a bezier super tiny or 0 length) 21578 if (segment.length > 8) { 21579 segment.splice(j, 6); 21580 j -= 6; 21581 endIndex -= 6; 21582 } 21583 } else { 21584 for (i = 1; i <= resolution; i++) { 21585 t = inc * i; 21586 inv = 1 - t; 21587 xd = xd1 - (xd1 = (t * t * x4 + 3 * inv * (t * x3 + inv * x2)) * t); 21588 yd = yd1 - (yd1 = (t * t * y4 + 3 * inv * (t * y3 + inv * y2)) * t); 21589 l = _sqrt(yd * yd + xd * xd); 21590 21591 if (l < min) { 21592 min = l; 21593 } 21594 21595 length += l; 21596 samples[samplesIndex++] = length; 21597 } 21598 } 21599 21600 x1 += x4; 21601 y1 += y4; 21602 } 21603 21604 if (prevLength) { 21605 prevLength -= length; 21606 21607 for (; samplesIndex < samples.length; samplesIndex++) { 21608 samples[samplesIndex] += prevLength; 21609 } 21610 } 21611 21612 if (samples.length && min) { 21613 segment.totalLength = segLength = samples[samples.length - 1] || 0; 21614 segment.minLength = min; 21615 l = lengthIndex = 0; 21616 21617 for (i = 0; i < segLength; i += min) { 21618 lookup[l++] = samples[lengthIndex] < i ? ++lengthIndex : lengthIndex; 21619 } 21620 } else { 21621 segment.totalLength = samples[0] = 0; 21622 } 21623 21624 return startIndex ? length - samples[startIndex / 2 - 1] : length; 21625} 21626 21627function cacheRawPathMeasurements(rawPath, resolution) { 21628 var pathLength, points, i; 21629 21630 for (i = pathLength = points = 0; i < rawPath.length; i++) { 21631 rawPath[i].resolution = ~~resolution || 12; //steps per Bezier curve (anchor, 2 control points, to anchor) 21632 21633 points += rawPath[i].length; 21634 pathLength += measureSegment(rawPath[i]); 21635 } 21636 21637 rawPath.totalPoints = points; 21638 rawPath.totalLength = pathLength; 21639 return rawPath; 21640} //divide segment[i] at position t (value between 0 and 1, progress along that particular cubic bezier segment that starts at segment[i]). Returns how many elements were spliced into the segment array (either 0 or 6) 21641 21642function subdivideSegment(segment, i, t) { 21643 if (t <= 0 || t >= 1) { 21644 return 0; 21645 } 21646 21647 var ax = segment[i], 21648 ay = segment[i + 1], 21649 cp1x = segment[i + 2], 21650 cp1y = segment[i + 3], 21651 cp2x = segment[i + 4], 21652 cp2y = segment[i + 5], 21653 bx = segment[i + 6], 21654 by = segment[i + 7], 21655 x1a = ax + (cp1x - ax) * t, 21656 x2 = cp1x + (cp2x - cp1x) * t, 21657 y1a = ay + (cp1y - ay) * t, 21658 y2 = cp1y + (cp2y - cp1y) * t, 21659 x1 = x1a + (x2 - x1a) * t, 21660 y1 = y1a + (y2 - y1a) * t, 21661 x2a = cp2x + (bx - cp2x) * t, 21662 y2a = cp2y + (by - cp2y) * t; 21663 x2 += (x2a - x2) * t; 21664 y2 += (y2a - y2) * t; 21665 segment.splice(i + 2, 4, _round(x1a), //first control point 21666 _round(y1a), _round(x1), //second control point 21667 _round(y1), _round(x1 + (x2 - x1) * t), //new fabricated anchor on line 21668 _round(y1 + (y2 - y1) * t), _round(x2), //third control point 21669 _round(y2), _round(x2a), //fourth control point 21670 _round(y2a)); 21671 segment.samples && segment.samples.splice(i / 6 * segment.resolution | 0, 0, 0, 0, 0, 0, 0, 0); 21672 return 6; 21673} // returns an object {path, segment, segIndex, i, t} 21674 21675function getProgressData(rawPath, progress, decoratee, pushToNextIfAtEnd) { 21676 decoratee = decoratee || {}; 21677 rawPath.totalLength || cacheRawPathMeasurements(rawPath); 21678 21679 if (progress < 0 || progress > 1) { 21680 progress = _wrapProgress(progress); 21681 } 21682 21683 var segIndex = 0, 21684 segment = rawPath[0], 21685 samples, 21686 resolution, 21687 length, 21688 min, 21689 max, 21690 i, 21691 t; 21692 21693 if (!progress) { 21694 t = i = segIndex = 0; 21695 segment = rawPath[0]; 21696 } else if (progress === 1) { 21697 t = 1; 21698 segIndex = rawPath.length - 1; 21699 segment = rawPath[segIndex]; 21700 i = segment.length - 8; 21701 } else { 21702 if (rawPath.length > 1) { 21703 //speed optimization: most of the time, there's only one segment so skip the recursion. 21704 length = rawPath.totalLength * progress; 21705 max = i = 0; 21706 21707 while ((max += rawPath[i++].totalLength) < length) { 21708 segIndex = i; 21709 } 21710 21711 segment = rawPath[segIndex]; 21712 min = max - segment.totalLength; 21713 progress = (length - min) / (max - min) || 0; 21714 } 21715 21716 samples = segment.samples; 21717 resolution = segment.resolution; //how many samples per cubic bezier chunk 21718 21719 length = segment.totalLength * progress; 21720 i = segment.lookup[~~(length / segment.minLength)] || 0; 21721 min = i ? samples[i - 1] : 0; 21722 max = samples[i]; 21723 21724 if (max < length) { 21725 min = max; 21726 max = samples[++i]; 21727 } 21728 21729 t = 1 / resolution * ((length - min) / (max - min) + i % resolution); 21730 i = ~~(i / resolution) * 6; 21731 21732 if (pushToNextIfAtEnd && t === 1) { 21733 if (i + 6 < segment.length) { 21734 i += 6; 21735 t = 0; 21736 } else if (segIndex + 1 < rawPath.length) { 21737 i = t = 0; 21738 segment = rawPath[++segIndex]; 21739 } 21740 } 21741 } 21742 21743 decoratee.t = t; 21744 decoratee.i = i; 21745 decoratee.path = rawPath; 21746 decoratee.segment = segment; 21747 decoratee.segIndex = segIndex; 21748 return decoratee; 21749} 21750 21751function getPositionOnPath(rawPath, progress, includeAngle, point) { 21752 var segment = rawPath[0], 21753 result = point || {}, 21754 samples, 21755 resolution, 21756 length, 21757 min, 21758 max, 21759 i, 21760 t, 21761 a, 21762 inv; 21763 21764 if (progress < 0 || progress > 1) { 21765 progress = _wrapProgress(progress); 21766 } 21767 21768 if (rawPath.length > 1) { 21769 //speed optimization: most of the time, there's only one segment so skip the recursion. 21770 length = rawPath.totalLength * progress; 21771 max = i = 0; 21772 21773 while ((max += rawPath[i++].totalLength) < length) { 21774 segment = rawPath[i]; 21775 } 21776 21777 min = max - segment.totalLength; 21778 progress = (length - min) / (max - min) || 0; 21779 } 21780 21781 samples = segment.samples; 21782 resolution = segment.resolution; 21783 length = segment.totalLength * progress; 21784 i = segment.lookup[progress < 1 ? ~~(length / segment.minLength) : segment.lookup.length - 1] || 0; 21785 min = i ? samples[i - 1] : 0; 21786 max = samples[i]; 21787 21788 if (max < length) { 21789 min = max; 21790 max = samples[++i]; 21791 } 21792 21793 t = 1 / resolution * ((length - min) / (max - min) + i % resolution) || 0; 21794 inv = 1 - t; 21795 i = ~~(i / resolution) * 6; 21796 a = segment[i]; 21797 result.x = _round((t * t * (segment[i + 6] - a) + 3 * inv * (t * (segment[i + 4] - a) + inv * (segment[i + 2] - a))) * t + a); 21798 result.y = _round((t * t * (segment[i + 7] - (a = segment[i + 1])) + 3 * inv * (t * (segment[i + 5] - a) + inv * (segment[i + 3] - a))) * t + a); 21799 21800 if (includeAngle) { 21801 result.angle = segment.totalLength ? getRotationAtBezierT(segment, i, t >= 1 ? 1 - 1e-9 : t ? t : 1e-9) : segment.angle || 0; 21802 } 21803 21804 return result; 21805} //applies a matrix transform to RawPath (or a segment in a RawPath) and returns whatever was passed in (it transforms the values in the array(s), not a copy). 21806 21807function transformRawPath(rawPath, a, b, c, d, tx, ty) { 21808 var j = rawPath.length, 21809 segment, 21810 l, 21811 i, 21812 x, 21813 y; 21814 21815 while (--j > -1) { 21816 segment = rawPath[j]; 21817 l = segment.length; 21818 21819 for (i = 0; i < l; i += 2) { 21820 x = segment[i]; 21821 y = segment[i + 1]; 21822 segment[i] = x * a + y * c + tx; 21823 segment[i + 1] = x * b + y * d + ty; 21824 } 21825 } 21826 21827 rawPath._dirty = 1; 21828 return rawPath; 21829} // translates SVG arc data into a segment (cubic beziers). Angle is in degrees. 21830 21831function arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) { 21832 if (lastX === x && lastY === y) { 21833 return; 21834 } 21835 21836 rx = _abs(rx); 21837 ry = _abs(ry); 21838 21839 var angleRad = angle % 360 * _DEG2RAD, 21840 cosAngle = _cos(angleRad), 21841 sinAngle = _sin(angleRad), 21842 PI = Math.PI, 21843 TWOPI = PI * 2, 21844 dx2 = (lastX - x) / 2, 21845 dy2 = (lastY - y) / 2, 21846 x1 = cosAngle * dx2 + sinAngle * dy2, 21847 y1 = -sinAngle * dx2 + cosAngle * dy2, 21848 x1_sq = x1 * x1, 21849 y1_sq = y1 * y1, 21850 radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry); 21851 21852 if (radiiCheck > 1) { 21853 rx = _sqrt(radiiCheck) * rx; 21854 ry = _sqrt(radiiCheck) * ry; 21855 } 21856 21857 var rx_sq = rx * rx, 21858 ry_sq = ry * ry, 21859 sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq); 21860 21861 if (sq < 0) { 21862 sq = 0; 21863 } 21864 21865 var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq), 21866 cx1 = coef * (rx * y1 / ry), 21867 cy1 = coef * -(ry * x1 / rx), 21868 sx2 = (lastX + x) / 2, 21869 sy2 = (lastY + y) / 2, 21870 cx = sx2 + (cosAngle * cx1 - sinAngle * cy1), 21871 cy = sy2 + (sinAngle * cx1 + cosAngle * cy1), 21872 ux = (x1 - cx1) / rx, 21873 uy = (y1 - cy1) / ry, 21874 vx = (-x1 - cx1) / rx, 21875 vy = (-y1 - cy1) / ry, 21876 temp = ux * ux + uy * uy, 21877 angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)), 21878 angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy))); 21879 21880 isNaN(angleExtent) && (angleExtent = PI); //rare edge case. Math.cos(-1) is NaN. 21881 21882 if (!sweepFlag && angleExtent > 0) { 21883 angleExtent -= TWOPI; 21884 } else if (sweepFlag && angleExtent < 0) { 21885 angleExtent += TWOPI; 21886 } 21887 21888 angleStart %= TWOPI; 21889 angleExtent %= TWOPI; 21890 21891 var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)), 21892 rawPath = [], 21893 angleIncrement = angleExtent / segments, 21894 controlLength = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)), 21895 ma = cosAngle * rx, 21896 mb = sinAngle * rx, 21897 mc = sinAngle * -ry, 21898 md = cosAngle * ry, 21899 i; 21900 21901 for (i = 0; i < segments; i++) { 21902 angle = angleStart + i * angleIncrement; 21903 x1 = _cos(angle); 21904 y1 = _sin(angle); 21905 ux = _cos(angle += angleIncrement); 21906 uy = _sin(angle); 21907 rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy); 21908 } //now transform according to the actual size of the ellipse/arc (the beziers were noramlized, between 0 and 1 on a circle). 21909 21910 21911 for (i = 0; i < rawPath.length; i += 2) { 21912 x1 = rawPath[i]; 21913 y1 = rawPath[i + 1]; 21914 rawPath[i] = x1 * ma + y1 * mc + cx; 21915 rawPath[i + 1] = x1 * mb + y1 * md + cy; 21916 } 21917 21918 rawPath[i - 2] = x; //always set the end to exactly where it's supposed to be 21919 21920 rawPath[i - 1] = y; 21921 return rawPath; 21922} //Spits back a RawPath with absolute coordinates. Each segment starts with a "moveTo" command (x coordinate, then y) and then 2 control points (x, y, x, y), then anchor. The goal is to minimize memory and maximize speed. 21923 21924 21925function stringToRawPath(d) { 21926 var a = (d + "").replace(_scientific, function (m) { 21927 var n = +m; 21928 return n < 0.0001 && n > -0.0001 ? 0 : n; 21929 }).match(_svgPathExp) || [], 21930 //some authoring programs spit out very small numbers in scientific notation like "1e-5", so make sure we round that down to 0 first. 21931 path = [], 21932 relativeX = 0, 21933 relativeY = 0, 21934 twoThirds = 2 / 3, 21935 elements = a.length, 21936 points = 0, 21937 errorMessage = "ERROR: malformed path: " + d, 21938 i, 21939 j, 21940 x, 21941 y, 21942 command, 21943 isRelative, 21944 segment, 21945 startX, 21946 startY, 21947 difX, 21948 difY, 21949 beziers, 21950 prevCommand, 21951 flag1, 21952 flag2, 21953 line = function line(sx, sy, ex, ey) { 21954 difX = (ex - sx) / 3; 21955 difY = (ey - sy) / 3; 21956 segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey); 21957 }; 21958 21959 if (!d || !isNaN(a[0]) || isNaN(a[1])) { 21960 console.log(errorMessage); 21961 return path; 21962 } 21963 21964 for (i = 0; i < elements; i++) { 21965 prevCommand = command; 21966 21967 if (isNaN(a[i])) { 21968 command = a[i].toUpperCase(); 21969 isRelative = command !== a[i]; //lower case means relative 21970 } else { 21971 //commands like "C" can be strung together without any new command characters between. 21972 i--; 21973 } 21974 21975 x = +a[i + 1]; 21976 y = +a[i + 2]; 21977 21978 if (isRelative) { 21979 x += relativeX; 21980 y += relativeY; 21981 } 21982 21983 if (!i) { 21984 startX = x; 21985 startY = y; 21986 } // "M" (move) 21987 21988 21989 if (command === "M") { 21990 if (segment) { 21991 if (segment.length < 8) { 21992 //if the path data was funky and just had a M with no actual drawing anywhere, skip it. 21993 path.length -= 1; 21994 } else { 21995 points += segment.length; 21996 } 21997 } 21998 21999 relativeX = startX = x; 22000 relativeY = startY = y; 22001 segment = [x, y]; 22002 path.push(segment); 22003 i += 2; 22004 command = "L"; //an "M" with more than 2 values gets interpreted as "lineTo" commands ("L"). 22005 // "C" (cubic bezier) 22006 } else if (command === "C") { 22007 if (!segment) { 22008 segment = [0, 0]; 22009 } 22010 22011 if (!isRelative) { 22012 relativeX = relativeY = 0; 22013 } //note: "*1" is just a fast/short way to cast the value as a Number. WAAAY faster in Chrome, slightly slower in Firefox. 22014 22015 22016 segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1); 22017 i += 6; // "S" (continuation of cubic bezier) 22018 } else if (command === "S") { 22019 difX = relativeX; 22020 difY = relativeY; 22021 22022 if (prevCommand === "C" || prevCommand === "S") { 22023 difX += relativeX - segment[segment.length - 4]; 22024 difY += relativeY - segment[segment.length - 3]; 22025 } 22026 22027 if (!isRelative) { 22028 relativeX = relativeY = 0; 22029 } 22030 22031 segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1); 22032 i += 4; // "Q" (quadratic bezier) 22033 } else if (command === "Q") { 22034 difX = relativeX + (x - relativeX) * twoThirds; 22035 difY = relativeY + (y - relativeY) * twoThirds; 22036 22037 if (!isRelative) { 22038 relativeX = relativeY = 0; 22039 } 22040 22041 relativeX += a[i + 3] * 1; 22042 relativeY += a[i + 4] * 1; 22043 segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY); 22044 i += 4; // "T" (continuation of quadratic bezier) 22045 } else if (command === "T") { 22046 difX = relativeX - segment[segment.length - 4]; 22047 difY = relativeY - segment[segment.length - 3]; 22048 segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y); 22049 i += 2; // "H" (horizontal line) 22050 } else if (command === "H") { 22051 line(relativeX, relativeY, relativeX = x, relativeY); 22052 i += 1; // "V" (vertical line) 22053 } else if (command === "V") { 22054 //adjust values because the first (and only one) isn't x in this case, it's y. 22055 line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0)); 22056 i += 1; // "L" (line) or "Z" (close) 22057 } else if (command === "L" || command === "Z") { 22058 if (command === "Z") { 22059 x = startX; 22060 y = startY; 22061 segment.closed = true; 22062 } 22063 22064 if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) { 22065 line(relativeX, relativeY, x, y); 22066 22067 if (command === "L") { 22068 i += 2; 22069 } 22070 } 22071 22072 relativeX = x; 22073 relativeY = y; // "A" (arc) 22074 } else if (command === "A") { 22075 flag1 = a[i + 4]; 22076 flag2 = a[i + 5]; 22077 difX = a[i + 6]; 22078 difY = a[i + 7]; 22079 j = 7; 22080 22081 if (flag1.length > 1) { 22082 // for cases when the flags are merged, like "a8 8 0 018 8" (the 0 and 1 flags are WITH the x value of 8, but it could also be "a8 8 0 01-8 8" so it may include x or not) 22083 if (flag1.length < 3) { 22084 difY = difX; 22085 difX = flag2; 22086 j--; 22087 } else { 22088 difY = flag2; 22089 difX = flag1.substr(2); 22090 j -= 2; 22091 } 22092 22093 flag2 = flag1.charAt(1); 22094 flag1 = flag1.charAt(0); 22095 } 22096 22097 beziers = arcToSegment(relativeX, relativeY, +a[i + 1], +a[i + 2], +a[i + 3], +flag1, +flag2, (isRelative ? relativeX : 0) + difX * 1, (isRelative ? relativeY : 0) + difY * 1); 22098 i += j; 22099 22100 if (beziers) { 22101 for (j = 0; j < beziers.length; j++) { 22102 segment.push(beziers[j]); 22103 } 22104 } 22105 22106 relativeX = segment[segment.length - 2]; 22107 relativeY = segment[segment.length - 1]; 22108 } else { 22109 console.log(errorMessage); 22110 } 22111 } 22112 22113 i = segment.length; 22114 22115 if (i < 6) { 22116 //in case there's odd SVG like a M0,0 command at the very end. 22117 path.pop(); 22118 i = 0; 22119 } else if (segment[0] === segment[i - 2] && segment[1] === segment[i - 1]) { 22120 segment.closed = true; 22121 } 22122 22123 path.totalPoints = points + i; 22124 return path; 22125} //populates the points array in alternating x/y values (like [x, y, x, y...] instead of individual point objects [{x, y}, {x, y}...] to conserve memory and stay in line with how we're handling segment arrays 22126 22127function bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) { 22128 var x12 = (x1 + x2) / 2, 22129 y12 = (y1 + y2) / 2, 22130 x23 = (x2 + x3) / 2, 22131 y23 = (y2 + y3) / 2, 22132 x34 = (x3 + x4) / 2, 22133 y34 = (y3 + y4) / 2, 22134 x123 = (x12 + x23) / 2, 22135 y123 = (y12 + y23) / 2, 22136 x234 = (x23 + x34) / 2, 22137 y234 = (y23 + y34) / 2, 22138 x1234 = (x123 + x234) / 2, 22139 y1234 = (y123 + y234) / 2, 22140 dx = x4 - x1, 22141 dy = y4 - y1, 22142 d2 = _abs((x2 - x4) * dy - (y2 - y4) * dx), 22143 d3 = _abs((x3 - x4) * dy - (y3 - y4) * dx), 22144 length; 22145 22146 if (!points) { 22147 points = [x1, y1, x4, y4]; 22148 index = 2; 22149 } 22150 22151 points.splice(index || points.length - 2, 0, x1234, y1234); 22152 22153 if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) { 22154 length = points.length; 22155 bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index); 22156 bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 2 + (points.length - length)); 22157 } 22158 22159 return points; 22160} 22161/* 22162function getAngleBetweenPoints(x0, y0, x1, y1, x2, y2) { //angle between 3 points in radians 22163 var dx1 = x1 - x0, 22164 dy1 = y1 - y0, 22165 dx2 = x2 - x1, 22166 dy2 = y2 - y1, 22167 dx3 = x2 - x0, 22168 dy3 = y2 - y0, 22169 a = dx1 * dx1 + dy1 * dy1, 22170 b = dx2 * dx2 + dy2 * dy2, 22171 c = dx3 * dx3 + dy3 * dy3; 22172 return Math.acos( (a + b - c) / _sqrt(4 * a * b) ); 22173}, 22174*/ 22175//pointsToSegment() doesn't handle flat coordinates (where y is always 0) the way we need (the resulting control points are always right on top of the anchors), so this function basically makes the control points go directly up and down, varying in length based on the curviness (more curvy, further control points) 22176 22177function flatPointsToSegment(points, curviness) { 22178 if (curviness === void 0) { 22179 curviness = 1; 22180 } 22181 22182 var x = points[0], 22183 y = 0, 22184 segment = [x, y], 22185 i = 2; 22186 22187 for (; i < points.length; i += 2) { 22188 segment.push(x, y, points[i], y = (points[i] - x) * curviness / 2, x = points[i], -y); 22189 } 22190 22191 return segment; 22192} //points is an array of x/y points, like [x, y, x, y, x, y] 22193 22194function pointsToSegment(points, curviness, cornerThreshold) { 22195 //points = simplifyPoints(points, tolerance); 22196 _abs(points[0] - points[2]) < 1e-4 && _abs(points[1] - points[3]) < 1e-4 && (points = points.slice(2)); // if the first two points are super close, dump the first one. 22197 22198 var l = points.length - 2, 22199 x = +points[0], 22200 y = +points[1], 22201 nextX = +points[2], 22202 nextY = +points[3], 22203 segment = [x, y, x, y], 22204 dx2 = nextX - x, 22205 dy2 = nextY - y, 22206 closed = Math.abs(points[l] - x) < 0.001 && Math.abs(points[l + 1] - y) < 0.001, 22207 prevX, 22208 prevY, 22209 angle, 22210 slope, 22211 i, 22212 dx1, 22213 dx3, 22214 dy1, 22215 dy3, 22216 d1, 22217 d2, 22218 a, 22219 b, 22220 c; 22221 22222 if (isNaN(cornerThreshold)) { 22223 cornerThreshold = Math.PI / 10; 22224 } 22225 22226 if (closed) { 22227 // if the start and end points are basically on top of each other, close the segment by adding the 2nd point to the end, and the 2nd-to-last point to the beginning (we'll remove them at the end, but this allows the curvature to look perfect) 22228 points.push(nextX, nextY); 22229 nextX = x; 22230 nextY = y; 22231 x = points[l - 2]; 22232 y = points[l - 1]; 22233 points.unshift(x, y); 22234 l += 4; 22235 } 22236 22237 curviness = curviness || curviness === 0 ? +curviness : 1; 22238 22239 for (i = 2; i < l; i += 2) { 22240 prevX = x; 22241 prevY = y; 22242 x = nextX; 22243 y = nextY; 22244 nextX = +points[i + 2]; 22245 nextY = +points[i + 3]; 22246 22247 if (x === nextX && y === nextY) { 22248 continue; 22249 } 22250 22251 dx1 = dx2; 22252 dy1 = dy2; 22253 dx2 = nextX - x; 22254 dy2 = nextY - y; 22255 dx3 = nextX - prevX; 22256 dy3 = nextY - prevY; 22257 a = dx1 * dx1 + dy1 * dy1; 22258 b = dx2 * dx2 + dy2 * dy2; 22259 c = dx3 * dx3 + dy3 * dy3; 22260 angle = Math.acos((a + b - c) / _sqrt(4 * a * b)); //angle between the 3 points 22261 22262 d2 = angle / Math.PI * curviness; //temporary precalculation for speed (reusing d2 variable) 22263 22264 d1 = _sqrt(a) * d2; //the tighter the angle, the shorter we make the handles in proportion. 22265 22266 d2 *= _sqrt(b); 22267 22268 if (x !== prevX || y !== prevY) { 22269 if (angle > cornerThreshold) { 22270 slope = _atan2(dy3, dx3); 22271 segment.push(_round(x - _cos(slope) * d1), //first control point 22272 _round(y - _sin(slope) * d1), _round(x), //anchor 22273 _round(y), _round(x + _cos(slope) * d2), //second control point 22274 _round(y + _sin(slope) * d2)); 22275 } else { 22276 slope = _atan2(dy1, dx1); 22277 segment.push(_round(x - _cos(slope) * d1), //first control point 22278 _round(y - _sin(slope) * d1)); 22279 slope = _atan2(dy2, dx2); 22280 segment.push(_round(x), //anchor 22281 _round(y), _round(x + _cos(slope) * d2), //second control point 22282 _round(y + _sin(slope) * d2)); 22283 } 22284 } 22285 } 22286 22287 x !== nextX || y !== nextY || segment.length < 4 ? segment.push(_round(nextX), _round(nextY), _round(nextX), _round(nextY)) : segment.length -= 2; 22288 22289 if (closed) { 22290 segment.splice(0, 6); 22291 segment.length = segment.length - 6; 22292 } 22293 22294 return segment; 22295} //returns the squared distance between an x/y coordinate and a segment between x1/y1 and x2/y2 22296 22297function pointToSegDist(x, y, x1, y1, x2, y2) { 22298 var dx = x2 - x1, 22299 dy = y2 - y1, 22300 t; 22301 22302 if (dx || dy) { 22303 t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy); 22304 22305 if (t > 1) { 22306 x1 = x2; 22307 y1 = y2; 22308 } else if (t > 0) { 22309 x1 += dx * t; 22310 y1 += dy * t; 22311 } 22312 } 22313 22314 return Math.pow(x - x1, 2) + Math.pow(y - y1, 2); 22315} 22316 22317function simplifyStep(points, first, last, tolerance, simplified) { 22318 var maxSqDist = tolerance, 22319 firstX = points[first], 22320 firstY = points[first + 1], 22321 lastX = points[last], 22322 lastY = points[last + 1], 22323 index, 22324 i, 22325 d; 22326 22327 for (i = first + 2; i < last; i += 2) { 22328 d = pointToSegDist(points[i], points[i + 1], firstX, firstY, lastX, lastY); 22329 22330 if (d > maxSqDist) { 22331 index = i; 22332 maxSqDist = d; 22333 } 22334 } 22335 22336 if (maxSqDist > tolerance) { 22337 index - first > 2 && simplifyStep(points, first, index, tolerance, simplified); 22338 simplified.push(points[index], points[index + 1]); 22339 last - index > 2 && simplifyStep(points, index, last, tolerance, simplified); 22340 } 22341} //points is an array of x/y values like [x, y, x, y, x, y] 22342 22343 22344function simplifyPoints(points, tolerance) { 22345 var prevX = parseFloat(points[0]), 22346 prevY = parseFloat(points[1]), 22347 temp = [prevX, prevY], 22348 l = points.length - 2, 22349 i, 22350 x, 22351 y, 22352 dx, 22353 dy, 22354 result, 22355 last; 22356 tolerance = Math.pow(tolerance || 1, 2); 22357 22358 for (i = 2; i < l; i += 2) { 22359 x = parseFloat(points[i]); 22360 y = parseFloat(points[i + 1]); 22361 dx = prevX - x; 22362 dy = prevY - y; 22363 22364 if (dx * dx + dy * dy > tolerance) { 22365 temp.push(x, y); 22366 prevX = x; 22367 prevY = y; 22368 } 22369 } 22370 22371 temp.push(parseFloat(points[l]), parseFloat(points[l + 1])); 22372 last = temp.length - 2; 22373 result = [temp[0], temp[1]]; 22374 simplifyStep(temp, 0, last, tolerance, result); 22375 result.push(temp[last], temp[last + 1]); 22376 return result; 22377} 22378 22379function getClosestProgressOnBezier(iterations, px, py, start, end, slices, x0, y0, x1, y1, x2, y2, x3, y3) { 22380 var inc = (end - start) / slices, 22381 best = 0, 22382 t = start, 22383 x, 22384 y, 22385 d, 22386 dx, 22387 dy, 22388 inv; 22389 _bestDistance = _largeNum; 22390 22391 while (t <= end) { 22392 inv = 1 - t; 22393 x = inv * inv * inv * x0 + 3 * inv * inv * t * x1 + 3 * inv * t * t * x2 + t * t * t * x3; 22394 y = inv * inv * inv * y0 + 3 * inv * inv * t * y1 + 3 * inv * t * t * y2 + t * t * t * y3; 22395 dx = x - px; 22396 dy = y - py; 22397 d = dx * dx + dy * dy; 22398 22399 if (d < _bestDistance) { 22400 _bestDistance = d; 22401 best = t; 22402 } 22403 22404 t += inc; 22405 } 22406 22407 return iterations > 1 ? getClosestProgressOnBezier(iterations - 1, px, py, Math.max(best - inc, 0), Math.min(best + inc, 1), slices, x0, y0, x1, y1, x2, y2, x3, y3) : best; 22408} 22409 22410function getClosestData(rawPath, x, y, slices) { 22411 //returns an object with the closest j, i, and t (j is the segment index, i is the index of the point in that segment, and t is the time/progress along that bezier) 22412 var closest = { 22413 j: 0, 22414 i: 0, 22415 t: 0 22416 }, 22417 bestDistance = _largeNum, 22418 i, 22419 j, 22420 t, 22421 segment; 22422 22423 for (j = 0; j < rawPath.length; j++) { 22424 segment = rawPath[j]; 22425 22426 for (i = 0; i < segment.length; i += 6) { 22427 t = getClosestProgressOnBezier(1, x, y, 0, 1, slices || 20, segment[i], segment[i + 1], segment[i + 2], segment[i + 3], segment[i + 4], segment[i + 5], segment[i + 6], segment[i + 7]); 22428 22429 if (bestDistance > _bestDistance) { 22430 bestDistance = _bestDistance; 22431 closest.j = j; 22432 closest.i = i; 22433 closest.t = t; 22434 } 22435 } 22436 } 22437 22438 return closest; 22439} //subdivide a Segment closest to a specific x,y coordinate 22440 22441function subdivideSegmentNear(x, y, segment, slices, iterations) { 22442 var l = segment.length, 22443 bestDistance = _largeNum, 22444 bestT = 0, 22445 bestSegmentIndex = 0, 22446 t, 22447 i; 22448 slices = slices || 20; 22449 iterations = iterations || 3; 22450 22451 for (i = 0; i < l; i += 6) { 22452 t = getClosestProgressOnBezier(1, x, y, 0, 1, slices, segment[i], segment[i + 1], segment[i + 2], segment[i + 3], segment[i + 4], segment[i + 5], segment[i + 6], segment[i + 7]); 22453 22454 if (bestDistance > _bestDistance) { 22455 bestDistance = _bestDistance; 22456 bestT = t; 22457 bestSegmentIndex = i; 22458 } 22459 } 22460 22461 t = getClosestProgressOnBezier(iterations, x, y, bestT - 0.05, bestT + 0.05, slices, segment[bestSegmentIndex], segment[bestSegmentIndex + 1], segment[bestSegmentIndex + 2], segment[bestSegmentIndex + 3], segment[bestSegmentIndex + 4], segment[bestSegmentIndex + 5], segment[bestSegmentIndex + 6], segment[bestSegmentIndex + 7]); 22462 subdivideSegment(segment, bestSegmentIndex, t); 22463 return bestSegmentIndex + 6; 22464} 22465/* 22466Takes any of the following and converts it to an all Cubic Bezier SVG data string: 22467- A <path> data string like "M0,0 L2,4 v20,15 H100" 22468- A RawPath, like [[x, y, x, y, x, y, x, y][[x, y, x, y, x, y, x, y]] 22469- A Segment, like [x, y, x, y, x, y, x, y] 22470 22471Note: all numbers are rounded down to the closest 0.001 to minimize memory, maximize speed, and avoid odd numbers like 1e-13 22472*/ 22473 22474function rawPathToString(rawPath) { 22475 if (_isNumber(rawPath[0])) { 22476 //in case a segment is passed in instead 22477 rawPath = [rawPath]; 22478 } 22479 22480 var result = "", 22481 l = rawPath.length, 22482 sl, 22483 s, 22484 i, 22485 segment; 22486 22487 for (s = 0; s < l; s++) { 22488 segment = rawPath[s]; 22489 result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C"; 22490 sl = segment.length; 22491 22492 for (i = 2; i < sl; i++) { 22493 result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " "; 22494 } 22495 22496 if (segment.closed) { 22497 result += "z"; 22498 } 22499 } 22500 22501 return result; 22502} 22503/* 22504// takes a segment with coordinates [x, y, x, y, ...] and converts the control points into angles and lengths [x, y, angle, length, angle, length, x, y, angle, length, ...] so that it animates more cleanly and avoids odd breaks/kinks. For example, if you animate from 1 o'clock to 6 o'clock, it'd just go directly/linearly rather than around. So the length would be very short in the middle of the tween. 22505export function cpCoordsToAngles(segment, copy) { 22506 var result = copy ? segment.slice(0) : segment, 22507 x, y, i; 22508 for (i = 0; i < segment.length; i+=6) { 22509 x = segment[i+2] - segment[i]; 22510 y = segment[i+3] - segment[i+1]; 22511 result[i+2] = Math.atan2(y, x); 22512 result[i+3] = Math.sqrt(x * x + y * y); 22513 x = segment[i+6] - segment[i+4]; 22514 y = segment[i+7] - segment[i+5]; 22515 result[i+4] = Math.atan2(y, x); 22516 result[i+5] = Math.sqrt(x * x + y * y); 22517 } 22518 return result; 22519} 22520 22521// takes a segment that was converted with cpCoordsToAngles() to have angles and lengths instead of coordinates for the control points, and converts it BACK into coordinates. 22522export function cpAnglesToCoords(segment, copy) { 22523 var result = copy ? segment.slice(0) : segment, 22524 length = segment.length, 22525 rnd = 1000, 22526 angle, l, i, j; 22527 for (i = 0; i < length; i+=6) { 22528 angle = segment[i+2]; 22529 l = segment[i+3]; //length 22530 result[i+2] = (((segment[i] + Math.cos(angle) * l) * rnd) | 0) / rnd; 22531 result[i+3] = (((segment[i+1] + Math.sin(angle) * l) * rnd) | 0) / rnd; 22532 angle = segment[i+4]; 22533 l = segment[i+5]; //length 22534 result[i+4] = (((segment[i+6] - Math.cos(angle) * l) * rnd) | 0) / rnd; 22535 result[i+5] = (((segment[i+7] - Math.sin(angle) * l) * rnd) | 0) / rnd; 22536 } 22537 return result; 22538} 22539 22540//adds an "isSmooth" array to each segment and populates it with a boolean value indicating whether or not it's smooth (the control points have basically the same slope). For any smooth control points, it converts the coordinates into angle (x, in radians) and length (y) and puts them into the same index value in a smoothData array. 22541export function populateSmoothData(rawPath) { 22542 let j = rawPath.length, 22543 smooth, segment, x, y, x2, y2, i, l, a, a2, isSmooth, smoothData; 22544 while (--j > -1) { 22545 segment = rawPath[j]; 22546 isSmooth = segment.isSmooth = segment.isSmooth || [0, 0, 0, 0]; 22547 smoothData = segment.smoothData = segment.smoothData || [0, 0, 0, 0]; 22548 isSmooth.length = 4; 22549 l = segment.length - 2; 22550 for (i = 6; i < l; i += 6) { 22551 x = segment[i] - segment[i - 2]; 22552 y = segment[i + 1] - segment[i - 1]; 22553 x2 = segment[i + 2] - segment[i]; 22554 y2 = segment[i + 3] - segment[i + 1]; 22555 a = _atan2(y, x); 22556 a2 = _atan2(y2, x2); 22557 smooth = (Math.abs(a - a2) < 0.09); 22558 if (smooth) { 22559 smoothData[i - 2] = a; 22560 smoothData[i + 2] = a2; 22561 smoothData[i - 1] = _sqrt(x * x + y * y); 22562 smoothData[i + 3] = _sqrt(x2 * x2 + y2 * y2); 22563 } 22564 isSmooth.push(smooth, smooth, 0, 0, smooth, smooth); 22565 } 22566 //if the first and last points are identical, check to see if there's a smooth transition. We must handle this a bit differently due to their positions in the array. 22567 if (segment[l] === segment[0] && segment[l+1] === segment[1]) { 22568 x = segment[0] - segment[l-2]; 22569 y = segment[1] - segment[l-1]; 22570 x2 = segment[2] - segment[0]; 22571 y2 = segment[3] - segment[1]; 22572 a = _atan2(y, x); 22573 a2 = _atan2(y2, x2); 22574 if (Math.abs(a - a2) < 0.09) { 22575 smoothData[l-2] = a; 22576 smoothData[2] = a2; 22577 smoothData[l-1] = _sqrt(x * x + y * y); 22578 smoothData[3] = _sqrt(x2 * x2 + y2 * y2); 22579 isSmooth[l-2] = isSmooth[l-1] = true; //don't change indexes 2 and 3 because we'll trigger everything from the END, and this will optimize file size a bit. 22580 } 22581 } 22582 } 22583 return rawPath; 22584} 22585export function pointToScreen(svgElement, point) { 22586 if (arguments.length < 2) { //by default, take the first set of coordinates in the path as the point 22587 let rawPath = getRawPath(svgElement); 22588 point = svgElement.ownerSVGElement.createSVGPoint(); 22589 point.x = rawPath[0][0]; 22590 point.y = rawPath[0][1]; 22591 } 22592 return point.matrixTransform(svgElement.getScreenCTM()); 22593} 22594 22595*/ 22596 22597/***/ }), 22598
vendor: 10,880 bytes, lines 22599-22710
22599/***/ "./node_modules/gsap/utils/strings.js": 22600/*!********************************************!*\ 22601 !*** ./node_modules/gsap/utils/strings.js ***! 22602 \********************************************/ 22603/*! exports provided: emojiExp, getText, splitInnerHTML, emojiSafeSplit */ 22604/***/ (function(module, __webpack_exports__, __webpack_require__) { 22605 22606"use strict"; 22607__webpack_require__.r(__webpack_exports__); 22608/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "emojiExp", function() { return emojiExp; }); 22609/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getText", function() { return getText; }); 22610/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "splitInnerHTML", function() { return splitInnerHTML; }); 22611/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "emojiSafeSplit", function() { return emojiSafeSplit; }); 22612/*! 22613 * strings: 3.6.0 22614 * https://greensock.com 22615 * 22616 * Copyright 2008-2021, GreenSock. All rights reserved. 22617 * Subject to the terms at https://greensock.com/standard-license or for 22618 * Club GreenSock members, the agreement issued with that membership. 22619 * @author: Jack Doyle, [email protected] 22620*/ 22621 22622/* eslint-disable */ 22623var _trimExp = /(^\s+|\s+$)/g; 22624var emojiExp = /([\uD800-\uDBFF][\uDC00-\uDFFF](?:[\u200D\uFE0F][\uD800-\uDBFF][\uDC00-\uDFFF]){2,}|\uD83D\uDC69(?:\u200D(?:(?:\uD83D\uDC69\u200D)?\uD83D\uDC67|(?:\uD83D\uDC69\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D(?:\uD83D\uDC69\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]\uFE0F|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC6F\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3C-\uDD3E\uDDD6-\uDDDF])\u200D[\u2640\u2642]\uFE0F|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F\u200D[\u2640\u2642]|(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642])\uFE0F|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\uD83D\uDC69\u200D[\u2695\u2696\u2708]|\uD83D\uDC68(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708]))\uFE0F|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83D\uDC69\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|\uD83D\uDC68(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66\u200D\uD83D\uDC66|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92])|(?:\uD83C[\uDFFB-\uDFFF])\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]))|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDD1-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\u200D(?:(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC67|(?:(?:\uD83D[\uDC68\uDC69])\u200D)?\uD83D\uDC66)|\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC69\uDC6E\uDC70-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD18-\uDD1C\uDD1E\uDD1F\uDD26\uDD30-\uDD39\uDD3D\uDD3E\uDDD1-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])?|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDEEB\uDEEC\uDEF4-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u2660\u2663\u2665\u2666\u2668\u267B\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEF8]|\uD83E[\uDD10-\uDD3A\uDD3C-\uDD3E\uDD40-\uDD45\uDD47-\uDD4C\uDD50-\uDD6B\uDD80-\uDD97\uDDC0\uDDD0-\uDDE6])\uFE0F)/; 22625function getText(e) { 22626 var type = e.nodeType, 22627 result = ""; 22628 22629 if (type === 1 || type === 9 || type === 11) { 22630 if (typeof e.textContent === "string") { 22631 return e.textContent; 22632 } else { 22633 for (e = e.firstChild; e; e = e.nextSibling) { 22634 result += getText(e); 22635 } 22636 } 22637 } else if (type === 3 || type === 4) { 22638 return e.nodeValue; 22639 } 22640 22641 return result; 22642} 22643function splitInnerHTML(element, delimiter, trim) { 22644 var node = element.firstChild, 22645 result = []; 22646 22647 while (node) { 22648 if (node.nodeType === 3) { 22649 result.push.apply(result, emojiSafeSplit((node.nodeValue + "").replace(/^\n+/g, "").replace(/\s+/g, " "), delimiter, trim)); 22650 } else if ((node.nodeName + "").toLowerCase() === "br") { 22651 result[result.length - 1] += "<br>"; 22652 } else { 22653 result.push(node.outerHTML); 22654 } 22655 22656 node = node.nextSibling; 22657 } 22658 22659 return result; 22660} 22661/* 22662//smaller kb version that only handles the simpler emoji's, which is often perfectly adequate. 22663 22664let _emoji = "[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2694-\u2697]|\uD83E[\uDD10-\uDD5D]|[\uD800-\uDBFF][\uDC00-\uDFFF]", 22665 _emojiExp = new RegExp(_emoji), 22666 _emojiAndCharsExp = new RegExp(_emoji + "|.", "g"), 22667 _emojiSafeSplit = (text, delimiter, trim) => { 22668 if (trim) { 22669 text = text.replace(_trimExp, ""); 22670 } 22671 return ((delimiter === "" || !delimiter) && _emojiExp.test(text)) ? text.match(_emojiAndCharsExp) : text.split(delimiter || ""); 22672 }; 22673 */ 22674 22675function emojiSafeSplit(text, delimiter, trim) { 22676 text += ""; // make sure it's cast as a string. Someone may pass in a number. 22677 22678 if (trim) { 22679 text = text.replace(_trimExp, ""); 22680 } 22681 22682 if (delimiter && delimiter !== "") { 22683 return text.replace(/>/g, ">").replace(/</g, "<").split(delimiter); 22684 } 22685 22686 var result = [], 22687 l = text.length, 22688 i = 0, 22689 j, 22690 character; 22691 22692 for (; i < l; i++) { 22693 character = text.charAt(i); 22694 22695 if (character.charCodeAt(0) >= 0xD800 && character.charCodeAt(0) <= 0xDBFF || text.charCodeAt(i + 1) >= 0xFE00 && text.charCodeAt(i + 1) <= 0xFE0F) { 22696 //special emoji characters use 2 or 4 unicode characters that we must keep together. 22697 j = ((text.substr(i, 12).split(emojiExp) || [])[1] || "").length || 2; 22698 character = text.substr(i, j); 22699 result.emoji = 1; 22700 i += j - 1; 22701 } 22702 22703 result.push(character === ">" ? ">" : character === "<" ? "<" : character); 22704 } 22705 22706 return result; 22707} 22708 22709/***/ }), 22710
vendor: 10,883 bytes, lines 22711-23157
22711/***/ "./node_modules/headroom.js/dist/headroom.js": 22712/*!***************************************************!*\ 22713 !*** ./node_modules/headroom.js/dist/headroom.js ***! 22714 \***************************************************/ 22715/*! no static exports found */ 22716/***/ (function(module, exports, __webpack_require__) { 22717 22718/*! 22719 * headroom.js v0.12.0 - Give your page some headroom. Hide your header until you need it 22720 * Copyright (c) 2020 Nick Williams - http://wicky.nillia.ms/headroom.js 22721 * License: MIT 22722 */ 22723 22724(function (global, factory) { 22725 true ? module.exports = factory() : 22726 undefined; 22727}(this, function () { 'use strict'; 22728 22729 function isBrowser() { 22730 return typeof window !== "undefined"; 22731 } 22732 22733 /** 22734 * Used to detect browser support for adding an event listener with options 22735 * Credit: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener 22736 */ 22737 function passiveEventsSupported() { 22738 var supported = false; 22739 22740 try { 22741 var options = { 22742 // eslint-disable-next-line getter-return 22743 get passive() { 22744 supported = true; 22745 } 22746 }; 22747 window.addEventListener("test", options, options); 22748 window.removeEventListener("test", options, options); 22749 } catch (err) { 22750 supported = false; 22751 } 22752 22753 return supported; 22754 } 22755 22756 function isSupported() { 22757 return !!( 22758 isBrowser() && 22759 function() {}.bind && 22760 "classList" in document.documentElement && 22761 Object.assign && 22762 Object.keys && 22763 requestAnimationFrame 22764 ); 22765 } 22766 22767 function isDocument(obj) { 22768 return obj.nodeType === 9; // Node.DOCUMENT_NODE === 9 22769 } 22770 22771 function isWindow(obj) { 22772 // `obj === window` or `obj instanceof Window` is not sufficient, 22773 // as the obj may be the window of an iframe. 22774 return obj && obj.document && isDocument(obj.document); 22775 } 22776 22777 function windowScroller(win) { 22778 var doc = win.document; 22779 var body = doc.body; 22780 var html = doc.documentElement; 22781 22782 return { 22783 /** 22784 * @see http://james.padolsey.com/javascript/get-document-height-cross-browser/ 22785 * @return {Number} the scroll height of the document in pixels 22786 */ 22787 scrollHeight: function() { 22788 return Math.max( 22789 body.scrollHeight, 22790 html.scrollHeight, 22791 body.offsetHeight, 22792 html.offsetHeight, 22793 body.clientHeight, 22794 html.clientHeight 22795 ); 22796 }, 22797 22798 /** 22799 * @see http://andylangton.co.uk/blog/development/get-viewport-size-width-and-height-javascript 22800 * @return {Number} the height of the viewport in pixels 22801 */ 22802 height: function() { 22803 return win.innerHeight || html.clientHeight || body.clientHeight; 22804 }, 22805 22806 /** 22807 * Gets the Y scroll position 22808 * @return {Number} pixels the page has scrolled along the Y-axis 22809 */ 22810 scrollY: function() { 22811 if (win.pageYOffset !== undefined) { 22812 return win.pageYOffset; 22813 } 22814 22815 return (html || body.parentNode || body).scrollTop; 22816 } 22817 }; 22818 } 22819 22820 function elementScroller(element) { 22821 return { 22822 /** 22823 * @return {Number} the scroll height of the element in pixels 22824 */ 22825 scrollHeight: function() { 22826 return Math.max( 22827 element.scrollHeight, 22828 element.offsetHeight, 22829 element.clientHeight 22830 ); 22831 }, 22832 22833 /** 22834 * @return {Number} the height of the element in pixels 22835 */ 22836 height: function() { 22837 return Math.max(element.offsetHeight, element.clientHeight); 22838 }, 22839 22840 /** 22841 * Gets the Y scroll position 22842 * @return {Number} pixels the element has scrolled along the Y-axis 22843 */ 22844 scrollY: function() { 22845 return element.scrollTop; 22846 } 22847 }; 22848 } 22849 22850 function createScroller(element) { 22851 return isWindow(element) ? windowScroller(element) : elementScroller(element); 22852 } 22853 22854 /** 22855 * @param element EventTarget 22856 */ 22857 function trackScroll(element, options, callback) { 22858 var isPassiveSupported = passiveEventsSupported(); 22859 var rafId; 22860 var scrolled = false; 22861 var scroller = createScroller(element); 22862 var lastScrollY = scroller.scrollY(); 22863 var details = {}; 22864 22865 function update() { 22866 var scrollY = Math.round(scroller.scrollY()); 22867 var height = scroller.height(); 22868 var scrollHeight = scroller.scrollHeight(); 22869 22870 // reuse object for less memory churn 22871 details.scrollY = scrollY; 22872 details.lastScrollY = lastScrollY; 22873 details.direction = scrollY > lastScrollY ? "down" : "up"; 22874 details.distance = Math.abs(scrollY - lastScrollY); 22875 details.isOutOfBounds = scrollY < 0 || scrollY + height > scrollHeight; 22876 details.top = scrollY <= options.offset[details.direction]; 22877 details.bottom = scrollY + height >= scrollHeight; 22878 details.toleranceExceeded = 22879 details.distance > options.tolerance[details.direction]; 22880 22881 callback(details); 22882 22883 lastScrollY = scrollY; 22884 scrolled = false; 22885 } 22886 22887 function handleScroll() { 22888 if (!scrolled) { 22889 scrolled = true; 22890 rafId = requestAnimationFrame(update); 22891 } 22892 } 22893 22894 var eventOptions = isPassiveSupported 22895 ? { passive: true, capture: false } 22896 : false; 22897 22898 element.addEventListener("scroll", handleScroll, eventOptions); 22899 update(); 22900 22901 return { 22902 destroy: function() { 22903 cancelAnimationFrame(rafId); 22904 element.removeEventListener("scroll", handleScroll, eventOptions); 22905 } 22906 }; 22907 } 22908 22909 function normalizeUpDown(t) { 22910 return t === Object(t) ? t : { down: t, up: t }; 22911 } 22912 22913 /** 22914 * UI enhancement for fixed headers. 22915 * Hides header when scrolling down 22916 * Shows header when scrolling up 22917 * @constructor 22918 * @param {DOMElement} elem the header element 22919 * @param {Object} options options for the widget 22920 */ 22921 function Headroom(elem, options) { 22922 options = options || {}; 22923 Object.assign(this, Headroom.options, options); 22924 this.classes = Object.assign({}, Headroom.options.classes, options.classes); 22925 22926 this.elem = elem; 22927 this.tolerance = normalizeUpDown(this.tolerance); 22928 this.offset = normalizeUpDown(this.offset); 22929 this.initialised = false; 22930 this.frozen = false; 22931 } 22932 Headroom.prototype = { 22933 constructor: Headroom, 22934 22935 /** 22936 * Start listening to scrolling 22937 * @public 22938 */ 22939 init: function() { 22940 if (Headroom.cutsTheMustard && !this.initialised) { 22941 this.addClass("initial"); 22942 this.initialised = true; 22943 22944 // defer event registration to handle browser 22945 // potentially restoring previous scroll position 22946 setTimeout( 22947 function(self) { 22948 self.scrollTracker = trackScroll( 22949 self.scroller, 22950 { offset: self.offset, tolerance: self.tolerance }, 22951 self.update.bind(self) 22952 ); 22953 }, 22954 100, 22955 this 22956 ); 22957 } 22958 22959 return this; 22960 }, 22961 22962 /** 22963 * Destroy the widget, clearing up after itself 22964 * @public 22965 */ 22966 destroy: function() { 22967 this.initialised = false; 22968 Object.keys(this.classes).forEach(this.removeClass, this); 22969 this.scrollTracker.destroy(); 22970 }, 22971 22972 /** 22973 * Unpin the element 22974 * @public 22975 */ 22976 unpin: function() { 22977 if (this.hasClass("pinned") || !this.hasClass("unpinned")) { 22978 this.addClass("unpinned"); 22979 this.removeClass("pinned"); 22980 22981 if (this.onUnpin) { 22982 this.onUnpin.call(this); 22983 } 22984 } 22985 }, 22986 22987 /** 22988 * Pin the element 22989 * @public 22990 */ 22991 pin: function() { 22992 if (this.hasClass("unpinned")) { 22993 this.addClass("pinned"); 22994 this.removeClass("unpinned"); 22995 22996 if (this.onPin) { 22997 this.onPin.call(this); 22998 } 22999 } 23000 }, 23001 23002 /** 23003 * Freezes the current state of the widget 23004 * @public 23005 */ 23006 freeze: function() { 23007 this.frozen = true; 23008 this.addClass("frozen"); 23009 }, 23010 23011 /** 23012 * Re-enables the default behaviour of the widget 23013 * @public 23014 */ 23015 unfreeze: function() { 23016 this.frozen = false; 23017 this.removeClass("frozen"); 23018 }, 23019 23020 top: function() { 23021 if (!this.hasClass("top")) { 23022 this.addClass("top"); 23023 this.removeClass("notTop"); 23024 23025 if (this.onTop) { 23026 this.onTop.call(this); 23027 } 23028 } 23029 }, 23030 23031 notTop: function() { 23032 if (!this.hasClass("notTop")) { 23033 this.addClass("notTop"); 23034 this.removeClass("top"); 23035 23036 if (this.onNotTop) { 23037 this.onNotTop.call(this); 23038 } 23039 } 23040 }, 23041 23042 bottom: function() { 23043 if (!this.hasClass("bottom")) { 23044 this.addClass("bottom"); 23045 this.removeClass("notBottom"); 23046 23047 if (this.onBottom) { 23048 this.onBottom.call(this); 23049 } 23050 } 23051 }, 23052 23053 notBottom: function() { 23054 if (!this.hasClass("notBottom")) { 23055 this.addClass("notBottom"); 23056 this.removeClass("bottom"); 23057 23058 if (this.onNotBottom) { 23059 this.onNotBottom.call(this); 23060 } 23061 } 23062 }, 23063 23064 shouldUnpin: function(details) { 23065 var scrollingDown = details.direction === "down"; 23066 23067 return scrollingDown && !details.top && details.toleranceExceeded; 23068 }, 23069 23070 shouldPin: function(details) { 23071 var scrollingUp = details.direction === "up"; 23072 23073 return (scrollingUp && details.toleranceExceeded) || details.top; 23074 }, 23075 23076 addClass: function(className) { 23077 this.elem.classList.add.apply( 23078 this.elem.classList, 23079 this.classes[className].split(" ") 23080 ); 23081 }, 23082 23083 removeClass: function(className) { 23084 this.elem.classList.remove.apply( 23085 this.elem.classList, 23086 this.classes[className].split(" ") 23087 ); 23088 }, 23089 23090 hasClass: function(className) { 23091 return this.classes[className].split(" ").every(function(cls) { 23092 return this.classList.contains(cls); 23093 }, this.elem); 23094 }, 23095 23096 update: function(details) { 23097 if (details.isOutOfBounds) { 23098 // Ignore bouncy scrolling in OSX 23099 return; 23100 } 23101 23102 if (this.frozen === true) { 23103 return; 23104 } 23105 23106 if (details.top) { 23107 this.top(); 23108 } else { 23109 this.notTop(); 23110 } 23111 23112 if (details.bottom) { 23113 this.bottom(); 23114 } else { 23115 this.notBottom(); 23116 } 23117 23118 if (this.shouldUnpin(details)) { 23119 this.unpin(); 23120 } else if (this.shouldPin(details)) { 23121 this.pin(); 23122 } 23123 } 23124 }; 23125 23126 /** 23127 * Default options 23128 * @type {Object} 23129 */ 23130 Headroom.options = { 23131 tolerance: { 23132 up: 0, 23133 down: 0 23134 }, 23135 offset: 0, 23136 scroller: isBrowser() ? window : null, 23137 classes: { 23138 frozen: "headroom--frozen", 23139 pinned: "headroom--pinned", 23140 unpinned: "headroom--unpinned", 23141 top: "headroom--top", 23142 notTop: "headroom--not-top", 23143 bottom: "headroom--bottom", 23144 notBottom: "headroom--not-bottom", 23145 initial: "headroom" 23146 } 23147 }; 23148 23149 Headroom.cutsTheMustard = isSupported(); 23150 23151 return Headroom; 23152 23153})); 23154 23155 23156/***/ }), 23157
vendor: 288,125 bytes, lines 23158-34041
23158/***/ "./node_modules/jquery/dist/jquery.js": 23159/*!********************************************!*\ 23160 !*** ./node_modules/jquery/dist/jquery.js ***! 23161 \********************************************/ 23162/*! no static exports found */ 23163/***/ (function(module, exports, __webpack_require__) { 23164 23165var __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! 23166 * jQuery JavaScript Library v3.5.1 23167 * https://jquery.com/ 23168 * 23169 * Includes Sizzle.js 23170 * https://sizzlejs.com/ 23171 * 23172 * Copyright JS Foundation and other contributors 23173 * Released under the MIT license 23174 * https://jquery.org/license 23175 * 23176 * Date: 2020-05-04T22:49Z 23177 */ 23178( function( global, factory ) { 23179 23180 "use strict"; 23181 23182 if ( true && typeof module.exports === "object" ) { 23183 23184 // For CommonJS and CommonJS-like environments where a proper `window` 23185 // is present, execute the factory and get jQuery. 23186 // For environments that do not have a `window` with a `document` 23187 // (such as Node.js), expose a factory as module.exports. 23188 // This accentuates the need for the creation of a real `window`. 23189 // e.g. var jQuery = require("jquery")(window); 23190 // See ticket #14549 for more info. 23191 module.exports = global.document ? 23192 factory( global, true ) : 23193 function( w ) { 23194 if ( !w.document ) { 23195 throw new Error( "jQuery requires a window with a document" ); 23196 } 23197 return factory( w ); 23198 }; 23199 } else { 23200 factory( global ); 23201 } 23202 23203// Pass this if window is not defined yet 23204} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) { 23205 23206// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1 23207// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode 23208// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common 23209// enough that all such attempts are guarded in a try block. 23210"use strict"; 23211 23212var arr = []; 23213 23214var getProto = Object.getPrototypeOf; 23215 23216var slice = arr.slice; 23217 23218var flat = arr.flat ? function( array ) { 23219 return arr.flat.call( array ); 23220} : function( array ) { 23221 return arr.concat.apply( [], array ); 23222}; 23223 23224 23225var push = arr.push; 23226 23227var indexOf = arr.indexOf; 23228 23229var class2type = {}; 23230 23231var toString = class2type.toString; 23232 23233var hasOwn = class2type.hasOwnProperty; 23234 23235var fnToString = hasOwn.toString; 23236 23237var ObjectFunctionString = fnToString.call( Object ); 23238 23239var support = {}; 23240 23241var isFunction = function isFunction( obj ) { 23242 23243 // Support: Chrome <=57, Firefox <=52 23244 // In some browsers, typeof returns "function" for HTML <object> elements 23245 // (i.e., `typeof document.createElement( "object" ) === "function"`). 23246 // We don't want to classify *any* DOM node as a function. 23247 return typeof obj === "function" && typeof obj.nodeType !== "number"; 23248 }; 23249 23250 23251var isWindow = function isWindow( obj ) { 23252 return obj != null && obj === obj.window; 23253 }; 23254 23255 23256var document = window.document; 23257 23258 23259 23260 var preservedScriptAttributes = { 23261 type: true, 23262 src: true, 23263 nonce: true, 23264 noModule: true 23265 }; 23266 23267 function DOMEval( code, node, doc ) { 23268 doc = doc || document; 23269 23270 var i, val, 23271 script = doc.createElement( "script" ); 23272 23273 script.text = code; 23274 if ( node ) { 23275 for ( i in preservedScriptAttributes ) { 23276 23277 // Support: Firefox 64+, Edge 18+ 23278 // Some browsers don't support the "nonce" property on scripts. 23279 // On the other hand, just using `getAttribute` is not enough as 23280 // the `nonce` attribute is reset to an empty string whenever it 23281 // becomes browsing-context connected. 23282 // See https://github.com/whatwg/html/issues/2369 23283 // See https://html.spec.whatwg.org/#nonce-attributes 23284 // The `node.getAttribute` check was added for the sake of 23285 // `jQuery.globalEval` so that it can fake a nonce-containing node 23286 // via an object. 23287 val = node[ i ] || node.getAttribute && node.getAttribute( i ); 23288 if ( val ) { 23289 script.setAttribute( i, val ); 23290 } 23291 } 23292 } 23293 doc.head.appendChild( script ).parentNode.removeChild( script ); 23294 } 23295 23296 23297function toType( obj ) { 23298 if ( obj == null ) { 23299 return obj + ""; 23300 } 23301 23302 // Support: Android <=2.3 only (functionish RegExp) 23303 return typeof obj === "object" || typeof obj === "function" ? 23304 class2type[ toString.call( obj ) ] || "object" : 23305 typeof obj; 23306} 23307/* global Symbol */ 23308// Defining this global in .eslintrc.json would create a danger of using the global 23309// unguarded in another place, it seems safer to define global only for this module 23310 23311 23312 23313var 23314 version = "3.5.1", 23315 23316 // Define a local copy of jQuery 23317 jQuery = function( selector, context ) { 23318 23319 // The jQuery object is actually just the init constructor 'enhanced' 23320 // Need init if jQuery is called (just allow error to be thrown if not included) 23321 return new jQuery.fn.init( selector, context ); 23322 }; 23323 23324jQuery.fn = jQuery.prototype = { 23325 23326 // The current version of jQuery being used 23327 jquery: version, 23328 23329 constructor: jQuery, 23330 23331 // The default length of a jQuery object is 0 23332 length: 0, 23333 23334 toArray: function() { 23335 return slice.call( this ); 23336 }, 23337 23338 // Get the Nth element in the matched element set OR 23339 // Get the whole matched element set as a clean array 23340 get: function( num ) { 23341 23342 // Return all the elements in a clean array 23343 if ( num == null ) { 23344 return slice.call( this ); 23345 } 23346 23347 // Return just the one element from the set 23348 return num < 0 ? this[ num + this.length ] : this[ num ]; 23349 }, 23350 23351 // Take an array of elements and push it onto the stack 23352 // (returning the new matched element set) 23353 pushStack: function( elems ) { 23354 23355 // Build a new jQuery matched element set 23356 var ret = jQuery.merge( this.constructor(), elems ); 23357 23358 // Add the old object onto the stack (as a reference) 23359 ret.prevObject = this; 23360 23361 // Return the newly-formed element set 23362 return ret; 23363 }, 23364 23365 // Execute a callback for every element in the matched set. 23366 each: function( callback ) { 23367 return jQuery.each( this, callback ); 23368 }, 23369 23370 map: function( callback ) { 23371 return this.pushStack( jQuery.map( this, function( elem, i ) { 23372 return callback.call( elem, i, elem ); 23373 } ) ); 23374 }, 23375 23376 slice: function() { 23377 return this.pushStack( slice.apply( this, arguments ) ); 23378 }, 23379 23380 first: function() { 23381 return this.eq( 0 ); 23382 }, 23383 23384 last: function() { 23385 return this.eq( -1 ); 23386 }, 23387 23388 even: function() { 23389 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 23390 return ( i + 1 ) % 2; 23391 } ) ); 23392 }, 23393 23394 odd: function() { 23395 return this.pushStack( jQuery.grep( this, function( _elem, i ) { 23396 return i % 2; 23397 } ) ); 23398 }, 23399 23400 eq: function( i ) { 23401 var len = this.length, 23402 j = +i + ( i < 0 ? len : 0 ); 23403 return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] ); 23404 }, 23405 23406 end: function() { 23407 return this.prevObject || this.constructor(); 23408 }, 23409 23410 // For internal use only. 23411 // Behaves like an Array's method, not like a jQuery method. 23412 push: push, 23413 sort: arr.sort, 23414 splice: arr.splice 23415}; 23416 23417jQuery.extend = jQuery.fn.extend = function() { 23418 var options, name, src, copy, copyIsArray, clone, 23419 target = arguments[ 0 ] || {}, 23420 i = 1, 23421 length = arguments.length, 23422 deep = false; 23423 23424 // Handle a deep copy situation 23425 if ( typeof target === "boolean" ) { 23426 deep = target; 23427 23428 // Skip the boolean and the target 23429 target = arguments[ i ] || {}; 23430 i++; 23431 } 23432 23433 // Handle case when target is a string or something (possible in deep copy) 23434 if ( typeof target !== "object" && !isFunction( target ) ) { 23435 target = {}; 23436 } 23437 23438 // Extend jQuery itself if only one argument is passed 23439 if ( i === length ) { 23440 target = this; 23441 i--; 23442 } 23443 23444 for ( ; i < length; i++ ) { 23445 23446 // Only deal with non-null/undefined values 23447 if ( ( options = arguments[ i ] ) != null ) { 23448 23449 // Extend the base object 23450 for ( name in options ) { 23451 copy = options[ name ]; 23452 23453 // Prevent Object.prototype pollution 23454 // Prevent never-ending loop 23455 if ( name === "__proto__" || target === copy ) { 23456 continue; 23457 } 23458 23459 // Recurse if we're merging plain objects or arrays 23460 if ( deep && copy && ( jQuery.isPlainObject( copy ) || 23461 ( copyIsArray = Array.isArray( copy ) ) ) ) { 23462 src = target[ name ]; 23463 23464 // Ensure proper type for the source value 23465 if ( copyIsArray && !Array.isArray( src ) ) { 23466 clone = []; 23467 } else if ( !copyIsArray && !jQuery.isPlainObject( src ) ) { 23468 clone = {}; 23469 } else { 23470 clone = src; 23471 } 23472 copyIsArray = false; 23473 23474 // Never move original objects, clone them 23475 target[ name ] = jQuery.extend( deep, clone, copy ); 23476 23477 // Don't bring in undefined values 23478 } else if ( copy !== undefined ) { 23479 target[ name ] = copy; 23480 } 23481 } 23482 } 23483 } 23484 23485 // Return the modified object 23486 return target; 23487}; 23488 23489jQuery.extend( { 23490 23491 // Unique for each copy of jQuery on the page 23492 expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), 23493 23494 // Assume jQuery is ready without the ready module 23495 isReady: true, 23496 23497 error: function( msg ) { 23498 throw new Error( msg ); 23499 }, 23500 23501 noop: function() {}, 23502 23503 isPlainObject: function( obj ) { 23504 var proto, Ctor; 23505 23506 // Detect obvious negatives 23507 // Use toString instead of jQuery.type to catch host objects 23508 if ( !obj || toString.call( obj ) !== "[object Object]" ) { 23509 return false; 23510 } 23511 23512 proto = getProto( obj ); 23513 23514 // Objects with no prototype (e.g., `Object.create( null )`) are plain 23515 if ( !proto ) { 23516 return true; 23517 } 23518 23519 // Objects with prototype are plain iff they were constructed by a global Object function 23520 Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor; 23521 return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString; 23522 }, 23523 23524 isEmptyObject: function( obj ) { 23525 var name; 23526 23527 for ( name in obj ) { 23528 return false; 23529 } 23530 return true; 23531 }, 23532 23533 // Evaluates a script in a provided context; falls back to the global one 23534 // if not specified. 23535 globalEval: function( code, options, doc ) { 23536 DOMEval( code, { nonce: options && options.nonce }, doc ); 23537 }, 23538 23539 each: function( obj, callback ) { 23540 var length, i = 0; 23541 23542 if ( isArrayLike( obj ) ) { 23543 length = obj.length; 23544 for ( ; i < length; i++ ) { 23545 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 23546 break; 23547 } 23548 } 23549 } else { 23550 for ( i in obj ) { 23551 if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) { 23552 break; 23553 } 23554 } 23555 } 23556 23557 return obj; 23558 }, 23559 23560 // results is for internal usage only 23561 makeArray: function( arr, results ) { 23562 var ret = results || []; 23563 23564 if ( arr != null ) { 23565 if ( isArrayLike( Object( arr ) ) ) { 23566 jQuery.merge( ret, 23567 typeof arr === "string" ? 23568 [ arr ] : arr 23569 ); 23570 } else { 23571 push.call( ret, arr ); 23572 } 23573 } 23574 23575 return ret; 23576 }, 23577 23578 inArray: function( elem, arr, i ) { 23579 return arr == null ? -1 : indexOf.call( arr, elem, i ); 23580 }, 23581 23582 // Support: Android <=4.0 only, PhantomJS 1 only 23583 // push.apply(_, arraylike) throws on ancient WebKit 23584 merge: function( first, second ) { 23585 var len = +second.length, 23586 j = 0, 23587 i = first.length; 23588 23589 for ( ; j < len; j++ ) { 23590 first[ i++ ] = second[ j ]; 23591 } 23592 23593 first.length = i; 23594 23595 return first; 23596 }, 23597 23598 grep: function( elems, callback, invert ) { 23599 var callbackInverse, 23600 matches = [], 23601 i = 0, 23602 length = elems.length, 23603 callbackExpect = !invert; 23604 23605 // Go through the array, only saving the items 23606 // that pass the validator function 23607 for ( ; i < length; i++ ) { 23608 callbackInverse = !callback( elems[ i ], i ); 23609 if ( callbackInverse !== callbackExpect ) { 23610 matches.push( elems[ i ] ); 23611 } 23612 } 23613 23614 return matches; 23615 }, 23616 23617 // arg is for internal usage only 23618 map: function( elems, callback, arg ) { 23619 var length, value, 23620 i = 0, 23621 ret = []; 23622 23623 // Go through the array, translating each of the items to their new values 23624 if ( isArrayLike( elems ) ) { 23625 length = elems.length; 23626 for ( ; i < length; i++ ) { 23627 value = callback( elems[ i ], i, arg ); 23628 23629 if ( value != null ) { 23630 ret.push( value ); 23631 } 23632 } 23633 23634 // Go through every key on the object, 23635 } else { 23636 for ( i in elems ) { 23637 value = callback( elems[ i ], i, arg ); 23638 23639 if ( value != null ) { 23640 ret.push( value ); 23641 } 23642 } 23643 } 23644 23645 // Flatten any nested arrays 23646 return flat( ret ); 23647 }, 23648 23649 // A global GUID counter for objects 23650 guid: 1, 23651 23652 // jQuery.support is not used in Core but other projects attach their 23653 // properties to it so it needs to exist. 23654 support: support 23655} ); 23656 23657if ( typeof Symbol === "function" ) { 23658 jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ]; 23659} 23660 23661// Populate the class2type map 23662jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), 23663function( _i, name ) { 23664 class2type[ "[object " + name + "]" ] = name.toLowerCase(); 23665} ); 23666 23667function isArrayLike( obj ) { 23668 23669 // Support: real iOS 8.2 only (not reproducible in simulator) 23670 // `in` check used to prevent JIT error (gh-2145) 23671 // hasOwn isn't used here due to false negatives 23672 // regarding Nodelist length in IE 23673 var length = !!obj && "length" in obj && obj.length, 23674 type = toType( obj ); 23675 23676 if ( isFunction( obj ) || isWindow( obj ) ) { 23677 return false; 23678 } 23679 23680 return type === "array" || length === 0 || 23681 typeof length === "number" && length > 0 && ( length - 1 ) in obj; 23682} 23683var Sizzle = 23684/*! 23685 * Sizzle CSS Selector Engine v2.3.5 23686 * https://sizzlejs.com/ 23687 * 23688 * Copyright JS Foundation and other contributors 23689 * Released under the MIT license 23690 * https://js.foundation/ 23691 * 23692 * Date: 2020-03-14 23693 */ 23694( function( window ) { 23695var i, 23696 support, 23697 Expr, 23698 getText, 23699 isXML, 23700 tokenize, 23701 compile, 23702 select, 23703 outermostContext, 23704 sortInput, 23705 hasDuplicate, 23706 23707 // Local document vars 23708 setDocument, 23709 document, 23710 docElem, 23711 documentIsHTML, 23712 rbuggyQSA, 23713 rbuggyMatches, 23714 matches, 23715 contains, 23716 23717 // Instance-specific data 23718 expando = "sizzle" + 1 * new Date(), 23719 preferredDoc = window.document, 23720 dirruns = 0, 23721 done = 0, 23722 classCache = createCache(), 23723 tokenCache = createCache(), 23724 compilerCache = createCache(), 23725 nonnativeSelectorCache = createCache(), 23726 sortOrder = function( a, b ) { 23727 if ( a === b ) { 23728 hasDuplicate = true; 23729 } 23730 return 0; 23731 }, 23732 23733 // Instance methods 23734 hasOwn = ( {} ).hasOwnProperty, 23735 arr = [], 23736 pop = arr.pop, 23737 pushNative = arr.push, 23738 push = arr.push, 23739 slice = arr.slice, 23740 23741 // Use a stripped-down indexOf as it's faster than native 23742 // https://jsperf.com/thor-indexof-vs-for/5 23743 indexOf = function( list, elem ) { 23744 var i = 0, 23745 len = list.length; 23746 for ( ; i < len; i++ ) { 23747 if ( list[ i ] === elem ) { 23748 return i; 23749 } 23750 } 23751 return -1; 23752 }, 23753 23754 booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|" + 23755 "ismap|loop|multiple|open|readonly|required|scoped", 23756 23757 // Regular expressions 23758 23759 // http://www.w3.org/TR/css3-selectors/#whitespace 23760 whitespace = "[\\x20\\t\\r\\n\\f]", 23761 23762 // https://www.w3.org/TR/css-syntax-3/#ident-token-diagram 23763 identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + 23764 "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+", 23765 23766 // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors 23767 attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + 23768 23769 // Operator (capture 2) 23770 "*([*^$|!~]?=)" + whitespace + 23771 23772 // "Attribute values must be CSS identifiers [capture 5] 23773 // or strings [capture 3 or capture 4]" 23774 "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + 23775 whitespace + "*\\]", 23776 23777 pseudos = ":(" + identifier + ")(?:\\((" + 23778 23779 // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: 23780 // 1. quoted (capture 3; capture 4 or capture 5) 23781 "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + 23782 23783 // 2. simple (capture 6) 23784 "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + 23785 23786 // 3. anything else (capture 2) 23787 ".*" + 23788 ")\\)|)", 23789 23790 // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter 23791 rwhitespace = new RegExp( whitespace + "+", "g" ), 23792 rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + 23793 whitespace + "+$", "g" ), 23794 23795 rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), 23796 rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + 23797 "*" ), 23798 rdescend = new RegExp( whitespace + "|>" ), 23799 23800 rpseudo = new RegExp( pseudos ), 23801 ridentifier = new RegExp( "^" + identifier + "$" ), 23802 23803 matchExpr = { 23804 "ID": new RegExp( "^#(" + identifier + ")" ), 23805 "CLASS": new RegExp( "^\\.(" + identifier + ")" ), 23806 "TAG": new RegExp( "^(" + identifier + "|[*])" ), 23807 "ATTR": new RegExp( "^" + attributes ), 23808 "PSEUDO": new RegExp( "^" + pseudos ), 23809 "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + 23810 whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + 23811 whitespace + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), 23812 "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), 23813 23814 // For use in libraries implementing .is() 23815 // We use this for POS matching in `select` 23816 "needsContext": new RegExp( "^" + whitespace + 23817 "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + 23818 "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) 23819 }, 23820 23821 rhtml = /HTML$/i, 23822 rinputs = /^(?:input|select|textarea|button)$/i, 23823 rheader = /^h\d$/i, 23824 23825 rnative = /^[^{]+\{\s*\[native \w/, 23826 23827 // Easily-parseable/retrievable ID or TAG or CLASS selectors 23828 rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, 23829 23830 rsibling = /[+~]/, 23831 23832 // CSS escapes 23833 // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters 23834 runescape = new RegExp( "\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g" ), 23835 funescape = function( escape, nonHex ) { 23836 var high = "0x" + escape.slice( 1 ) - 0x10000; 23837 23838 return nonHex ? 23839 23840 // Strip the backslash prefix from a non-hex escape sequence 23841 nonHex : 23842 23843 // Replace a hexadecimal escape sequence with the encoded Unicode code point 23844 // Support: IE <=11+ 23845 // For values outside the Basic Multilingual Plane (BMP), manually construct a 23846 // surrogate pair 23847 high < 0 ? 23848 String.fromCharCode( high + 0x10000 ) : 23849 String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); 23850 }, 23851 23852 // CSS string/identifier serialization 23853 // https://drafts.csswg.org/cssom/#common-serializing-idioms 23854 rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g, 23855 fcssescape = function( ch, asCodePoint ) { 23856 if ( asCodePoint ) { 23857 23858 // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER 23859 if ( ch === "\0" ) { 23860 return "\uFFFD"; 23861 } 23862 23863 // Control characters and (dependent upon position) numbers get escaped as code points 23864 return ch.slice( 0, -1 ) + "\\" + 23865 ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " "; 23866 } 23867 23868 // Other potentially-special ASCII characters get backslash-escaped 23869 return "\\" + ch; 23870 }, 23871 23872 // Used for iframes 23873 // See setDocument() 23874 // Removing the function wrapper causes a "Permission Denied" 23875 // error in IE 23876 unloadHandler = function() { 23877 setDocument(); 23878 }, 23879 23880 inDisabledFieldset = addCombinator( 23881 function( elem ) { 23882 return elem.disabled === true && elem.nodeName.toLowerCase() === "fieldset"; 23883 }, 23884 { dir: "parentNode", next: "legend" } 23885 ); 23886 23887// Optimize for push.apply( _, NodeList ) 23888try { 23889 push.apply( 23890 ( arr = slice.call( preferredDoc.childNodes ) ), 23891 preferredDoc.childNodes 23892 ); 23893 23894 // Support: Android<4.0 23895 // Detect silently failing push.apply 23896 // eslint-disable-next-line no-unused-expressions 23897 arr[ preferredDoc.childNodes.length ].nodeType; 23898} catch ( e ) { 23899 push = { apply: arr.length ? 23900 23901 // Leverage slice if possible 23902 function( target, els ) { 23903 pushNative.apply( target, slice.call( els ) ); 23904 } : 23905 23906 // Support: IE<9 23907 // Otherwise append directly 23908 function( target, els ) { 23909 var j = target.length, 23910 i = 0; 23911 23912 // Can't trust NodeList.length 23913 while ( ( target[ j++ ] = els[ i++ ] ) ) {} 23914 target.length = j - 1; 23915 } 23916 }; 23917} 23918 23919function Sizzle( selector, context, results, seed ) { 23920 var m, i, elem, nid, match, groups, newSelector, 23921 newContext = context && context.ownerDocument, 23922 23923 // nodeType defaults to 9, since context defaults to document 23924 nodeType = context ? context.nodeType : 9; 23925 23926 results = results || []; 23927 23928 // Return early from calls with invalid selector or context 23929 if ( typeof selector !== "string" || !selector || 23930 nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { 23931 23932 return results; 23933 } 23934 23935 // Try to shortcut find operations (as opposed to filters) in HTML documents 23936 if ( !seed ) { 23937 setDocument( context ); 23938 context = context || document; 23939 23940 if ( documentIsHTML ) { 23941 23942 // If the selector is sufficiently simple, try using a "get*By*" DOM method 23943 // (excepting DocumentFragment context, where the methods don't exist) 23944 if ( nodeType !== 11 && ( match = rquickExpr.exec( selector ) ) ) { 23945 23946 // ID selector 23947 if ( ( m = match[ 1 ] ) ) { 23948 23949 // Document context 23950 if ( nodeType === 9 ) { 23951 if ( ( elem = context.getElementById( m ) ) ) { 23952 23953 // Support: IE, Opera, Webkit 23954 // TODO: identify versions 23955 // getElementById can match elements by name instead of ID 23956 if ( elem.id === m ) { 23957 results.push( elem ); 23958 return results; 23959 } 23960 } else { 23961 return results; 23962 } 23963 23964 // Element context 23965 } else { 23966 23967 // Support: IE, Opera, Webkit 23968 // TODO: identify versions 23969 // getElementById can match elements by name instead of ID 23970 if ( newContext && ( elem = newContext.getElementById( m ) ) && 23971 contains( context, elem ) && 23972 elem.id === m ) { 23973 23974 results.push( elem ); 23975 return results; 23976 } 23977 } 23978 23979 // Type selector 23980 } else if ( match[ 2 ] ) { 23981 push.apply( results, context.getElementsByTagName( selector ) ); 23982 return results; 23983 23984 // Class selector 23985 } else if ( ( m = match[ 3 ] ) && support.getElementsByClassName && 23986 context.getElementsByClassName ) { 23987 23988 push.apply( results, context.getElementsByClassName( m ) ); 23989 return results; 23990 } 23991 } 23992 23993 // Take advantage of querySelectorAll 23994 if ( support.qsa && 23995 !nonnativeSelectorCache[ selector + " " ] && 23996 ( !rbuggyQSA || !rbuggyQSA.test( selector ) ) && 23997 23998 // Support: IE 8 only 23999 // Exclude object elements 24000 ( nodeType !== 1 || context.nodeName.toLowerCase() !== "object" ) ) { 24001 24002 newSelector = selector; 24003 newContext = context; 24004 24005 // qSA considers elements outside a scoping root when evaluating child or 24006 // descendant combinators, which is not what we want. 24007 // In such cases, we work around the behavior by prefixing every selector in the 24008 // list with an ID selector referencing the scope context. 24009 // The technique has to be used as well when a leading combinator is used 24010 // as such selectors are not recognized by querySelectorAll. 24011 // Thanks to Andrew Dupont for this technique. 24012 if ( nodeType === 1 && 24013 ( rdescend.test( selector ) || rcombinators.test( selector ) ) ) { 24014 24015 // Expand context for sibling selectors 24016 newContext = rsibling.test( selector ) && testContext( context.parentNode ) || 24017 context; 24018 24019 // We can use :scope instead of the ID hack if the browser 24020 // supports it & if we're not changing the context. 24021 if ( newContext !== context || !support.scope ) { 24022 24023 // Capture the context ID, setting it first if necessary 24024 if ( ( nid = context.getAttribute( "id" ) ) ) { 24025 nid = nid.replace( rcssescape, fcssescape ); 24026 } else { 24027 context.setAttribute( "id", ( nid = expando ) ); 24028 } 24029 } 24030 24031 // Prefix every selector in the list 24032 groups = tokenize( selector ); 24033 i = groups.length; 24034 while ( i-- ) { 24035 groups[ i ] = ( nid ? "#" + nid : ":scope" ) + " " + 24036 toSelector( groups[ i ] ); 24037 } 24038 newSelector = groups.join( "," ); 24039 } 24040 24041 try { 24042 push.apply( results, 24043 newContext.querySelectorAll( newSelector ) 24044 ); 24045 return results; 24046 } catch ( qsaError ) { 24047 nonnativeSelectorCache( selector, true ); 24048 } finally { 24049 if ( nid === expando ) { 24050 context.removeAttribute( "id" ); 24051 } 24052 } 24053 } 24054 } 24055 } 24056 24057 // All others 24058 return select( selector.replace( rtrim, "$1" ), context, results, seed ); 24059} 24060 24061/** 24062 * Create key-value caches of limited size 24063 * @returns {function(string, object)} Returns the Object data after storing it on itself with 24064 * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) 24065 * deleting the oldest entry 24066 */ 24067function createCache() { 24068 var keys = []; 24069 24070 function cache( key, value ) { 24071 24072 // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) 24073 if ( keys.push( key + " " ) > Expr.cacheLength ) { 24074 24075 // Only keep the most recent entries 24076 delete cache[ keys.shift() ]; 24077 } 24078 return ( cache[ key + " " ] = value ); 24079 } 24080 return cache; 24081} 24082 24083/** 24084 * Mark a function for special use by Sizzle 24085 * @param {Function} fn The function to mark 24086 */ 24087function markFunction( fn ) { 24088 fn[ expando ] = true; 24089 return fn; 24090} 24091 24092/** 24093 * Support testing using an element 24094 * @param {Function} fn Passed the created element and returns a boolean result 24095 */ 24096function assert( fn ) { 24097 var el = document.createElement( "fieldset" ); 24098 24099 try { 24100 return !!fn( el ); 24101 } catch ( e ) { 24102 return false; 24103 } finally { 24104 24105 // Remove from its parent by default 24106 if ( el.parentNode ) { 24107 el.parentNode.removeChild( el ); 24108 } 24109 24110 // release memory in IE 24111 el = null; 24112 } 24113} 24114 24115/** 24116 * Adds the same handler for all of the specified attrs 24117 * @param {String} attrs Pipe-separated list of attributes 24118 * @param {Function} handler The method that will be applied 24119 */ 24120function addHandle( attrs, handler ) { 24121 var arr = attrs.split( "|" ), 24122 i = arr.length; 24123 24124 while ( i-- ) { 24125 Expr.attrHandle[ arr[ i ] ] = handler; 24126 } 24127} 24128 24129/** 24130 * Checks document order of two siblings 24131 * @param {Element} a 24132 * @param {Element} b 24133 * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b 24134 */ 24135function siblingCheck( a, b ) { 24136 var cur = b && a, 24137 diff = cur && a.nodeType === 1 && b.nodeType === 1 && 24138 a.sourceIndex - b.sourceIndex; 24139 24140 // Use IE sourceIndex if available on both nodes 24141 if ( diff ) { 24142 return diff; 24143 } 24144 24145 // Check if b follows a 24146 if ( cur ) { 24147 while ( ( cur = cur.nextSibling ) ) { 24148 if ( cur === b ) { 24149 return -1; 24150 } 24151 } 24152 } 24153 24154 return a ? 1 : -1; 24155} 24156 24157/** 24158 * Returns a function to use in pseudos for input types 24159 * @param {String} type 24160 */ 24161function createInputPseudo( type ) { 24162 return function( elem ) { 24163 var name = elem.nodeName.toLowerCase(); 24164 return name === "input" && elem.type === type; 24165 }; 24166} 24167 24168/** 24169 * Returns a function to use in pseudos for buttons 24170 * @param {String} type 24171 */ 24172function createButtonPseudo( type ) { 24173 return function( elem ) { 24174 var name = elem.nodeName.toLowerCase(); 24175 return ( name === "input" || name === "button" ) && elem.type === type; 24176 }; 24177} 24178 24179/** 24180 * Returns a function to use in pseudos for :enabled/:disabled 24181 * @param {Boolean} disabled true for :disabled; false for :enabled 24182 */ 24183function createDisabledPseudo( disabled ) { 24184 24185 // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable 24186 return function( elem ) { 24187 24188 // Only certain elements can match :enabled or :disabled 24189 // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled 24190 // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled 24191 if ( "form" in elem ) { 24192 24193 // Check for inherited disabledness on relevant non-disabled elements: 24194 // * listed form-associated elements in a disabled fieldset 24195 // https://html.spec.whatwg.org/multipage/forms.html#category-listed 24196 // https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled 24197 // * option elements in a disabled optgroup 24198 // https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled 24199 // All such elements have a "form" property. 24200 if ( elem.parentNode && elem.disabled === false ) { 24201 24202 // Option elements defer to a parent optgroup if present 24203 if ( "label" in elem ) { 24204 if ( "label" in elem.parentNode ) { 24205 return elem.parentNode.disabled === disabled; 24206 } else { 24207 return elem.disabled === disabled; 24208 } 24209 } 24210 24211 // Support: IE 6 - 11 24212 // Use the isDisabled shortcut property to check for disabled fieldset ancestors 24213 return elem.isDisabled === disabled || 24214 24215 // Where there is no isDisabled, check manually 24216 /* jshint -W018 */ 24217 elem.isDisabled !== !disabled && 24218 inDisabledFieldset( elem ) === disabled; 24219 } 24220 24221 return elem.disabled === disabled; 24222 24223 // Try to winnow out elements that can't be disabled before trusting the disabled property. 24224 // Some victims get caught in our net (label, legend, menu, track), but it shouldn't 24225 // even exist on them, let alone have a boolean value. 24226 } else if ( "label" in elem ) { 24227 return elem.disabled === disabled; 24228 } 24229 24230 // Remaining elements are neither :enabled nor :disabled 24231 return false; 24232 }; 24233} 24234 24235/** 24236 * Returns a function to use in pseudos for positionals 24237 * @param {Function} fn 24238 */ 24239function createPositionalPseudo( fn ) { 24240 return markFunction( function( argument ) { 24241 argument = +argument; 24242 return markFunction( function( seed, matches ) { 24243 var j, 24244 matchIndexes = fn( [], seed.length, argument ), 24245 i = matchIndexes.length; 24246 24247 // Match elements found at the specified indexes 24248 while ( i-- ) { 24249 if ( seed[ ( j = matchIndexes[ i ] ) ] ) { 24250 seed[ j ] = !( matches[ j ] = seed[ j ] ); 24251 } 24252 } 24253 } ); 24254 } ); 24255} 24256 24257/** 24258 * Checks a node for validity as a Sizzle context 24259 * @param {Element|Object=} context 24260 * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value 24261 */ 24262function testContext( context ) { 24263 return context && typeof context.getElementsByTagName !== "undefined" && context; 24264} 24265 24266// Expose support vars for convenience 24267support = Sizzle.support = {}; 24268 24269/** 24270 * Detects XML nodes 24271 * @param {Element|Object} elem An element or a document 24272 * @returns {Boolean} True iff elem is a non-HTML XML node 24273 */ 24274isXML = Sizzle.isXML = function( elem ) { 24275 var namespace = elem.namespaceURI, 24276 docElem = ( elem.ownerDocument || elem ).documentElement; 24277 24278 // Support: IE <=8 24279 // Assume HTML when documentElement doesn't yet exist, such as inside loading iframes 24280 // https://bugs.jquery.com/ticket/4833 24281 return !rhtml.test( namespace || docElem && docElem.nodeName || "HTML" ); 24282}; 24283 24284/** 24285 * Sets document-related variables once based on the current document 24286 * @param {Element|Object} [doc] An element or document object to use to set the document 24287 * @returns {Object} Returns the current document 24288 */ 24289setDocument = Sizzle.setDocument = function( node ) { 24290 var hasCompare, subWindow, 24291 doc = node ? node.ownerDocument || node : preferredDoc; 24292 24293 // Return early if doc is invalid or already selected 24294 // Support: IE 11+, Edge 17 - 18+ 24295 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24296 // two documents; shallow comparisons work. 24297 // eslint-disable-next-line eqeqeq 24298 if ( doc == document || doc.nodeType !== 9 || !doc.documentElement ) { 24299 return document; 24300 } 24301 24302 // Update global variables 24303 document = doc; 24304 docElem = document.documentElement; 24305 documentIsHTML = !isXML( document ); 24306 24307 // Support: IE 9 - 11+, Edge 12 - 18+ 24308 // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936) 24309 // Support: IE 11+, Edge 17 - 18+ 24310 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24311 // two documents; shallow comparisons work. 24312 // eslint-disable-next-line eqeqeq 24313 if ( preferredDoc != document && 24314 ( subWindow = document.defaultView ) && subWindow.top !== subWindow ) { 24315 24316 // Support: IE 11, Edge 24317 if ( subWindow.addEventListener ) { 24318 subWindow.addEventListener( "unload", unloadHandler, false ); 24319 24320 // Support: IE 9 - 10 only 24321 } else if ( subWindow.attachEvent ) { 24322 subWindow.attachEvent( "onunload", unloadHandler ); 24323 } 24324 } 24325 24326 // Support: IE 8 - 11+, Edge 12 - 18+, Chrome <=16 - 25 only, Firefox <=3.6 - 31 only, 24327 // Safari 4 - 5 only, Opera <=11.6 - 12.x only 24328 // IE/Edge & older browsers don't support the :scope pseudo-class. 24329 // Support: Safari 6.0 only 24330 // Safari 6.0 supports :scope but it's an alias of :root there. 24331 support.scope = assert( function( el ) { 24332 docElem.appendChild( el ).appendChild( document.createElement( "div" ) ); 24333 return typeof el.querySelectorAll !== "undefined" && 24334 !el.querySelectorAll( ":scope fieldset div" ).length; 24335 } ); 24336 24337 /* Attributes 24338 ---------------------------------------------------------------------- */ 24339 24340 // Support: IE<8 24341 // Verify that getAttribute really returns attributes and not properties 24342 // (excepting IE8 booleans) 24343 support.attributes = assert( function( el ) { 24344 el.className = "i"; 24345 return !el.getAttribute( "className" ); 24346 } ); 24347 24348 /* getElement(s)By* 24349 ---------------------------------------------------------------------- */ 24350 24351 // Check if getElementsByTagName("*") returns only elements 24352 support.getElementsByTagName = assert( function( el ) { 24353 el.appendChild( document.createComment( "" ) ); 24354 return !el.getElementsByTagName( "*" ).length; 24355 } ); 24356 24357 // Support: IE<9 24358 support.getElementsByClassName = rnative.test( document.getElementsByClassName ); 24359 24360 // Support: IE<10 24361 // Check if getElementById returns elements by name 24362 // The broken getElementById methods don't pick up programmatically-set names, 24363 // so use a roundabout getElementsByName test 24364 support.getById = assert( function( el ) { 24365 docElem.appendChild( el ).id = expando; 24366 return !document.getElementsByName || !document.getElementsByName( expando ).length; 24367 } ); 24368 24369 // ID filter and find 24370 if ( support.getById ) { 24371 Expr.filter[ "ID" ] = function( id ) { 24372 var attrId = id.replace( runescape, funescape ); 24373 return function( elem ) { 24374 return elem.getAttribute( "id" ) === attrId; 24375 }; 24376 }; 24377 Expr.find[ "ID" ] = function( id, context ) { 24378 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 24379 var elem = context.getElementById( id ); 24380 return elem ? [ elem ] : []; 24381 } 24382 }; 24383 } else { 24384 Expr.filter[ "ID" ] = function( id ) { 24385 var attrId = id.replace( runescape, funescape ); 24386 return function( elem ) { 24387 var node = typeof elem.getAttributeNode !== "undefined" && 24388 elem.getAttributeNode( "id" ); 24389 return node && node.value === attrId; 24390 }; 24391 }; 24392 24393 // Support: IE 6 - 7 only 24394 // getElementById is not reliable as a find shortcut 24395 Expr.find[ "ID" ] = function( id, context ) { 24396 if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { 24397 var node, i, elems, 24398 elem = context.getElementById( id ); 24399 24400 if ( elem ) { 24401 24402 // Verify the id attribute 24403 node = elem.getAttributeNode( "id" ); 24404 if ( node && node.value === id ) { 24405 return [ elem ]; 24406 } 24407 24408 // Fall back on getElementsByName 24409 elems = context.getElementsByName( id ); 24410 i = 0; 24411 while ( ( elem = elems[ i++ ] ) ) { 24412 node = elem.getAttributeNode( "id" ); 24413 if ( node && node.value === id ) { 24414 return [ elem ]; 24415 } 24416 } 24417 } 24418 24419 return []; 24420 } 24421 }; 24422 } 24423 24424 // Tag 24425 Expr.find[ "TAG" ] = support.getElementsByTagName ? 24426 function( tag, context ) { 24427 if ( typeof context.getElementsByTagName !== "undefined" ) { 24428 return context.getElementsByTagName( tag ); 24429 24430 // DocumentFragment nodes don't have gEBTN 24431 } else if ( support.qsa ) { 24432 return context.querySelectorAll( tag ); 24433 } 24434 } : 24435 24436 function( tag, context ) { 24437 var elem, 24438 tmp = [], 24439 i = 0, 24440 24441 // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too 24442 results = context.getElementsByTagName( tag ); 24443 24444 // Filter out possible comments 24445 if ( tag === "*" ) { 24446 while ( ( elem = results[ i++ ] ) ) { 24447 if ( elem.nodeType === 1 ) { 24448 tmp.push( elem ); 24449 } 24450 } 24451 24452 return tmp; 24453 } 24454 return results; 24455 }; 24456 24457 // Class 24458 Expr.find[ "CLASS" ] = support.getElementsByClassName && function( className, context ) { 24459 if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) { 24460 return context.getElementsByClassName( className ); 24461 } 24462 }; 24463 24464 /* QSA/matchesSelector 24465 ---------------------------------------------------------------------- */ 24466 24467 // QSA and matchesSelector support 24468 24469 // matchesSelector(:active) reports false when true (IE9/Opera 11.5) 24470 rbuggyMatches = []; 24471 24472 // qSa(:focus) reports false when true (Chrome 21) 24473 // We allow this because of a bug in IE8/9 that throws an error 24474 // whenever `document.activeElement` is accessed on an iframe 24475 // So, we allow :focus to pass through QSA all the time to avoid the IE error 24476 // See https://bugs.jquery.com/ticket/13378 24477 rbuggyQSA = []; 24478 24479 if ( ( support.qsa = rnative.test( document.querySelectorAll ) ) ) { 24480 24481 // Build QSA regex 24482 // Regex strategy adopted from Diego Perini 24483 assert( function( el ) { 24484 24485 var input; 24486 24487 // Select is set to empty string on purpose 24488 // This is to test IE's treatment of not explicitly 24489 // setting a boolean content attribute, 24490 // since its presence should be enough 24491 // https://bugs.jquery.com/ticket/12359 24492 docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" + 24493 "<select id='" + expando + "-\r\\' msallowcapture=''>" + 24494 "<option selected=''></option></select>"; 24495 24496 // Support: IE8, Opera 11-12.16 24497 // Nothing should be selected when empty strings follow ^= or $= or *= 24498 // The test attribute must be unknown in Opera but "safe" for WinRT 24499 // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section 24500 if ( el.querySelectorAll( "[msallowcapture^='']" ).length ) { 24501 rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); 24502 } 24503 24504 // Support: IE8 24505 // Boolean attributes and "value" are not treated correctly 24506 if ( !el.querySelectorAll( "[selected]" ).length ) { 24507 rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); 24508 } 24509 24510 // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+ 24511 if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) { 24512 rbuggyQSA.push( "~=" ); 24513 } 24514 24515 // Support: IE 11+, Edge 15 - 18+ 24516 // IE 11/Edge don't find elements on a `[name='']` query in some cases. 24517 // Adding a temporary attribute to the document before the selection works 24518 // around the issue. 24519 // Interestingly, IE 10 & older don't seem to have the issue. 24520 input = document.createElement( "input" ); 24521 input.setAttribute( "name", "" ); 24522 el.appendChild( input ); 24523 if ( !el.querySelectorAll( "[name='']" ).length ) { 24524 rbuggyQSA.push( "\\[" + whitespace + "*name" + whitespace + "*=" + 24525 whitespace + "*(?:''|\"\")" ); 24526 } 24527 24528 // Webkit/Opera - :checked should return selected option elements 24529 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 24530 // IE8 throws error here and will not see later tests 24531 if ( !el.querySelectorAll( ":checked" ).length ) { 24532 rbuggyQSA.push( ":checked" ); 24533 } 24534 24535 // Support: Safari 8+, iOS 8+ 24536 // https://bugs.webkit.org/show_bug.cgi?id=136851 24537 // In-page `selector#id sibling-combinator selector` fails 24538 if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) { 24539 rbuggyQSA.push( ".#.+[+~]" ); 24540 } 24541 24542 // Support: Firefox <=3.6 - 5 only 24543 // Old Firefox doesn't throw on a badly-escaped identifier. 24544 el.querySelectorAll( "\\\f" ); 24545 rbuggyQSA.push( "[\\r\\n\\f]" ); 24546 } ); 24547 24548 assert( function( el ) { 24549 el.innerHTML = "<a href='' disabled='disabled'></a>" + 24550 "<select disabled='disabled'><option/></select>"; 24551 24552 // Support: Windows 8 Native Apps 24553 // The type and name attributes are restricted during .innerHTML assignment 24554 var input = document.createElement( "input" ); 24555 input.setAttribute( "type", "hidden" ); 24556 el.appendChild( input ).setAttribute( "name", "D" ); 24557 24558 // Support: IE8 24559 // Enforce case-sensitivity of name attribute 24560 if ( el.querySelectorAll( "[name=d]" ).length ) { 24561 rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); 24562 } 24563 24564 // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) 24565 // IE8 throws error here and will not see later tests 24566 if ( el.querySelectorAll( ":enabled" ).length !== 2 ) { 24567 rbuggyQSA.push( ":enabled", ":disabled" ); 24568 } 24569 24570 // Support: IE9-11+ 24571 // IE's :disabled selector does not pick up the children of disabled fieldsets 24572 docElem.appendChild( el ).disabled = true; 24573 if ( el.querySelectorAll( ":disabled" ).length !== 2 ) { 24574 rbuggyQSA.push( ":enabled", ":disabled" ); 24575 } 24576 24577 // Support: Opera 10 - 11 only 24578 // Opera 10-11 does not throw on post-comma invalid pseudos 24579 el.querySelectorAll( "*,:x" ); 24580 rbuggyQSA.push( ",.*:" ); 24581 } ); 24582 } 24583 24584 if ( ( support.matchesSelector = rnative.test( ( matches = docElem.matches || 24585 docElem.webkitMatchesSelector || 24586 docElem.mozMatchesSelector || 24587 docElem.oMatchesSelector || 24588 docElem.msMatchesSelector ) ) ) ) { 24589 24590 assert( function( el ) { 24591 24592 // Check to see if it's possible to do matchesSelector 24593 // on a disconnected node (IE 9) 24594 support.disconnectedMatch = matches.call( el, "*" ); 24595 24596 // This should fail with an exception 24597 // Gecko does not error, returns false instead 24598 matches.call( el, "[s!='']:x" ); 24599 rbuggyMatches.push( "!=", pseudos ); 24600 } ); 24601 } 24602 24603 rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join( "|" ) ); 24604 rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join( "|" ) ); 24605 24606 /* Contains 24607 ---------------------------------------------------------------------- */ 24608 hasCompare = rnative.test( docElem.compareDocumentPosition ); 24609 24610 // Element contains another 24611 // Purposefully self-exclusive 24612 // As in, an element does not contain itself 24613 contains = hasCompare || rnative.test( docElem.contains ) ? 24614 function( a, b ) { 24615 var adown = a.nodeType === 9 ? a.documentElement : a, 24616 bup = b && b.parentNode; 24617 return a === bup || !!( bup && bup.nodeType === 1 && ( 24618 adown.contains ? 24619 adown.contains( bup ) : 24620 a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 24621 ) ); 24622 } : 24623 function( a, b ) { 24624 if ( b ) { 24625 while ( ( b = b.parentNode ) ) { 24626 if ( b === a ) { 24627 return true; 24628 } 24629 } 24630 } 24631 return false; 24632 }; 24633 24634 /* Sorting 24635 ---------------------------------------------------------------------- */ 24636 24637 // Document order sorting 24638 sortOrder = hasCompare ? 24639 function( a, b ) { 24640 24641 // Flag for duplicate removal 24642 if ( a === b ) { 24643 hasDuplicate = true; 24644 return 0; 24645 } 24646 24647 // Sort on method existence if only one input has compareDocumentPosition 24648 var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; 24649 if ( compare ) { 24650 return compare; 24651 } 24652 24653 // Calculate position if both inputs belong to the same document 24654 // Support: IE 11+, Edge 17 - 18+ 24655 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24656 // two documents; shallow comparisons work. 24657 // eslint-disable-next-line eqeqeq 24658 compare = ( a.ownerDocument || a ) == ( b.ownerDocument || b ) ? 24659 a.compareDocumentPosition( b ) : 24660 24661 // Otherwise we know they are disconnected 24662 1; 24663 24664 // Disconnected nodes 24665 if ( compare & 1 || 24666 ( !support.sortDetached && b.compareDocumentPosition( a ) === compare ) ) { 24667 24668 // Choose the first element that is related to our preferred document 24669 // Support: IE 11+, Edge 17 - 18+ 24670 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24671 // two documents; shallow comparisons work. 24672 // eslint-disable-next-line eqeqeq 24673 if ( a == document || a.ownerDocument == preferredDoc && 24674 contains( preferredDoc, a ) ) { 24675 return -1; 24676 } 24677 24678 // Support: IE 11+, Edge 17 - 18+ 24679 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24680 // two documents; shallow comparisons work. 24681 // eslint-disable-next-line eqeqeq 24682 if ( b == document || b.ownerDocument == preferredDoc && 24683 contains( preferredDoc, b ) ) { 24684 return 1; 24685 } 24686 24687 // Maintain original order 24688 return sortInput ? 24689 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 24690 0; 24691 } 24692 24693 return compare & 4 ? -1 : 1; 24694 } : 24695 function( a, b ) { 24696 24697 // Exit early if the nodes are identical 24698 if ( a === b ) { 24699 hasDuplicate = true; 24700 return 0; 24701 } 24702 24703 var cur, 24704 i = 0, 24705 aup = a.parentNode, 24706 bup = b.parentNode, 24707 ap = [ a ], 24708 bp = [ b ]; 24709 24710 // Parentless nodes are either documents or disconnected 24711 if ( !aup || !bup ) { 24712 24713 // Support: IE 11+, Edge 17 - 18+ 24714 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24715 // two documents; shallow comparisons work. 24716 /* eslint-disable eqeqeq */ 24717 return a == document ? -1 : 24718 b == document ? 1 : 24719 /* eslint-enable eqeqeq */ 24720 aup ? -1 : 24721 bup ? 1 : 24722 sortInput ? 24723 ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : 24724 0; 24725 24726 // If the nodes are siblings, we can do a quick check 24727 } else if ( aup === bup ) { 24728 return siblingCheck( a, b ); 24729 } 24730 24731 // Otherwise we need full lists of their ancestors for comparison 24732 cur = a; 24733 while ( ( cur = cur.parentNode ) ) { 24734 ap.unshift( cur ); 24735 } 24736 cur = b; 24737 while ( ( cur = cur.parentNode ) ) { 24738 bp.unshift( cur ); 24739 } 24740 24741 // Walk down the tree looking for a discrepancy 24742 while ( ap[ i ] === bp[ i ] ) { 24743 i++; 24744 } 24745 24746 return i ? 24747 24748 // Do a sibling check if the nodes have a common ancestor 24749 siblingCheck( ap[ i ], bp[ i ] ) : 24750 24751 // Otherwise nodes in our document sort first 24752 // Support: IE 11+, Edge 17 - 18+ 24753 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24754 // two documents; shallow comparisons work. 24755 /* eslint-disable eqeqeq */ 24756 ap[ i ] == preferredDoc ? -1 : 24757 bp[ i ] == preferredDoc ? 1 : 24758 /* eslint-enable eqeqeq */ 24759 0; 24760 }; 24761 24762 return document; 24763}; 24764 24765Sizzle.matches = function( expr, elements ) { 24766 return Sizzle( expr, null, null, elements ); 24767}; 24768 24769Sizzle.matchesSelector = function( elem, expr ) { 24770 setDocument( elem ); 24771 24772 if ( support.matchesSelector && documentIsHTML && 24773 !nonnativeSelectorCache[ expr + " " ] && 24774 ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && 24775 ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { 24776 24777 try { 24778 var ret = matches.call( elem, expr ); 24779 24780 // IE 9's matchesSelector returns false on disconnected nodes 24781 if ( ret || support.disconnectedMatch || 24782 24783 // As well, disconnected nodes are said to be in a document 24784 // fragment in IE 9 24785 elem.document && elem.document.nodeType !== 11 ) { 24786 return ret; 24787 } 24788 } catch ( e ) { 24789 nonnativeSelectorCache( expr, true ); 24790 } 24791 } 24792 24793 return Sizzle( expr, document, null, [ elem ] ).length > 0; 24794}; 24795 24796Sizzle.contains = function( context, elem ) { 24797 24798 // Set document vars if needed 24799 // Support: IE 11+, Edge 17 - 18+ 24800 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24801 // two documents; shallow comparisons work. 24802 // eslint-disable-next-line eqeqeq 24803 if ( ( context.ownerDocument || context ) != document ) { 24804 setDocument( context ); 24805 } 24806 return contains( context, elem ); 24807}; 24808 24809Sizzle.attr = function( elem, name ) { 24810 24811 // Set document vars if needed 24812 // Support: IE 11+, Edge 17 - 18+ 24813 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 24814 // two documents; shallow comparisons work. 24815 // eslint-disable-next-line eqeqeq 24816 if ( ( elem.ownerDocument || elem ) != document ) { 24817 setDocument( elem ); 24818 } 24819 24820 var fn = Expr.attrHandle[ name.toLowerCase() ], 24821 24822 // Don't get fooled by Object.prototype properties (jQuery #13807) 24823 val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? 24824 fn( elem, name, !documentIsHTML ) : 24825 undefined; 24826 24827 return val !== undefined ? 24828 val : 24829 support.attributes || !documentIsHTML ? 24830 elem.getAttribute( name ) : 24831 ( val = elem.getAttributeNode( name ) ) && val.specified ? 24832 val.value : 24833 null; 24834}; 24835 24836Sizzle.escape = function( sel ) { 24837 return ( sel + "" ).replace( rcssescape, fcssescape ); 24838}; 24839 24840Sizzle.error = function( msg ) { 24841 throw new Error( "Syntax error, unrecognized expression: " + msg ); 24842}; 24843 24844/** 24845 * Document sorting and removing duplicates 24846 * @param {ArrayLike} results 24847 */ 24848Sizzle.uniqueSort = function( results ) { 24849 var elem, 24850 duplicates = [], 24851 j = 0, 24852 i = 0; 24853 24854 // Unless we *know* we can detect duplicates, assume their presence 24855 hasDuplicate = !support.detectDuplicates; 24856 sortInput = !support.sortStable && results.slice( 0 ); 24857 results.sort( sortOrder ); 24858 24859 if ( hasDuplicate ) { 24860 while ( ( elem = results[ i++ ] ) ) { 24861 if ( elem === results[ i ] ) { 24862 j = duplicates.push( i ); 24863 } 24864 } 24865 while ( j-- ) { 24866 results.splice( duplicates[ j ], 1 ); 24867 } 24868 } 24869 24870 // Clear input after sorting to release objects 24871 // See https://github.com/jquery/sizzle/pull/225 24872 sortInput = null; 24873 24874 return results; 24875}; 24876 24877/** 24878 * Utility function for retrieving the text value of an array of DOM nodes 24879 * @param {Array|Element} elem 24880 */ 24881getText = Sizzle.getText = function( elem ) { 24882 var node, 24883 ret = "", 24884 i = 0, 24885 nodeType = elem.nodeType; 24886 24887 if ( !nodeType ) { 24888 24889 // If no nodeType, this is expected to be an array 24890 while ( ( node = elem[ i++ ] ) ) { 24891 24892 // Do not traverse comment nodes 24893 ret += getText( node ); 24894 } 24895 } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { 24896 24897 // Use textContent for elements 24898 // innerText usage removed for consistency of new lines (jQuery #11153) 24899 if ( typeof elem.textContent === "string" ) { 24900 return elem.textContent; 24901 } else { 24902 24903 // Traverse its children 24904 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 24905 ret += getText( elem ); 24906 } 24907 } 24908 } else if ( nodeType === 3 || nodeType === 4 ) { 24909 return elem.nodeValue; 24910 } 24911 24912 // Do not include comment or processing instruction nodes 24913 24914 return ret; 24915}; 24916 24917Expr = Sizzle.selectors = { 24918 24919 // Can be adjusted by the user 24920 cacheLength: 50, 24921 24922 createPseudo: markFunction, 24923 24924 match: matchExpr, 24925 24926 attrHandle: {}, 24927 24928 find: {}, 24929 24930 relative: { 24931 ">": { dir: "parentNode", first: true }, 24932 " ": { dir: "parentNode" }, 24933 "+": { dir: "previousSibling", first: true }, 24934 "~": { dir: "previousSibling" } 24935 }, 24936 24937 preFilter: { 24938 "ATTR": function( match ) { 24939 match[ 1 ] = match[ 1 ].replace( runescape, funescape ); 24940 24941 // Move the given value to match[3] whether quoted or unquoted 24942 match[ 3 ] = ( match[ 3 ] || match[ 4 ] || 24943 match[ 5 ] || "" ).replace( runescape, funescape ); 24944 24945 if ( match[ 2 ] === "~=" ) { 24946 match[ 3 ] = " " + match[ 3 ] + " "; 24947 } 24948 24949 return match.slice( 0, 4 ); 24950 }, 24951 24952 "CHILD": function( match ) { 24953 24954 /* matches from matchExpr["CHILD"] 24955 1 type (only|nth|...) 24956 2 what (child|of-type) 24957 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) 24958 4 xn-component of xn+y argument ([+-]?\d*n|) 24959 5 sign of xn-component 24960 6 x of xn-component 24961 7 sign of y-component 24962 8 y of y-component 24963 */ 24964 match[ 1 ] = match[ 1 ].toLowerCase(); 24965 24966 if ( match[ 1 ].slice( 0, 3 ) === "nth" ) { 24967 24968 // nth-* requires argument 24969 if ( !match[ 3 ] ) { 24970 Sizzle.error( match[ 0 ] ); 24971 } 24972 24973 // numeric x and y parameters for Expr.filter.CHILD 24974 // remember that false/true cast respectively to 0/1 24975 match[ 4 ] = +( match[ 4 ] ? 24976 match[ 5 ] + ( match[ 6 ] || 1 ) : 24977 2 * ( match[ 3 ] === "even" || match[ 3 ] === "odd" ) ); 24978 match[ 5 ] = +( ( match[ 7 ] + match[ 8 ] ) || match[ 3 ] === "odd" ); 24979 24980 // other types prohibit arguments 24981 } else if ( match[ 3 ] ) { 24982 Sizzle.error( match[ 0 ] ); 24983 } 24984 24985 return match; 24986 }, 24987 24988 "PSEUDO": function( match ) { 24989 var excess, 24990 unquoted = !match[ 6 ] && match[ 2 ]; 24991 24992 if ( matchExpr[ "CHILD" ].test( match[ 0 ] ) ) { 24993 return null; 24994 } 24995 24996 // Accept quoted arguments as-is 24997 if ( match[ 3 ] ) { 24998 match[ 2 ] = match[ 4 ] || match[ 5 ] || ""; 24999 25000 // Strip excess characters from unquoted arguments 25001 } else if ( unquoted && rpseudo.test( unquoted ) && 25002 25003 // Get excess from tokenize (recursively) 25004 ( excess = tokenize( unquoted, true ) ) && 25005 25006 // advance to the next closing parenthesis 25007 ( excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length ) ) { 25008 25009 // excess is a negative index 25010 match[ 0 ] = match[ 0 ].slice( 0, excess ); 25011 match[ 2 ] = unquoted.slice( 0, excess ); 25012 } 25013 25014 // Return only captures needed by the pseudo filter method (type and argument) 25015 return match.slice( 0, 3 ); 25016 } 25017 }, 25018 25019 filter: { 25020 25021 "TAG": function( nodeNameSelector ) { 25022 var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); 25023 return nodeNameSelector === "*" ? 25024 function() { 25025 return true; 25026 } : 25027 function( elem ) { 25028 return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; 25029 }; 25030 }, 25031 25032 "CLASS": function( className ) { 25033 var pattern = classCache[ className + " " ]; 25034 25035 return pattern || 25036 ( pattern = new RegExp( "(^|" + whitespace + 25037 ")" + className + "(" + whitespace + "|$)" ) ) && classCache( 25038 className, function( elem ) { 25039 return pattern.test( 25040 typeof elem.className === "string" && elem.className || 25041 typeof elem.getAttribute !== "undefined" && 25042 elem.getAttribute( "class" ) || 25043 "" 25044 ); 25045 } ); 25046 }, 25047 25048 "ATTR": function( name, operator, check ) { 25049 return function( elem ) { 25050 var result = Sizzle.attr( elem, name ); 25051 25052 if ( result == null ) { 25053 return operator === "!="; 25054 } 25055 if ( !operator ) { 25056 return true; 25057 } 25058 25059 result += ""; 25060 25061 /* eslint-disable max-len */ 25062 25063 return operator === "=" ? result === check : 25064 operator === "!=" ? result !== check : 25065 operator === "^=" ? check && result.indexOf( check ) === 0 : 25066 operator === "*=" ? check && result.indexOf( check ) > -1 : 25067 operator === "$=" ? check && result.slice( -check.length ) === check : 25068 operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : 25069 operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : 25070 false; 25071 /* eslint-enable max-len */ 25072 25073 }; 25074 }, 25075 25076 "CHILD": function( type, what, _argument, first, last ) { 25077 var simple = type.slice( 0, 3 ) !== "nth", 25078 forward = type.slice( -4 ) !== "last", 25079 ofType = what === "of-type"; 25080 25081 return first === 1 && last === 0 ? 25082 25083 // Shortcut for :nth-*(n) 25084 function( elem ) { 25085 return !!elem.parentNode; 25086 } : 25087 25088 function( elem, _context, xml ) { 25089 var cache, uniqueCache, outerCache, node, nodeIndex, start, 25090 dir = simple !== forward ? "nextSibling" : "previousSibling", 25091 parent = elem.parentNode, 25092 name = ofType && elem.nodeName.toLowerCase(), 25093 useCache = !xml && !ofType, 25094 diff = false; 25095 25096 if ( parent ) { 25097 25098 // :(first|last|only)-(child|of-type) 25099 if ( simple ) { 25100 while ( dir ) { 25101 node = elem; 25102 while ( ( node = node[ dir ] ) ) { 25103 if ( ofType ? 25104 node.nodeName.toLowerCase() === name : 25105 node.nodeType === 1 ) { 25106 25107 return false; 25108 } 25109 } 25110 25111 // Reverse direction for :only-* (if we haven't yet done so) 25112 start = dir = type === "only" && !start && "nextSibling"; 25113 } 25114 return true; 25115 } 25116 25117 start = [ forward ? parent.firstChild : parent.lastChild ]; 25118 25119 // non-xml :nth-child(...) stores cache data on `parent` 25120 if ( forward && useCache ) { 25121 25122 // Seek `elem` from a previously-cached index 25123 25124 // ...in a gzip-friendly way 25125 node = parent; 25126 outerCache = node[ expando ] || ( node[ expando ] = {} ); 25127 25128 // Support: IE <9 only 25129 // Defend against cloned attroperties (jQuery gh-1709) 25130 uniqueCache = outerCache[ node.uniqueID ] || 25131 ( outerCache[ node.uniqueID ] = {} ); 25132 25133 cache = uniqueCache[ type ] || []; 25134 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 25135 diff = nodeIndex && cache[ 2 ]; 25136 node = nodeIndex && parent.childNodes[ nodeIndex ]; 25137 25138 while ( ( node = ++nodeIndex && node && node[ dir ] || 25139 25140 // Fallback to seeking `elem` from the start 25141 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 25142 25143 // When found, cache indexes on `parent` and break 25144 if ( node.nodeType === 1 && ++diff && node === elem ) { 25145 uniqueCache[ type ] = [ dirruns, nodeIndex, diff ]; 25146 break; 25147 } 25148 } 25149 25150 } else { 25151 25152 // Use previously-cached element index if available 25153 if ( useCache ) { 25154 25155 // ...in a gzip-friendly way 25156 node = elem; 25157 outerCache = node[ expando ] || ( node[ expando ] = {} ); 25158 25159 // Support: IE <9 only 25160 // Defend against cloned attroperties (jQuery gh-1709) 25161 uniqueCache = outerCache[ node.uniqueID ] || 25162 ( outerCache[ node.uniqueID ] = {} ); 25163 25164 cache = uniqueCache[ type ] || []; 25165 nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ]; 25166 diff = nodeIndex; 25167 } 25168 25169 // xml :nth-child(...) 25170 // or :nth-last-child(...) or :nth(-last)?-of-type(...) 25171 if ( diff === false ) { 25172 25173 // Use the same loop as above to seek `elem` from the start 25174 while ( ( node = ++nodeIndex && node && node[ dir ] || 25175 ( diff = nodeIndex = 0 ) || start.pop() ) ) { 25176 25177 if ( ( ofType ? 25178 node.nodeName.toLowerCase() === name : 25179 node.nodeType === 1 ) && 25180 ++diff ) { 25181 25182 // Cache the index of each encountered element 25183 if ( useCache ) { 25184 outerCache = node[ expando ] || 25185 ( node[ expando ] = {} ); 25186 25187 // Support: IE <9 only 25188 // Defend against cloned attroperties (jQuery gh-1709) 25189 uniqueCache = outerCache[ node.uniqueID ] || 25190 ( outerCache[ node.uniqueID ] = {} ); 25191 25192 uniqueCache[ type ] = [ dirruns, diff ]; 25193 } 25194 25195 if ( node === elem ) { 25196 break; 25197 } 25198 } 25199 } 25200 } 25201 } 25202 25203 // Incorporate the offset, then check against cycle size 25204 diff -= last; 25205 return diff === first || ( diff % first === 0 && diff / first >= 0 ); 25206 } 25207 }; 25208 }, 25209 25210 "PSEUDO": function( pseudo, argument ) { 25211 25212 // pseudo-class names are case-insensitive 25213 // http://www.w3.org/TR/selectors/#pseudo-classes 25214 // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters 25215 // Remember that setFilters inherits from pseudos 25216 var args, 25217 fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || 25218 Sizzle.error( "unsupported pseudo: " + pseudo ); 25219 25220 // The user may use createPseudo to indicate that 25221 // arguments are needed to create the filter function 25222 // just as Sizzle does 25223 if ( fn[ expando ] ) { 25224 return fn( argument ); 25225 } 25226 25227 // But maintain support for old signatures 25228 if ( fn.length > 1 ) { 25229 args = [ pseudo, pseudo, "", argument ]; 25230 return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? 25231 markFunction( function( seed, matches ) { 25232 var idx, 25233 matched = fn( seed, argument ), 25234 i = matched.length; 25235 while ( i-- ) { 25236 idx = indexOf( seed, matched[ i ] ); 25237 seed[ idx ] = !( matches[ idx ] = matched[ i ] ); 25238 } 25239 } ) : 25240 function( elem ) { 25241 return fn( elem, 0, args ); 25242 }; 25243 } 25244 25245 return fn; 25246 } 25247 }, 25248 25249 pseudos: { 25250 25251 // Potentially complex pseudos 25252 "not": markFunction( function( selector ) { 25253 25254 // Trim the selector passed to compile 25255 // to avoid treating leading and trailing 25256 // spaces as combinators 25257 var input = [], 25258 results = [], 25259 matcher = compile( selector.replace( rtrim, "$1" ) ); 25260 25261 return matcher[ expando ] ? 25262 markFunction( function( seed, matches, _context, xml ) { 25263 var elem, 25264 unmatched = matcher( seed, null, xml, [] ), 25265 i = seed.length; 25266 25267 // Match elements unmatched by `matcher` 25268 while ( i-- ) { 25269 if ( ( elem = unmatched[ i ] ) ) { 25270 seed[ i ] = !( matches[ i ] = elem ); 25271 } 25272 } 25273 } ) : 25274 function( elem, _context, xml ) { 25275 input[ 0 ] = elem; 25276 matcher( input, null, xml, results ); 25277 25278 // Don't keep the element (issue #299) 25279 input[ 0 ] = null; 25280 return !results.pop(); 25281 }; 25282 } ), 25283 25284 "has": markFunction( function( selector ) { 25285 return function( elem ) { 25286 return Sizzle( selector, elem ).length > 0; 25287 }; 25288 } ), 25289 25290 "contains": markFunction( function( text ) { 25291 text = text.replace( runescape, funescape ); 25292 return function( elem ) { 25293 return ( elem.textContent || getText( elem ) ).indexOf( text ) > -1; 25294 }; 25295 } ), 25296 25297 // "Whether an element is represented by a :lang() selector 25298 // is based solely on the element's language value 25299 // being equal to the identifier C, 25300 // or beginning with the identifier C immediately followed by "-". 25301 // The matching of C against the element's language value is performed case-insensitively. 25302 // The identifier C does not have to be a valid language name." 25303 // http://www.w3.org/TR/selectors/#lang-pseudo 25304 "lang": markFunction( function( lang ) { 25305 25306 // lang value must be a valid identifier 25307 if ( !ridentifier.test( lang || "" ) ) { 25308 Sizzle.error( "unsupported lang: " + lang ); 25309 } 25310 lang = lang.replace( runescape, funescape ).toLowerCase(); 25311 return function( elem ) { 25312 var elemLang; 25313 do { 25314 if ( ( elemLang = documentIsHTML ? 25315 elem.lang : 25316 elem.getAttribute( "xml:lang" ) || elem.getAttribute( "lang" ) ) ) { 25317 25318 elemLang = elemLang.toLowerCase(); 25319 return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; 25320 } 25321 } while ( ( elem = elem.parentNode ) && elem.nodeType === 1 ); 25322 return false; 25323 }; 25324 } ), 25325 25326 // Miscellaneous 25327 "target": function( elem ) { 25328 var hash = window.location && window.location.hash; 25329 return hash && hash.slice( 1 ) === elem.id; 25330 }, 25331 25332 "root": function( elem ) { 25333 return elem === docElem; 25334 }, 25335 25336 "focus": function( elem ) { 25337 return elem === document.activeElement && 25338 ( !document.hasFocus || document.hasFocus() ) && 25339 !!( elem.type || elem.href || ~elem.tabIndex ); 25340 }, 25341 25342 // Boolean properties 25343 "enabled": createDisabledPseudo( false ), 25344 "disabled": createDisabledPseudo( true ), 25345 25346 "checked": function( elem ) { 25347 25348 // In CSS3, :checked should return both checked and selected elements 25349 // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked 25350 var nodeName = elem.nodeName.toLowerCase(); 25351 return ( nodeName === "input" && !!elem.checked ) || 25352 ( nodeName === "option" && !!elem.selected ); 25353 }, 25354 25355 "selected": function( elem ) { 25356 25357 // Accessing this property makes selected-by-default 25358 // options in Safari work properly 25359 if ( elem.parentNode ) { 25360 // eslint-disable-next-line no-unused-expressions 25361 elem.parentNode.selectedIndex; 25362 } 25363 25364 return elem.selected === true; 25365 }, 25366 25367 // Contents 25368 "empty": function( elem ) { 25369 25370 // http://www.w3.org/TR/selectors/#empty-pseudo 25371 // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), 25372 // but not by others (comment: 8; processing instruction: 7; etc.) 25373 // nodeType < 6 works because attributes (2) do not appear as children 25374 for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { 25375 if ( elem.nodeType < 6 ) { 25376 return false; 25377 } 25378 } 25379 return true; 25380 }, 25381 25382 "parent": function( elem ) { 25383 return !Expr.pseudos[ "empty" ]( elem ); 25384 }, 25385 25386 // Element/input types 25387 "header": function( elem ) { 25388 return rheader.test( elem.nodeName ); 25389 }, 25390 25391 "input": function( elem ) { 25392 return rinputs.test( elem.nodeName ); 25393 }, 25394 25395 "button": function( elem ) { 25396 var name = elem.nodeName.toLowerCase(); 25397 return name === "input" && elem.type === "button" || name === "button"; 25398 }, 25399 25400 "text": function( elem ) { 25401 var attr; 25402 return elem.nodeName.toLowerCase() === "input" && 25403 elem.type === "text" && 25404 25405 // Support: IE<8 25406 // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" 25407 ( ( attr = elem.getAttribute( "type" ) ) == null || 25408 attr.toLowerCase() === "text" ); 25409 }, 25410 25411 // Position-in-collection 25412 "first": createPositionalPseudo( function() { 25413 return [ 0 ]; 25414 } ), 25415 25416 "last": createPositionalPseudo( function( _matchIndexes, length ) { 25417 return [ length - 1 ]; 25418 } ), 25419 25420 "eq": createPositionalPseudo( function( _matchIndexes, length, argument ) { 25421 return [ argument < 0 ? argument + length : argument ]; 25422 } ), 25423 25424 "even": createPositionalPseudo( function( matchIndexes, length ) { 25425 var i = 0; 25426 for ( ; i < length; i += 2 ) { 25427 matchIndexes.push( i ); 25428 } 25429 return matchIndexes; 25430 } ), 25431 25432 "odd": createPositionalPseudo( function( matchIndexes, length ) { 25433 var i = 1; 25434 for ( ; i < length; i += 2 ) { 25435 matchIndexes.push( i ); 25436 } 25437 return matchIndexes; 25438 } ), 25439 25440 "lt": createPositionalPseudo( function( matchIndexes, length, argument ) { 25441 var i = argument < 0 ? 25442 argument + length : 25443 argument > length ? 25444 length : 25445 argument; 25446 for ( ; --i >= 0; ) { 25447 matchIndexes.push( i ); 25448 } 25449 return matchIndexes; 25450 } ), 25451 25452 "gt": createPositionalPseudo( function( matchIndexes, length, argument ) { 25453 var i = argument < 0 ? argument + length : argument; 25454 for ( ; ++i < length; ) { 25455 matchIndexes.push( i ); 25456 } 25457 return matchIndexes; 25458 } ) 25459 } 25460}; 25461 25462Expr.pseudos[ "nth" ] = Expr.pseudos[ "eq" ]; 25463 25464// Add button/input type pseudos 25465for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { 25466 Expr.pseudos[ i ] = createInputPseudo( i ); 25467} 25468for ( i in { submit: true, reset: true } ) { 25469 Expr.pseudos[ i ] = createButtonPseudo( i ); 25470} 25471 25472// Easy API for creating new setFilters 25473function setFilters() {} 25474setFilters.prototype = Expr.filters = Expr.pseudos; 25475Expr.setFilters = new setFilters(); 25476 25477tokenize = Sizzle.tokenize = function( selector, parseOnly ) { 25478 var matched, match, tokens, type, 25479 soFar, groups, preFilters, 25480 cached = tokenCache[ selector + " " ]; 25481 25482 if ( cached ) { 25483 return parseOnly ? 0 : cached.slice( 0 ); 25484 } 25485 25486 soFar = selector; 25487 groups = []; 25488 preFilters = Expr.preFilter; 25489 25490 while ( soFar ) { 25491 25492 // Comma and first run 25493 if ( !matched || ( match = rcomma.exec( soFar ) ) ) { 25494 if ( match ) { 25495 25496 // Don't consume trailing commas as valid 25497 soFar = soFar.slice( match[ 0 ].length ) || soFar; 25498 } 25499 groups.push( ( tokens = [] ) ); 25500 } 25501 25502 matched = false; 25503 25504 // Combinators 25505 if ( ( match = rcombinators.exec( soFar ) ) ) { 25506 matched = match.shift(); 25507 tokens.push( { 25508 value: matched, 25509 25510 // Cast descendant combinators to space 25511 type: match[ 0 ].replace( rtrim, " " ) 25512 } ); 25513 soFar = soFar.slice( matched.length ); 25514 } 25515 25516 // Filters 25517 for ( type in Expr.filter ) { 25518 if ( ( match = matchExpr[ type ].exec( soFar ) ) && ( !preFilters[ type ] || 25519 ( match = preFilters[ type ]( match ) ) ) ) { 25520 matched = match.shift(); 25521 tokens.push( { 25522 value: matched, 25523 type: type, 25524 matches: match 25525 } ); 25526 soFar = soFar.slice( matched.length ); 25527 } 25528 } 25529 25530 if ( !matched ) { 25531 break; 25532 } 25533 } 25534 25535 // Return the length of the invalid excess 25536 // if we're just parsing 25537 // Otherwise, throw an error or return tokens 25538 return parseOnly ? 25539 soFar.length : 25540 soFar ? 25541 Sizzle.error( selector ) : 25542 25543 // Cache the tokens 25544 tokenCache( selector, groups ).slice( 0 ); 25545}; 25546 25547function toSelector( tokens ) { 25548 var i = 0, 25549 len = tokens.length, 25550 selector = ""; 25551 for ( ; i < len; i++ ) { 25552 selector += tokens[ i ].value; 25553 } 25554 return selector; 25555} 25556 25557function addCombinator( matcher, combinator, base ) { 25558 var dir = combinator.dir, 25559 skip = combinator.next, 25560 key = skip || dir, 25561 checkNonElements = base && key === "parentNode", 25562 doneName = done++; 25563 25564 return combinator.first ? 25565 25566 // Check against closest ancestor/preceding element 25567 function( elem, context, xml ) { 25568 while ( ( elem = elem[ dir ] ) ) { 25569 if ( elem.nodeType === 1 || checkNonElements ) { 25570 return matcher( elem, context, xml ); 25571 } 25572 } 25573 return false; 25574 } : 25575 25576 // Check against all ancestor/preceding elements 25577 function( elem, context, xml ) { 25578 var oldCache, uniqueCache, outerCache, 25579 newCache = [ dirruns, doneName ]; 25580 25581 // We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching 25582 if ( xml ) { 25583 while ( ( elem = elem[ dir ] ) ) { 25584 if ( elem.nodeType === 1 || checkNonElements ) { 25585 if ( matcher( elem, context, xml ) ) { 25586 return true; 25587 } 25588 } 25589 } 25590 } else { 25591 while ( ( elem = elem[ dir ] ) ) { 25592 if ( elem.nodeType === 1 || checkNonElements ) { 25593 outerCache = elem[ expando ] || ( elem[ expando ] = {} ); 25594 25595 // Support: IE <9 only 25596 // Defend against cloned attroperties (jQuery gh-1709) 25597 uniqueCache = outerCache[ elem.uniqueID ] || 25598 ( outerCache[ elem.uniqueID ] = {} ); 25599 25600 if ( skip && skip === elem.nodeName.toLowerCase() ) { 25601 elem = elem[ dir ] || elem; 25602 } else if ( ( oldCache = uniqueCache[ key ] ) && 25603 oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { 25604 25605 // Assign to newCache so results back-propagate to previous elements 25606 return ( newCache[ 2 ] = oldCache[ 2 ] ); 25607 } else { 25608 25609 // Reuse newcache so results back-propagate to previous elements 25610 uniqueCache[ key ] = newCache; 25611 25612 // A match means we're done; a fail means we have to keep checking 25613 if ( ( newCache[ 2 ] = matcher( elem, context, xml ) ) ) { 25614 return true; 25615 } 25616 } 25617 } 25618 } 25619 } 25620 return false; 25621 }; 25622} 25623 25624function elementMatcher( matchers ) { 25625 return matchers.length > 1 ? 25626 function( elem, context, xml ) { 25627 var i = matchers.length; 25628 while ( i-- ) { 25629 if ( !matchers[ i ]( elem, context, xml ) ) { 25630 return false; 25631 } 25632 } 25633 return true; 25634 } : 25635 matchers[ 0 ]; 25636} 25637 25638function multipleContexts( selector, contexts, results ) { 25639 var i = 0, 25640 len = contexts.length; 25641 for ( ; i < len; i++ ) { 25642 Sizzle( selector, contexts[ i ], results ); 25643 } 25644 return results; 25645} 25646 25647function condense( unmatched, map, filter, context, xml ) { 25648 var elem, 25649 newUnmatched = [], 25650 i = 0, 25651 len = unmatched.length, 25652 mapped = map != null; 25653 25654 for ( ; i < len; i++ ) { 25655 if ( ( elem = unmatched[ i ] ) ) { 25656 if ( !filter || filter( elem, context, xml ) ) { 25657 newUnmatched.push( elem ); 25658 if ( mapped ) { 25659 map.push( i ); 25660 } 25661 } 25662 } 25663 } 25664 25665 return newUnmatched; 25666} 25667 25668function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { 25669 if ( postFilter && !postFilter[ expando ] ) { 25670 postFilter = setMatcher( postFilter ); 25671 } 25672 if ( postFinder && !postFinder[ expando ] ) { 25673 postFinder = setMatcher( postFinder, postSelector ); 25674 } 25675 return markFunction( function( seed, results, context, xml ) { 25676 var temp, i, elem, 25677 preMap = [], 25678 postMap = [], 25679 preexisting = results.length, 25680 25681 // Get initial elements from seed or context 25682 elems = seed || multipleContexts( 25683 selector || "*", 25684 context.nodeType ? [ context ] : context, 25685 [] 25686 ), 25687 25688 // Prefilter to get matcher input, preserving a map for seed-results synchronization 25689 matcherIn = preFilter && ( seed || !selector ) ? 25690 condense( elems, preMap, preFilter, context, xml ) : 25691 elems, 25692 25693 matcherOut = matcher ? 25694 25695 // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, 25696 postFinder || ( seed ? preFilter : preexisting || postFilter ) ? 25697 25698 // ...intermediate processing is necessary 25699 [] : 25700 25701 // ...otherwise use results directly 25702 results : 25703 matcherIn; 25704 25705 // Find primary matches 25706 if ( matcher ) { 25707 matcher( matcherIn, matcherOut, context, xml ); 25708 } 25709 25710 // Apply postFilter 25711 if ( postFilter ) { 25712 temp = condense( matcherOut, postMap ); 25713 postFilter( temp, [], context, xml ); 25714 25715 // Un-match failing elements by moving them back to matcherIn 25716 i = temp.length; 25717 while ( i-- ) { 25718 if ( ( elem = temp[ i ] ) ) { 25719 matcherOut[ postMap[ i ] ] = !( matcherIn[ postMap[ i ] ] = elem ); 25720 } 25721 } 25722 } 25723 25724 if ( seed ) { 25725 if ( postFinder || preFilter ) { 25726 if ( postFinder ) { 25727 25728 // Get the final matcherOut by condensing this intermediate into postFinder contexts 25729 temp = []; 25730 i = matcherOut.length; 25731 while ( i-- ) { 25732 if ( ( elem = matcherOut[ i ] ) ) { 25733 25734 // Restore matcherIn since elem is not yet a final match 25735 temp.push( ( matcherIn[ i ] = elem ) ); 25736 } 25737 } 25738 postFinder( null, ( matcherOut = [] ), temp, xml ); 25739 } 25740 25741 // Move matched elements from seed to results to keep them synchronized 25742 i = matcherOut.length; 25743 while ( i-- ) { 25744 if ( ( elem = matcherOut[ i ] ) && 25745 ( temp = postFinder ? indexOf( seed, elem ) : preMap[ i ] ) > -1 ) { 25746 25747 seed[ temp ] = !( results[ temp ] = elem ); 25748 } 25749 } 25750 } 25751 25752 // Add elements to results, through postFinder if defined 25753 } else { 25754 matcherOut = condense( 25755 matcherOut === results ? 25756 matcherOut.splice( preexisting, matcherOut.length ) : 25757 matcherOut 25758 ); 25759 if ( postFinder ) { 25760 postFinder( null, results, matcherOut, xml ); 25761 } else { 25762 push.apply( results, matcherOut ); 25763 } 25764 } 25765 } ); 25766} 25767 25768function matcherFromTokens( tokens ) { 25769 var checkContext, matcher, j, 25770 len = tokens.length, 25771 leadingRelative = Expr.relative[ tokens[ 0 ].type ], 25772 implicitRelative = leadingRelative || Expr.relative[ " " ], 25773 i = leadingRelative ? 1 : 0, 25774 25775 // The foundational matcher ensures that elements are reachable from top-level context(s) 25776 matchContext = addCombinator( function( elem ) { 25777 return elem === checkContext; 25778 }, implicitRelative, true ), 25779 matchAnyContext = addCombinator( function( elem ) { 25780 return indexOf( checkContext, elem ) > -1; 25781 }, implicitRelative, true ), 25782 matchers = [ function( elem, context, xml ) { 25783 var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( 25784 ( checkContext = context ).nodeType ? 25785 matchContext( elem, context, xml ) : 25786 matchAnyContext( elem, context, xml ) ); 25787 25788 // Avoid hanging onto element (issue #299) 25789 checkContext = null; 25790 return ret; 25791 } ]; 25792 25793 for ( ; i < len; i++ ) { 25794 if ( ( matcher = Expr.relative[ tokens[ i ].type ] ) ) { 25795 matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; 25796 } else { 25797 matcher = Expr.filter[ tokens[ i ].type ].apply( null, tokens[ i ].matches ); 25798 25799 // Return special upon seeing a positional matcher 25800 if ( matcher[ expando ] ) { 25801 25802 // Find the next relative operator (if any) for proper handling 25803 j = ++i; 25804 for ( ; j < len; j++ ) { 25805 if ( Expr.relative[ tokens[ j ].type ] ) { 25806 break; 25807 } 25808 } 25809 return setMatcher( 25810 i > 1 && elementMatcher( matchers ), 25811 i > 1 && toSelector( 25812 25813 // If the preceding token was a descendant combinator, insert an implicit any-element `*` 25814 tokens 25815 .slice( 0, i - 1 ) 25816 .concat( { value: tokens[ i - 2 ].type === " " ? "*" : "" } ) 25817 ).replace( rtrim, "$1" ), 25818 matcher, 25819 i < j && matcherFromTokens( tokens.slice( i, j ) ), 25820 j < len && matcherFromTokens( ( tokens = tokens.slice( j ) ) ), 25821 j < len && toSelector( tokens ) 25822 ); 25823 } 25824 matchers.push( matcher ); 25825 } 25826 } 25827 25828 return elementMatcher( matchers ); 25829} 25830 25831function matcherFromGroupMatchers( elementMatchers, setMatchers ) { 25832 var bySet = setMatchers.length > 0, 25833 byElement = elementMatchers.length > 0, 25834 superMatcher = function( seed, context, xml, results, outermost ) { 25835 var elem, j, matcher, 25836 matchedCount = 0, 25837 i = "0", 25838 unmatched = seed && [], 25839 setMatched = [], 25840 contextBackup = outermostContext, 25841 25842 // We must always have either seed elements or outermost context 25843 elems = seed || byElement && Expr.find[ "TAG" ]( "*", outermost ), 25844 25845 // Use integer dirruns iff this is the outermost matcher 25846 dirrunsUnique = ( dirruns += contextBackup == null ? 1 : Math.random() || 0.1 ), 25847 len = elems.length; 25848 25849 if ( outermost ) { 25850 25851 // Support: IE 11+, Edge 17 - 18+ 25852 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 25853 // two documents; shallow comparisons work. 25854 // eslint-disable-next-line eqeqeq 25855 outermostContext = context == document || context || outermost; 25856 } 25857 25858 // Add elements passing elementMatchers directly to results 25859 // Support: IE<9, Safari 25860 // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id 25861 for ( ; i !== len && ( elem = elems[ i ] ) != null; i++ ) { 25862 if ( byElement && elem ) { 25863 j = 0; 25864 25865 // Support: IE 11+, Edge 17 - 18+ 25866 // IE/Edge sometimes throw a "Permission denied" error when strict-comparing 25867 // two documents; shallow comparisons work. 25868 // eslint-disable-next-line eqeqeq 25869 if ( !context && elem.ownerDocument != document ) { 25870 setDocument( elem ); 25871 xml = !documentIsHTML; 25872 } 25873 while ( ( matcher = elementMatchers[ j++ ] ) ) { 25874 if ( matcher( elem, context || document, xml ) ) { 25875 results.push( elem ); 25876 break; 25877 } 25878 } 25879 if ( outermost ) { 25880 dirruns = dirrunsUnique; 25881 } 25882 } 25883 25884 // Track unmatched elements for set filters 25885 if ( bySet ) { 25886 25887 // They will have gone through all possible matchers 25888 if ( ( elem = !matcher && elem ) ) { 25889 matchedCount--; 25890 } 25891 25892 // Lengthen the array for every element, matched or not 25893 if ( seed ) { 25894 unmatched.push( elem ); 25895 } 25896 } 25897 } 25898 25899 // `i` is now the count of elements visited above, and adding it to `matchedCount` 25900 // makes the latter nonnegative. 25901 matchedCount += i; 25902 25903 // Apply set filters to unmatched elements 25904 // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount` 25905 // equals `i`), unless we didn't visit _any_ elements in the above loop because we have 25906 // no element matchers and no seed. 25907 // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that 25908 // case, which will result in a "00" `matchedCount` that differs from `i` but is also 25909 // numerically zero. 25910 if ( bySet && i !== matchedCount ) { 25911 j = 0; 25912 while ( ( matcher = setMatchers[ j++ ] ) ) { 25913 matcher( unmatched, setMatched, context, xml ); 25914 } 25915 25916 if ( seed ) { 25917 25918 // Reintegrate element matches to eliminate the need for sorting 25919 if ( matchedCount > 0 ) { 25920 while ( i-- ) { 25921 if ( !( unmatched[ i ] || setMatched[ i ] ) ) { 25922 setMatched[ i ] = pop.call( results ); 25923 } 25924 } 25925 } 25926 25927 // Discard index placeholder values to get only actual matches 25928 setMatched = condense( setMatched ); 25929 } 25930 25931 // Add matches to results 25932 push.apply( results, setMatched ); 25933 25934 // Seedless set matches succeeding multiple successful matchers stipulate sorting 25935 if ( outermost && !seed && setMatched.length > 0 && 25936 ( matchedCount + setMatchers.length ) > 1 ) { 25937 25938 Sizzle.uniqueSort( results ); 25939 } 25940 } 25941 25942 // Override manipulation of globals by nested matchers 25943 if ( outermost ) { 25944 dirruns = dirrunsUnique; 25945 outermostContext = contextBackup; 25946 } 25947 25948 return unmatched; 25949 }; 25950 25951 return bySet ? 25952 markFunction( superMatcher ) : 25953 superMatcher; 25954} 25955 25956compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { 25957 var i, 25958 setMatchers = [], 25959 elementMatchers = [], 25960 cached = compilerCache[ selector + " " ]; 25961 25962 if ( !cached ) { 25963 25964 // Generate a function of recursive functions that can be used to check each element 25965 if ( !match ) { 25966 match = tokenize( selector ); 25967 } 25968 i = match.length; 25969 while ( i-- ) { 25970 cached = matcherFromTokens( match[ i ] ); 25971 if ( cached[ expando ] ) { 25972 setMatchers.push( cached ); 25973 } else { 25974 elementMatchers.push( cached ); 25975 } 25976 } 25977 25978 // Cache the compiled function 25979 cached = compilerCache( 25980 selector, 25981 matcherFromGroupMatchers( elementMatchers, setMatchers ) 25982 ); 25983 25984 // Save selector and tokenization 25985 cached.selector = selector; 25986 } 25987 return cached; 25988}; 25989 25990/** 25991 * A low-level selection function that works with Sizzle's compiled 25992 * selector functions 25993 * @param {String|Function} selector A selector or a pre-compiled 25994 * selector function built with Sizzle.compile 25995 * @param {Element} context 25996 * @param {Array} [results] 25997 * @param {Array} [seed] A set of elements to match against 25998 */ 25999select = Sizzle.select = function( selector, context, results, seed ) { 26000 var i, tokens, token, type, find, 26001 compiled = typeof selector === "function" && selector, 26002 match = !seed && tokenize( ( selector = compiled.selector || selector ) ); 26003 26004 results = results || []; 26005 26006 // Try to minimize operations if there is only one selector in the list and no seed 26007 // (the latter of which guarantees us context) 26008 if ( match.length === 1 ) { 26009 26010 // Reduce context if the leading compound selector is an ID 26011 tokens = match[ 0 ] = match[ 0 ].slice( 0 ); 26012 if ( tokens.length > 2 && ( token = tokens[ 0 ] ).type === "ID" && 26013 context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[ 1 ].type ] ) { 26014 26015 context = ( Expr.find[ "ID" ]( token.matches[ 0 ] 26016 .replace( runescape, funescape ), context ) || [] )[ 0 ]; 26017 if ( !context ) { 26018 return results; 26019 26020 // Precompiled matchers will still verify ancestry, so step up a level 26021 } else if ( compiled ) { 26022 context = context.parentNode; 26023 } 26024 26025 selector = selector.slice( tokens.shift().value.length ); 26026 } 26027 26028 // Fetch a seed set for right-to-left matching 26029 i = matchExpr[ "needsContext" ].test( selector ) ? 0 : tokens.length; 26030 while ( i-- ) { 26031 token = tokens[ i ]; 26032 26033 // Abort if we hit a combinator 26034 if ( Expr.relative[ ( type = token.type ) ] ) { 26035 break; 26036 } 26037 if ( ( find = Expr.find[ type ] ) ) { 26038 26039 // Search, expanding context for leading sibling combinators 26040 if ( ( seed = find( 26041 token.matches[ 0 ].replace( runescape, funescape ), 26042 rsibling.test( tokens[ 0 ].type ) && testContext( context.parentNode ) || 26043 context 26044 ) ) ) { 26045 26046 // If seed is empty or no tokens remain, we can return early 26047 tokens.splice( i, 1 ); 26048 selector = seed.length && toSelector( tokens ); 26049 if ( !selector ) { 26050 push.apply( results, seed ); 26051 return results; 26052 } 26053 26054 break; 26055 } 26056 } 26057 } 26058 } 26059 26060 // Compile and execute a filtering function if one is not provided 26061 // Provide `match` to avoid retokenization if we modified the selector above 26062 ( compiled || compile( selector, match ) )( 26063 seed, 26064 context, 26065 !documentIsHTML, 26066 results, 26067 !context || rsibling.test( selector ) && testContext( context.parentNode ) || context 26068 ); 26069 return results; 26070}; 26071 26072// One-time assignments 26073 26074// Sort stability 26075support.sortStable = expando.split( "" ).sort( sortOrder ).join( "" ) === expando; 26076 26077// Support: Chrome 14-35+ 26078// Always assume duplicates if they aren't passed to the comparison function 26079support.detectDuplicates = !!hasDuplicate; 26080 26081// Initialize against the default document 26082setDocument(); 26083 26084// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) 26085// Detached nodes confoundingly follow *each other* 26086support.sortDetached = assert( function( el ) { 26087 26088 // Should return 1, but returns 4 (following) 26089 return el.compareDocumentPosition( document.createElement( "fieldset" ) ) & 1; 26090} ); 26091 26092// Support: IE<8 26093// Prevent attribute/property "interpolation" 26094// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx 26095if ( !assert( function( el ) { 26096 el.innerHTML = "<a href='#'></a>"; 26097 return el.firstChild.getAttribute( "href" ) === "#"; 26098} ) ) { 26099 addHandle( "type|href|height|width", function( elem, name, isXML ) { 26100 if ( !isXML ) { 26101 return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); 26102 } 26103 } ); 26104} 26105 26106// Support: IE<9 26107// Use defaultValue in place of getAttribute("value") 26108if ( !support.attributes || !assert( function( el ) { 26109 el.innerHTML = "<input/>"; 26110 el.firstChild.setAttribute( "value", "" ); 26111 return el.firstChild.getAttribute( "value" ) === ""; 26112} ) ) { 26113 addHandle( "value", function( elem, _name, isXML ) { 26114 if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { 26115 return elem.defaultValue; 26116 } 26117 } ); 26118} 26119 26120// Support: IE<9 26121// Use getAttributeNode to fetch booleans when getAttribute lies 26122if ( !assert( function( el ) { 26123 return el.getAttribute( "disabled" ) == null; 26124} ) ) { 26125 addHandle( booleans, function( elem, name, isXML ) { 26126 var val; 26127 if ( !isXML ) { 26128 return elem[ name ] === true ? name.toLowerCase() : 26129 ( val = elem.getAttributeNode( name ) ) && val.specified ? 26130 val.value : 26131 null; 26132 } 26133 } ); 26134} 26135 26136return Sizzle; 26137 26138} )( window ); 26139 26140 26141 26142jQuery.find = Sizzle; 26143jQuery.expr = Sizzle.selectors; 26144 26145// Deprecated 26146jQuery.expr[ ":" ] = jQuery.expr.pseudos; 26147jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort; 26148jQuery.text = Sizzle.getText; 26149jQuery.isXMLDoc = Sizzle.isXML; 26150jQuery.contains = Sizzle.contains; 26151jQuery.escapeSelector = Sizzle.escape; 26152 26153 26154 26155 26156var dir = function( elem, dir, until ) { 26157 var matched = [], 26158 truncate = until !== undefined; 26159 26160 while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) { 26161 if ( elem.nodeType === 1 ) { 26162 if ( truncate && jQuery( elem ).is( until ) ) { 26163 break; 26164 } 26165 matched.push( elem ); 26166 } 26167 } 26168 return matched; 26169}; 26170 26171 26172var siblings = function( n, elem ) { 26173 var matched = []; 26174 26175 for ( ; n; n = n.nextSibling ) { 26176 if ( n.nodeType === 1 && n !== elem ) { 26177 matched.push( n ); 26178 } 26179 } 26180 26181 return matched; 26182}; 26183 26184 26185var rneedsContext = jQuery.expr.match.needsContext; 26186 26187 26188 26189function nodeName( elem, name ) { 26190 26191 return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); 26192 26193}; 26194var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i ); 26195 26196 26197 26198// Implement the identical functionality for filter and not 26199function winnow( elements, qualifier, not ) { 26200 if ( isFunction( qualifier ) ) { 26201 return jQuery.grep( elements, function( elem, i ) { 26202 return !!qualifier.call( elem, i, elem ) !== not; 26203 } ); 26204 } 26205 26206 // Single element 26207 if ( qualifier.nodeType ) { 26208 return jQuery.grep( elements, function( elem ) { 26209 return ( elem === qualifier ) !== not; 26210 } ); 26211 } 26212 26213 // Arraylike of elements (jQuery, arguments, Array) 26214 if ( typeof qualifier !== "string" ) { 26215 return jQuery.grep( elements, function( elem ) { 26216 return ( indexOf.call( qualifier, elem ) > -1 ) !== not; 26217 } ); 26218 } 26219 26220 // Filtered directly for both simple and complex selectors 26221 return jQuery.filter( qualifier, elements, not ); 26222} 26223 26224jQuery.filter = function( expr, elems, not ) { 26225 var elem = elems[ 0 ]; 26226 26227 if ( not ) { 26228 expr = ":not(" + expr + ")"; 26229 } 26230 26231 if ( elems.length === 1 && elem.nodeType === 1 ) { 26232 return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : []; 26233 } 26234 26235 return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { 26236 return elem.nodeType === 1; 26237 } ) ); 26238}; 26239 26240jQuery.fn.extend( { 26241 find: function( selector ) { 26242 var i, ret, 26243 len = this.length, 26244 self = this; 26245 26246 if ( typeof selector !== "string" ) { 26247 return this.pushStack( jQuery( selector ).filter( function() { 26248 for ( i = 0; i < len; i++ ) { 26249 if ( jQuery.contains( self[ i ], this ) ) { 26250 return true; 26251 } 26252 } 26253 } ) ); 26254 } 26255 26256 ret = this.pushStack( [] ); 26257 26258 for ( i = 0; i < len; i++ ) { 26259 jQuery.find( selector, self[ i ], ret ); 26260 } 26261 26262 return len > 1 ? jQuery.uniqueSort( ret ) : ret; 26263 }, 26264 filter: function( selector ) { 26265 return this.pushStack( winnow( this, selector || [], false ) ); 26266 }, 26267 not: function( selector ) { 26268 return this.pushStack( winnow( this, selector || [], true ) ); 26269 }, 26270 is: function( selector ) { 26271 return !!winnow( 26272 this, 26273 26274 // If this is a positional/relative selector, check membership in the returned set 26275 // so $("p:first").is("p:last") won't return true for a doc with two "p". 26276 typeof selector === "string" && rneedsContext.test( selector ) ? 26277 jQuery( selector ) : 26278 selector || [], 26279 false 26280 ).length; 26281 } 26282} ); 26283 26284 26285// Initialize a jQuery object 26286 26287 26288// A central reference to the root jQuery(document) 26289var rootjQuery, 26290 26291 // A simple way to check for HTML strings 26292 // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) 26293 // Strict HTML recognition (#11290: must start with <) 26294 // Shortcut simple #id case for speed 26295 rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/, 26296 26297 init = jQuery.fn.init = function( selector, context, root ) { 26298 var match, elem; 26299 26300 // HANDLE: $(""), $(null), $(undefined), $(false) 26301 if ( !selector ) { 26302 return this; 26303 } 26304 26305 // Method init() accepts an alternate rootjQuery 26306 // so migrate can support jQuery.sub (gh-2101) 26307 root = root || rootjQuery; 26308 26309 // Handle HTML strings 26310 if ( typeof selector === "string" ) { 26311 if ( selector[ 0 ] === "<" && 26312 selector[ selector.length - 1 ] === ">" && 26313 selector.length >= 3 ) { 26314 26315 // Assume that strings that start and end with <> are HTML and skip the regex check 26316 match = [ null, selector, null ]; 26317 26318 } else { 26319 match = rquickExpr.exec( selector ); 26320 } 26321 26322 // Match html or make sure no context is specified for #id 26323 if ( match && ( match[ 1 ] || !context ) ) { 26324 26325 // HANDLE: $(html) -> $(array) 26326 if ( match[ 1 ] ) { 26327 context = context instanceof jQuery ? context[ 0 ] : context; 26328 26329 // Option to run scripts is true for back-compat 26330 // Intentionally let the error be thrown if parseHTML is not present 26331 jQuery.merge( this, jQuery.parseHTML( 26332 match[ 1 ], 26333 context && context.nodeType ? context.ownerDocument || context : document, 26334 true 26335 ) ); 26336 26337 // HANDLE: $(html, props) 26338 if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) { 26339 for ( match in context ) { 26340 26341 // Properties of context are called as methods if possible 26342 if ( isFunction( this[ match ] ) ) { 26343 this[ match ]( context[ match ] ); 26344 26345 // ...and otherwise set as attributes 26346 } else { 26347 this.attr( match, context[ match ] ); 26348 } 26349 } 26350 } 26351 26352 return this; 26353 26354 // HANDLE: $(#id) 26355 } else { 26356 elem = document.getElementById( match[ 2 ] ); 26357 26358 if ( elem ) { 26359 26360 // Inject the element directly into the jQuery object 26361 this[ 0 ] = elem; 26362 this.length = 1; 26363 } 26364 return this; 26365 } 26366 26367 // HANDLE: $(expr, $(...)) 26368 } else if ( !context || context.jquery ) { 26369 return ( context || root ).find( selector ); 26370 26371 // HANDLE: $(expr, context) 26372 // (which is just equivalent to: $(context).find(expr) 26373 } else { 26374 return this.constructor( context ).find( selector ); 26375 } 26376 26377 // HANDLE: $(DOMElement) 26378 } else if ( selector.nodeType ) { 26379 this[ 0 ] = selector; 26380 this.length = 1; 26381 return this; 26382 26383 // HANDLE: $(function) 26384 // Shortcut for document ready 26385 } else if ( isFunction( selector ) ) { 26386 return root.ready !== undefined ? 26387 root.ready( selector ) : 26388 26389 // Execute immediately if ready is not present 26390 selector( jQuery ); 26391 } 26392 26393 return jQuery.makeArray( selector, this ); 26394 }; 26395 26396// Give the init function the jQuery prototype for later instantiation 26397init.prototype = jQuery.fn; 26398 26399// Initialize central reference 26400rootjQuery = jQuery( document ); 26401 26402 26403var rparentsprev = /^(?:parents|prev(?:Until|All))/, 26404 26405 // Methods guaranteed to produce a unique set when starting from a unique set 26406 guaranteedUnique = { 26407 children: true, 26408 contents: true, 26409 next: true, 26410 prev: true 26411 }; 26412 26413jQuery.fn.extend( { 26414 has: function( target ) { 26415 var targets = jQuery( target, this ), 26416 l = targets.length; 26417 26418 return this.filter( function() { 26419 var i = 0; 26420 for ( ; i < l; i++ ) { 26421 if ( jQuery.contains( this, targets[ i ] ) ) { 26422 return true; 26423 } 26424 } 26425 } ); 26426 }, 26427 26428 closest: function( selectors, context ) { 26429 var cur, 26430 i = 0, 26431 l = this.length, 26432 matched = [], 26433 targets = typeof selectors !== "string" && jQuery( selectors ); 26434 26435 // Positional selectors never match, since there's no _selection_ context 26436 if ( !rneedsContext.test( selectors ) ) { 26437 for ( ; i < l; i++ ) { 26438 for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) { 26439 26440 // Always skip document fragments 26441 if ( cur.nodeType < 11 && ( targets ? 26442 targets.index( cur ) > -1 : 26443 26444 // Don't pass non-elements to Sizzle 26445 cur.nodeType === 1 && 26446 jQuery.find.matchesSelector( cur, selectors ) ) ) { 26447 26448 matched.push( cur ); 26449 break; 26450 } 26451 } 26452 } 26453 } 26454 26455 return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched ); 26456 }, 26457 26458 // Determine the position of an element within the set 26459 index: function( elem ) { 26460 26461 // No argument, return index in parent 26462 if ( !elem ) { 26463 return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1; 26464 } 26465 26466 // Index in selector 26467 if ( typeof elem === "string" ) { 26468 return indexOf.call( jQuery( elem ), this[ 0 ] ); 26469 } 26470 26471 // Locate the position of the desired element 26472 return indexOf.call( this, 26473 26474 // If it receives a jQuery object, the first element is used 26475 elem.jquery ? elem[ 0 ] : elem 26476 ); 26477 }, 26478 26479 add: function( selector, context ) { 26480 return this.pushStack( 26481 jQuery.uniqueSort( 26482 jQuery.merge( this.get(), jQuery( selector, context ) ) 26483 ) 26484 ); 26485 }, 26486 26487 addBack: function( selector ) { 26488 return this.add( selector == null ? 26489 this.prevObject : this.prevObject.filter( selector ) 26490 ); 26491 } 26492} ); 26493 26494function sibling( cur, dir ) { 26495 while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {} 26496 return cur; 26497} 26498 26499jQuery.each( { 26500 parent: function( elem ) { 26501 var parent = elem.parentNode; 26502 return parent && parent.nodeType !== 11 ? parent : null; 26503 }, 26504 parents: function( elem ) { 26505 return dir( elem, "parentNode" ); 26506 }, 26507 parentsUntil: function( elem, _i, until ) { 26508 return dir( elem, "parentNode", until ); 26509 }, 26510 next: function( elem ) { 26511 return sibling( elem, "nextSibling" ); 26512 }, 26513 prev: function( elem ) { 26514 return sibling( elem, "previousSibling" ); 26515 }, 26516 nextAll: function( elem ) { 26517 return dir( elem, "nextSibling" ); 26518 }, 26519 prevAll: function( elem ) { 26520 return dir( elem, "previousSibling" ); 26521 }, 26522 nextUntil: function( elem, _i, until ) { 26523 return dir( elem, "nextSibling", until ); 26524 }, 26525 prevUntil: function( elem, _i, until ) { 26526 return dir( elem, "previousSibling", until ); 26527 }, 26528 siblings: function( elem ) { 26529 return siblings( ( elem.parentNode || {} ).firstChild, elem ); 26530 }, 26531 children: function( elem ) { 26532 return siblings( elem.firstChild ); 26533 }, 26534 contents: function( elem ) { 26535 if ( elem.contentDocument != null && 26536 26537 // Support: IE 11+ 26538 // <object> elements with no `data` attribute has an object 26539 // `contentDocument` with a `null` prototype. 26540 getProto( elem.contentDocument ) ) { 26541 26542 return elem.contentDocument; 26543 } 26544 26545 // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only 26546 // Treat the template element as a regular one in browsers that 26547 // don't support it. 26548 if ( nodeName( elem, "template" ) ) { 26549 elem = elem.content || elem; 26550 } 26551 26552 return jQuery.merge( [], elem.childNodes ); 26553 } 26554}, function( name, fn ) { 26555 jQuery.fn[ name ] = function( until, selector ) { 26556 var matched = jQuery.map( this, fn, until ); 26557 26558 if ( name.slice( -5 ) !== "Until" ) { 26559 selector = until; 26560 } 26561 26562 if ( selector && typeof selector === "string" ) { 26563 matched = jQuery.filter( selector, matched ); 26564 } 26565 26566 if ( this.length > 1 ) { 26567 26568 // Remove duplicates 26569 if ( !guaranteedUnique[ name ] ) { 26570 jQuery.uniqueSort( matched ); 26571 } 26572 26573 // Reverse order for parents* and prev-derivatives 26574 if ( rparentsprev.test( name ) ) { 26575 matched.reverse(); 26576 } 26577 } 26578 26579 return this.pushStack( matched ); 26580 }; 26581} ); 26582var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g ); 26583 26584 26585 26586// Convert String-formatted options into Object-formatted ones 26587function createOptions( options ) { 26588 var object = {}; 26589 jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) { 26590 object[ flag ] = true; 26591 } ); 26592 return object; 26593} 26594 26595/* 26596 * Create a callback list using the following parameters: 26597 * 26598 * options: an optional list of space-separated options that will change how 26599 * the callback list behaves or a more traditional option object 26600 * 26601 * By default a callback list will act like an event callback list and can be 26602 * "fired" multiple times. 26603 * 26604 * Possible options: 26605 * 26606 * once: will ensure the callback list can only be fired once (like a Deferred) 26607 * 26608 * memory: will keep track of previous values and will call any callback added 26609 * after the list has been fired right away with the latest "memorized" 26610 * values (like a Deferred) 26611 * 26612 * unique: will ensure a callback can only be added once (no duplicate in the list) 26613 * 26614 * stopOnFalse: interrupt callings when a callback returns false 26615 * 26616 */ 26617jQuery.Callbacks = function( options ) { 26618 26619 // Convert options from String-formatted to Object-formatted if needed 26620 // (we check in cache first) 26621 options = typeof options === "string" ? 26622 createOptions( options ) : 26623 jQuery.extend( {}, options ); 26624 26625 var // Flag to know if list is currently firing 26626 firing, 26627 26628 // Last fire value for non-forgettable lists 26629 memory, 26630 26631 // Flag to know if list was already fired 26632 fired, 26633 26634 // Flag to prevent firing 26635 locked, 26636 26637 // Actual callback list 26638 list = [], 26639 26640 // Queue of execution data for repeatable lists 26641 queue = [], 26642 26643 // Index of currently firing callback (modified by add/remove as needed) 26644 firingIndex = -1, 26645 26646 // Fire callbacks 26647 fire = function() { 26648 26649 // Enforce single-firing 26650 locked = locked || options.once; 26651 26652 // Execute callbacks for all pending executions, 26653 // respecting firingIndex overrides and runtime changes 26654 fired = firing = true; 26655 for ( ; queue.length; firingIndex = -1 ) { 26656 memory = queue.shift(); 26657 while ( ++firingIndex < list.length ) { 26658 26659 // Run callback and check for early termination 26660 if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false && 26661 options.stopOnFalse ) { 26662 26663 // Jump to end and forget the data so .add doesn't re-fire 26664 firingIndex = list.length; 26665 memory = false; 26666 } 26667 } 26668 } 26669 26670 // Forget the data if we're done with it 26671 if ( !options.memory ) { 26672 memory = false; 26673 } 26674 26675 firing = false; 26676 26677 // Clean up if we're done firing for good 26678 if ( locked ) { 26679 26680 // Keep an empty list if we have data for future add calls 26681 if ( memory ) { 26682 list = []; 26683 26684 // Otherwise, this object is spent 26685 } else { 26686 list = ""; 26687 } 26688 } 26689 }, 26690 26691 // Actual Callbacks object 26692 self = { 26693 26694 // Add a callback or a collection of callbacks to the list 26695 add: function() { 26696 if ( list ) { 26697 26698 // If we have memory from a past run, we should fire after adding 26699 if ( memory && !firing ) { 26700 firingIndex = list.length - 1; 26701 queue.push( memory ); 26702 } 26703 26704 ( function add( args ) { 26705 jQuery.each( args, function( _, arg ) { 26706 if ( isFunction( arg ) ) { 26707 if ( !options.unique || !self.has( arg ) ) { 26708 list.push( arg ); 26709 } 26710 } else if ( arg && arg.length && toType( arg ) !== "string" ) { 26711 26712 // Inspect recursively 26713 add( arg ); 26714 } 26715 } ); 26716 } )( arguments ); 26717 26718 if ( memory && !firing ) { 26719 fire(); 26720 } 26721 } 26722 return this; 26723 }, 26724 26725 // Remove a callback from the list 26726 remove: function() { 26727 jQuery.each( arguments, function( _, arg ) { 26728 var index; 26729 while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { 26730 list.splice( index, 1 ); 26731 26732 // Handle firing indexes 26733 if ( index <= firingIndex ) { 26734 firingIndex--; 26735 } 26736 } 26737 } ); 26738 return this; 26739 }, 26740 26741 // Check if a given callback is in the list. 26742 // If no argument is given, return whether or not list has callbacks attached. 26743 has: function( fn ) { 26744 return fn ? 26745 jQuery.inArray( fn, list ) > -1 : 26746 list.length > 0; 26747 }, 26748 26749 // Remove all callbacks from the list 26750 empty: function() { 26751 if ( list ) { 26752 list = []; 26753 } 26754 return this; 26755 }, 26756 26757 // Disable .fire and .add 26758 // Abort any current/pending executions 26759 // Clear all callbacks and values 26760 disable: function() { 26761 locked = queue = []; 26762 list = memory = ""; 26763 return this; 26764 }, 26765 disabled: function() { 26766 return !list; 26767 }, 26768 26769 // Disable .fire 26770 // Also disable .add unless we have memory (since it would have no effect) 26771 // Abort any pending executions 26772 lock: function() { 26773 locked = queue = []; 26774 if ( !memory && !firing ) { 26775 list = memory = ""; 26776 } 26777 return this; 26778 }, 26779 locked: function() { 26780 return !!locked; 26781 }, 26782 26783 // Call all callbacks with the given context and arguments 26784 fireWith: function( context, args ) { 26785 if ( !locked ) { 26786 args = args || []; 26787 args = [ context, args.slice ? args.slice() : args ]; 26788 queue.push( args ); 26789 if ( !firing ) { 26790 fire(); 26791 } 26792 } 26793 return this; 26794 }, 26795 26796 // Call all the callbacks with the given arguments 26797 fire: function() { 26798 self.fireWith( this, arguments ); 26799 return this; 26800 }, 26801 26802 // To know if the callbacks have already been called at least once 26803 fired: function() { 26804 return !!fired; 26805 } 26806 }; 26807 26808 return self; 26809}; 26810 26811 26812function Identity( v ) { 26813 return v; 26814} 26815function Thrower( ex ) { 26816 throw ex; 26817} 26818 26819function adoptValue( value, resolve, reject, noValue ) { 26820 var method; 26821 26822 try { 26823 26824 // Check for promise aspect first to privilege synchronous behavior 26825 if ( value && isFunction( ( method = value.promise ) ) ) { 26826 method.call( value ).done( resolve ).fail( reject ); 26827 26828 // Other thenables 26829 } else if ( value && isFunction( ( method = value.then ) ) ) { 26830 method.call( value, resolve, reject ); 26831 26832 // Other non-thenables 26833 } else { 26834 26835 // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to integer: 26836 // * false: [ value ].slice( 0 ) => resolve( value ) 26837 // * true: [ value ].slice( 1 ) => resolve() 26838 resolve.apply( undefined, [ value ].slice( noValue ) ); 26839 } 26840 26841 // For Promises/A+, convert exceptions into rejections 26842 // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in 26843 // Deferred#then to conditionally suppress rejection. 26844 } catch ( value ) { 26845 26846 // Support: Android 4.0 only 26847 // Strict mode functions invoked without .call/.apply get global-object context 26848 reject.apply( undefined, [ value ] ); 26849 } 26850} 26851 26852jQuery.extend( { 26853 26854 Deferred: function( func ) { 26855 var tuples = [ 26856 26857 // action, add listener, callbacks, 26858 // ... .then handlers, argument index, [final state] 26859 [ "notify", "progress", jQuery.Callbacks( "memory" ), 26860 jQuery.Callbacks( "memory" ), 2 ], 26861 [ "resolve", "done", jQuery.Callbacks( "once memory" ), 26862 jQuery.Callbacks( "once memory" ), 0, "resolved" ], 26863 [ "reject", "fail", jQuery.Callbacks( "once memory" ), 26864 jQuery.Callbacks( "once memory" ), 1, "rejected" ] 26865 ], 26866 state = "pending", 26867 promise = { 26868 state: function() { 26869 return state; 26870 }, 26871 always: function() { 26872 deferred.done( arguments ).fail( arguments ); 26873 return this; 26874 }, 26875 "catch": function( fn ) { 26876 return promise.then( null, fn ); 26877 }, 26878 26879 // Keep pipe for back-compat 26880 pipe: function( /* fnDone, fnFail, fnProgress */ ) { 26881 var fns = arguments; 26882 26883 return jQuery.Deferred( function( newDefer ) { 26884 jQuery.each( tuples, function( _i, tuple ) { 26885 26886 // Map tuples (progress, done, fail) to arguments (done, fail, progress) 26887 var fn = isFunction( fns[ tuple[ 4 ] ] ) && fns[ tuple[ 4 ] ]; 26888 26889 // deferred.progress(function() { bind to newDefer or newDefer.notify }) 26890 // deferred.done(function() { bind to newDefer or newDefer.resolve }) 26891 // deferred.fail(function() { bind to newDefer or newDefer.reject }) 26892 deferred[ tuple[ 1 ] ]( function() { 26893 var returned = fn && fn.apply( this, arguments ); 26894 if ( returned && isFunction( returned.promise ) ) { 26895 returned.promise() 26896 .progress( newDefer.notify ) 26897 .done( newDefer.resolve ) 26898 .fail( newDefer.reject ); 26899 } else { 26900 newDefer[ tuple[ 0 ] + "With" ]( 26901 this, 26902 fn ? [ returned ] : arguments 26903 ); 26904 } 26905 } ); 26906 } ); 26907 fns = null; 26908 } ).promise(); 26909 }, 26910 then: function( onFulfilled, onRejected, onProgress ) { 26911 var maxDepth = 0; 26912 function resolve( depth, deferred, handler, special ) { 26913 return function() { 26914 var that = this, 26915 args = arguments, 26916 mightThrow = function() { 26917 var returned, then; 26918 26919 // Support: Promises/A+ section 2.3.3.3.3 26920 // https://promisesaplus.com/#point-59 26921 // Ignore double-resolution attempts 26922 if ( depth < maxDepth ) { 26923 return; 26924 } 26925 26926 returned = handler.apply( that, args ); 26927 26928 // Support: Promises/A+ section 2.3.1 26929 // https://promisesaplus.com/#point-48 26930 if ( returned === deferred.promise() ) { 26931 throw new TypeError( "Thenable self-resolution" ); 26932 } 26933 26934 // Support: Promises/A+ sections 2.3.3.1, 3.5 26935 // https://promisesaplus.com/#point-54 26936 // https://promisesaplus.com/#point-75 26937 // Retrieve `then` only once 26938 then = returned && 26939 26940 // Support: Promises/A+ section 2.3.4 26941 // https://promisesaplus.com/#point-64 26942 // Only check objects and functions for thenability 26943 ( typeof returned === "object" || 26944 typeof returned === "function" ) && 26945 returned.then; 26946 26947 // Handle a returned thenable 26948 if ( isFunction( then ) ) { 26949 26950 // Special processors (notify) just wait for resolution 26951 if ( special ) { 26952 then.call( 26953 returned, 26954 resolve( maxDepth, deferred, Identity, special ), 26955 resolve( maxDepth, deferred, Thrower, special ) 26956 ); 26957 26958 // Normal processors (resolve) also hook into progress 26959 } else { 26960 26961 // ...and disregard older resolution values 26962 maxDepth++; 26963 26964 then.call( 26965 returned, 26966 resolve( maxDepth, deferred, Identity, special ), 26967 resolve( maxDepth, deferred, Thrower, special ), 26968 resolve( maxDepth, deferred, Identity, 26969 deferred.notifyWith ) 26970 ); 26971 } 26972 26973 // Handle all other returned values 26974 } else { 26975 26976 // Only substitute handlers pass on context 26977 // and multiple values (non-spec behavior) 26978 if ( handler !== Identity ) { 26979 that = undefined; 26980 args = [ returned ]; 26981 } 26982 26983 // Process the value(s) 26984 // Default process is resolve 26985 ( special || deferred.resolveWith )( that, args ); 26986 } 26987 }, 26988 26989 // Only normal processors (resolve) catch and reject exceptions 26990 process = special ? 26991 mightThrow : 26992 function() { 26993 try { 26994 mightThrow(); 26995 } catch ( e ) { 26996 26997 if ( jQuery.Deferred.exceptionHook ) { 26998 jQuery.Deferred.exceptionHook( e, 26999 process.stackTrace ); 27000 } 27001 27002 // Support: Promises/A+ section 2.3.3.3.4.1 27003 // https://promisesaplus.com/#point-61 27004 // Ignore post-resolution exceptions 27005 if ( depth + 1 >= maxDepth ) { 27006 27007 // Only substitute handlers pass on context 27008 // and multiple values (non-spec behavior) 27009 if ( handler !== Thrower ) { 27010 that = undefined; 27011 args = [ e ]; 27012 } 27013 27014 deferred.rejectWith( that, args ); 27015 } 27016 } 27017 }; 27018 27019 // Support: Promises/A+ section 2.3.3.3.1 27020 // https://promisesaplus.com/#point-57 27021 // Re-resolve promises immediately to dodge false rejection from 27022 // subsequent errors 27023 if ( depth ) { 27024 process(); 27025 } else { 27026 27027 // Call an optional hook to record the stack, in case of exception 27028 // since it's otherwise lost when execution goes async 27029 if ( jQuery.Deferred.getStackHook ) { 27030 process.stackTrace = jQuery.Deferred.getStackHook(); 27031 } 27032 window.setTimeout( process ); 27033 } 27034 }; 27035 } 27036 27037 return jQuery.Deferred( function( newDefer ) { 27038 27039 // progress_handlers.add( ... ) 27040 tuples[ 0 ][ 3 ].add( 27041 resolve( 27042 0, 27043 newDefer, 27044 isFunction( onProgress ) ? 27045 onProgress : 27046 Identity, 27047 newDefer.notifyWith 27048 ) 27049 ); 27050 27051 // fulfilled_handlers.add( ... ) 27052 tuples[ 1 ][ 3 ].add( 27053 resolve( 27054 0, 27055 newDefer, 27056 isFunction( onFulfilled ) ? 27057 onFulfilled : 27058 Identity 27059 ) 27060 ); 27061 27062 // rejected_handlers.add( ... ) 27063 tuples[ 2 ][ 3 ].add( 27064 resolve( 27065 0, 27066 newDefer, 27067 isFunction( onRejected ) ? 27068 onRejected : 27069 Thrower 27070 ) 27071 ); 27072 } ).promise(); 27073 }, 27074 27075 // Get a promise for this deferred 27076 // If obj is provided, the promise aspect is added to the object 27077 promise: function( obj ) { 27078 return obj != null ? jQuery.extend( obj, promise ) : promise; 27079 } 27080 }, 27081 deferred = {}; 27082 27083 // Add list-specific methods 27084 jQuery.each( tuples, function( i, tuple ) { 27085 var list = tuple[ 2 ], 27086 stateString = tuple[ 5 ]; 27087 27088 // promise.progress = list.add 27089 // promise.done = list.add 27090 // promise.fail = list.add 27091 promise[ tuple[ 1 ] ] = list.add; 27092 27093 // Handle state 27094 if ( stateString ) { 27095 list.add( 27096 function() { 27097 27098 // state = "resolved" (i.e., fulfilled) 27099 // state = "rejected" 27100 state = stateString; 27101 }, 27102 27103 // rejected_callbacks.disable 27104 // fulfilled_callbacks.disable 27105 tuples[ 3 - i ][ 2 ].disable, 27106 27107 // rejected_handlers.disable 27108 // fulfilled_handlers.disable 27109 tuples[ 3 - i ][ 3 ].disable, 27110 27111 // progress_callbacks.lock 27112 tuples[ 0 ][ 2 ].lock, 27113 27114 // progress_handlers.lock 27115 tuples[ 0 ][ 3 ].lock 27116 ); 27117 } 27118 27119 // progress_handlers.fire 27120 // fulfilled_handlers.fire 27121 // rejected_handlers.fire 27122 list.add( tuple[ 3 ].fire ); 27123 27124 // deferred.notify = function() { deferred.notifyWith(...) } 27125 // deferred.resolve = function() { deferred.resolveWith(...) } 27126 // deferred.reject = function() { deferred.rejectWith(...) } 27127 deferred[ tuple[ 0 ] ] = function() { 27128 deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, arguments ); 27129 return this; 27130 }; 27131 27132 // deferred.notifyWith = list.fireWith 27133 // deferred.resolveWith = list.fireWith 27134 // deferred.rejectWith = list.fireWith 27135 deferred[ tuple[ 0 ] + "With" ] = list.fireWith; 27136 } ); 27137 27138 // Make the deferred a promise 27139 promise.promise( deferred ); 27140 27141 // Call given func if any 27142 if ( func ) { 27143 func.call( deferred, deferred ); 27144 } 27145 27146 // All done! 27147 return deferred; 27148 }, 27149 27150 // Deferred helper 27151 when: function( singleValue ) { 27152 var 27153 27154 // count of uncompleted subordinates 27155 remaining = arguments.length, 27156 27157 // count of unprocessed arguments 27158 i = remaining, 27159 27160 // subordinate fulfillment data 27161 resolveContexts = Array( i ), 27162 resolveValues = slice.call( arguments ), 27163 27164 // the master Deferred 27165 master = jQuery.Deferred(), 27166 27167 // subordinate callback factory 27168 updateFunc = function( i ) { 27169 return function( value ) { 27170 resolveContexts[ i ] = this; 27171 resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; 27172 if ( !( --remaining ) ) { 27173 master.resolveWith( resolveContexts, resolveValues ); 27174 } 27175 }; 27176 }; 27177 27178 // Single- and empty arguments are adopted like Promise.resolve 27179 if ( remaining <= 1 ) { 27180 adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject, 27181 !remaining ); 27182 27183 // Use .then() to unwrap secondary thenables (cf. gh-3000) 27184 if ( master.state() === "pending" || 27185 isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) { 27186 27187 return master.then(); 27188 } 27189 } 27190 27191 // Multiple arguments are aggregated like Promise.all array elements 27192 while ( i-- ) { 27193 adoptValue( resolveValues[ i ], updateFunc( i ), master.reject ); 27194 } 27195 27196 return master.promise(); 27197 } 27198} ); 27199 27200 27201// These usually indicate a programmer mistake during development, 27202// warn about them ASAP rather than swallowing them by default. 27203var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/; 27204 27205jQuery.Deferred.exceptionHook = function( error, stack ) { 27206 27207 // Support: IE 8 - 9 only 27208 // Console exists when dev tools are open, which can happen at any time 27209 if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) { 27210 window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack ); 27211 } 27212}; 27213 27214 27215 27216 27217jQuery.readyException = function( error ) { 27218 window.setTimeout( function() { 27219 throw error; 27220 } ); 27221}; 27222 27223 27224 27225 27226// The deferred used on DOM ready 27227var readyList = jQuery.Deferred(); 27228 27229jQuery.fn.ready = function( fn ) { 27230 27231 readyList 27232 .then( fn ) 27233 27234 // Wrap jQuery.readyException in a function so that the lookup 27235 // happens at the time of error handling instead of callback 27236 // registration. 27237 .catch( function( error ) { 27238 jQuery.readyException( error ); 27239 } ); 27240 27241 return this; 27242}; 27243 27244jQuery.extend( { 27245 27246 // Is the DOM ready to be used? Set to true once it occurs. 27247 isReady: false, 27248 27249 // A counter to track how many items to wait for before 27250 // the ready event fires. See #6781 27251 readyWait: 1, 27252 27253 // Handle when the DOM is ready 27254 ready: function( wait ) { 27255 27256 // Abort if there are pending holds or we're already ready 27257 if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { 27258 return; 27259 } 27260 27261 // Remember that the DOM is ready 27262 jQuery.isReady = true; 27263 27264 // If a normal DOM Ready event fired, decrement, and wait if need be 27265 if ( wait !== true && --jQuery.readyWait > 0 ) { 27266 return; 27267 } 27268 27269 // If there are functions bound, to execute 27270 readyList.resolveWith( document, [ jQuery ] ); 27271 } 27272} ); 27273 27274jQuery.ready.then = readyList.then; 27275 27276// The ready event handler and self cleanup method 27277function completed() { 27278 document.removeEventListener( "DOMContentLoaded", completed ); 27279 window.removeEventListener( "load", completed ); 27280 jQuery.ready(); 27281} 27282 27283// Catch cases where $(document).ready() is called 27284// after the browser event has already occurred. 27285// Support: IE <=9 - 10 only 27286// Older IE sometimes signals "interactive" too soon 27287if ( document.readyState === "complete" || 27288 ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) { 27289 27290 // Handle it asynchronously to allow scripts the opportunity to delay ready 27291 window.setTimeout( jQuery.ready ); 27292 27293} else { 27294 27295 // Use the handy event callback 27296 document.addEventListener( "DOMContentLoaded", completed ); 27297 27298 // A fallback to window.onload, that will always work 27299 window.addEventListener( "load", completed ); 27300} 27301 27302 27303 27304 27305// Multifunctional method to get and set values of a collection 27306// The value/s can optionally be executed if it's a function 27307var access = function( elems, fn, key, value, chainable, emptyGet, raw ) { 27308 var i = 0, 27309 len = elems.length, 27310 bulk = key == null; 27311 27312 // Sets many values 27313 if ( toType( key ) === "object" ) { 27314 chainable = true; 27315 for ( i in key ) { 27316 access( elems, fn, i, key[ i ], true, emptyGet, raw ); 27317 } 27318 27319 // Sets one value 27320 } else if ( value !== undefined ) { 27321 chainable = true; 27322 27323 if ( !isFunction( value ) ) { 27324 raw = true; 27325 } 27326 27327 if ( bulk ) { 27328 27329 // Bulk operations run against the entire set 27330 if ( raw ) { 27331 fn.call( elems, value ); 27332 fn = null; 27333 27334 // ...except when executing function values 27335 } else { 27336 bulk = fn; 27337 fn = function( elem, _key, value ) { 27338 return bulk.call( jQuery( elem ), value ); 27339 }; 27340 } 27341 } 27342 27343 if ( fn ) { 27344 for ( ; i < len; i++ ) { 27345 fn( 27346 elems[ i ], key, raw ? 27347 value : 27348 value.call( elems[ i ], i, fn( elems[ i ], key ) ) 27349 ); 27350 } 27351 } 27352 } 27353 27354 if ( chainable ) { 27355 return elems; 27356 } 27357 27358 // Gets 27359 if ( bulk ) { 27360 return fn.call( elems ); 27361 } 27362 27363 return len ? fn( elems[ 0 ], key ) : emptyGet; 27364}; 27365 27366 27367// Matches dashed string for camelizing 27368var rmsPrefix = /^-ms-/, 27369 rdashAlpha = /-([a-z])/g; 27370 27371// Used by camelCase as callback to replace() 27372function fcamelCase( _all, letter ) { 27373 return letter.toUpperCase(); 27374} 27375 27376// Convert dashed to camelCase; used by the css and data modules 27377// Support: IE <=9 - 11, Edge 12 - 15 27378// Microsoft forgot to hump their vendor prefix (#9572) 27379function camelCase( string ) { 27380 return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); 27381} 27382var acceptData = function( owner ) { 27383 27384 // Accepts only: 27385 // - Node 27386 // - Node.ELEMENT_NODE 27387 // - Node.DOCUMENT_NODE 27388 // - Object 27389 // - Any 27390 return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType ); 27391}; 27392 27393 27394 27395 27396function Data() { 27397 this.expando = jQuery.expando + Data.uid++; 27398} 27399 27400Data.uid = 1; 27401 27402Data.prototype = { 27403 27404 cache: function( owner ) { 27405 27406 // Check if the owner object already has a cache 27407 var value = owner[ this.expando ]; 27408 27409 // If not, create one 27410 if ( !value ) { 27411 value = {}; 27412 27413 // We can accept data for non-element nodes in modern browsers, 27414 // but we should not, see #8335. 27415 // Always return an empty object. 27416 if ( acceptData( owner ) ) { 27417 27418 // If it is a node unlikely to be stringify-ed or looped over 27419 // use plain assignment 27420 if ( owner.nodeType ) { 27421 owner[ this.expando ] = value; 27422 27423 // Otherwise secure it in a non-enumerable property 27424 // configurable must be true to allow the property to be 27425 // deleted when data is removed 27426 } else { 27427 Object.defineProperty( owner, this.expando, { 27428 value: value, 27429 configurable: true 27430 } ); 27431 } 27432 } 27433 } 27434 27435 return value; 27436 }, 27437 set: function( owner, data, value ) { 27438 var prop, 27439 cache = this.cache( owner ); 27440 27441 // Handle: [ owner, key, value ] args 27442 // Always use camelCase key (gh-2257) 27443 if ( typeof data === "string" ) { 27444 cache[ camelCase( data ) ] = value; 27445 27446 // Handle: [ owner, { properties } ] args 27447 } else { 27448 27449 // Copy the properties one-by-one to the cache object 27450 for ( prop in data ) { 27451 cache[ camelCase( prop ) ] = data[ prop ]; 27452 } 27453 } 27454 return cache; 27455 }, 27456 get: function( owner, key ) { 27457 return key === undefined ? 27458 this.cache( owner ) : 27459 27460 // Always use camelCase key (gh-2257) 27461 owner[ this.expando ] && owner[ this.expando ][ camelCase( key ) ]; 27462 }, 27463 access: function( owner, key, value ) { 27464 27465 // In cases where either: 27466 // 27467 // 1. No key was specified 27468 // 2. A string key was specified, but no value provided 27469 // 27470 // Take the "read" path and allow the get method to determine 27471 // which value to return, respectively either: 27472 // 27473 // 1. The entire cache object 27474 // 2. The data stored at the key 27475 // 27476 if ( key === undefined || 27477 ( ( key && typeof key === "string" ) && value === undefined ) ) { 27478 27479 return this.get( owner, key ); 27480 } 27481 27482 // When the key is not a string, or both a key and value 27483 // are specified, set or extend (existing objects) with either: 27484 // 27485 // 1. An object of properties 27486 // 2. A key and value 27487 // 27488 this.set( owner, key, value ); 27489 27490 // Since the "set" path can have two possible entry points 27491 // return the expected data based on which path was taken[*] 27492 return value !== undefined ? value : key; 27493 }, 27494 remove: function( owner, key ) { 27495 var i, 27496 cache = owner[ this.expando ]; 27497 27498 if ( cache === undefined ) { 27499 return; 27500 } 27501 27502 if ( key !== undefined ) { 27503 27504 // Support array or space separated string of keys 27505 if ( Array.isArray( key ) ) { 27506 27507 // If key is an array of keys... 27508 // We always set camelCase keys, so remove that. 27509 key = key.map( camelCase ); 27510 } else { 27511 key = camelCase( key ); 27512 27513 // If a key with the spaces exists, use it. 27514 // Otherwise, create an array by matching non-whitespace 27515 key = key in cache ? 27516 [ key ] : 27517 ( key.match( rnothtmlwhite ) || [] ); 27518 } 27519 27520 i = key.length; 27521 27522 while ( i-- ) { 27523 delete cache[ key[ i ] ]; 27524 } 27525 } 27526 27527 // Remove the expando if there's no more data 27528 if ( key === undefined || jQuery.isEmptyObject( cache ) ) { 27529 27530 // Support: Chrome <=35 - 45 27531 // Webkit & Blink performance suffers when deleting properties 27532 // from DOM nodes, so set to undefined instead 27533 // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted) 27534 if ( owner.nodeType ) { 27535 owner[ this.expando ] = undefined; 27536 } else { 27537 delete owner[ this.expando ]; 27538 } 27539 } 27540 }, 27541 hasData: function( owner ) { 27542 var cache = owner[ this.expando ]; 27543 return cache !== undefined && !jQuery.isEmptyObject( cache ); 27544 } 27545}; 27546var dataPriv = new Data(); 27547 27548var dataUser = new Data(); 27549 27550 27551 27552// Implementation Summary 27553// 27554// 1. Enforce API surface and semantic compatibility with 1.9.x branch 27555// 2. Improve the module's maintainability by reducing the storage 27556// paths to a single mechanism. 27557// 3. Use the same single mechanism to support "private" and "user" data. 27558// 4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData) 27559// 5. Avoid exposing implementation details on user objects (eg. expando properties) 27560// 6. Provide a clear path for implementation upgrade to WeakMap in 2014 27561 27562var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, 27563 rmultiDash = /[A-Z]/g; 27564 27565function getData( data ) { 27566 if ( data === "true" ) { 27567 return true; 27568 } 27569 27570 if ( data === "false" ) { 27571 return false; 27572 } 27573 27574 if ( data === "null" ) { 27575 return null; 27576 } 27577 27578 // Only convert to a number if it doesn't change the string 27579 if ( data === +data + "" ) { 27580 return +data; 27581 } 27582 27583 if ( rbrace.test( data ) ) { 27584 return JSON.parse( data ); 27585 } 27586 27587 return data; 27588} 27589 27590function dataAttr( elem, key, data ) { 27591 var name; 27592 27593 // If nothing was found internally, try to fetch any 27594 // data from the HTML5 data-* attribute 27595 if ( data === undefined && elem.nodeType === 1 ) { 27596 name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase(); 27597 data = elem.getAttribute( name ); 27598 27599 if ( typeof data === "string" ) { 27600 try { 27601 data = getData( data ); 27602 } catch ( e ) {} 27603 27604 // Make sure we set the data so it isn't changed later 27605 dataUser.set( elem, key, data ); 27606 } else { 27607 data = undefined; 27608 } 27609 } 27610 return data; 27611} 27612 27613jQuery.extend( { 27614 hasData: function( elem ) { 27615 return dataUser.hasData( elem ) || dataPriv.hasData( elem ); 27616 }, 27617 27618 data: function( elem, name, data ) { 27619 return dataUser.access( elem, name, data ); 27620 }, 27621 27622 removeData: function( elem, name ) { 27623 dataUser.remove( elem, name ); 27624 }, 27625 27626 // TODO: Now that all calls to _data and _removeData have been replaced 27627 // with direct calls to dataPriv methods, these can be deprecated. 27628 _data: function( elem, name, data ) { 27629 return dataPriv.access( elem, name, data ); 27630 }, 27631 27632 _removeData: function( elem, name ) { 27633 dataPriv.remove( elem, name ); 27634 } 27635} ); 27636 27637jQuery.fn.extend( { 27638 data: function( key, value ) { 27639 var i, name, data, 27640 elem = this[ 0 ], 27641 attrs = elem && elem.attributes; 27642 27643 // Gets all values 27644 if ( key === undefined ) { 27645 if ( this.length ) { 27646 data = dataUser.get( elem ); 27647 27648 if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) { 27649 i = attrs.length; 27650 while ( i-- ) { 27651 27652 // Support: IE 11 only 27653 // The attrs elements can be null (#14894) 27654 if ( attrs[ i ] ) { 27655 name = attrs[ i ].name; 27656 if ( name.indexOf( "data-" ) === 0 ) { 27657 name = camelCase( name.slice( 5 ) ); 27658 dataAttr( elem, name, data[ name ] ); 27659 } 27660 } 27661 } 27662 dataPriv.set( elem, "hasDataAttrs", true ); 27663 } 27664 } 27665 27666 return data; 27667 } 27668 27669 // Sets multiple values 27670 if ( typeof key === "object" ) { 27671 return this.each( function() { 27672 dataUser.set( this, key ); 27673 } ); 27674 } 27675 27676 return access( this, function( value ) { 27677 var data; 27678 27679 // The calling jQuery object (element matches) is not empty 27680 // (and therefore has an element appears at this[ 0 ]) and the 27681 // `value` parameter was not undefined. An empty jQuery object 27682 // will result in `undefined` for elem = this[ 0 ] which will 27683 // throw an exception if an attempt to read a data cache is made. 27684 if ( elem && value === undefined ) { 27685 27686 // Attempt to get data from the cache 27687 // The key will always be camelCased in Data 27688 data = dataUser.get( elem, key ); 27689 if ( data !== undefined ) { 27690 return data; 27691 } 27692 27693 // Attempt to "discover" the data in 27694 // HTML5 custom data-* attrs 27695 data = dataAttr( elem, key ); 27696 if ( data !== undefined ) { 27697 return data; 27698 } 27699 27700 // We tried really hard, but the data doesn't exist. 27701 return; 27702 } 27703 27704 // Set the data... 27705 this.each( function() { 27706 27707 // We always store the camelCased key 27708 dataUser.set( this, key, value ); 27709 } ); 27710 }, null, value, arguments.length > 1, null, true ); 27711 }, 27712 27713 removeData: function( key ) { 27714 return this.each( function() { 27715 dataUser.remove( this, key ); 27716 } ); 27717 } 27718} ); 27719 27720 27721jQuery.extend( { 27722 queue: function( elem, type, data ) { 27723 var queue; 27724 27725 if ( elem ) { 27726 type = ( type || "fx" ) + "queue"; 27727 queue = dataPriv.get( elem, type ); 27728 27729 // Speed up dequeue by getting out quickly if this is just a lookup 27730 if ( data ) { 27731 if ( !queue || Array.isArray( data ) ) { 27732 queue = dataPriv.access( elem, type, jQuery.makeArray( data ) ); 27733 } else { 27734 queue.push( data ); 27735 } 27736 } 27737 return queue || []; 27738 } 27739 }, 27740 27741 dequeue: function( elem, type ) { 27742 type = type || "fx"; 27743 27744 var queue = jQuery.queue( elem, type ), 27745 startLength = queue.length, 27746 fn = queue.shift(), 27747 hooks = jQuery._queueHooks( elem, type ), 27748 next = function() { 27749 jQuery.dequeue( elem, type ); 27750 }; 27751 27752 // If the fx queue is dequeued, always remove the progress sentinel 27753 if ( fn === "inprogress" ) { 27754 fn = queue.shift(); 27755 startLength--; 27756 } 27757 27758 if ( fn ) { 27759 27760 // Add a progress sentinel to prevent the fx queue from being 27761 // automatically dequeued 27762 if ( type === "fx" ) { 27763 queue.unshift( "inprogress" ); 27764 } 27765 27766 // Clear up the last queue stop function 27767 delete hooks.stop; 27768 fn.call( elem, next, hooks ); 27769 } 27770 27771 if ( !startLength && hooks ) { 27772 hooks.empty.fire(); 27773 } 27774 }, 27775 27776 // Not public - generate a queueHooks object, or return the current one 27777 _queueHooks: function( elem, type ) { 27778 var key = type + "queueHooks"; 27779 return dataPriv.get( elem, key ) || dataPriv.access( elem, key, { 27780 empty: jQuery.Callbacks( "once memory" ).add( function() { 27781 dataPriv.remove( elem, [ type + "queue", key ] ); 27782 } ) 27783 } ); 27784 } 27785} ); 27786 27787jQuery.fn.extend( { 27788 queue: function( type, data ) { 27789 var setter = 2; 27790 27791 if ( typeof type !== "string" ) { 27792 data = type; 27793 type = "fx"; 27794 setter--; 27795 } 27796 27797 if ( arguments.length < setter ) { 27798 return jQuery.queue( this[ 0 ], type ); 27799 } 27800 27801 return data === undefined ? 27802 this : 27803 this.each( function() { 27804 var queue = jQuery.queue( this, type, data ); 27805 27806 // Ensure a hooks for this queue 27807 jQuery._queueHooks( this, type ); 27808 27809 if ( type === "fx" && queue[ 0 ] !== "inprogress" ) { 27810 jQuery.dequeue( this, type ); 27811 } 27812 } ); 27813 }, 27814 dequeue: function( type ) { 27815 return this.each( function() { 27816 jQuery.dequeue( this, type ); 27817 } ); 27818 }, 27819 clearQueue: function( type ) { 27820 return this.queue( type || "fx", [] ); 27821 }, 27822 27823 // Get a promise resolved when queues of a certain type 27824 // are emptied (fx is the type by default) 27825 promise: function( type, obj ) { 27826 var tmp, 27827 count = 1, 27828 defer = jQuery.Deferred(), 27829 elements = this, 27830 i = this.length, 27831 resolve = function() { 27832 if ( !( --count ) ) { 27833 defer.resolveWith( elements, [ elements ] ); 27834 } 27835 }; 27836 27837 if ( typeof type !== "string" ) { 27838 obj = type; 27839 type = undefined; 27840 } 27841 type = type || "fx"; 27842 27843 while ( i-- ) { 27844 tmp = dataPriv.get( elements[ i ], type + "queueHooks" ); 27845 if ( tmp && tmp.empty ) { 27846 count++; 27847 tmp.empty.add( resolve ); 27848 } 27849 } 27850 resolve(); 27851 return defer.promise( obj ); 27852 } 27853} ); 27854var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source; 27855 27856var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ); 27857 27858 27859var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; 27860 27861var documentElement = document.documentElement; 27862 27863 27864 27865 var isAttached = function( elem ) { 27866 return jQuery.contains( elem.ownerDocument, elem ); 27867 }, 27868 composed = { composed: true }; 27869 27870 // Support: IE 9 - 11+, Edge 12 - 18+, iOS 10.0 - 10.2 only 27871 // Check attachment across shadow DOM boundaries when possible (gh-3504) 27872 // Support: iOS 10.0-10.2 only 27873 // Early iOS 10 versions support `attachShadow` but not `getRootNode`, 27874 // leading to errors. We need to check for `getRootNode`. 27875 if ( documentElement.getRootNode ) { 27876 isAttached = function( elem ) { 27877 return jQuery.contains( elem.ownerDocument, elem ) || 27878 elem.getRootNode( composed ) === elem.ownerDocument; 27879 }; 27880 } 27881var isHiddenWithinTree = function( elem, el ) { 27882 27883 // isHiddenWithinTree might be called from jQuery#filter function; 27884 // in that case, element will be second argument 27885 elem = el || elem; 27886 27887 // Inline style trumps all 27888 return elem.style.display === "none" || 27889 elem.style.display === "" && 27890 27891 // Otherwise, check computed style 27892 // Support: Firefox <=43 - 45 27893 // Disconnected elements can have computed display: none, so first confirm that elem is 27894 // in the document. 27895 isAttached( elem ) && 27896 27897 jQuery.css( elem, "display" ) === "none"; 27898 }; 27899 27900 27901 27902function adjustCSS( elem, prop, valueParts, tween ) { 27903 var adjusted, scale, 27904 maxIterations = 20, 27905 currentValue = tween ? 27906 function() { 27907 return tween.cur(); 27908 } : 27909 function() { 27910 return jQuery.css( elem, prop, "" ); 27911 }, 27912 initial = currentValue(), 27913 unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), 27914 27915 // Starting value computation is required for potential unit mismatches 27916 initialInUnit = elem.nodeType && 27917 ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) && 27918 rcssNum.exec( jQuery.css( elem, prop ) ); 27919 27920 if ( initialInUnit && initialInUnit[ 3 ] !== unit ) { 27921 27922 // Support: Firefox <=54 27923 // Halve the iteration target value to prevent interference from CSS upper bounds (gh-2144) 27924 initial = initial / 2; 27925 27926 // Trust units reported by jQuery.css 27927 unit = unit || initialInUnit[ 3 ]; 27928 27929 // Iteratively approximate from a nonzero starting point 27930 initialInUnit = +initial || 1; 27931 27932 while ( maxIterations-- ) { 27933 27934 // Evaluate and update our best guess (doubling guesses that zero out). 27935 // Finish if the scale equals or crosses 1 (making the old*new product non-positive). 27936 jQuery.style( elem, prop, initialInUnit + unit ); 27937 if ( ( 1 - scale ) * ( 1 - ( scale = currentValue() / initial || 0.5 ) ) <= 0 ) { 27938 maxIterations = 0; 27939 } 27940 initialInUnit = initialInUnit / scale; 27941 27942 } 27943 27944 initialInUnit = initialInUnit * 2; 27945 jQuery.style( elem, prop, initialInUnit + unit ); 27946 27947 // Make sure we update the tween properties later on 27948 valueParts = valueParts || []; 27949 } 27950 27951 if ( valueParts ) { 27952 initialInUnit = +initialInUnit || +initial || 0; 27953 27954 // Apply relative offset (+=/-=) if specified 27955 adjusted = valueParts[ 1 ] ? 27956 initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] : 27957 +valueParts[ 2 ]; 27958 if ( tween ) { 27959 tween.unit = unit; 27960 tween.start = initialInUnit; 27961 tween.end = adjusted; 27962 } 27963 } 27964 return adjusted; 27965} 27966 27967 27968var defaultDisplayMap = {}; 27969 27970function getDefaultDisplay( elem ) { 27971 var temp, 27972 doc = elem.ownerDocument, 27973 nodeName = elem.nodeName, 27974 display = defaultDisplayMap[ nodeName ]; 27975 27976 if ( display ) { 27977 return display; 27978 } 27979 27980 temp = doc.body.appendChild( doc.createElement( nodeName ) ); 27981 display = jQuery.css( temp, "display" ); 27982 27983 temp.parentNode.removeChild( temp ); 27984 27985 if ( display === "none" ) { 27986 display = "block"; 27987 } 27988 defaultDisplayMap[ nodeName ] = display; 27989 27990 return display; 27991} 27992 27993function showHide( elements, show ) { 27994 var display, elem, 27995 values = [], 27996 index = 0, 27997 length = elements.length; 27998 27999 // Determine new display value for elements that need to change 28000 for ( ; index < length; index++ ) { 28001 elem = elements[ index ]; 28002 if ( !elem.style ) { 28003 continue; 28004 } 28005 28006 display = elem.style.display; 28007 if ( show ) { 28008 28009 // Since we force visibility upon cascade-hidden elements, an immediate (and slow) 28010 // check is required in this first loop unless we have a nonempty display value (either 28011 // inline or about-to-be-restored) 28012 if ( display === "none" ) { 28013 values[ index ] = dataPriv.get( elem, "display" ) || null; 28014 if ( !values[ index ] ) { 28015 elem.style.display = ""; 28016 } 28017 } 28018 if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) { 28019 values[ index ] = getDefaultDisplay( elem ); 28020 } 28021 } else { 28022 if ( display !== "none" ) { 28023 values[ index ] = "none"; 28024 28025 // Remember what we're overwriting 28026 dataPriv.set( elem, "display", display ); 28027 } 28028 } 28029 } 28030 28031 // Set the display of the elements in a second loop to avoid constant reflow 28032 for ( index = 0; index < length; index++ ) { 28033 if ( values[ index ] != null ) { 28034 elements[ index ].style.display = values[ index ]; 28035 } 28036 } 28037 28038 return elements; 28039} 28040 28041jQuery.fn.extend( { 28042 show: function() { 28043 return showHide( this, true ); 28044 }, 28045 hide: function() { 28046 return showHide( this ); 28047 }, 28048 toggle: function( state ) { 28049 if ( typeof state === "boolean" ) { 28050 return state ? this.show() : this.hide(); 28051 } 28052 28053 return this.each( function() { 28054 if ( isHiddenWithinTree( this ) ) { 28055 jQuery( this ).show(); 28056 } else { 28057 jQuery( this ).hide(); 28058 } 28059 } ); 28060 } 28061} ); 28062var rcheckableType = ( /^(?:checkbox|radio)$/i ); 28063 28064var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]*)/i ); 28065 28066var rscriptType = ( /^$|^module$|\/(?:java|ecma)script/i ); 28067 28068 28069 28070( function() { 28071 var fragment = document.createDocumentFragment(), 28072 div = fragment.appendChild( document.createElement( "div" ) ), 28073 input = document.createElement( "input" ); 28074 28075 // Support: Android 4.0 - 4.3 only 28076 // Check state lost if the name is set (#11217) 28077 // Support: Windows Web Apps (WWA) 28078 // `name` and `type` must use .setAttribute for WWA (#14901) 28079 input.setAttribute( "type", "radio" ); 28080 input.setAttribute( "checked", "checked" ); 28081 input.setAttribute( "name", "t" ); 28082 28083 div.appendChild( input ); 28084 28085 // Support: Android <=4.1 only 28086 // Older WebKit doesn't clone checked state correctly in fragments 28087 support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; 28088 28089 // Support: IE <=11 only 28090 // Make sure textarea (and checkbox) defaultValue is properly cloned 28091 div.innerHTML = "<textarea>x</textarea>"; 28092 support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; 28093 28094 // Support: IE <=9 only 28095 // IE <=9 replaces <option> tags with their contents when inserted outside of 28096 // the select element. 28097 div.innerHTML = "<option></option>"; 28098 support.option = !!div.lastChild; 28099} )(); 28100 28101 28102// We have to close these tags to support XHTML (#13200) 28103var wrapMap = { 28104 28105 // XHTML parsers do not magically insert elements in the 28106 // same way that tag soup parsers do. So we cannot shorten 28107 // this by omitting <tbody> or other required elements. 28108 thead: [ 1, "<table>", "</table>" ], 28109 col: [ 2, "<table><colgroup>", "</colgroup></table>" ], 28110 tr: [ 2, "<table><tbody>", "</tbody></table>" ], 28111 td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], 28112 28113 _default: [ 0, "", "" ] 28114}; 28115 28116wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; 28117wrapMap.th = wrapMap.td; 28118 28119// Support: IE <=9 only 28120if ( !support.option ) { 28121 wrapMap.optgroup = wrapMap.option = [ 1, "<select multiple='multiple'>", "</select>" ]; 28122} 28123 28124 28125function getAll( context, tag ) { 28126 28127 // Support: IE <=9 - 11 only 28128 // Use typeof to avoid zero-argument method invocation on host objects (#15151) 28129 var ret; 28130 28131 if ( typeof context.getElementsByTagName !== "undefined" ) { 28132 ret = context.getElementsByTagName( tag || "*" ); 28133 28134 } else if ( typeof context.querySelectorAll !== "undefined" ) { 28135 ret = context.querySelectorAll( tag || "*" ); 28136 28137 } else { 28138 ret = []; 28139 } 28140 28141 if ( tag === undefined || tag && nodeName( context, tag ) ) { 28142 return jQuery.merge( [ context ], ret ); 28143 } 28144 28145 return ret; 28146} 28147 28148 28149// Mark scripts as having already been evaluated 28150function setGlobalEval( elems, refElements ) { 28151 var i = 0, 28152 l = elems.length; 28153 28154 for ( ; i < l; i++ ) { 28155 dataPriv.set( 28156 elems[ i ], 28157 "globalEval", 28158 !refElements || dataPriv.get( refElements[ i ], "globalEval" ) 28159 ); 28160 } 28161} 28162 28163 28164var rhtml = /<|&#?\w+;/; 28165 28166function buildFragment( elems, context, scripts, selection, ignored ) { 28167 var elem, tmp, tag, wrap, attached, j, 28168 fragment = context.createDocumentFragment(), 28169 nodes = [], 28170 i = 0, 28171 l = elems.length; 28172 28173 for ( ; i < l; i++ ) { 28174 elem = elems[ i ]; 28175 28176 if ( elem || elem === 0 ) { 28177 28178 // Add nodes directly 28179 if ( toType( elem ) === "object" ) { 28180 28181 // Support: Android <=4.0 only, PhantomJS 1 only 28182 // push.apply(_, arraylike) throws on ancient WebKit 28183 jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); 28184 28185 // Convert non-html into a text node 28186 } else if ( !rhtml.test( elem ) ) { 28187 nodes.push( context.createTextNode( elem ) ); 28188 28189 // Convert html into DOM nodes 28190 } else { 28191 tmp = tmp || fragment.appendChild( context.createElement( "div" ) ); 28192 28193 // Deserialize a standard representation 28194 tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase(); 28195 wrap = wrapMap[ tag ] || wrapMap._default; 28196 tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ]; 28197 28198 // Descend through wrappers to the right content 28199 j = wrap[ 0 ]; 28200 while ( j-- ) { 28201 tmp = tmp.lastChild; 28202 } 28203 28204 // Support: Android <=4.0 only, PhantomJS 1 only 28205 // push.apply(_, arraylike) throws on ancient WebKit 28206 jQuery.merge( nodes, tmp.childNodes ); 28207 28208 // Remember the top-level container 28209 tmp = fragment.firstChild; 28210 28211 // Ensure the created nodes are orphaned (#12392) 28212 tmp.textContent = ""; 28213 } 28214 } 28215 } 28216 28217 // Remove wrapper from fragment 28218 fragment.textContent = ""; 28219 28220 i = 0; 28221 while ( ( elem = nodes[ i++ ] ) ) { 28222 28223 // Skip elements already in the context collection (trac-4087) 28224 if ( selection && jQuery.inArray( elem, selection ) > -1 ) { 28225 if ( ignored ) { 28226 ignored.push( elem ); 28227 } 28228 continue; 28229 } 28230 28231 attached = isAttached( elem ); 28232 28233 // Append to fragment 28234 tmp = getAll( fragment.appendChild( elem ), "script" ); 28235 28236 // Preserve script evaluation history 28237 if ( attached ) { 28238 setGlobalEval( tmp ); 28239 } 28240 28241 // Capture executables 28242 if ( scripts ) { 28243 j = 0; 28244 while ( ( elem = tmp[ j++ ] ) ) { 28245 if ( rscriptType.test( elem.type || "" ) ) { 28246 scripts.push( elem ); 28247 } 28248 } 28249 } 28250 } 28251 28252 return fragment; 28253} 28254 28255 28256var 28257 rkeyEvent = /^key/, 28258 rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/, 28259 rtypenamespace = /^([^.]*)(?:\.(.+)|)/; 28260 28261function returnTrue() { 28262 return true; 28263} 28264 28265function returnFalse() { 28266 return false; 28267} 28268 28269// Support: IE <=9 - 11+ 28270// focus() and blur() are asynchronous, except when they are no-op. 28271// So expect focus to be synchronous when the element is already active, 28272// and blur to be synchronous when the element is not already active. 28273// (focus and blur are always synchronous in other supported browsers, 28274// this just defines when we can count on it). 28275function expectSync( elem, type ) { 28276 return ( elem === safeActiveElement() ) === ( type === "focus" ); 28277} 28278 28279// Support: IE <=9 only 28280// Accessing document.activeElement can throw unexpectedly 28281// https://bugs.jquery.com/ticket/13393 28282function safeActiveElement() { 28283 try { 28284 return document.activeElement; 28285 } catch ( err ) { } 28286} 28287 28288function on( elem, types, selector, data, fn, one ) { 28289 var origFn, type; 28290 28291 // Types can be a map of types/handlers 28292 if ( typeof types === "object" ) { 28293 28294 // ( types-Object, selector, data ) 28295 if ( typeof selector !== "string" ) { 28296 28297 // ( types-Object, data ) 28298 data = data || selector; 28299 selector = undefined; 28300 } 28301 for ( type in types ) { 28302 on( elem, type, selector, data, types[ type ], one ); 28303 } 28304 return elem; 28305 } 28306 28307 if ( data == null && fn == null ) { 28308 28309 // ( types, fn ) 28310 fn = selector; 28311 data = selector = undefined; 28312 } else if ( fn == null ) { 28313 if ( typeof selector === "string" ) { 28314 28315 // ( types, selector, fn ) 28316 fn = data; 28317 data = undefined; 28318 } else { 28319 28320 // ( types, data, fn ) 28321 fn = data; 28322 data = selector; 28323 selector = undefined; 28324 } 28325 } 28326 if ( fn === false ) { 28327 fn = returnFalse; 28328 } else if ( !fn ) { 28329 return elem; 28330 } 28331 28332 if ( one === 1 ) { 28333 origFn = fn; 28334 fn = function( event ) { 28335 28336 // Can use an empty set, since event contains the info 28337 jQuery().off( event ); 28338 return origFn.apply( this, arguments ); 28339 }; 28340 28341 // Use same guid so caller can remove using origFn 28342 fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); 28343 } 28344 return elem.each( function() { 28345 jQuery.event.add( this, types, fn, data, selector ); 28346 } ); 28347} 28348 28349/* 28350 * Helper functions for managing events -- not part of the public interface. 28351 * Props to Dean Edwards' addEvent library for many of the ideas. 28352 */ 28353jQuery.event = { 28354 28355 global: {}, 28356 28357 add: function( elem, types, handler, data, selector ) { 28358 28359 var handleObjIn, eventHandle, tmp, 28360 events, t, handleObj, 28361 special, handlers, type, namespaces, origType, 28362 elemData = dataPriv.get( elem ); 28363 28364 // Only attach events to objects that accept data 28365 if ( !acceptData( elem ) ) { 28366 return; 28367 } 28368 28369 // Caller can pass in an object of custom data in lieu of the handler 28370 if ( handler.handler ) { 28371 handleObjIn = handler; 28372 handler = handleObjIn.handler; 28373 selector = handleObjIn.selector; 28374 } 28375 28376 // Ensure that invalid selectors throw exceptions at attach time 28377 // Evaluate against documentElement in case elem is a non-element node (e.g., document) 28378 if ( selector ) { 28379 jQuery.find.matchesSelector( documentElement, selector ); 28380 } 28381 28382 // Make sure that the handler has a unique ID, used to find/remove it later 28383 if ( !handler.guid ) { 28384 handler.guid = jQuery.guid++; 28385 } 28386 28387 // Init the element's event structure and main handler, if this is the first 28388 if ( !( events = elemData.events ) ) { 28389 events = elemData.events = Object.create( null ); 28390 } 28391 if ( !( eventHandle = elemData.handle ) ) { 28392 eventHandle = elemData.handle = function( e ) { 28393 28394 // Discard the second event of a jQuery.event.trigger() and 28395 // when an event is called after a page has unloaded 28396 return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? 28397 jQuery.event.dispatch.apply( elem, arguments ) : undefined; 28398 }; 28399 } 28400 28401 // Handle multiple events separated by a space 28402 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 28403 t = types.length; 28404 while ( t-- ) { 28405 tmp = rtypenamespace.exec( types[ t ] ) || []; 28406 type = origType = tmp[ 1 ]; 28407 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 28408 28409 // There *must* be a type, no attaching namespace-only handlers 28410 if ( !type ) { 28411 continue; 28412 } 28413 28414 // If event changes its type, use the special event handlers for the changed type 28415 special = jQuery.event.special[ type ] || {}; 28416 28417 // If selector defined, determine special event api type, otherwise given type 28418 type = ( selector ? special.delegateType : special.bindType ) || type; 28419 28420 // Update special based on newly reset type 28421 special = jQuery.event.special[ type ] || {}; 28422 28423 // handleObj is passed to all event handlers 28424 handleObj = jQuery.extend( { 28425 type: type, 28426 origType: origType, 28427 data: data, 28428 handler: handler, 28429 guid: handler.guid, 28430 selector: selector, 28431 needsContext: selector && jQuery.expr.match.needsContext.test( selector ), 28432 namespace: namespaces.join( "." ) 28433 }, handleObjIn ); 28434 28435 // Init the event handler queue if we're the first 28436 if ( !( handlers = events[ type ] ) ) { 28437 handlers = events[ type ] = []; 28438 handlers.delegateCount = 0; 28439 28440 // Only use addEventListener if the special events handler returns false 28441 if ( !special.setup || 28442 special.setup.call( elem, data, namespaces, eventHandle ) === false ) { 28443 28444 if ( elem.addEventListener ) { 28445 elem.addEventListener( type, eventHandle ); 28446 } 28447 } 28448 } 28449 28450 if ( special.add ) { 28451 special.add.call( elem, handleObj ); 28452 28453 if ( !handleObj.handler.guid ) { 28454 handleObj.handler.guid = handler.guid; 28455 } 28456 } 28457 28458 // Add to the element's handler list, delegates in front 28459 if ( selector ) { 28460 handlers.splice( handlers.delegateCount++, 0, handleObj ); 28461 } else { 28462 handlers.push( handleObj ); 28463 } 28464 28465 // Keep track of which events have ever been used, for event optimization 28466 jQuery.event.global[ type ] = true; 28467 } 28468 28469 }, 28470 28471 // Detach an event or set of events from an element 28472 remove: function( elem, types, handler, selector, mappedTypes ) { 28473 28474 var j, origCount, tmp, 28475 events, t, handleObj, 28476 special, handlers, type, namespaces, origType, 28477 elemData = dataPriv.hasData( elem ) && dataPriv.get( elem ); 28478 28479 if ( !elemData || !( events = elemData.events ) ) { 28480 return; 28481 } 28482 28483 // Once for each type.namespace in types; type may be omitted 28484 types = ( types || "" ).match( rnothtmlwhite ) || [ "" ]; 28485 t = types.length; 28486 while ( t-- ) { 28487 tmp = rtypenamespace.exec( types[ t ] ) || []; 28488 type = origType = tmp[ 1 ]; 28489 namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort(); 28490 28491 // Unbind all events (on this namespace, if provided) for the element 28492 if ( !type ) { 28493 for ( type in events ) { 28494 jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); 28495 } 28496 continue; 28497 } 28498 28499 special = jQuery.event.special[ type ] || {}; 28500 type = ( selector ? special.delegateType : special.bindType ) || type; 28501 handlers = events[ type ] || []; 28502 tmp = tmp[ 2 ] && 28503 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ); 28504 28505 // Remove matching events 28506 origCount = j = handlers.length; 28507 while ( j-- ) { 28508 handleObj = handlers[ j ]; 28509 28510 if ( ( mappedTypes || origType === handleObj.origType ) && 28511 ( !handler || handler.guid === handleObj.guid ) && 28512 ( !tmp || tmp.test( handleObj.namespace ) ) && 28513 ( !selector || selector === handleObj.selector || 28514 selector === "**" && handleObj.selector ) ) { 28515 handlers.splice( j, 1 ); 28516 28517 if ( handleObj.selector ) { 28518 handlers.delegateCount--; 28519 } 28520 if ( special.remove ) { 28521 special.remove.call( elem, handleObj ); 28522 } 28523 } 28524 } 28525 28526 // Remove generic event handler if we removed something and no more handlers exist 28527 // (avoids potential for endless recursion during removal of special event handlers) 28528 if ( origCount && !handlers.length ) { 28529 if ( !special.teardown || 28530 special.teardown.call( elem, namespaces, elemData.handle ) === false ) { 28531 28532 jQuery.removeEvent( elem, type, elemData.handle ); 28533 } 28534 28535 delete events[ type ]; 28536 } 28537 } 28538 28539 // Remove data and the expando if it's no longer used 28540 if ( jQuery.isEmptyObject( events ) ) { 28541 dataPriv.remove( elem, "handle events" ); 28542 } 28543 }, 28544 28545 dispatch: function( nativeEvent ) { 28546 28547 var i, j, ret, matched, handleObj, handlerQueue, 28548 args = new Array( arguments.length ), 28549 28550 // Make a writable jQuery.Event from the native event object 28551 event = jQuery.event.fix( nativeEvent ), 28552 28553 handlers = ( 28554 dataPriv.get( this, "events" ) || Object.create( null ) 28555 )[ event.type ] || [], 28556 special = jQuery.event.special[ event.type ] || {}; 28557 28558 // Use the fix-ed jQuery.Event rather than the (read-only) native event 28559 args[ 0 ] = event; 28560 28561 for ( i = 1; i < arguments.length; i++ ) { 28562 args[ i ] = arguments[ i ]; 28563 } 28564 28565 event.delegateTarget = this; 28566 28567 // Call the preDispatch hook for the mapped type, and let it bail if desired 28568 if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { 28569 return; 28570 } 28571 28572 // Determine handlers 28573 handlerQueue = jQuery.event.handlers.call( this, event, handlers ); 28574 28575 // Run delegates first; they may want to stop propagation beneath us 28576 i = 0; 28577 while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) { 28578 event.currentTarget = matched.elem; 28579 28580 j = 0; 28581 while ( ( handleObj = matched.handlers[ j++ ] ) && 28582 !event.isImmediatePropagationStopped() ) { 28583 28584 // If the event is namespaced, then each handler is only invoked if it is 28585 // specially universal or its namespaces are a superset of the event's. 28586 if ( !event.rnamespace || handleObj.namespace === false || 28587 event.rnamespace.test( handleObj.namespace ) ) { 28588 28589 event.handleObj = handleObj; 28590 event.data = handleObj.data; 28591 28592 ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle || 28593 handleObj.handler ).apply( matched.elem, args ); 28594 28595 if ( ret !== undefined ) { 28596 if ( ( event.result = ret ) === false ) { 28597 event.preventDefault(); 28598 event.stopPropagation(); 28599 } 28600 } 28601 } 28602 } 28603 } 28604 28605 // Call the postDispatch hook for the mapped type 28606 if ( special.postDispatch ) { 28607 special.postDispatch.call( this, event ); 28608 } 28609 28610 return event.result; 28611 }, 28612 28613 handlers: function( event, handlers ) { 28614 var i, handleObj, sel, matchedHandlers, matchedSelectors, 28615 handlerQueue = [], 28616 delegateCount = handlers.delegateCount, 28617 cur = event.target; 28618 28619 // Find delegate handlers 28620 if ( delegateCount && 28621 28622 // Support: IE <=9 28623 // Black-hole SVG <use> instance trees (trac-13180) 28624 cur.nodeType && 28625 28626 // Support: Firefox <=42 28627 // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861) 28628 // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click 28629 // Support: IE 11 only 28630 // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343) 28631 !( event.type === "click" && event.button >= 1 ) ) { 28632 28633 for ( ; cur !== this; cur = cur.parentNode || this ) { 28634 28635 // Don't check non-elements (#13208) 28636 // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) 28637 if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true ) ) { 28638 matchedHandlers = []; 28639 matchedSelectors = {}; 28640 for ( i = 0; i < delegateCount; i++ ) { 28641 handleObj = handlers[ i ]; 28642 28643 // Don't conflict with Object.prototype properties (#13203) 28644 sel = handleObj.selector + " "; 28645 28646 if ( matchedSelectors[ sel ] === undefined ) { 28647 matchedSelectors[ sel ] = handleObj.needsContext ? 28648 jQuery( sel, this ).index( cur ) > -1 : 28649 jQuery.find( sel, this, null, [ cur ] ).length; 28650 } 28651 if ( matchedSelectors[ sel ] ) { 28652 matchedHandlers.push( handleObj ); 28653 } 28654 } 28655 if ( matchedHandlers.length ) { 28656 handlerQueue.push( { elem: cur, handlers: matchedHandlers } ); 28657 } 28658 } 28659 } 28660 } 28661 28662 // Add the remaining (directly-bound) handlers 28663 cur = this; 28664 if ( delegateCount < handlers.length ) { 28665 handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } ); 28666 } 28667 28668 return handlerQueue; 28669 }, 28670 28671 addProp: function( name, hook ) { 28672 Object.defineProperty( jQuery.Event.prototype, name, { 28673 enumerable: true, 28674 configurable: true, 28675 28676 get: isFunction( hook ) ? 28677 function() { 28678 if ( this.originalEvent ) { 28679 return hook( this.originalEvent ); 28680 } 28681 } : 28682 function() { 28683 if ( this.originalEvent ) { 28684 return this.originalEvent[ name ]; 28685 } 28686 }, 28687 28688 set: function( value ) { 28689 Object.defineProperty( this, name, { 28690 enumerable: true, 28691 configurable: true, 28692 writable: true, 28693 value: value 28694 } ); 28695 } 28696 } ); 28697 }, 28698 28699 fix: function( originalEvent ) { 28700 return originalEvent[ jQuery.expando ] ? 28701 originalEvent : 28702 new jQuery.Event( originalEvent ); 28703 }, 28704 28705 special: { 28706 load: { 28707 28708 // Prevent triggered image.load events from bubbling to window.load 28709 noBubble: true 28710 }, 28711 click: { 28712 28713 // Utilize native event to ensure correct state for checkable inputs 28714 setup: function( data ) { 28715 28716 // For mutual compressibility with _default, replace `this` access with a local var. 28717 // `|| data` is dead code meant only to preserve the variable through minification. 28718 var el = this || data; 28719 28720 // Claim the first handler 28721 if ( rcheckableType.test( el.type ) && 28722 el.click && nodeName( el, "input" ) ) { 28723 28724 // dataPriv.set( el, "click", ... ) 28725 leverageNative( el, "click", returnTrue ); 28726 } 28727 28728 // Return false to allow normal processing in the caller 28729 return false; 28730 }, 28731 trigger: function( data ) { 28732 28733 // For mutual compressibility with _default, replace `this` access with a local var. 28734 // `|| data` is dead code meant only to preserve the variable through minification. 28735 var el = this || data; 28736 28737 // Force setup before triggering a click 28738 if ( rcheckableType.test( el.type ) && 28739 el.click && nodeName( el, "input" ) ) { 28740 28741 leverageNative( el, "click" ); 28742 } 28743 28744 // Return non-false to allow normal event-path propagation 28745 return true; 28746 }, 28747 28748 // For cross-browser consistency, suppress native .click() on links 28749 // Also prevent it if we're currently inside a leveraged native-event stack 28750 _default: function( event ) { 28751 var target = event.target; 28752 return rcheckableType.test( target.type ) && 28753 target.click && nodeName( target, "input" ) && 28754 dataPriv.get( target, "click" ) || 28755 nodeName( target, "a" ); 28756 } 28757 }, 28758 28759 beforeunload: { 28760 postDispatch: function( event ) { 28761 28762 // Support: Firefox 20+ 28763 // Firefox doesn't alert if the returnValue field is not set. 28764 if ( event.result !== undefined && event.originalEvent ) { 28765 event.originalEvent.returnValue = event.result; 28766 } 28767 } 28768 } 28769 } 28770}; 28771 28772// Ensure the presence of an event listener that handles manually-triggered 28773// synthetic events by interrupting progress until reinvoked in response to 28774// *native* events that it fires directly, ensuring that state changes have 28775// already occurred before other listeners are invoked. 28776function leverageNative( el, type, expectSync ) { 28777 28778 // Missing expectSync indicates a trigger call, which must force setup through jQuery.event.add 28779 if ( !expectSync ) { 28780 if ( dataPriv.get( el, type ) === undefined ) { 28781 jQuery.event.add( el, type, returnTrue ); 28782 } 28783 return; 28784 } 28785 28786 // Register the controller as a special universal handler for all event namespaces 28787 dataPriv.set( el, type, false ); 28788 jQuery.event.add( el, type, { 28789 namespace: false, 28790 handler: function( event ) { 28791 var notAsync, result, 28792 saved = dataPriv.get( this, type ); 28793 28794 if ( ( event.isTrigger & 1 ) && this[ type ] ) { 28795 28796 // Interrupt processing of the outer synthetic .trigger()ed event 28797 // Saved data should be false in such cases, but might be a leftover capture object 28798 // from an async native handler (gh-4350) 28799 if ( !saved.length ) { 28800 28801 // Store arguments for use when handling the inner native event 28802 // There will always be at least one argument (an event object), so this array 28803 // will not be confused with a leftover capture object. 28804 saved = slice.call( arguments ); 28805 dataPriv.set( this, type, saved ); 28806 28807 // Trigger the native event and capture its result 28808 // Support: IE <=9 - 11+ 28809 // focus() and blur() are asynchronous 28810 notAsync = expectSync( this, type ); 28811 this[ type ](); 28812 result = dataPriv.get( this, type ); 28813 if ( saved !== result || notAsync ) { 28814 dataPriv.set( this, type, false ); 28815 } else { 28816 result = {}; 28817 } 28818 if ( saved !== result ) { 28819 28820 // Cancel the outer synthetic event 28821 event.stopImmediatePropagation(); 28822 event.preventDefault(); 28823 return result.value; 28824 } 28825 28826 // If this is an inner synthetic event for an event with a bubbling surrogate 28827 // (focus or blur), assume that the surrogate already propagated from triggering the 28828 // native event and prevent that from happening again here. 28829 // This technically gets the ordering wrong w.r.t. to `.trigger()` (in which the 28830 // bubbling surrogate propagates *after* the non-bubbling base), but that seems 28831 // less bad than duplication. 28832 } else if ( ( jQuery.event.special[ type ] || {} ).delegateType ) { 28833 event.stopPropagation(); 28834 } 28835 28836 // If this is a native event triggered above, everything is now in order 28837 // Fire an inner synthetic event with the original arguments 28838 } else if ( saved.length ) { 28839 28840 // ...and capture the result 28841 dataPriv.set( this, type, { 28842 value: jQuery.event.trigger( 28843 28844 // Support: IE <=9 - 11+ 28845 // Extend with the prototype to reset the above stopImmediatePropagation() 28846 jQuery.extend( saved[ 0 ], jQuery.Event.prototype ), 28847 saved.slice( 1 ), 28848 this 28849 ) 28850 } ); 28851 28852 // Abort handling of the native event 28853 event.stopImmediatePropagation(); 28854 } 28855 } 28856 } ); 28857} 28858 28859jQuery.removeEvent = function( elem, type, handle ) { 28860 28861 // This "if" is needed for plain objects 28862 if ( elem.removeEventListener ) { 28863 elem.removeEventListener( type, handle ); 28864 } 28865}; 28866 28867jQuery.Event = function( src, props ) { 28868 28869 // Allow instantiation without the 'new' keyword 28870 if ( !( this instanceof jQuery.Event ) ) { 28871 return new jQuery.Event( src, props ); 28872 } 28873 28874 // Event object 28875 if ( src && src.type ) { 28876 this.originalEvent = src; 28877 this.type = src.type; 28878 28879 // Events bubbling up the document may have been marked as prevented 28880 // by a handler lower down the tree; reflect the correct value. 28881 this.isDefaultPrevented = src.defaultPrevented || 28882 src.defaultPrevented === undefined && 28883 28884 // Support: Android <=2.3 only 28885 src.returnValue === false ? 28886 returnTrue : 28887 returnFalse; 28888 28889 // Create target properties 28890 // Support: Safari <=6 - 7 only 28891 // Target should not be a text node (#504, #13143) 28892 this.target = ( src.target && src.target.nodeType === 3 ) ? 28893 src.target.parentNode : 28894 src.target; 28895 28896 this.currentTarget = src.currentTarget; 28897 this.relatedTarget = src.relatedTarget; 28898 28899 // Event type 28900 } else { 28901 this.type = src; 28902 } 28903 28904 // Put explicitly provided properties onto the event object 28905 if ( props ) { 28906 jQuery.extend( this, props ); 28907 } 28908 28909 // Create a timestamp if incoming event doesn't have one 28910 this.timeStamp = src && src.timeStamp || Date.now(); 28911 28912 // Mark it as fixed 28913 this[ jQuery.expando ] = true; 28914}; 28915 28916// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding 28917// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html 28918jQuery.Event.prototype = { 28919 constructor: jQuery.Event, 28920 isDefaultPrevented: returnFalse, 28921 isPropagationStopped: returnFalse, 28922 isImmediatePropagationStopped: returnFalse, 28923 isSimulated: false, 28924 28925 preventDefault: function() { 28926 var e = this.originalEvent; 28927 28928 this.isDefaultPrevented = returnTrue; 28929 28930 if ( e && !this.isSimulated ) { 28931 e.preventDefault(); 28932 } 28933 }, 28934 stopPropagation: function() { 28935 var e = this.originalEvent; 28936 28937 this.isPropagationStopped = returnTrue; 28938 28939 if ( e && !this.isSimulated ) { 28940 e.stopPropagation(); 28941 } 28942 }, 28943 stopImmediatePropagation: function() { 28944 var e = this.originalEvent; 28945 28946 this.isImmediatePropagationStopped = returnTrue; 28947 28948 if ( e && !this.isSimulated ) { 28949 e.stopImmediatePropagation(); 28950 } 28951 28952 this.stopPropagation(); 28953 } 28954}; 28955 28956// Includes all common event props including KeyEvent and MouseEvent specific props 28957jQuery.each( { 28958 altKey: true, 28959 bubbles: true, 28960 cancelable: true, 28961 changedTouches: true, 28962 ctrlKey: true, 28963 detail: true, 28964 eventPhase: true, 28965 metaKey: true, 28966 pageX: true, 28967 pageY: true, 28968 shiftKey: true, 28969 view: true, 28970 "char": true, 28971 code: true, 28972 charCode: true, 28973 key: true, 28974 keyCode: true, 28975 button: true, 28976 buttons: true, 28977 clientX: true, 28978 clientY: true, 28979 offsetX: true, 28980 offsetY: true, 28981 pointerId: true, 28982 pointerType: true, 28983 screenX: true, 28984 screenY: true, 28985 targetTouches: true, 28986 toElement: true, 28987 touches: true, 28988 28989 which: function( event ) { 28990 var button = event.button; 28991 28992 // Add which for key events 28993 if ( event.which == null && rkeyEvent.test( event.type ) ) { 28994 return event.charCode != null ? event.charCode : event.keyCode; 28995 } 28996 28997 // Add which for click: 1 === left; 2 === middle; 3 === right 28998 if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) { 28999 if ( button & 1 ) { 29000 return 1; 29001 } 29002 29003 if ( button & 2 ) { 29004 return 3; 29005 } 29006 29007 if ( button & 4 ) { 29008 return 2; 29009 } 29010 29011 return 0; 29012 } 29013 29014 return event.which; 29015 } 29016}, jQuery.event.addProp ); 29017 29018jQuery.each( { focus: "focusin", blur: "focusout" }, function( type, delegateType ) { 29019 jQuery.event.special[ type ] = { 29020 29021 // Utilize native event if possible so blur/focus sequence is correct 29022 setup: function() { 29023 29024 // Claim the first handler 29025 // dataPriv.set( this, "focus", ... ) 29026 // dataPriv.set( this, "blur", ... ) 29027 leverageNative( this, type, expectSync ); 29028 29029 // Return false to allow normal processing in the caller 29030 return false; 29031 }, 29032 trigger: function() { 29033 29034 // Force setup before trigger 29035 leverageNative( this, type ); 29036 29037 // Return non-false to allow normal event-path propagation 29038 return true; 29039 }, 29040 29041 delegateType: delegateType 29042 }; 29043} ); 29044 29045// Create mouseenter/leave events using mouseover/out and event-time checks 29046// so that event delegation works in jQuery. 29047// Do the same for pointerenter/pointerleave and pointerover/pointerout 29048// 29049// Support: Safari 7 only 29050// Safari sends mouseenter too often; see: 29051// https://bugs.chromium.org/p/chromium/issues/detail?id=470258 29052// for the description of the bug (it existed in older Chrome versions as well). 29053jQuery.each( { 29054 mouseenter: "mouseover", 29055 mouseleave: "mouseout", 29056 pointerenter: "pointerover", 29057 pointerleave: "pointerout" 29058}, function( orig, fix ) { 29059 jQuery.event.special[ orig ] = { 29060 delegateType: fix, 29061 bindType: fix, 29062 29063 handle: function( event ) { 29064 var ret, 29065 target = this, 29066 related = event.relatedTarget, 29067 handleObj = event.handleObj; 29068 29069 // For mouseenter/leave call the handler if related is outside the target. 29070 // NB: No relatedTarget if the mouse left/entered the browser window 29071 if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) { 29072 event.type = handleObj.origType; 29073 ret = handleObj.handler.apply( this, arguments ); 29074 event.type = fix; 29075 } 29076 return ret; 29077 } 29078 }; 29079} ); 29080 29081jQuery.fn.extend( { 29082 29083 on: function( types, selector, data, fn ) { 29084 return on( this, types, selector, data, fn ); 29085 }, 29086 one: function( types, selector, data, fn ) { 29087 return on( this, types, selector, data, fn, 1 ); 29088 }, 29089 off: function( types, selector, fn ) { 29090 var handleObj, type; 29091 if ( types && types.preventDefault && types.handleObj ) { 29092 29093 // ( event ) dispatched jQuery.Event 29094 handleObj = types.handleObj; 29095 jQuery( types.delegateTarget ).off( 29096 handleObj.namespace ? 29097 handleObj.origType + "." + handleObj.namespace : 29098 handleObj.origType, 29099 handleObj.selector, 29100 handleObj.handler 29101 ); 29102 return this; 29103 } 29104 if ( typeof types === "object" ) { 29105 29106 // ( types-object [, selector] ) 29107 for ( type in types ) { 29108 this.off( type, selector, types[ type ] ); 29109 } 29110 return this; 29111 } 29112 if ( selector === false || typeof selector === "function" ) { 29113 29114 // ( types [, fn] ) 29115 fn = selector; 29116 selector = undefined; 29117 } 29118 if ( fn === false ) { 29119 fn = returnFalse; 29120 } 29121 return this.each( function() { 29122 jQuery.event.remove( this, types, fn, selector ); 29123 } ); 29124 } 29125} ); 29126 29127 29128var 29129 29130 // Support: IE <=10 - 11, Edge 12 - 13 only 29131 // In IE/Edge using regex groups here causes severe slowdowns. 29132 // See https://connect.microsoft.com/IE/feedback/details/1736512/ 29133 rnoInnerhtml = /<script|<style|<link/i, 29134 29135 // checked="checked" or checked 29136 rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, 29137 rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g; 29138 29139// Prefer a tbody over its parent table for containing new rows 29140function manipulationTarget( elem, content ) { 29141 if ( nodeName( elem, "table" ) && 29142 nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) { 29143 29144 return jQuery( elem ).children( "tbody" )[ 0 ] || elem; 29145 } 29146 29147 return elem; 29148} 29149 29150// Replace/restore the type attribute of script elements for safe DOM manipulation 29151function disableScript( elem ) { 29152 elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type; 29153 return elem; 29154} 29155function restoreScript( elem ) { 29156 if ( ( elem.type || "" ).slice( 0, 5 ) === "true/" ) { 29157 elem.type = elem.type.slice( 5 ); 29158 } else { 29159 elem.removeAttribute( "type" ); 29160 } 29161 29162 return elem; 29163} 29164 29165function cloneCopyEvent( src, dest ) { 29166 var i, l, type, pdataOld, udataOld, udataCur, events; 29167 29168 if ( dest.nodeType !== 1 ) { 29169 return; 29170 } 29171 29172 // 1. Copy private data: events, handlers, etc. 29173 if ( dataPriv.hasData( src ) ) { 29174 pdataOld = dataPriv.get( src ); 29175 events = pdataOld.events; 29176 29177 if ( events ) { 29178 dataPriv.remove( dest, "handle events" ); 29179 29180 for ( type in events ) { 29181 for ( i = 0, l = events[ type ].length; i < l; i++ ) { 29182 jQuery.event.add( dest, type, events[ type ][ i ] ); 29183 } 29184 } 29185 } 29186 } 29187 29188 // 2. Copy user data 29189 if ( dataUser.hasData( src ) ) { 29190 udataOld = dataUser.access( src ); 29191 udataCur = jQuery.extend( {}, udataOld ); 29192 29193 dataUser.set( dest, udataCur ); 29194 } 29195} 29196 29197// Fix IE bugs, see support tests 29198function fixInput( src, dest ) { 29199 var nodeName = dest.nodeName.toLowerCase(); 29200 29201 // Fails to persist the checked state of a cloned checkbox or radio button. 29202 if ( nodeName === "input" && rcheckableType.test( src.type ) ) { 29203 dest.checked = src.checked; 29204 29205 // Fails to return the selected option to the default selected state when cloning options 29206 } else if ( nodeName === "input" || nodeName === "textarea" ) { 29207 dest.defaultValue = src.defaultValue; 29208 } 29209} 29210 29211function domManip( collection, args, callback, ignored ) { 29212 29213 // Flatten any nested arrays 29214 args = flat( args ); 29215 29216 var fragment, first, scripts, hasScripts, node, doc, 29217 i = 0, 29218 l = collection.length, 29219 iNoClone = l - 1, 29220 value = args[ 0 ], 29221 valueIsFunction = isFunction( value ); 29222 29223 // We can't cloneNode fragments that contain checked, in WebKit 29224 if ( valueIsFunction || 29225 ( l > 1 && typeof value === "string" && 29226 !support.checkClone && rchecked.test( value ) ) ) { 29227 return collection.each( function( index ) { 29228 var self = collection.eq( index ); 29229 if ( valueIsFunction ) { 29230 args[ 0 ] = value.call( this, index, self.html() ); 29231 } 29232 domManip( self, args, callback, ignored ); 29233 } ); 29234 } 29235 29236 if ( l ) { 29237 fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored ); 29238 first = fragment.firstChild; 29239 29240 if ( fragment.childNodes.length === 1 ) { 29241 fragment = first; 29242 } 29243 29244 // Require either new content or an interest in ignored elements to invoke the callback 29245 if ( first || ignored ) { 29246 scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); 29247 hasScripts = scripts.length; 29248 29249 // Use the original fragment for the last item 29250 // instead of the first because it can end up 29251 // being emptied incorrectly in certain situations (#8070). 29252 for ( ; i < l; i++ ) { 29253 node = fragment; 29254 29255 if ( i !== iNoClone ) { 29256 node = jQuery.clone( node, true, true ); 29257 29258 // Keep references to cloned scripts for later restoration 29259 if ( hasScripts ) { 29260 29261 // Support: Android <=4.0 only, PhantomJS 1 only 29262 // push.apply(_, arraylike) throws on ancient WebKit 29263 jQuery.merge( scripts, getAll( node, "script" ) ); 29264 } 29265 } 29266 29267 callback.call( collection[ i ], node, i ); 29268 } 29269 29270 if ( hasScripts ) { 29271 doc = scripts[ scripts.length - 1 ].ownerDocument; 29272 29273 // Reenable scripts 29274 jQuery.map( scripts, restoreScript ); 29275 29276 // Evaluate executable scripts on first document insertion 29277 for ( i = 0; i < hasScripts; i++ ) { 29278 node = scripts[ i ]; 29279 if ( rscriptType.test( node.type || "" ) && 29280 !dataPriv.access( node, "globalEval" ) && 29281 jQuery.contains( doc, node ) ) { 29282 29283 if ( node.src && ( node.type || "" ).toLowerCase() !== "module" ) { 29284 29285 // Optional AJAX dependency, but won't run scripts if not present 29286 if ( jQuery._evalUrl && !node.noModule ) { 29287 jQuery._evalUrl( node.src, { 29288 nonce: node.nonce || node.getAttribute( "nonce" ) 29289 }, doc ); 29290 } 29291 } else { 29292 DOMEval( node.textContent.replace( rcleanScript, "" ), node, doc ); 29293 } 29294 } 29295 } 29296 } 29297 } 29298 } 29299 29300 return collection; 29301} 29302 29303function remove( elem, selector, keepData ) { 29304 var node, 29305 nodes = selector ? jQuery.filter( selector, elem ) : elem, 29306 i = 0; 29307 29308 for ( ; ( node = nodes[ i ] ) != null; i++ ) { 29309 if ( !keepData && node.nodeType === 1 ) { 29310 jQuery.cleanData( getAll( node ) ); 29311 } 29312 29313 if ( node.parentNode ) { 29314 if ( keepData && isAttached( node ) ) { 29315 setGlobalEval( getAll( node, "script" ) ); 29316 } 29317 node.parentNode.removeChild( node ); 29318 } 29319 } 29320 29321 return elem; 29322} 29323 29324jQuery.extend( { 29325 htmlPrefilter: function( html ) { 29326 return html; 29327 }, 29328 29329 clone: function( elem, dataAndEvents, deepDataAndEvents ) { 29330 var i, l, srcElements, destElements, 29331 clone = elem.cloneNode( true ), 29332 inPage = isAttached( elem ); 29333 29334 // Fix IE cloning issues 29335 if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) && 29336 !jQuery.isXMLDoc( elem ) ) { 29337 29338 // We eschew Sizzle here for performance reasons: https://jsperf.com/getall-vs-sizzle/2 29339 destElements = getAll( clone ); 29340 srcElements = getAll( elem ); 29341 29342 for ( i = 0, l = srcElements.length; i < l; i++ ) { 29343 fixInput( srcElements[ i ], destElements[ i ] ); 29344 } 29345 } 29346 29347 // Copy the events from the original to the clone 29348 if ( dataAndEvents ) { 29349 if ( deepDataAndEvents ) { 29350 srcElements = srcElements || getAll( elem ); 29351 destElements = destElements || getAll( clone ); 29352 29353 for ( i = 0, l = srcElements.length; i < l; i++ ) { 29354 cloneCopyEvent( srcElements[ i ], destElements[ i ] ); 29355 } 29356 } else { 29357 cloneCopyEvent( elem, clone ); 29358 } 29359 } 29360 29361 // Preserve script evaluation history 29362 destElements = getAll( clone, "script" ); 29363 if ( destElements.length > 0 ) { 29364 setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); 29365 } 29366 29367 // Return the cloned set 29368 return clone; 29369 }, 29370 29371 cleanData: function( elems ) { 29372 var data, elem, type, 29373 special = jQuery.event.special, 29374 i = 0; 29375 29376 for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) { 29377 if ( acceptData( elem ) ) { 29378 if ( ( data = elem[ dataPriv.expando ] ) ) { 29379 if ( data.events ) { 29380 for ( type in data.events ) { 29381 if ( special[ type ] ) { 29382 jQuery.event.remove( elem, type ); 29383 29384 // This is a shortcut to avoid jQuery.event.remove's overhead 29385 } else { 29386 jQuery.removeEvent( elem, type, data.handle ); 29387 } 29388 } 29389 } 29390 29391 // Support: Chrome <=35 - 45+ 29392 // Assign undefined instead of using delete, see Data#remove 29393 elem[ dataPriv.expando ] = undefined; 29394 } 29395 if ( elem[ dataUser.expando ] ) { 29396 29397 // Support: Chrome <=35 - 45+ 29398 // Assign undefined instead of using delete, see Data#remove 29399 elem[ dataUser.expando ] = undefined; 29400 } 29401 } 29402 } 29403 } 29404} ); 29405 29406jQuery.fn.extend( { 29407 detach: function( selector ) { 29408 return remove( this, selector, true ); 29409 }, 29410 29411 remove: function( selector ) { 29412 return remove( this, selector ); 29413 }, 29414 29415 text: function( value ) { 29416 return access( this, function( value ) { 29417 return value === undefined ? 29418 jQuery.text( this ) : 29419 this.empty().each( function() { 29420 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 29421 this.textContent = value; 29422 } 29423 } ); 29424 }, null, value, arguments.length ); 29425 }, 29426 29427 append: function() { 29428 return domManip( this, arguments, function( elem ) { 29429 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 29430 var target = manipulationTarget( this, elem ); 29431 target.appendChild( elem ); 29432 } 29433 } ); 29434 }, 29435 29436 prepend: function() { 29437 return domManip( this, arguments, function( elem ) { 29438 if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { 29439 var target = manipulationTarget( this, elem ); 29440 target.insertBefore( elem, target.firstChild ); 29441 } 29442 } ); 29443 }, 29444 29445 before: function() { 29446 return domManip( this, arguments, function( elem ) { 29447 if ( this.parentNode ) { 29448 this.parentNode.insertBefore( elem, this ); 29449 } 29450 } ); 29451 }, 29452 29453 after: function() { 29454 return domManip( this, arguments, function( elem ) { 29455 if ( this.parentNode ) { 29456 this.parentNode.insertBefore( elem, this.nextSibling ); 29457 } 29458 } ); 29459 }, 29460 29461 empty: function() { 29462 var elem, 29463 i = 0; 29464 29465 for ( ; ( elem = this[ i ] ) != null; i++ ) { 29466 if ( elem.nodeType === 1 ) { 29467 29468 // Prevent memory leaks 29469 jQuery.cleanData( getAll( elem, false ) ); 29470 29471 // Remove any remaining nodes 29472 elem.textContent = ""; 29473 } 29474 } 29475 29476 return this; 29477 }, 29478 29479 clone: function( dataAndEvents, deepDataAndEvents ) { 29480 dataAndEvents = dataAndEvents == null ? false : dataAndEvents; 29481 deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; 29482 29483 return this.map( function() { 29484 return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); 29485 } ); 29486 }, 29487 29488 html: function( value ) { 29489 return access( this, function( value ) { 29490 var elem = this[ 0 ] || {}, 29491 i = 0, 29492 l = this.length; 29493 29494 if ( value === undefined && elem.nodeType === 1 ) { 29495 return elem.innerHTML; 29496 } 29497 29498 // See if we can take a shortcut and just use innerHTML 29499 if ( typeof value === "string" && !rnoInnerhtml.test( value ) && 29500 !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) { 29501 29502 value = jQuery.htmlPrefilter( value ); 29503 29504 try { 29505 for ( ; i < l; i++ ) { 29506 elem = this[ i ] || {}; 29507 29508 // Remove element nodes and prevent memory leaks 29509 if ( elem.nodeType === 1 ) { 29510 jQuery.cleanData( getAll( elem, false ) ); 29511 elem.innerHTML = value; 29512 } 29513 } 29514 29515 elem = 0; 29516 29517 // If using innerHTML throws an exception, use the fallback method 29518 } catch ( e ) {} 29519 } 29520 29521 if ( elem ) { 29522 this.empty().append( value ); 29523 } 29524 }, null, value, arguments.length ); 29525 }, 29526 29527 replaceWith: function() { 29528 var ignored = []; 29529 29530 // Make the changes, replacing each non-ignored context element with the new content 29531 return domManip( this, arguments, function( elem ) { 29532 var parent = this.parentNode; 29533 29534 if ( jQuery.inArray( this, ignored ) < 0 ) { 29535 jQuery.cleanData( getAll( this ) ); 29536 if ( parent ) { 29537 parent.replaceChild( elem, this ); 29538 } 29539 } 29540 29541 // Force callback invocation 29542 }, ignored ); 29543 } 29544} ); 29545 29546jQuery.each( { 29547 appendTo: "append", 29548 prependTo: "prepend", 29549 insertBefore: "before", 29550 insertAfter: "after", 29551 replaceAll: "replaceWith" 29552}, function( name, original ) { 29553 jQuery.fn[ name ] = function( selector ) { 29554 var elems, 29555 ret = [], 29556 insert = jQuery( selector ), 29557 last = insert.length - 1, 29558 i = 0; 29559 29560 for ( ; i <= last; i++ ) { 29561 elems = i === last ? this : this.clone( true ); 29562 jQuery( insert[ i ] )[ original ]( elems ); 29563 29564 // Support: Android <=4.0 only, PhantomJS 1 only 29565 // .get() because push.apply(_, arraylike) throws on ancient WebKit 29566 push.apply( ret, elems.get() ); 29567 } 29568 29569 return this.pushStack( ret ); 29570 }; 29571} ); 29572var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); 29573 29574var getStyles = function( elem ) { 29575 29576 // Support: IE <=11 only, Firefox <=30 (#15098, #14150) 29577 // IE throws on elements created in popups 29578 // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" 29579 var view = elem.ownerDocument.defaultView; 29580 29581 if ( !view || !view.opener ) { 29582 view = window; 29583 } 29584 29585 return view.getComputedStyle( elem ); 29586 }; 29587 29588var swap = function( elem, options, callback ) { 29589 var ret, name, 29590 old = {}; 29591 29592 // Remember the old values, and insert the new ones 29593 for ( name in options ) { 29594 old[ name ] = elem.style[ name ]; 29595 elem.style[ name ] = options[ name ]; 29596 } 29597 29598 ret = callback.call( elem ); 29599 29600 // Revert the old values 29601 for ( name in options ) { 29602 elem.style[ name ] = old[ name ]; 29603 } 29604 29605 return ret; 29606}; 29607 29608 29609var rboxStyle = new RegExp( cssExpand.join( "|" ), "i" ); 29610 29611 29612 29613( function() { 29614 29615 // Executing both pixelPosition & boxSizingReliable tests require only one layout 29616 // so they're executed at the same time to save the second computation. 29617 function computeStyleTests() { 29618 29619 // This is a singleton, we need to execute it only once 29620 if ( !div ) { 29621 return; 29622 } 29623 29624 container.style.cssText = "position:absolute;left:-11111px;width:60px;" + 29625 "margin-top:1px;padding:0;border:0"; 29626 div.style.cssText = 29627 "position:relative;display:block;box-sizing:border-box;overflow:scroll;" + 29628 "margin:auto;border:1px;padding:1px;" + 29629 "width:60%;top:1%"; 29630 documentElement.appendChild( container ).appendChild( div ); 29631 29632 var divStyle = window.getComputedStyle( div ); 29633 pixelPositionVal = divStyle.top !== "1%"; 29634 29635 // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44 29636 reliableMarginLeftVal = roundPixelMeasures( divStyle.marginLeft ) === 12; 29637 29638 // Support: Android 4.0 - 4.3 only, Safari <=9.1 - 10.1, iOS <=7.0 - 9.3 29639 // Some styles come back with percentage values, even though they shouldn't 29640 div.style.right = "60%"; 29641 pixelBoxStylesVal = roundPixelMeasures( divStyle.right ) === 36; 29642 29643 // Support: IE 9 - 11 only 29644 // Detect misreporting of content dimensions for box-sizing:border-box elements 29645 boxSizingReliableVal = roundPixelMeasures( divStyle.width ) === 36; 29646 29647 // Support: IE 9 only 29648 // Detect overflow:scroll screwiness (gh-3699) 29649 // Support: Chrome <=64 29650 // Don't get tricked when zoom affects offsetWidth (gh-4029) 29651 div.style.position = "absolute"; 29652 scrollboxSizeVal = roundPixelMeasures( div.offsetWidth / 3 ) === 12; 29653 29654 documentElement.removeChild( container ); 29655 29656 // Nullify the div so it wouldn't be stored in the memory and 29657 // it will also be a sign that checks already performed 29658 div = null; 29659 } 29660 29661 function roundPixelMeasures( measure ) { 29662 return Math.round( parseFloat( measure ) ); 29663 } 29664 29665 var pixelPositionVal, boxSizingReliableVal, scrollboxSizeVal, pixelBoxStylesVal, 29666 reliableTrDimensionsVal, reliableMarginLeftVal, 29667 container = document.createElement( "div" ), 29668 div = document.createElement( "div" ); 29669 29670 // Finish early in limited (non-browser) environments 29671 if ( !div.style ) { 29672 return; 29673 } 29674 29675 // Support: IE <=9 - 11 only 29676 // Style of cloned element affects source element cloned (#8908) 29677 div.style.backgroundClip = "content-box"; 29678 div.cloneNode( true ).style.backgroundClip = ""; 29679 support.clearCloneStyle = div.style.backgroundClip === "content-box"; 29680 29681 jQuery.extend( support, { 29682 boxSizingReliable: function() { 29683 computeStyleTests(); 29684 return boxSizingReliableVal; 29685 }, 29686 pixelBoxStyles: function() { 29687 computeStyleTests(); 29688 return pixelBoxStylesVal; 29689 }, 29690 pixelPosition: function() { 29691 computeStyleTests(); 29692 return pixelPositionVal; 29693 }, 29694 reliableMarginLeft: function() { 29695 computeStyleTests(); 29696 return reliableMarginLeftVal; 29697 }, 29698 scrollboxSize: function() { 29699 computeStyleTests(); 29700 return scrollboxSizeVal; 29701 }, 29702 29703 // Support: IE 9 - 11+, Edge 15 - 18+ 29704 // IE/Edge misreport `getComputedStyle` of table rows with width/height 29705 // set in CSS while `offset*` properties report correct values. 29706 // Behavior in IE 9 is more subtle than in newer versions & it passes 29707 // some versions of this test; make sure not to make it pass there! 29708 reliableTrDimensions: function() { 29709 var table, tr, trChild, trStyle; 29710 if ( reliableTrDimensionsVal == null ) { 29711 table = document.createElement( "table" ); 29712 tr = document.createElement( "tr" ); 29713 trChild = document.createElement( "div" ); 29714 29715 table.style.cssText = "position:absolute;left:-11111px"; 29716 tr.style.height = "1px"; 29717 trChild.style.height = "9px"; 29718 29719 documentElement 29720 .appendChild( table ) 29721 .appendChild( tr ) 29722 .appendChild( trChild ); 29723 29724 trStyle = window.getComputedStyle( tr ); 29725 reliableTrDimensionsVal = parseInt( trStyle.height ) > 3; 29726 29727 documentElement.removeChild( table ); 29728 } 29729 return reliableTrDimensionsVal; 29730 } 29731 } ); 29732} )(); 29733 29734 29735function curCSS( elem, name, computed ) { 29736 var width, minWidth, maxWidth, ret, 29737 29738 // Support: Firefox 51+ 29739 // Retrieving style before computed somehow 29740 // fixes an issue with getting wrong values 29741 // on detached elements 29742 style = elem.style; 29743 29744 computed = computed || getStyles( elem ); 29745 29746 // getPropertyValue is needed for: 29747 // .css('filter') (IE 9 only, #12537) 29748 // .css('--customProperty) (#3144) 29749 if ( computed ) { 29750 ret = computed.getPropertyValue( name ) || computed[ name ]; 29751 29752 if ( ret === "" && !isAttached( elem ) ) { 29753 ret = jQuery.style( elem, name ); 29754 } 29755 29756 // A tribute to the "awesome hack by Dean Edwards" 29757 // Android Browser returns percentage for some values, 29758 // but width seems to be reliably pixels. 29759 // This is against the CSSOM draft spec: 29760 // https://drafts.csswg.org/cssom/#resolved-values 29761 if ( !support.pixelBoxStyles() && rnumnonpx.test( ret ) && rboxStyle.test( name ) ) { 29762 29763 // Remember the original values 29764 width = style.width; 29765 minWidth = style.minWidth; 29766 maxWidth = style.maxWidth; 29767 29768 // Put in the new values to get a computed value out 29769 style.minWidth = style.maxWidth = style.width = ret; 29770 ret = computed.width; 29771 29772 // Revert the changed values 29773 style.width = width; 29774 style.minWidth = minWidth; 29775 style.maxWidth = maxWidth; 29776 } 29777 } 29778 29779 return ret !== undefined ? 29780 29781 // Support: IE <=9 - 11 only 29782 // IE returns zIndex value as an integer. 29783 ret + "" : 29784 ret; 29785} 29786 29787 29788function addGetHookIf( conditionFn, hookFn ) { 29789 29790 // Define the hook, we'll check on the first run if it's really needed. 29791 return { 29792 get: function() { 29793 if ( conditionFn() ) { 29794 29795 // Hook not needed (or it's not possible to use it due 29796 // to missing dependency), remove it. 29797 delete this.get; 29798 return; 29799 } 29800 29801 // Hook needed; redefine it so that the support test is not executed again. 29802 return ( this.get = hookFn ).apply( this, arguments ); 29803 } 29804 }; 29805} 29806 29807 29808var cssPrefixes = [ "Webkit", "Moz", "ms" ], 29809 emptyStyle = document.createElement( "div" ).style, 29810 vendorProps = {}; 29811 29812// Return a vendor-prefixed property or undefined 29813function vendorPropName( name ) { 29814 29815 // Check for vendor prefixed names 29816 var capName = name[ 0 ].toUpperCase() + name.slice( 1 ), 29817 i = cssPrefixes.length; 29818 29819 while ( i-- ) { 29820 name = cssPrefixes[ i ] + capName; 29821 if ( name in emptyStyle ) { 29822 return name; 29823 } 29824 } 29825} 29826 29827// Return a potentially-mapped jQuery.cssProps or vendor prefixed property 29828function finalPropName( name ) { 29829 var final = jQuery.cssProps[ name ] || vendorProps[ name ]; 29830 29831 if ( final ) { 29832 return final; 29833 } 29834 if ( name in emptyStyle ) { 29835 return name; 29836 } 29837 return vendorProps[ name ] = vendorPropName( name ) || name; 29838} 29839 29840 29841var 29842 29843 // Swappable if display is none or starts with table 29844 // except "table", "table-cell", or "table-caption" 29845 // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display 29846 rdisplayswap = /^(none|table(?!-c[ea]).+)/, 29847 rcustomProp = /^--/, 29848 cssShow = { position: "absolute", visibility: "hidden", display: "block" }, 29849 cssNormalTransform = { 29850 letterSpacing: "0", 29851 fontWeight: "400" 29852 }; 29853 29854function setPositiveNumber( _elem, value, subtract ) { 29855 29856 // Any relative (+/-) values have already been 29857 // normalized at this point 29858 var matches = rcssNum.exec( value ); 29859 return matches ? 29860 29861 // Guard against undefined "subtract", e.g., when used as in cssHooks 29862 Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) : 29863 value; 29864} 29865 29866function boxModelAdjustment( elem, dimension, box, isBorderBox, styles, computedVal ) { 29867 var i = dimension === "width" ? 1 : 0, 29868 extra = 0, 29869 delta = 0; 29870 29871 // Adjustment may not be necessary 29872 if ( box === ( isBorderBox ? "border" : "content" ) ) { 29873 return 0; 29874 } 29875 29876 for ( ; i < 4; i += 2 ) { 29877 29878 // Both box models exclude margin 29879 if ( box === "margin" ) { 29880 delta += jQuery.css( elem, box + cssExpand[ i ], true, styles ); 29881 } 29882 29883 // If we get here with a content-box, we're seeking "padding" or "border" or "margin" 29884 if ( !isBorderBox ) { 29885 29886 // Add padding 29887 delta += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 29888 29889 // For "border" or "margin", add border 29890 if ( box !== "padding" ) { 29891 delta += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 29892 29893 // But still keep track of it otherwise 29894 } else { 29895 extra += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 29896 } 29897 29898 // If we get here with a border-box (content + padding + border), we're seeking "content" or 29899 // "padding" or "margin" 29900 } else { 29901 29902 // For "content", subtract padding 29903 if ( box === "content" ) { 29904 delta -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); 29905 } 29906 29907 // For "content" or "padding", subtract border 29908 if ( box !== "margin" ) { 29909 delta -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); 29910 } 29911 } 29912 } 29913 29914 // Account for positive content-box scroll gutter when requested by providing computedVal 29915 if ( !isBorderBox && computedVal >= 0 ) { 29916 29917 // offsetWidth/offsetHeight is a rounded sum of content, padding, scroll gutter, and border 29918 // Assuming integer scroll gutter, subtract the rest and round down 29919 delta += Math.max( 0, Math.ceil( 29920 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 29921 computedVal - 29922 delta - 29923 extra - 29924 0.5 29925 29926 // If offsetWidth/offsetHeight is unknown, then we can't determine content-box scroll gutter 29927 // Use an explicit zero to avoid NaN (gh-3964) 29928 ) ) || 0; 29929 } 29930 29931 return delta; 29932} 29933 29934function getWidthOrHeight( elem, dimension, extra ) { 29935 29936 // Start with computed style 29937 var styles = getStyles( elem ), 29938 29939 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-4322). 29940 // Fake content-box until we know it's needed to know the true value. 29941 boxSizingNeeded = !support.boxSizingReliable() || extra, 29942 isBorderBox = boxSizingNeeded && 29943 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 29944 valueIsBorderBox = isBorderBox, 29945 29946 val = curCSS( elem, dimension, styles ), 29947 offsetProp = "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ); 29948 29949 // Support: Firefox <=54 29950 // Return a confounding non-pixel value or feign ignorance, as appropriate. 29951 if ( rnumnonpx.test( val ) ) { 29952 if ( !extra ) { 29953 return val; 29954 } 29955 val = "auto"; 29956 } 29957 29958 29959 // Support: IE 9 - 11 only 29960 // Use offsetWidth/offsetHeight for when box sizing is unreliable. 29961 // In those cases, the computed value can be trusted to be border-box. 29962 if ( ( !support.boxSizingReliable() && isBorderBox || 29963 29964 // Support: IE 10 - 11+, Edge 15 - 18+ 29965 // IE/Edge misreport `getComputedStyle` of table rows with width/height 29966 // set in CSS while `offset*` properties report correct values. 29967 // Interestingly, in some cases IE 9 doesn't suffer from this issue. 29968 !support.reliableTrDimensions() && nodeName( elem, "tr" ) || 29969 29970 // Fall back to offsetWidth/offsetHeight when value is "auto" 29971 // This happens for inline elements with no explicit setting (gh-3571) 29972 val === "auto" || 29973 29974 // Support: Android <=4.1 - 4.3 only 29975 // Also use offsetWidth/offsetHeight for misreported inline dimensions (gh-3602) 29976 !parseFloat( val ) && jQuery.css( elem, "display", false, styles ) === "inline" ) && 29977 29978 // Make sure the element is visible & connected 29979 elem.getClientRects().length ) { 29980 29981 isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; 29982 29983 // Where available, offsetWidth/offsetHeight approximate border box dimensions. 29984 // Where not available (e.g., SVG), assume unreliable box-sizing and interpret the 29985 // retrieved value as a content box dimension. 29986 valueIsBorderBox = offsetProp in elem; 29987 if ( valueIsBorderBox ) { 29988 val = elem[ offsetProp ]; 29989 } 29990 } 29991 29992 // Normalize "" and auto 29993 val = parseFloat( val ) || 0; 29994 29995 // Adjust for the element's box model 29996 return ( val + 29997 boxModelAdjustment( 29998 elem, 29999 dimension, 30000 extra || ( isBorderBox ? "border" : "content" ), 30001 valueIsBorderBox, 30002 styles, 30003 30004 // Provide the current computed size to request scroll gutter calculation (gh-3589) 30005 val 30006 ) 30007 ) + "px"; 30008} 30009 30010jQuery.extend( { 30011 30012 // Add in style property hooks for overriding the default 30013 // behavior of getting and setting a style property 30014 cssHooks: { 30015 opacity: { 30016 get: function( elem, computed ) { 30017 if ( computed ) { 30018 30019 // We should always get a number back from opacity 30020 var ret = curCSS( elem, "opacity" ); 30021 return ret === "" ? "1" : ret; 30022 } 30023 } 30024 } 30025 }, 30026 30027 // Don't automatically add "px" to these possibly-unitless properties 30028 cssNumber: { 30029 "animationIterationCount": true, 30030 "columnCount": true, 30031 "fillOpacity": true, 30032 "flexGrow": true, 30033 "flexShrink": true, 30034 "fontWeight": true, 30035 "gridArea": true, 30036 "gridColumn": true, 30037 "gridColumnEnd": true, 30038 "gridColumnStart": true, 30039 "gridRow": true, 30040 "gridRowEnd": true, 30041 "gridRowStart": true, 30042 "lineHeight": true, 30043 "opacity": true, 30044 "order": true, 30045 "orphans": true, 30046 "widows": true, 30047 "zIndex": true, 30048 "zoom": true 30049 }, 30050 30051 // Add in properties whose names you wish to fix before 30052 // setting or getting the value 30053 cssProps: {}, 30054 30055 // Get and set the style property on a DOM Node 30056 style: function( elem, name, value, extra ) { 30057 30058 // Don't set styles on text and comment nodes 30059 if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { 30060 return; 30061 } 30062 30063 // Make sure that we're working with the right name 30064 var ret, type, hooks, 30065 origName = camelCase( name ), 30066 isCustomProp = rcustomProp.test( name ), 30067 style = elem.style; 30068 30069 // Make sure that we're working with the right name. We don't 30070 // want to query the value if it is a CSS custom property 30071 // since they are user-defined. 30072 if ( !isCustomProp ) { 30073 name = finalPropName( origName ); 30074 } 30075 30076 // Gets hook for the prefixed version, then unprefixed version 30077 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 30078 30079 // Check if we're setting a value 30080 if ( value !== undefined ) { 30081 type = typeof value; 30082 30083 // Convert "+=" or "-=" to relative numbers (#7345) 30084 if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) { 30085 value = adjustCSS( elem, name, ret ); 30086 30087 // Fixes bug #9237 30088 type = "number"; 30089 } 30090 30091 // Make sure that null and NaN values aren't set (#7116) 30092 if ( value == null || value !== value ) { 30093 return; 30094 } 30095 30096 // If a number was passed in, add the unit (except for certain CSS properties) 30097 // The isCustomProp check can be removed in jQuery 4.0 when we only auto-append 30098 // "px" to a few hardcoded values. 30099 if ( type === "number" && !isCustomProp ) { 30100 value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" ); 30101 } 30102 30103 // background-* props affect original clone's values 30104 if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) { 30105 style[ name ] = "inherit"; 30106 } 30107 30108 // If a hook was provided, use that value, otherwise just set the specified value 30109 if ( !hooks || !( "set" in hooks ) || 30110 ( value = hooks.set( elem, value, extra ) ) !== undefined ) { 30111 30112 if ( isCustomProp ) { 30113 style.setProperty( name, value ); 30114 } else { 30115 style[ name ] = value; 30116 } 30117 } 30118 30119 } else { 30120 30121 // If a hook was provided get the non-computed value from there 30122 if ( hooks && "get" in hooks && 30123 ( ret = hooks.get( elem, false, extra ) ) !== undefined ) { 30124 30125 return ret; 30126 } 30127 30128 // Otherwise just get the value from the style object 30129 return style[ name ]; 30130 } 30131 }, 30132 30133 css: function( elem, name, extra, styles ) { 30134 var val, num, hooks, 30135 origName = camelCase( name ), 30136 isCustomProp = rcustomProp.test( name ); 30137 30138 // Make sure that we're working with the right name. We don't 30139 // want to modify the value if it is a CSS custom property 30140 // since they are user-defined. 30141 if ( !isCustomProp ) { 30142 name = finalPropName( origName ); 30143 } 30144 30145 // Try prefixed name followed by the unprefixed name 30146 hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; 30147 30148 // If a hook was provided get the computed value from there 30149 if ( hooks && "get" in hooks ) { 30150 val = hooks.get( elem, true, extra ); 30151 } 30152 30153 // Otherwise, if a way to get the computed value exists, use that 30154 if ( val === undefined ) { 30155 val = curCSS( elem, name, styles ); 30156 } 30157 30158 // Convert "normal" to computed value 30159 if ( val === "normal" && name in cssNormalTransform ) { 30160 val = cssNormalTransform[ name ]; 30161 } 30162 30163 // Make numeric if forced or a qualifier was provided and val looks numeric 30164 if ( extra === "" || extra ) { 30165 num = parseFloat( val ); 30166 return extra === true || isFinite( num ) ? num || 0 : val; 30167 } 30168 30169 return val; 30170 } 30171} ); 30172 30173jQuery.each( [ "height", "width" ], function( _i, dimension ) { 30174 jQuery.cssHooks[ dimension ] = { 30175 get: function( elem, computed, extra ) { 30176 if ( computed ) { 30177 30178 // Certain elements can have dimension info if we invisibly show them 30179 // but it must have a current display style that would benefit 30180 return rdisplayswap.test( jQuery.css( elem, "display" ) ) && 30181 30182 // Support: Safari 8+ 30183 // Table columns in Safari have non-zero offsetWidth & zero 30184 // getBoundingClientRect().width unless display is changed. 30185 // Support: IE <=11 only 30186 // Running getBoundingClientRect on a disconnected node 30187 // in IE throws an error. 30188 ( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ? 30189 swap( elem, cssShow, function() { 30190 return getWidthOrHeight( elem, dimension, extra ); 30191 } ) : 30192 getWidthOrHeight( elem, dimension, extra ); 30193 } 30194 }, 30195 30196 set: function( elem, value, extra ) { 30197 var matches, 30198 styles = getStyles( elem ), 30199 30200 // Only read styles.position if the test has a chance to fail 30201 // to avoid forcing a reflow. 30202 scrollboxSizeBuggy = !support.scrollboxSize() && 30203 styles.position === "absolute", 30204 30205 // To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991) 30206 boxSizingNeeded = scrollboxSizeBuggy || extra, 30207 isBorderBox = boxSizingNeeded && 30208 jQuery.css( elem, "boxSizing", false, styles ) === "border-box", 30209 subtract = extra ? 30210 boxModelAdjustment( 30211 elem, 30212 dimension, 30213 extra, 30214 isBorderBox, 30215 styles 30216 ) : 30217 0; 30218 30219 // Account for unreliable border-box dimensions by comparing offset* to computed and 30220 // faking a content-box to get border and padding (gh-3699) 30221 if ( isBorderBox && scrollboxSizeBuggy ) { 30222 subtract -= Math.ceil( 30223 elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] - 30224 parseFloat( styles[ dimension ] ) - 30225 boxModelAdjustment( elem, dimension, "border", false, styles ) - 30226 0.5 30227 ); 30228 } 30229 30230 // Convert to pixels if value adjustment is needed 30231 if ( subtract && ( matches = rcssNum.exec( value ) ) && 30232 ( matches[ 3 ] || "px" ) !== "px" ) { 30233 30234 elem.style[ dimension ] = value; 30235 value = jQuery.css( elem, dimension ); 30236 } 30237 30238 return setPositiveNumber( elem, value, subtract ); 30239 } 30240 }; 30241} ); 30242 30243jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft, 30244 function( elem, computed ) { 30245 if ( computed ) { 30246 return ( parseFloat( curCSS( elem, "marginLeft" ) ) || 30247 elem.getBoundingClientRect().left - 30248 swap( elem, { marginLeft: 0 }, function() { 30249 return elem.getBoundingClientRect().left; 30250 } ) 30251 ) + "px"; 30252 } 30253 } 30254); 30255 30256// These hooks are used by animate to expand properties 30257jQuery.each( { 30258 margin: "", 30259 padding: "", 30260 border: "Width" 30261}, function( prefix, suffix ) { 30262 jQuery.cssHooks[ prefix + suffix ] = { 30263 expand: function( value ) { 30264 var i = 0, 30265 expanded = {}, 30266 30267 // Assumes a single number if not a string 30268 parts = typeof value === "string" ? value.split( " " ) : [ value ]; 30269 30270 for ( ; i < 4; i++ ) { 30271 expanded[ prefix + cssExpand[ i ] + suffix ] = 30272 parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; 30273 } 30274 30275 return expanded; 30276 } 30277 }; 30278 30279 if ( prefix !== "margin" ) { 30280 jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; 30281 } 30282} ); 30283 30284jQuery.fn.extend( { 30285 css: function( name, value ) { 30286 return access( this, function( elem, name, value ) { 30287 var styles, len, 30288 map = {}, 30289 i = 0; 30290 30291 if ( Array.isArray( name ) ) { 30292 styles = getStyles( elem ); 30293 len = name.length; 30294 30295 for ( ; i < len; i++ ) { 30296 map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); 30297 } 30298 30299 return map; 30300 } 30301 30302 return value !== undefined ? 30303 jQuery.style( elem, name, value ) : 30304 jQuery.css( elem, name ); 30305 }, name, value, arguments.length > 1 ); 30306 } 30307} ); 30308 30309 30310function Tween( elem, options, prop, end, easing ) { 30311 return new Tween.prototype.init( elem, options, prop, end, easing ); 30312} 30313jQuery.Tween = Tween; 30314 30315Tween.prototype = { 30316 constructor: Tween, 30317 init: function( elem, options, prop, end, easing, unit ) { 30318 this.elem = elem; 30319 this.prop = prop; 30320 this.easing = easing || jQuery.easing._default; 30321 this.options = options; 30322 this.start = this.now = this.cur(); 30323 this.end = end; 30324 this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); 30325 }, 30326 cur: function() { 30327 var hooks = Tween.propHooks[ this.prop ]; 30328 30329 return hooks && hooks.get ? 30330 hooks.get( this ) : 30331 Tween.propHooks._default.get( this ); 30332 }, 30333 run: function( percent ) { 30334 var eased, 30335 hooks = Tween.propHooks[ this.prop ]; 30336 30337 if ( this.options.duration ) { 30338 this.pos = eased = jQuery.easing[ this.easing ]( 30339 percent, this.options.duration * percent, 0, 1, this.options.duration 30340 ); 30341 } else { 30342 this.pos = eased = percent; 30343 } 30344 this.now = ( this.end - this.start ) * eased + this.start; 30345 30346 if ( this.options.step ) { 30347 this.options.step.call( this.elem, this.now, this ); 30348 } 30349 30350 if ( hooks && hooks.set ) { 30351 hooks.set( this ); 30352 } else { 30353 Tween.propHooks._default.set( this ); 30354 } 30355 return this; 30356 } 30357}; 30358 30359Tween.prototype.init.prototype = Tween.prototype; 30360 30361Tween.propHooks = { 30362 _default: { 30363 get: function( tween ) { 30364 var result; 30365 30366 // Use a property on the element directly when it is not a DOM element, 30367 // or when there is no matching style property that exists. 30368 if ( tween.elem.nodeType !== 1 || 30369 tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) { 30370 return tween.elem[ tween.prop ]; 30371 } 30372 30373 // Passing an empty string as a 3rd parameter to .css will automatically 30374 // attempt a parseFloat and fallback to a string if the parse fails. 30375 // Simple values such as "10px" are parsed to Float; 30376 // complex values such as "rotate(1rad)" are returned as-is. 30377 result = jQuery.css( tween.elem, tween.prop, "" ); 30378 30379 // Empty strings, null, undefined and "auto" are converted to 0. 30380 return !result || result === "auto" ? 0 : result; 30381 }, 30382 set: function( tween ) { 30383 30384 // Use step hook for back compat. 30385 // Use cssHook if its there. 30386 // Use .style if available and use plain properties where available. 30387 if ( jQuery.fx.step[ tween.prop ] ) { 30388 jQuery.fx.step[ tween.prop ]( tween ); 30389 } else if ( tween.elem.nodeType === 1 && ( 30390 jQuery.cssHooks[ tween.prop ] || 30391 tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) { 30392 jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); 30393 } else { 30394 tween.elem[ tween.prop ] = tween.now; 30395 } 30396 } 30397 } 30398}; 30399 30400// Support: IE <=9 only 30401// Panic based approach to setting things on disconnected nodes 30402Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { 30403 set: function( tween ) { 30404 if ( tween.elem.nodeType && tween.elem.parentNode ) { 30405 tween.elem[ tween.prop ] = tween.now; 30406 } 30407 } 30408}; 30409 30410jQuery.easing = { 30411 linear: function( p ) { 30412 return p; 30413 }, 30414 swing: function( p ) { 30415 return 0.5 - Math.cos( p * Math.PI ) / 2; 30416 }, 30417 _default: "swing" 30418}; 30419 30420jQuery.fx = Tween.prototype.init; 30421 30422// Back compat <1.8 extension point 30423jQuery.fx.step = {}; 30424 30425 30426 30427 30428var 30429 fxNow, inProgress, 30430 rfxtypes = /^(?:toggle|show|hide)$/, 30431 rrun = /queueHooks$/; 30432 30433function schedule() { 30434 if ( inProgress ) { 30435 if ( document.hidden === false && window.requestAnimationFrame ) { 30436 window.requestAnimationFrame( schedule ); 30437 } else { 30438 window.setTimeout( schedule, jQuery.fx.interval ); 30439 } 30440 30441 jQuery.fx.tick(); 30442 } 30443} 30444 30445// Animations created synchronously will run synchronously 30446function createFxNow() { 30447 window.setTimeout( function() { 30448 fxNow = undefined; 30449 } ); 30450 return ( fxNow = Date.now() ); 30451} 30452 30453// Generate parameters to create a standard animation 30454function genFx( type, includeWidth ) { 30455 var which, 30456 i = 0, 30457 attrs = { height: type }; 30458 30459 // If we include width, step value is 1 to do all cssExpand values, 30460 // otherwise step value is 2 to skip over Left and Right 30461 includeWidth = includeWidth ? 1 : 0; 30462 for ( ; i < 4; i += 2 - includeWidth ) { 30463 which = cssExpand[ i ]; 30464 attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; 30465 } 30466 30467 if ( includeWidth ) { 30468 attrs.opacity = attrs.width = type; 30469 } 30470 30471 return attrs; 30472} 30473 30474function createTween( value, prop, animation ) { 30475 var tween, 30476 collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), 30477 index = 0, 30478 length = collection.length; 30479 for ( ; index < length; index++ ) { 30480 if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { 30481 30482 // We're done with this property 30483 return tween; 30484 } 30485 } 30486} 30487 30488function defaultPrefilter( elem, props, opts ) { 30489 var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, 30490 isBox = "width" in props || "height" in props, 30491 anim = this, 30492 orig = {}, 30493 style = elem.style, 30494 hidden = elem.nodeType && isHiddenWithinTree( elem ), 30495 dataShow = dataPriv.get( elem, "fxshow" ); 30496 30497 // Queue-skipping animations hijack the fx hooks 30498 if ( !opts.queue ) { 30499 hooks = jQuery._queueHooks( elem, "fx" ); 30500 if ( hooks.unqueued == null ) { 30501 hooks.unqueued = 0; 30502 oldfire = hooks.empty.fire; 30503 hooks.empty.fire = function() { 30504 if ( !hooks.unqueued ) { 30505 oldfire(); 30506 } 30507 }; 30508 } 30509 hooks.unqueued++; 30510 30511 anim.always( function() { 30512 30513 // Ensure the complete handler is called before this completes 30514 anim.always( function() { 30515 hooks.unqueued--; 30516 if ( !jQuery.queue( elem, "fx" ).length ) { 30517 hooks.empty.fire(); 30518 } 30519 } ); 30520 } ); 30521 } 30522 30523 // Detect show/hide animations 30524 for ( prop in props ) { 30525 value = props[ prop ]; 30526 if ( rfxtypes.test( value ) ) { 30527 delete props[ prop ]; 30528 toggle = toggle || value === "toggle"; 30529 if ( value === ( hidden ? "hide" : "show" ) ) { 30530 30531 // Pretend to be hidden if this is a "show" and 30532 // there is still data from a stopped show/hide 30533 if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { 30534 hidden = true; 30535 30536 // Ignore all other no-op show/hide data 30537 } else { 30538 continue; 30539 } 30540 } 30541 orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); 30542 } 30543 } 30544 30545 // Bail out if this is a no-op like .hide().hide() 30546 propTween = !jQuery.isEmptyObject( props ); 30547 if ( !propTween && jQuery.isEmptyObject( orig ) ) { 30548 return; 30549 } 30550 30551 // Restrict "overflow" and "display" styles during box animations 30552 if ( isBox && elem.nodeType === 1 ) { 30553 30554 // Support: IE <=9 - 11, Edge 12 - 15 30555 // Record all 3 overflow attributes because IE does not infer the shorthand 30556 // from identically-valued overflowX and overflowY and Edge just mirrors 30557 // the overflowX value there. 30558 opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; 30559 30560 // Identify a display type, preferring old show/hide data over the CSS cascade 30561 restoreDisplay = dataShow && dataShow.display; 30562 if ( restoreDisplay == null ) { 30563 restoreDisplay = dataPriv.get( elem, "display" ); 30564 } 30565 display = jQuery.css( elem, "display" ); 30566 if ( display === "none" ) { 30567 if ( restoreDisplay ) { 30568 display = restoreDisplay; 30569 } else { 30570 30571 // Get nonempty value(s) by temporarily forcing visibility 30572 showHide( [ elem ], true ); 30573 restoreDisplay = elem.style.display || restoreDisplay; 30574 display = jQuery.css( elem, "display" ); 30575 showHide( [ elem ] ); 30576 } 30577 } 30578 30579 // Animate inline elements as inline-block 30580 if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { 30581 if ( jQuery.css( elem, "float" ) === "none" ) { 30582 30583 // Restore the original display value at the end of pure show/hide animations 30584 if ( !propTween ) { 30585 anim.done( function() { 30586 style.display = restoreDisplay; 30587 } ); 30588 if ( restoreDisplay == null ) { 30589 display = style.display; 30590 restoreDisplay = display === "none" ? "" : display; 30591 } 30592 } 30593 style.display = "inline-block"; 30594 } 30595 } 30596 } 30597 30598 if ( opts.overflow ) { 30599 style.overflow = "hidden"; 30600 anim.always( function() { 30601 style.overflow = opts.overflow[ 0 ]; 30602 style.overflowX = opts.overflow[ 1 ]; 30603 style.overflowY = opts.overflow[ 2 ]; 30604 } ); 30605 } 30606 30607 // Implement show/hide animations 30608 propTween = false; 30609 for ( prop in orig ) { 30610 30611 // General show/hide setup for this element animation 30612 if ( !propTween ) { 30613 if ( dataShow ) { 30614 if ( "hidden" in dataShow ) { 30615 hidden = dataShow.hidden; 30616 } 30617 } else { 30618 dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); 30619 } 30620 30621 // Store hidden/visible for toggle so `.stop().toggle()` "reverses" 30622 if ( toggle ) { 30623 dataShow.hidden = !hidden; 30624 } 30625 30626 // Show elements before animating them 30627 if ( hidden ) { 30628 showHide( [ elem ], true ); 30629 } 30630 30631 /* eslint-disable no-loop-func */ 30632 30633 anim.done( function() { 30634 30635 /* eslint-enable no-loop-func */ 30636 30637 // The final step of a "hide" animation is actually hiding the element 30638 if ( !hidden ) { 30639 showHide( [ elem ] ); 30640 } 30641 dataPriv.remove( elem, "fxshow" ); 30642 for ( prop in orig ) { 30643 jQuery.style( elem, prop, orig[ prop ] ); 30644 } 30645 } ); 30646 } 30647 30648 // Per-property setup 30649 propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); 30650 if ( !( prop in dataShow ) ) { 30651 dataShow[ prop ] = propTween.start; 30652 if ( hidden ) { 30653 propTween.end = propTween.start; 30654 propTween.start = 0; 30655 } 30656 } 30657 } 30658} 30659 30660function propFilter( props, specialEasing ) { 30661 var index, name, easing, value, hooks; 30662 30663 // camelCase, specialEasing and expand cssHook pass 30664 for ( index in props ) { 30665 name = camelCase( index ); 30666 easing = specialEasing[ name ]; 30667 value = props[ index ]; 30668 if ( Array.isArray( value ) ) { 30669 easing = value[ 1 ]; 30670 value = props[ index ] = value[ 0 ]; 30671 } 30672 30673 if ( index !== name ) { 30674 props[ name ] = value; 30675 delete props[ index ]; 30676 } 30677 30678 hooks = jQuery.cssHooks[ name ]; 30679 if ( hooks && "expand" in hooks ) { 30680 value = hooks.expand( value ); 30681 delete props[ name ]; 30682 30683 // Not quite $.extend, this won't overwrite existing keys. 30684 // Reusing 'index' because we have the correct "name" 30685 for ( index in value ) { 30686 if ( !( index in props ) ) { 30687 props[ index ] = value[ index ]; 30688 specialEasing[ index ] = easing; 30689 } 30690 } 30691 } else { 30692 specialEasing[ name ] = easing; 30693 } 30694 } 30695} 30696 30697function Animation( elem, properties, options ) { 30698 var result, 30699 stopped, 30700 index = 0, 30701 length = Animation.prefilters.length, 30702 deferred = jQuery.Deferred().always( function() { 30703 30704 // Don't match elem in the :animated selector 30705 delete tick.elem; 30706 } ), 30707 tick = function() { 30708 if ( stopped ) { 30709 return false; 30710 } 30711 var currentTime = fxNow || createFxNow(), 30712 remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), 30713 30714 // Support: Android 2.3 only 30715 // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) 30716 temp = remaining / animation.duration || 0, 30717 percent = 1 - temp, 30718 index = 0, 30719 length = animation.tweens.length; 30720 30721 for ( ; index < length; index++ ) { 30722 animation.tweens[ index ].run( percent ); 30723 } 30724 30725 deferred.notifyWith( elem, [ animation, percent, remaining ] ); 30726 30727 // If there's more to do, yield 30728 if ( percent < 1 && length ) { 30729 return remaining; 30730 } 30731 30732 // If this was an empty animation, synthesize a final progress notification 30733 if ( !length ) { 30734 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 30735 } 30736 30737 // Resolve the animation and report its conclusion 30738 deferred.resolveWith( elem, [ animation ] ); 30739 return false; 30740 }, 30741 animation = deferred.promise( { 30742 elem: elem, 30743 props: jQuery.extend( {}, properties ), 30744 opts: jQuery.extend( true, { 30745 specialEasing: {}, 30746 easing: jQuery.easing._default 30747 }, options ), 30748 originalProperties: properties, 30749 originalOptions: options, 30750 startTime: fxNow || createFxNow(), 30751 duration: options.duration, 30752 tweens: [], 30753 createTween: function( prop, end ) { 30754 var tween = jQuery.Tween( elem, animation.opts, prop, end, 30755 animation.opts.specialEasing[ prop ] || animation.opts.easing ); 30756 animation.tweens.push( tween ); 30757 return tween; 30758 }, 30759 stop: function( gotoEnd ) { 30760 var index = 0, 30761 30762 // If we are going to the end, we want to run all the tweens 30763 // otherwise we skip this part 30764 length = gotoEnd ? animation.tweens.length : 0; 30765 if ( stopped ) { 30766 return this; 30767 } 30768 stopped = true; 30769 for ( ; index < length; index++ ) { 30770 animation.tweens[ index ].run( 1 ); 30771 } 30772 30773 // Resolve when we played the last frame; otherwise, reject 30774 if ( gotoEnd ) { 30775 deferred.notifyWith( elem, [ animation, 1, 0 ] ); 30776 deferred.resolveWith( elem, [ animation, gotoEnd ] ); 30777 } else { 30778 deferred.rejectWith( elem, [ animation, gotoEnd ] ); 30779 } 30780 return this; 30781 } 30782 } ), 30783 props = animation.props; 30784 30785 propFilter( props, animation.opts.specialEasing ); 30786 30787 for ( ; index < length; index++ ) { 30788 result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); 30789 if ( result ) { 30790 if ( isFunction( result.stop ) ) { 30791 jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = 30792 result.stop.bind( result ); 30793 } 30794 return result; 30795 } 30796 } 30797 30798 jQuery.map( props, createTween, animation ); 30799 30800 if ( isFunction( animation.opts.start ) ) { 30801 animation.opts.start.call( elem, animation ); 30802 } 30803 30804 // Attach callbacks from options 30805 animation 30806 .progress( animation.opts.progress ) 30807 .done( animation.opts.done, animation.opts.complete ) 30808 .fail( animation.opts.fail ) 30809 .always( animation.opts.always ); 30810 30811 jQuery.fx.timer( 30812 jQuery.extend( tick, { 30813 elem: elem, 30814 anim: animation, 30815 queue: animation.opts.queue 30816 } ) 30817 ); 30818 30819 return animation; 30820} 30821 30822jQuery.Animation = jQuery.extend( Animation, { 30823 30824 tweeners: { 30825 "*": [ function( prop, value ) { 30826 var tween = this.createTween( prop, value ); 30827 adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); 30828 return tween; 30829 } ] 30830 }, 30831 30832 tweener: function( props, callback ) { 30833 if ( isFunction( props ) ) { 30834 callback = props; 30835 props = [ "*" ]; 30836 } else { 30837 props = props.match( rnothtmlwhite ); 30838 } 30839 30840 var prop, 30841 index = 0, 30842 length = props.length; 30843 30844 for ( ; index < length; index++ ) { 30845 prop = props[ index ]; 30846 Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; 30847 Animation.tweeners[ prop ].unshift( callback ); 30848 } 30849 }, 30850 30851 prefilters: [ defaultPrefilter ], 30852 30853 prefilter: function( callback, prepend ) { 30854 if ( prepend ) { 30855 Animation.prefilters.unshift( callback ); 30856 } else { 30857 Animation.prefilters.push( callback ); 30858 } 30859 } 30860} ); 30861 30862jQuery.speed = function( speed, easing, fn ) { 30863 var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { 30864 complete: fn || !fn && easing || 30865 isFunction( speed ) && speed, 30866 duration: speed, 30867 easing: fn && easing || easing && !isFunction( easing ) && easing 30868 }; 30869 30870 // Go to the end state if fx are off 30871 if ( jQuery.fx.off ) { 30872 opt.duration = 0; 30873 30874 } else { 30875 if ( typeof opt.duration !== "number" ) { 30876 if ( opt.duration in jQuery.fx.speeds ) { 30877 opt.duration = jQuery.fx.speeds[ opt.duration ]; 30878 30879 } else { 30880 opt.duration = jQuery.fx.speeds._default; 30881 } 30882 } 30883 } 30884 30885 // Normalize opt.queue - true/undefined/null -> "fx" 30886 if ( opt.queue == null || opt.queue === true ) { 30887 opt.queue = "fx"; 30888 } 30889 30890 // Queueing 30891 opt.old = opt.complete; 30892 30893 opt.complete = function() { 30894 if ( isFunction( opt.old ) ) { 30895 opt.old.call( this ); 30896 } 30897 30898 if ( opt.queue ) { 30899 jQuery.dequeue( this, opt.queue ); 30900 } 30901 }; 30902 30903 return opt; 30904}; 30905 30906jQuery.fn.extend( { 30907 fadeTo: function( speed, to, easing, callback ) { 30908 30909 // Show any hidden elements after setting opacity to 0 30910 return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() 30911 30912 // Animate to the value specified 30913 .end().animate( { opacity: to }, speed, easing, callback ); 30914 }, 30915 animate: function( prop, speed, easing, callback ) { 30916 var empty = jQuery.isEmptyObject( prop ), 30917 optall = jQuery.speed( speed, easing, callback ), 30918 doAnimation = function() { 30919 30920 // Operate on a copy of prop so per-property easing won't be lost 30921 var anim = Animation( this, jQuery.extend( {}, prop ), optall ); 30922 30923 // Empty animations, or finishing resolves immediately 30924 if ( empty || dataPriv.get( this, "finish" ) ) { 30925 anim.stop( true ); 30926 } 30927 }; 30928 doAnimation.finish = doAnimation; 30929 30930 return empty || optall.queue === false ? 30931 this.each( doAnimation ) : 30932 this.queue( optall.queue, doAnimation ); 30933 }, 30934 stop: function( type, clearQueue, gotoEnd ) { 30935 var stopQueue = function( hooks ) { 30936 var stop = hooks.stop; 30937 delete hooks.stop; 30938 stop( gotoEnd ); 30939 }; 30940 30941 if ( typeof type !== "string" ) { 30942 gotoEnd = clearQueue; 30943 clearQueue = type; 30944 type = undefined; 30945 } 30946 if ( clearQueue ) { 30947 this.queue( type || "fx", [] ); 30948 } 30949 30950 return this.each( function() { 30951 var dequeue = true, 30952 index = type != null && type + "queueHooks", 30953 timers = jQuery.timers, 30954 data = dataPriv.get( this ); 30955 30956 if ( index ) { 30957 if ( data[ index ] && data[ index ].stop ) { 30958 stopQueue( data[ index ] ); 30959 } 30960 } else { 30961 for ( index in data ) { 30962 if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { 30963 stopQueue( data[ index ] ); 30964 } 30965 } 30966 } 30967 30968 for ( index = timers.length; index--; ) { 30969 if ( timers[ index ].elem === this && 30970 ( type == null || timers[ index ].queue === type ) ) { 30971 30972 timers[ index ].anim.stop( gotoEnd ); 30973 dequeue = false; 30974 timers.splice( index, 1 ); 30975 } 30976 } 30977 30978 // Start the next in the queue if the last step wasn't forced. 30979 // Timers currently will call their complete callbacks, which 30980 // will dequeue but only if they were gotoEnd. 30981 if ( dequeue || !gotoEnd ) { 30982 jQuery.dequeue( this, type ); 30983 } 30984 } ); 30985 }, 30986 finish: function( type ) { 30987 if ( type !== false ) { 30988 type = type || "fx"; 30989 } 30990 return this.each( function() { 30991 var index, 30992 data = dataPriv.get( this ), 30993 queue = data[ type + "queue" ], 30994 hooks = data[ type + "queueHooks" ], 30995 timers = jQuery.timers, 30996 length = queue ? queue.length : 0; 30997 30998 // Enable finishing flag on private data 30999 data.finish = true; 31000 31001 // Empty the queue first 31002 jQuery.queue( this, type, [] ); 31003 31004 if ( hooks && hooks.stop ) { 31005 hooks.stop.call( this, true ); 31006 } 31007 31008 // Look for any active animations, and finish them 31009 for ( index = timers.length; index--; ) { 31010 if ( timers[ index ].elem === this && timers[ index ].queue === type ) { 31011 timers[ index ].anim.stop( true ); 31012 timers.splice( index, 1 ); 31013 } 31014 } 31015 31016 // Look for any animations in the old queue and finish them 31017 for ( index = 0; index < length; index++ ) { 31018 if ( queue[ index ] && queue[ index ].finish ) { 31019 queue[ index ].finish.call( this ); 31020 } 31021 } 31022 31023 // Turn off finishing flag 31024 delete data.finish; 31025 } ); 31026 } 31027} ); 31028 31029jQuery.each( [ "toggle", "show", "hide" ], function( _i, name ) { 31030 var cssFn = jQuery.fn[ name ]; 31031 jQuery.fn[ name ] = function( speed, easing, callback ) { 31032 return speed == null || typeof speed === "boolean" ? 31033 cssFn.apply( this, arguments ) : 31034 this.animate( genFx( name, true ), speed, easing, callback ); 31035 }; 31036} ); 31037 31038// Generate shortcuts for custom animations 31039jQuery.each( { 31040 slideDown: genFx( "show" ), 31041 slideUp: genFx( "hide" ), 31042 slideToggle: genFx( "toggle" ), 31043 fadeIn: { opacity: "show" }, 31044 fadeOut: { opacity: "hide" }, 31045 fadeToggle: { opacity: "toggle" } 31046}, function( name, props ) { 31047 jQuery.fn[ name ] = function( speed, easing, callback ) { 31048 return this.animate( props, speed, easing, callback ); 31049 }; 31050} ); 31051 31052jQuery.timers = []; 31053jQuery.fx.tick = function() { 31054 var timer, 31055 i = 0, 31056 timers = jQuery.timers; 31057 31058 fxNow = Date.now(); 31059 31060 for ( ; i < timers.length; i++ ) { 31061 timer = timers[ i ]; 31062 31063 // Run the timer and safely remove it when done (allowing for external removal) 31064 if ( !timer() && timers[ i ] === timer ) { 31065 timers.splice( i--, 1 ); 31066 } 31067 } 31068 31069 if ( !timers.length ) { 31070 jQuery.fx.stop(); 31071 } 31072 fxNow = undefined; 31073}; 31074 31075jQuery.fx.timer = function( timer ) { 31076 jQuery.timers.push( timer ); 31077 jQuery.fx.start(); 31078}; 31079 31080jQuery.fx.interval = 13; 31081jQuery.fx.start = function() { 31082 if ( inProgress ) { 31083 return; 31084 } 31085 31086 inProgress = true; 31087 schedule(); 31088}; 31089 31090jQuery.fx.stop = function() { 31091 inProgress = null; 31092}; 31093 31094jQuery.fx.speeds = { 31095 slow: 600, 31096 fast: 200, 31097 31098 // Default speed 31099 _default: 400 31100}; 31101 31102 31103// Based off of the plugin by Clint Helfers, with permission. 31104// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/ 31105jQuery.fn.delay = function( time, type ) { 31106 time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; 31107 type = type || "fx"; 31108 31109 return this.queue( type, function( next, hooks ) { 31110 var timeout = window.setTimeout( next, time ); 31111 hooks.stop = function() { 31112 window.clearTimeout( timeout ); 31113 }; 31114 } ); 31115}; 31116 31117 31118( function() { 31119 var input = document.createElement( "input" ), 31120 select = document.createElement( "select" ), 31121 opt = select.appendChild( document.createElement( "option" ) ); 31122 31123 input.type = "checkbox"; 31124 31125 // Support: Android <=4.3 only 31126 // Default value for a checkbox should be "on" 31127 support.checkOn = input.value !== ""; 31128 31129 // Support: IE <=11 only 31130 // Must access selectedIndex to make default options select 31131 support.optSelected = opt.selected; 31132 31133 // Support: IE <=11 only 31134 // An input loses its value after becoming a radio 31135 input = document.createElement( "input" ); 31136 input.value = "t"; 31137 input.type = "radio"; 31138 support.radioValue = input.value === "t"; 31139} )(); 31140 31141 31142var boolHook, 31143 attrHandle = jQuery.expr.attrHandle; 31144 31145jQuery.fn.extend( { 31146 attr: function( name, value ) { 31147 return access( this, jQuery.attr, name, value, arguments.length > 1 ); 31148 }, 31149 31150 removeAttr: function( name ) { 31151 return this.each( function() { 31152 jQuery.removeAttr( this, name ); 31153 } ); 31154 } 31155} ); 31156 31157jQuery.extend( { 31158 attr: function( elem, name, value ) { 31159 var ret, hooks, 31160 nType = elem.nodeType; 31161 31162 // Don't get/set attributes on text, comment and attribute nodes 31163 if ( nType === 3 || nType === 8 || nType === 2 ) { 31164 return; 31165 } 31166 31167 // Fallback to prop when attributes are not supported 31168 if ( typeof elem.getAttribute === "undefined" ) { 31169 return jQuery.prop( elem, name, value ); 31170 } 31171 31172 // Attribute hooks are determined by the lowercase version 31173 // Grab necessary hook if one is defined 31174 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 31175 hooks = jQuery.attrHooks[ name.toLowerCase() ] || 31176 ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined ); 31177 } 31178 31179 if ( value !== undefined ) { 31180 if ( value === null ) { 31181 jQuery.removeAttr( elem, name ); 31182 return; 31183 } 31184 31185 if ( hooks && "set" in hooks && 31186 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 31187 return ret; 31188 } 31189 31190 elem.setAttribute( name, value + "" ); 31191 return value; 31192 } 31193 31194 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 31195 return ret; 31196 } 31197 31198 ret = jQuery.find.attr( elem, name ); 31199 31200 // Non-existent attributes return null, we normalize to undefined 31201 return ret == null ? undefined : ret; 31202 }, 31203 31204 attrHooks: { 31205 type: { 31206 set: function( elem, value ) { 31207 if ( !support.radioValue && value === "radio" && 31208 nodeName( elem, "input" ) ) { 31209 var val = elem.value; 31210 elem.setAttribute( "type", value ); 31211 if ( val ) { 31212 elem.value = val; 31213 } 31214 return value; 31215 } 31216 } 31217 } 31218 }, 31219 31220 removeAttr: function( elem, value ) { 31221 var name, 31222 i = 0, 31223 31224 // Attribute names can contain non-HTML whitespace characters 31225 // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2 31226 attrNames = value && value.match( rnothtmlwhite ); 31227 31228 if ( attrNames && elem.nodeType === 1 ) { 31229 while ( ( name = attrNames[ i++ ] ) ) { 31230 elem.removeAttribute( name ); 31231 } 31232 } 31233 } 31234} ); 31235 31236// Hooks for boolean attributes 31237boolHook = { 31238 set: function( elem, value, name ) { 31239 if ( value === false ) { 31240 31241 // Remove boolean attributes when set to false 31242 jQuery.removeAttr( elem, name ); 31243 } else { 31244 elem.setAttribute( name, name ); 31245 } 31246 return name; 31247 } 31248}; 31249 31250jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( _i, name ) { 31251 var getter = attrHandle[ name ] || jQuery.find.attr; 31252 31253 attrHandle[ name ] = function( elem, name, isXML ) { 31254 var ret, handle, 31255 lowercaseName = name.toLowerCase(); 31256 31257 if ( !isXML ) { 31258 31259 // Avoid an infinite loop by temporarily removing this function from the getter 31260 handle = attrHandle[ lowercaseName ]; 31261 attrHandle[ lowercaseName ] = ret; 31262 ret = getter( elem, name, isXML ) != null ? 31263 lowercaseName : 31264 null; 31265 attrHandle[ lowercaseName ] = handle; 31266 } 31267 return ret; 31268 }; 31269} ); 31270 31271 31272 31273 31274var rfocusable = /^(?:input|select|textarea|button)$/i, 31275 rclickable = /^(?:a|area)$/i; 31276 31277jQuery.fn.extend( { 31278 prop: function( name, value ) { 31279 return access( this, jQuery.prop, name, value, arguments.length > 1 ); 31280 }, 31281 31282 removeProp: function( name ) { 31283 return this.each( function() { 31284 delete this[ jQuery.propFix[ name ] || name ]; 31285 } ); 31286 } 31287} ); 31288 31289jQuery.extend( { 31290 prop: function( elem, name, value ) { 31291 var ret, hooks, 31292 nType = elem.nodeType; 31293 31294 // Don't get/set properties on text, comment and attribute nodes 31295 if ( nType === 3 || nType === 8 || nType === 2 ) { 31296 return; 31297 } 31298 31299 if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { 31300 31301 // Fix name and attach hooks 31302 name = jQuery.propFix[ name ] || name; 31303 hooks = jQuery.propHooks[ name ]; 31304 } 31305 31306 if ( value !== undefined ) { 31307 if ( hooks && "set" in hooks && 31308 ( ret = hooks.set( elem, value, name ) ) !== undefined ) { 31309 return ret; 31310 } 31311 31312 return ( elem[ name ] = value ); 31313 } 31314 31315 if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) { 31316 return ret; 31317 } 31318 31319 return elem[ name ]; 31320 }, 31321 31322 propHooks: { 31323 tabIndex: { 31324 get: function( elem ) { 31325 31326 // Support: IE <=9 - 11 only 31327 // elem.tabIndex doesn't always return the 31328 // correct value when it hasn't been explicitly set 31329 // https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ 31330 // Use proper attribute retrieval(#12072) 31331 var tabindex = jQuery.find.attr( elem, "tabindex" ); 31332 31333 if ( tabindex ) { 31334 return parseInt( tabindex, 10 ); 31335 } 31336 31337 if ( 31338 rfocusable.test( elem.nodeName ) || 31339 rclickable.test( elem.nodeName ) && 31340 elem.href 31341 ) { 31342 return 0; 31343 } 31344 31345 return -1; 31346 } 31347 } 31348 }, 31349 31350 propFix: { 31351 "for": "htmlFor", 31352 "class": "className" 31353 } 31354} ); 31355 31356// Support: IE <=11 only 31357// Accessing the selectedIndex property 31358// forces the browser to respect setting selected 31359// on the option 31360// The getter ensures a default option is selected 31361// when in an optgroup 31362// eslint rule "no-unused-expressions" is disabled for this code 31363// since it considers such accessions noop 31364if ( !support.optSelected ) { 31365 jQuery.propHooks.selected = { 31366 get: function( elem ) { 31367 31368 /* eslint no-unused-expressions: "off" */ 31369 31370 var parent = elem.parentNode; 31371 if ( parent && parent.parentNode ) { 31372 parent.parentNode.selectedIndex; 31373 } 31374 return null; 31375 }, 31376 set: function( elem ) { 31377 31378 /* eslint no-unused-expressions: "off" */ 31379 31380 var parent = elem.parentNode; 31381 if ( parent ) { 31382 parent.selectedIndex; 31383 31384 if ( parent.parentNode ) { 31385 parent.parentNode.selectedIndex; 31386 } 31387 } 31388 } 31389 }; 31390} 31391 31392jQuery.each( [ 31393 "tabIndex", 31394 "readOnly", 31395 "maxLength", 31396 "cellSpacing", 31397 "cellPadding", 31398 "rowSpan", 31399 "colSpan", 31400 "useMap", 31401 "frameBorder", 31402 "contentEditable" 31403], function() { 31404 jQuery.propFix[ this.toLowerCase() ] = this; 31405} ); 31406 31407 31408 31409 31410 // Strip and collapse whitespace according to HTML spec 31411 // https://infra.spec.whatwg.org/#strip-and-collapse-ascii-whitespace 31412 function stripAndCollapse( value ) { 31413 var tokens = value.match( rnothtmlwhite ) || []; 31414 return tokens.join( " " ); 31415 } 31416 31417 31418function getClass( elem ) { 31419 return elem.getAttribute && elem.getAttribute( "class" ) || ""; 31420} 31421 31422function classesToArray( value ) { 31423 if ( Array.isArray( value ) ) { 31424 return value; 31425 } 31426 if ( typeof value === "string" ) { 31427 return value.match( rnothtmlwhite ) || []; 31428 } 31429 return []; 31430} 31431 31432jQuery.fn.extend( { 31433 addClass: function( value ) { 31434 var classes, elem, cur, curValue, clazz, j, finalValue, 31435 i = 0; 31436 31437 if ( isFunction( value ) ) { 31438 return this.each( function( j ) { 31439 jQuery( this ).addClass( value.call( this, j, getClass( this ) ) ); 31440 } ); 31441 } 31442 31443 classes = classesToArray( value ); 31444 31445 if ( classes.length ) { 31446 while ( ( elem = this[ i++ ] ) ) { 31447 curValue = getClass( elem ); 31448 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 31449 31450 if ( cur ) { 31451 j = 0; 31452 while ( ( clazz = classes[ j++ ] ) ) { 31453 if ( cur.indexOf( " " + clazz + " " ) < 0 ) { 31454 cur += clazz + " "; 31455 } 31456 } 31457 31458 // Only assign if different to avoid unneeded rendering. 31459 finalValue = stripAndCollapse( cur ); 31460 if ( curValue !== finalValue ) { 31461 elem.setAttribute( "class", finalValue ); 31462 } 31463 } 31464 } 31465 } 31466 31467 return this; 31468 }, 31469 31470 removeClass: function( value ) { 31471 var classes, elem, cur, curValue, clazz, j, finalValue, 31472 i = 0; 31473 31474 if ( isFunction( value ) ) { 31475 return this.each( function( j ) { 31476 jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) ); 31477 } ); 31478 } 31479 31480 if ( !arguments.length ) { 31481 return this.attr( "class", "" ); 31482 } 31483 31484 classes = classesToArray( value ); 31485 31486 if ( classes.length ) { 31487 while ( ( elem = this[ i++ ] ) ) { 31488 curValue = getClass( elem ); 31489 31490 // This expression is here for better compressibility (see addClass) 31491 cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " ); 31492 31493 if ( cur ) { 31494 j = 0; 31495 while ( ( clazz = classes[ j++ ] ) ) { 31496 31497 // Remove *all* instances 31498 while ( cur.indexOf( " " + clazz + " " ) > -1 ) { 31499 cur = cur.replace( " " + clazz + " ", " " ); 31500 } 31501 } 31502 31503 // Only assign if different to avoid unneeded rendering. 31504 finalValue = stripAndCollapse( cur ); 31505 if ( curValue !== finalValue ) { 31506 elem.setAttribute( "class", finalValue ); 31507 } 31508 } 31509 } 31510 } 31511 31512 return this; 31513 }, 31514 31515 toggleClass: function( value, stateVal ) { 31516 var type = typeof value, 31517 isValidValue = type === "string" || Array.isArray( value ); 31518 31519 if ( typeof stateVal === "boolean" && isValidValue ) { 31520 return stateVal ? this.addClass( value ) : this.removeClass( value ); 31521 } 31522 31523 if ( isFunction( value ) ) { 31524 return this.each( function( i ) { 31525 jQuery( this ).toggleClass( 31526 value.call( this, i, getClass( this ), stateVal ), 31527 stateVal 31528 ); 31529 } ); 31530 } 31531 31532 return this.each( function() { 31533 var className, i, self, classNames; 31534 31535 if ( isValidValue ) { 31536 31537 // Toggle individual class names 31538 i = 0; 31539 self = jQuery( this ); 31540 classNames = classesToArray( value ); 31541 31542 while ( ( className = classNames[ i++ ] ) ) { 31543 31544 // Check each className given, space separated list 31545 if ( self.hasClass( className ) ) { 31546 self.removeClass( className ); 31547 } else { 31548 self.addClass( className ); 31549 } 31550 } 31551 31552 // Toggle whole class name 31553 } else if ( value === undefined || type === "boolean" ) { 31554 className = getClass( this ); 31555 if ( className ) { 31556 31557 // Store className if set 31558 dataPriv.set( this, "__className__", className ); 31559 } 31560 31561 // If the element has a class name or if we're passed `false`, 31562 // then remove the whole classname (if there was one, the above saved it). 31563 // Otherwise bring back whatever was previously saved (if anything), 31564 // falling back to the empty string if nothing was stored. 31565 if ( this.setAttribute ) { 31566 this.setAttribute( "class", 31567 className || value === false ? 31568 "" : 31569 dataPriv.get( this, "__className__" ) || "" 31570 ); 31571 } 31572 } 31573 } ); 31574 }, 31575 31576 hasClass: function( selector ) { 31577 var className, elem, 31578 i = 0; 31579 31580 className = " " + selector + " "; 31581 while ( ( elem = this[ i++ ] ) ) { 31582 if ( elem.nodeType === 1 && 31583 ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > -1 ) { 31584 return true; 31585 } 31586 } 31587 31588 return false; 31589 } 31590} ); 31591 31592 31593 31594 31595var rreturn = /\r/g; 31596 31597jQuery.fn.extend( { 31598 val: function( value ) { 31599 var hooks, ret, valueIsFunction, 31600 elem = this[ 0 ]; 31601 31602 if ( !arguments.length ) { 31603 if ( elem ) { 31604 hooks = jQuery.valHooks[ elem.type ] || 31605 jQuery.valHooks[ elem.nodeName.toLowerCase() ]; 31606 31607 if ( hooks && 31608 "get" in hooks && 31609 ( ret = hooks.get( elem, "value" ) ) !== undefined 31610 ) { 31611 return ret; 31612 } 31613 31614 ret = elem.value; 31615 31616 // Handle most common string cases 31617 if ( typeof ret === "string" ) { 31618 return ret.replace( rreturn, "" ); 31619 } 31620 31621 // Handle cases where value is null/undef or number 31622 return ret == null ? "" : ret; 31623 } 31624 31625 return; 31626 } 31627 31628 valueIsFunction = isFunction( value ); 31629 31630 return this.each( function( i ) { 31631 var val; 31632 31633 if ( this.nodeType !== 1 ) { 31634 return; 31635 } 31636 31637 if ( valueIsFunction ) { 31638 val = value.call( this, i, jQuery( this ).val() ); 31639 } else { 31640 val = value; 31641 } 31642 31643 // Treat null/undefined as ""; convert numbers to string 31644 if ( val == null ) { 31645 val = ""; 31646 31647 } else if ( typeof val === "number" ) { 31648 val += ""; 31649 31650 } else if ( Array.isArray( val ) ) { 31651 val = jQuery.map( val, function( value ) { 31652 return value == null ? "" : value + ""; 31653 } ); 31654 } 31655 31656 hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; 31657 31658 // If set returns undefined, fall back to normal setting 31659 if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) { 31660 this.value = val; 31661 } 31662 } ); 31663 } 31664} ); 31665 31666jQuery.extend( { 31667 valHooks: { 31668 option: { 31669 get: function( elem ) { 31670 31671 var val = jQuery.find.attr( elem, "value" ); 31672 return val != null ? 31673 val : 31674 31675 // Support: IE <=10 - 11 only 31676 // option.text throws exceptions (#14686, #14858) 31677 // Strip and collapse whitespace 31678 // https://html.spec.whatwg.org/#strip-and-collapse-whitespace 31679 stripAndCollapse( jQuery.text( elem ) ); 31680 } 31681 }, 31682 select: { 31683 get: function( elem ) { 31684 var value, option, i, 31685 options = elem.options, 31686 index = elem.selectedIndex, 31687 one = elem.type === "select-one", 31688 values = one ? null : [], 31689 max = one ? index + 1 : options.length; 31690 31691 if ( index < 0 ) { 31692 i = max; 31693 31694 } else { 31695 i = one ? index : 0; 31696 } 31697 31698 // Loop through all the selected options 31699 for ( ; i < max; i++ ) { 31700 option = options[ i ]; 31701 31702 // Support: IE <=9 only 31703 // IE8-9 doesn't update selected after form reset (#2551) 31704 if ( ( option.selected || i === index ) && 31705 31706 // Don't return options that are disabled or in a disabled optgroup 31707 !option.disabled && 31708 ( !option.parentNode.disabled || 31709 !nodeName( option.parentNode, "optgroup" ) ) ) { 31710 31711 // Get the specific value for the option 31712 value = jQuery( option ).val(); 31713 31714 // We don't need an array for one selects 31715 if ( one ) { 31716 return value; 31717 } 31718 31719 // Multi-Selects return an array 31720 values.push( value ); 31721 } 31722 } 31723 31724 return values; 31725 }, 31726 31727 set: function( elem, value ) { 31728 var optionSet, option, 31729 options = elem.options, 31730 values = jQuery.makeArray( value ), 31731 i = options.length; 31732 31733 while ( i-- ) { 31734 option = options[ i ]; 31735 31736 /* eslint-disable no-cond-assign */ 31737 31738 if ( option.selected = 31739 jQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1 31740 ) { 31741 optionSet = true; 31742 } 31743 31744 /* eslint-enable no-cond-assign */ 31745 } 31746 31747 // Force browsers to behave consistently when non-matching value is set 31748 if ( !optionSet ) { 31749 elem.selectedIndex = -1; 31750 } 31751 return values; 31752 } 31753 } 31754 } 31755} ); 31756 31757// Radios and checkboxes getter/setter 31758jQuery.each( [ "radio", "checkbox" ], function() { 31759 jQuery.valHooks[ this ] = { 31760 set: function( elem, value ) { 31761 if ( Array.isArray( value ) ) { 31762 return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 ); 31763 } 31764 } 31765 }; 31766 if ( !support.checkOn ) { 31767 jQuery.valHooks[ this ].get = function( elem ) { 31768 return elem.getAttribute( "value" ) === null ? "on" : elem.value; 31769 }; 31770 } 31771} ); 31772 31773 31774 31775 31776// Return jQuery for attributes-only inclusion 31777 31778 31779support.focusin = "onfocusin" in window; 31780 31781 31782var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, 31783 stopPropagationCallback = function( e ) { 31784 e.stopPropagation(); 31785 }; 31786 31787jQuery.extend( jQuery.event, { 31788 31789 trigger: function( event, data, elem, onlyHandlers ) { 31790 31791 var i, cur, tmp, bubbleType, ontype, handle, special, lastElement, 31792 eventPath = [ elem || document ], 31793 type = hasOwn.call( event, "type" ) ? event.type : event, 31794 namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : []; 31795 31796 cur = lastElement = tmp = elem = elem || document; 31797 31798 // Don't do events on text and comment nodes 31799 if ( elem.nodeType === 3 || elem.nodeType === 8 ) { 31800 return; 31801 } 31802 31803 // focus/blur morphs to focusin/out; ensure we're not firing them right now 31804 if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { 31805 return; 31806 } 31807 31808 if ( type.indexOf( "." ) > -1 ) { 31809 31810 // Namespaced trigger; create a regexp to match event type in handle() 31811 namespaces = type.split( "." ); 31812 type = namespaces.shift(); 31813 namespaces.sort(); 31814 } 31815 ontype = type.indexOf( ":" ) < 0 && "on" + type; 31816 31817 // Caller can pass in a jQuery.Event object, Object, or just an event type string 31818 event = event[ jQuery.expando ] ? 31819 event : 31820 new jQuery.Event( type, typeof event === "object" && event ); 31821 31822 // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) 31823 event.isTrigger = onlyHandlers ? 2 : 3; 31824 event.namespace = namespaces.join( "." ); 31825 event.rnamespace = event.namespace ? 31826 new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) : 31827 null; 31828 31829 // Clean up the event in case it is being reused 31830 event.result = undefined; 31831 if ( !event.target ) { 31832 event.target = elem; 31833 } 31834 31835 // Clone any incoming data and prepend the event, creating the handler arg list 31836 data = data == null ? 31837 [ event ] : 31838 jQuery.makeArray( data, [ event ] ); 31839 31840 // Allow special events to draw outside the lines 31841 special = jQuery.event.special[ type ] || {}; 31842 if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { 31843 return; 31844 } 31845 31846 // Determine event propagation path in advance, per W3C events spec (#9951) 31847 // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) 31848 if ( !onlyHandlers && !special.noBubble && !isWindow( elem ) ) { 31849 31850 bubbleType = special.delegateType || type; 31851 if ( !rfocusMorph.test( bubbleType + type ) ) { 31852 cur = cur.parentNode; 31853 } 31854 for ( ; cur; cur = cur.parentNode ) { 31855 eventPath.push( cur ); 31856 tmp = cur; 31857 } 31858 31859 // Only add window if we got to document (e.g., not plain obj or detached DOM) 31860 if ( tmp === ( elem.ownerDocument || document ) ) { 31861 eventPath.push( tmp.defaultView || tmp.parentWindow || window ); 31862 } 31863 } 31864 31865 // Fire handlers on the event path 31866 i = 0; 31867 while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) { 31868 lastElement = cur; 31869 event.type = i > 1 ? 31870 bubbleType : 31871 special.bindType || type; 31872 31873 // jQuery handler 31874 handle = ( 31875 dataPriv.get( cur, "events" ) || Object.create( null ) 31876 )[ event.type ] && 31877 dataPriv.get( cur, "handle" ); 31878 if ( handle ) { 31879 handle.apply( cur, data ); 31880 } 31881 31882 // Native handler 31883 handle = ontype && cur[ ontype ]; 31884 if ( handle && handle.apply && acceptData( cur ) ) { 31885 event.result = handle.apply( cur, data ); 31886 if ( event.result === false ) { 31887 event.preventDefault(); 31888 } 31889 } 31890 } 31891 event.type = type; 31892 31893 // If nobody prevented the default action, do it now 31894 if ( !onlyHandlers && !event.isDefaultPrevented() ) { 31895 31896 if ( ( !special._default || 31897 special._default.apply( eventPath.pop(), data ) === false ) && 31898 acceptData( elem ) ) { 31899 31900 // Call a native DOM method on the target with the same name as the event. 31901 // Don't do default actions on window, that's where global variables be (#6170) 31902 if ( ontype && isFunction( elem[ type ] ) && !isWindow( elem ) ) { 31903 31904 // Don't re-trigger an onFOO event when we call its FOO() method 31905 tmp = elem[ ontype ]; 31906 31907 if ( tmp ) { 31908 elem[ ontype ] = null; 31909 } 31910 31911 // Prevent re-triggering of the same event, since we already bubbled it above 31912 jQuery.event.triggered = type; 31913 31914 if ( event.isPropagationStopped() ) { 31915 lastElement.addEventListener( type, stopPropagationCallback ); 31916 } 31917 31918 elem[ type ](); 31919 31920 if ( event.isPropagationStopped() ) { 31921 lastElement.removeEventListener( type, stopPropagationCallback ); 31922 } 31923 31924 jQuery.event.triggered = undefined; 31925 31926 if ( tmp ) { 31927 elem[ ontype ] = tmp; 31928 } 31929 } 31930 } 31931 } 31932 31933 return event.result; 31934 }, 31935 31936 // Piggyback on a donor event to simulate a different one 31937 // Used only for `focus(in | out)` events 31938 simulate: function( type, elem, event ) { 31939 var e = jQuery.extend( 31940 new jQuery.Event(), 31941 event, 31942 { 31943 type: type, 31944 isSimulated: true 31945 } 31946 ); 31947 31948 jQuery.event.trigger( e, null, elem ); 31949 } 31950 31951} ); 31952 31953jQuery.fn.extend( { 31954 31955 trigger: function( type, data ) { 31956 return this.each( function() { 31957 jQuery.event.trigger( type, data, this ); 31958 } ); 31959 }, 31960 triggerHandler: function( type, data ) { 31961 var elem = this[ 0 ]; 31962 if ( elem ) { 31963 return jQuery.event.trigger( type, data, elem, true ); 31964 } 31965 } 31966} ); 31967 31968 31969// Support: Firefox <=44 31970// Firefox doesn't have focus(in | out) events 31971// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787 31972// 31973// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1 31974// focus(in | out) events fire after focus & blur events, 31975// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order 31976// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857 31977if ( !support.focusin ) { 31978 jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) { 31979 31980 // Attach a single capturing handler on the document while someone wants focusin/focusout 31981 var handler = function( event ) { 31982 jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) ); 31983 }; 31984 31985 jQuery.event.special[ fix ] = { 31986 setup: function() { 31987 31988 // Handle: regular nodes (via `this.ownerDocument`), window 31989 // (via `this.document`) & document (via `this`). 31990 var doc = this.ownerDocument || this.document || this, 31991 attaches = dataPriv.access( doc, fix ); 31992 31993 if ( !attaches ) { 31994 doc.addEventListener( orig, handler, true ); 31995 } 31996 dataPriv.access( doc, fix, ( attaches || 0 ) + 1 ); 31997 }, 31998 teardown: function() { 31999 var doc = this.ownerDocument || this.document || this, 32000 attaches = dataPriv.access( doc, fix ) - 1; 32001 32002 if ( !attaches ) { 32003 doc.removeEventListener( orig, handler, true ); 32004 dataPriv.remove( doc, fix ); 32005 32006 } else { 32007 dataPriv.access( doc, fix, attaches ); 32008 } 32009 } 32010 }; 32011 } ); 32012} 32013var location = window.location; 32014 32015var nonce = { guid: Date.now() }; 32016 32017var rquery = ( /\?/ ); 32018 32019 32020 32021// Cross-browser xml parsing 32022jQuery.parseXML = function( data ) { 32023 var xml; 32024 if ( !data || typeof data !== "string" ) { 32025 return null; 32026 } 32027 32028 // Support: IE 9 - 11 only 32029 // IE throws on parseFromString with invalid input. 32030 try { 32031 xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" ); 32032 } catch ( e ) { 32033 xml = undefined; 32034 } 32035 32036 if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) { 32037 jQuery.error( "Invalid XML: " + data ); 32038 } 32039 return xml; 32040}; 32041 32042 32043var 32044 rbracket = /\[\]$/, 32045 rCRLF = /\r?\n/g, 32046 rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, 32047 rsubmittable = /^(?:input|select|textarea|keygen)/i; 32048 32049function buildParams( prefix, obj, traditional, add ) { 32050 var name; 32051 32052 if ( Array.isArray( obj ) ) { 32053 32054 // Serialize array item. 32055 jQuery.each( obj, function( i, v ) { 32056 if ( traditional || rbracket.test( prefix ) ) { 32057 32058 // Treat each array item as a scalar. 32059 add( prefix, v ); 32060 32061 } else { 32062 32063 // Item is non-scalar (array or object), encode its numeric index. 32064 buildParams( 32065 prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]", 32066 v, 32067 traditional, 32068 add 32069 ); 32070 } 32071 } ); 32072 32073 } else if ( !traditional && toType( obj ) === "object" ) { 32074 32075 // Serialize object item. 32076 for ( name in obj ) { 32077 buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); 32078 } 32079 32080 } else { 32081 32082 // Serialize scalar item. 32083 add( prefix, obj ); 32084 } 32085} 32086 32087// Serialize an array of form elements or a set of 32088// key/values into a query string 32089jQuery.param = function( a, traditional ) { 32090 var prefix, 32091 s = [], 32092 add = function( key, valueOrFunction ) { 32093 32094 // If value is a function, invoke it and use its return value 32095 var value = isFunction( valueOrFunction ) ? 32096 valueOrFunction() : 32097 valueOrFunction; 32098 32099 s[ s.length ] = encodeURIComponent( key ) + "=" + 32100 encodeURIComponent( value == null ? "" : value ); 32101 }; 32102 32103 if ( a == null ) { 32104 return ""; 32105 } 32106 32107 // If an array was passed in, assume that it is an array of form elements. 32108 if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { 32109 32110 // Serialize the form elements 32111 jQuery.each( a, function() { 32112 add( this.name, this.value ); 32113 } ); 32114 32115 } else { 32116 32117 // If traditional, encode the "old" way (the way 1.3.2 or older 32118 // did it), otherwise encode params recursively. 32119 for ( prefix in a ) { 32120 buildParams( prefix, a[ prefix ], traditional, add ); 32121 } 32122 } 32123 32124 // Return the resulting serialization 32125 return s.join( "&" ); 32126}; 32127 32128jQuery.fn.extend( { 32129 serialize: function() { 32130 return jQuery.param( this.serializeArray() ); 32131 }, 32132 serializeArray: function() { 32133 return this.map( function() { 32134 32135 // Can add propHook for "elements" to filter or add form elements 32136 var elements = jQuery.prop( this, "elements" ); 32137 return elements ? jQuery.makeArray( elements ) : this; 32138 } ) 32139 .filter( function() { 32140 var type = this.type; 32141 32142 // Use .is( ":disabled" ) so that fieldset[disabled] works 32143 return this.name && !jQuery( this ).is( ":disabled" ) && 32144 rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && 32145 ( this.checked || !rcheckableType.test( type ) ); 32146 } ) 32147 .map( function( _i, elem ) { 32148 var val = jQuery( this ).val(); 32149 32150 if ( val == null ) { 32151 return null; 32152 } 32153 32154 if ( Array.isArray( val ) ) { 32155 return jQuery.map( val, function( val ) { 32156 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 32157 } ); 32158 } 32159 32160 return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; 32161 } ).get(); 32162 } 32163} ); 32164 32165 32166var 32167 r20 = /%20/g, 32168 rhash = /#.*$/, 32169 rantiCache = /([?&])_=[^&]*/, 32170 rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg, 32171 32172 // #7653, #8125, #8152: local protocol detection 32173 rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, 32174 rnoContent = /^(?:GET|HEAD)$/, 32175 rprotocol = /^\/\//, 32176 32177 /* Prefilters 32178 * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) 32179 * 2) These are called: 32180 * - BEFORE asking for a transport 32181 * - AFTER param serialization (s.data is a string if s.processData is true) 32182 * 3) key is the dataType 32183 * 4) the catchall symbol "*" can be used 32184 * 5) execution will start with transport dataType and THEN continue down to "*" if needed 32185 */ 32186 prefilters = {}, 32187 32188 /* Transports bindings 32189 * 1) key is the dataType 32190 * 2) the catchall symbol "*" can be used 32191 * 3) selection will start with transport dataType and THEN go to "*" if needed 32192 */ 32193 transports = {}, 32194 32195 // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression 32196 allTypes = "*/".concat( "*" ), 32197 32198 // Anchor tag for parsing the document origin 32199 originAnchor = document.createElement( "a" ); 32200 originAnchor.href = location.href; 32201 32202// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport 32203function addToPrefiltersOrTransports( structure ) { 32204 32205 // dataTypeExpression is optional and defaults to "*" 32206 return function( dataTypeExpression, func ) { 32207 32208 if ( typeof dataTypeExpression !== "string" ) { 32209 func = dataTypeExpression; 32210 dataTypeExpression = "*"; 32211 } 32212 32213 var dataType, 32214 i = 0, 32215 dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || []; 32216 32217 if ( isFunction( func ) ) { 32218 32219 // For each dataType in the dataTypeExpression 32220 while ( ( dataType = dataTypes[ i++ ] ) ) { 32221 32222 // Prepend if requested 32223 if ( dataType[ 0 ] === "+" ) { 32224 dataType = dataType.slice( 1 ) || "*"; 32225 ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func ); 32226 32227 // Otherwise append 32228 } else { 32229 ( structure[ dataType ] = structure[ dataType ] || [] ).push( func ); 32230 } 32231 } 32232 } 32233 }; 32234} 32235 32236// Base inspection function for prefilters and transports 32237function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { 32238 32239 var inspected = {}, 32240 seekingTransport = ( structure === transports ); 32241 32242 function inspect( dataType ) { 32243 var selected; 32244 inspected[ dataType ] = true; 32245 jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { 32246 var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); 32247 if ( typeof dataTypeOrTransport === "string" && 32248 !seekingTransport && !inspected[ dataTypeOrTransport ] ) { 32249 32250 options.dataTypes.unshift( dataTypeOrTransport ); 32251 inspect( dataTypeOrTransport ); 32252 return false; 32253 } else if ( seekingTransport ) { 32254 return !( selected = dataTypeOrTransport ); 32255 } 32256 } ); 32257 return selected; 32258 } 32259 32260 return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); 32261} 32262 32263// A special extend for ajax options 32264// that takes "flat" options (not to be deep extended) 32265// Fixes #9887 32266function ajaxExtend( target, src ) { 32267 var key, deep, 32268 flatOptions = jQuery.ajaxSettings.flatOptions || {}; 32269 32270 for ( key in src ) { 32271 if ( src[ key ] !== undefined ) { 32272 ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; 32273 } 32274 } 32275 if ( deep ) { 32276 jQuery.extend( true, target, deep ); 32277 } 32278 32279 return target; 32280} 32281 32282/* Handles responses to an ajax request: 32283 * - finds the right dataType (mediates between content-type and expected dataType) 32284 * - returns the corresponding response 32285 */ 32286function ajaxHandleResponses( s, jqXHR, responses ) { 32287 32288 var ct, type, finalDataType, firstDataType, 32289 contents = s.contents, 32290 dataTypes = s.dataTypes; 32291 32292 // Remove auto dataType and get content-type in the process 32293 while ( dataTypes[ 0 ] === "*" ) { 32294 dataTypes.shift(); 32295 if ( ct === undefined ) { 32296 ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" ); 32297 } 32298 } 32299 32300 // Check if we're dealing with a known content-type 32301 if ( ct ) { 32302 for ( type in contents ) { 32303 if ( contents[ type ] && contents[ type ].test( ct ) ) { 32304 dataTypes.unshift( type ); 32305 break; 32306 } 32307 } 32308 } 32309 32310 // Check to see if we have a response for the expected dataType 32311 if ( dataTypes[ 0 ] in responses ) { 32312 finalDataType = dataTypes[ 0 ]; 32313 } else { 32314 32315 // Try convertible dataTypes 32316 for ( type in responses ) { 32317 if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) { 32318 finalDataType = type; 32319 break; 32320 } 32321 if ( !firstDataType ) { 32322 firstDataType = type; 32323 } 32324 } 32325 32326 // Or just use first one 32327 finalDataType = finalDataType || firstDataType; 32328 } 32329 32330 // If we found a dataType 32331 // We add the dataType to the list if needed 32332 // and return the corresponding response 32333 if ( finalDataType ) { 32334 if ( finalDataType !== dataTypes[ 0 ] ) { 32335 dataTypes.unshift( finalDataType ); 32336 } 32337 return responses[ finalDataType ]; 32338 } 32339} 32340 32341/* Chain conversions given the request and the original response 32342 * Also sets the responseXXX fields on the jqXHR instance 32343 */ 32344function ajaxConvert( s, response, jqXHR, isSuccess ) { 32345 var conv2, current, conv, tmp, prev, 32346 converters = {}, 32347 32348 // Work with a copy of dataTypes in case we need to modify it for conversion 32349 dataTypes = s.dataTypes.slice(); 32350 32351 // Create converters map with lowercased keys 32352 if ( dataTypes[ 1 ] ) { 32353 for ( conv in s.converters ) { 32354 converters[ conv.toLowerCase() ] = s.converters[ conv ]; 32355 } 32356 } 32357 32358 current = dataTypes.shift(); 32359 32360 // Convert to each sequential dataType 32361 while ( current ) { 32362 32363 if ( s.responseFields[ current ] ) { 32364 jqXHR[ s.responseFields[ current ] ] = response; 32365 } 32366 32367 // Apply the dataFilter if provided 32368 if ( !prev && isSuccess && s.dataFilter ) { 32369 response = s.dataFilter( response, s.dataType ); 32370 } 32371 32372 prev = current; 32373 current = dataTypes.shift(); 32374 32375 if ( current ) { 32376 32377 // There's only work to do if current dataType is non-auto 32378 if ( current === "*" ) { 32379 32380 current = prev; 32381 32382 // Convert response if prev dataType is non-auto and differs from current 32383 } else if ( prev !== "*" && prev !== current ) { 32384 32385 // Seek a direct converter 32386 conv = converters[ prev + " " + current ] || converters[ "* " + current ]; 32387 32388 // If none found, seek a pair 32389 if ( !conv ) { 32390 for ( conv2 in converters ) { 32391 32392 // If conv2 outputs current 32393 tmp = conv2.split( " " ); 32394 if ( tmp[ 1 ] === current ) { 32395 32396 // If prev can be converted to accepted input 32397 conv = converters[ prev + " " + tmp[ 0 ] ] || 32398 converters[ "* " + tmp[ 0 ] ]; 32399 if ( conv ) { 32400 32401 // Condense equivalence converters 32402 if ( conv === true ) { 32403 conv = converters[ conv2 ]; 32404 32405 // Otherwise, insert the intermediate dataType 32406 } else if ( converters[ conv2 ] !== true ) { 32407 current = tmp[ 0 ]; 32408 dataTypes.unshift( tmp[ 1 ] ); 32409 } 32410 break; 32411 } 32412 } 32413 } 32414 } 32415 32416 // Apply converter (if not an equivalence) 32417 if ( conv !== true ) { 32418 32419 // Unless errors are allowed to bubble, catch and return them 32420 if ( conv && s.throws ) { 32421 response = conv( response ); 32422 } else { 32423 try { 32424 response = conv( response ); 32425 } catch ( e ) { 32426 return { 32427 state: "parsererror", 32428 error: conv ? e : "No conversion from " + prev + " to " + current 32429 }; 32430 } 32431 } 32432 } 32433 } 32434 } 32435 } 32436 32437 return { state: "success", data: response }; 32438} 32439 32440jQuery.extend( { 32441 32442 // Counter for holding the number of active queries 32443 active: 0, 32444 32445 // Last-Modified header cache for next request 32446 lastModified: {}, 32447 etag: {}, 32448 32449 ajaxSettings: { 32450 url: location.href, 32451 type: "GET", 32452 isLocal: rlocalProtocol.test( location.protocol ), 32453 global: true, 32454 processData: true, 32455 async: true, 32456 contentType: "application/x-www-form-urlencoded; charset=UTF-8", 32457 32458 /* 32459 timeout: 0, 32460 data: null, 32461 dataType: null, 32462 username: null, 32463 password: null, 32464 cache: null, 32465 throws: false, 32466 traditional: false, 32467 headers: {}, 32468 */ 32469 32470 accepts: { 32471 "*": allTypes, 32472 text: "text/plain", 32473 html: "text/html", 32474 xml: "application/xml, text/xml", 32475 json: "application/json, text/javascript" 32476 }, 32477 32478 contents: { 32479 xml: /\bxml\b/, 32480 html: /\bhtml/, 32481 json: /\bjson\b/ 32482 }, 32483 32484 responseFields: { 32485 xml: "responseXML", 32486 text: "responseText", 32487 json: "responseJSON" 32488 }, 32489 32490 // Data converters 32491 // Keys separate source (or catchall "*") and destination types with a single space 32492 converters: { 32493 32494 // Convert anything to text 32495 "* text": String, 32496 32497 // Text to html (true = no transformation) 32498 "text html": true, 32499 32500 // Evaluate text as a json expression 32501 "text json": JSON.parse, 32502 32503 // Parse text as xml 32504 "text xml": jQuery.parseXML 32505 }, 32506 32507 // For options that shouldn't be deep extended: 32508 // you can add your own custom options here if 32509 // and when you create one that shouldn't be 32510 // deep extended (see ajaxExtend) 32511 flatOptions: { 32512 url: true, 32513 context: true 32514 } 32515 }, 32516 32517 // Creates a full fledged settings object into target 32518 // with both ajaxSettings and settings fields. 32519 // If target is omitted, writes into ajaxSettings. 32520 ajaxSetup: function( target, settings ) { 32521 return settings ? 32522 32523 // Building a settings object 32524 ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : 32525 32526 // Extending ajaxSettings 32527 ajaxExtend( jQuery.ajaxSettings, target ); 32528 }, 32529 32530 ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), 32531 ajaxTransport: addToPrefiltersOrTransports( transports ), 32532 32533 // Main method 32534 ajax: function( url, options ) { 32535 32536 // If url is an object, simulate pre-1.5 signature 32537 if ( typeof url === "object" ) { 32538 options = url; 32539 url = undefined; 32540 } 32541 32542 // Force options to be an object 32543 options = options || {}; 32544 32545 var transport, 32546 32547 // URL without anti-cache param 32548 cacheURL, 32549 32550 // Response headers 32551 responseHeadersString, 32552 responseHeaders, 32553 32554 // timeout handle 32555 timeoutTimer, 32556 32557 // Url cleanup var 32558 urlAnchor, 32559 32560 // Request state (becomes false upon send and true upon completion) 32561 completed, 32562 32563 // To know if global events are to be dispatched 32564 fireGlobals, 32565 32566 // Loop variable 32567 i, 32568 32569 // uncached part of the url 32570 uncached, 32571 32572 // Create the final options object 32573 s = jQuery.ajaxSetup( {}, options ), 32574 32575 // Callbacks context 32576 callbackContext = s.context || s, 32577 32578 // Context for global events is callbackContext if it is a DOM node or jQuery collection 32579 globalEventContext = s.context && 32580 ( callbackContext.nodeType || callbackContext.jquery ) ? 32581 jQuery( callbackContext ) : 32582 jQuery.event, 32583 32584 // Deferreds 32585 deferred = jQuery.Deferred(), 32586 completeDeferred = jQuery.Callbacks( "once memory" ), 32587 32588 // Status-dependent callbacks 32589 statusCode = s.statusCode || {}, 32590 32591 // Headers (they are sent all at once) 32592 requestHeaders = {}, 32593 requestHeadersNames = {}, 32594 32595 // Default abort message 32596 strAbort = "canceled", 32597 32598 // Fake xhr 32599 jqXHR = { 32600 readyState: 0, 32601 32602 // Builds headers hashtable if needed 32603 getResponseHeader: function( key ) { 32604 var match; 32605 if ( completed ) { 32606 if ( !responseHeaders ) { 32607 responseHeaders = {}; 32608 while ( ( match = rheaders.exec( responseHeadersString ) ) ) { 32609 responseHeaders[ match[ 1 ].toLowerCase() + " " ] = 32610 ( responseHeaders[ match[ 1 ].toLowerCase() + " " ] || [] ) 32611 .concat( match[ 2 ] ); 32612 } 32613 } 32614 match = responseHeaders[ key.toLowerCase() + " " ]; 32615 } 32616 return match == null ? null : match.join( ", " ); 32617 }, 32618 32619 // Raw string 32620 getAllResponseHeaders: function() { 32621 return completed ? responseHeadersString : null; 32622 }, 32623 32624 // Caches the header 32625 setRequestHeader: function( name, value ) { 32626 if ( completed == null ) { 32627 name = requestHeadersNames[ name.toLowerCase() ] = 32628 requestHeadersNames[ name.toLowerCase() ] || name; 32629 requestHeaders[ name ] = value; 32630 } 32631 return this; 32632 }, 32633 32634 // Overrides response content-type header 32635 overrideMimeType: function( type ) { 32636 if ( completed == null ) { 32637 s.mimeType = type; 32638 } 32639 return this; 32640 }, 32641 32642 // Status-dependent callbacks 32643 statusCode: function( map ) { 32644 var code; 32645 if ( map ) { 32646 if ( completed ) { 32647 32648 // Execute the appropriate callbacks 32649 jqXHR.always( map[ jqXHR.status ] ); 32650 } else { 32651 32652 // Lazy-add the new callbacks in a way that preserves old ones 32653 for ( code in map ) { 32654 statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; 32655 } 32656 } 32657 } 32658 return this; 32659 }, 32660 32661 // Cancel the request 32662 abort: function( statusText ) { 32663 var finalText = statusText || strAbort; 32664 if ( transport ) { 32665 transport.abort( finalText ); 32666 } 32667 done( 0, finalText ); 32668 return this; 32669 } 32670 }; 32671 32672 // Attach deferreds 32673 deferred.promise( jqXHR ); 32674 32675 // Add protocol if not provided (prefilters might expect it) 32676 // Handle falsy url in the settings object (#10093: consistency with old signature) 32677 // We also use the url parameter if available 32678 s.url = ( ( url || s.url || location.href ) + "" ) 32679 .replace( rprotocol, location.protocol + "//" ); 32680 32681 // Alias method option to type as per ticket #12004 32682 s.type = options.method || options.type || s.method || s.type; 32683 32684 // Extract dataTypes list 32685 s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ]; 32686 32687 // A cross-domain request is in order when the origin doesn't match the current origin. 32688 if ( s.crossDomain == null ) { 32689 urlAnchor = document.createElement( "a" ); 32690 32691 // Support: IE <=8 - 11, Edge 12 - 15 32692 // IE throws exception on accessing the href property if url is malformed, 32693 // e.g. http://example.com:80x/ 32694 try { 32695 urlAnchor.href = s.url; 32696 32697 // Support: IE <=8 - 11 only 32698 // Anchor's host property isn't correctly set when s.url is relative 32699 urlAnchor.href = urlAnchor.href; 32700 s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !== 32701 urlAnchor.protocol + "//" + urlAnchor.host; 32702 } catch ( e ) { 32703 32704 // If there is an error parsing the URL, assume it is crossDomain, 32705 // it can be rejected by the transport if it is invalid 32706 s.crossDomain = true; 32707 } 32708 } 32709 32710 // Convert data if not already a string 32711 if ( s.data && s.processData && typeof s.data !== "string" ) { 32712 s.data = jQuery.param( s.data, s.traditional ); 32713 } 32714 32715 // Apply prefilters 32716 inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); 32717 32718 // If request was aborted inside a prefilter, stop there 32719 if ( completed ) { 32720 return jqXHR; 32721 } 32722 32723 // We can fire global events as of now if asked to 32724 // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) 32725 fireGlobals = jQuery.event && s.global; 32726 32727 // Watch for a new set of requests 32728 if ( fireGlobals && jQuery.active++ === 0 ) { 32729 jQuery.event.trigger( "ajaxStart" ); 32730 } 32731 32732 // Uppercase the type 32733 s.type = s.type.toUpperCase(); 32734 32735 // Determine if request has content 32736 s.hasContent = !rnoContent.test( s.type ); 32737 32738 // Save the URL in case we're toying with the If-Modified-Since 32739 // and/or If-None-Match header later on 32740 // Remove hash to simplify url manipulation 32741 cacheURL = s.url.replace( rhash, "" ); 32742 32743 // More options handling for requests with no content 32744 if ( !s.hasContent ) { 32745 32746 // Remember the hash so we can put it back 32747 uncached = s.url.slice( cacheURL.length ); 32748 32749 // If data is available and should be processed, append data to url 32750 if ( s.data && ( s.processData || typeof s.data === "string" ) ) { 32751 cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data; 32752 32753 // #9682: remove data so that it's not used in an eventual retry 32754 delete s.data; 32755 } 32756 32757 // Add or update anti-cache param if needed 32758 if ( s.cache === false ) { 32759 cacheURL = cacheURL.replace( rantiCache, "$1" ); 32760 uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce.guid++ ) + 32761 uncached; 32762 } 32763 32764 // Put hash and anti-cache on the URL that will be requested (gh-1732) 32765 s.url = cacheURL + uncached; 32766 32767 // Change '%20' to '+' if this is encoded form body content (gh-2658) 32768 } else if ( s.data && s.processData && 32769 ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) { 32770 s.data = s.data.replace( r20, "+" ); 32771 } 32772 32773 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 32774 if ( s.ifModified ) { 32775 if ( jQuery.lastModified[ cacheURL ] ) { 32776 jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); 32777 } 32778 if ( jQuery.etag[ cacheURL ] ) { 32779 jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); 32780 } 32781 } 32782 32783 // Set the correct header, if data is being sent 32784 if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { 32785 jqXHR.setRequestHeader( "Content-Type", s.contentType ); 32786 } 32787 32788 // Set the Accepts header for the server, depending on the dataType 32789 jqXHR.setRequestHeader( 32790 "Accept", 32791 s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ? 32792 s.accepts[ s.dataTypes[ 0 ] ] + 32793 ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : 32794 s.accepts[ "*" ] 32795 ); 32796 32797 // Check for headers option 32798 for ( i in s.headers ) { 32799 jqXHR.setRequestHeader( i, s.headers[ i ] ); 32800 } 32801 32802 // Allow custom headers/mimetypes and early abort 32803 if ( s.beforeSend && 32804 ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) { 32805 32806 // Abort if not done already and return 32807 return jqXHR.abort(); 32808 } 32809 32810 // Aborting is no longer a cancellation 32811 strAbort = "abort"; 32812 32813 // Install callbacks on deferreds 32814 completeDeferred.add( s.complete ); 32815 jqXHR.done( s.success ); 32816 jqXHR.fail( s.error ); 32817 32818 // Get transport 32819 transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); 32820 32821 // If no transport, we auto-abort 32822 if ( !transport ) { 32823 done( -1, "No Transport" ); 32824 } else { 32825 jqXHR.readyState = 1; 32826 32827 // Send global event 32828 if ( fireGlobals ) { 32829 globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); 32830 } 32831 32832 // If request was aborted inside ajaxSend, stop there 32833 if ( completed ) { 32834 return jqXHR; 32835 } 32836 32837 // Timeout 32838 if ( s.async && s.timeout > 0 ) { 32839 timeoutTimer = window.setTimeout( function() { 32840 jqXHR.abort( "timeout" ); 32841 }, s.timeout ); 32842 } 32843 32844 try { 32845 completed = false; 32846 transport.send( requestHeaders, done ); 32847 } catch ( e ) { 32848 32849 // Rethrow post-completion exceptions 32850 if ( completed ) { 32851 throw e; 32852 } 32853 32854 // Propagate others as results 32855 done( -1, e ); 32856 } 32857 } 32858 32859 // Callback for when everything is done 32860 function done( status, nativeStatusText, responses, headers ) { 32861 var isSuccess, success, error, response, modified, 32862 statusText = nativeStatusText; 32863 32864 // Ignore repeat invocations 32865 if ( completed ) { 32866 return; 32867 } 32868 32869 completed = true; 32870 32871 // Clear timeout if it exists 32872 if ( timeoutTimer ) { 32873 window.clearTimeout( timeoutTimer ); 32874 } 32875 32876 // Dereference transport for early garbage collection 32877 // (no matter how long the jqXHR object will be used) 32878 transport = undefined; 32879 32880 // Cache response headers 32881 responseHeadersString = headers || ""; 32882 32883 // Set readyState 32884 jqXHR.readyState = status > 0 ? 4 : 0; 32885 32886 // Determine if successful 32887 isSuccess = status >= 200 && status < 300 || status === 304; 32888 32889 // Get response data 32890 if ( responses ) { 32891 response = ajaxHandleResponses( s, jqXHR, responses ); 32892 } 32893 32894 // Use a noop converter for missing script 32895 if ( !isSuccess && jQuery.inArray( "script", s.dataTypes ) > -1 ) { 32896 s.converters[ "text script" ] = function() {}; 32897 } 32898 32899 // Convert no matter what (that way responseXXX fields are always set) 32900 response = ajaxConvert( s, response, jqXHR, isSuccess ); 32901 32902 // If successful, handle type chaining 32903 if ( isSuccess ) { 32904 32905 // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. 32906 if ( s.ifModified ) { 32907 modified = jqXHR.getResponseHeader( "Last-Modified" ); 32908 if ( modified ) { 32909 jQuery.lastModified[ cacheURL ] = modified; 32910 } 32911 modified = jqXHR.getResponseHeader( "etag" ); 32912 if ( modified ) { 32913 jQuery.etag[ cacheURL ] = modified; 32914 } 32915 } 32916 32917 // if no content 32918 if ( status === 204 || s.type === "HEAD" ) { 32919 statusText = "nocontent"; 32920 32921 // if not modified 32922 } else if ( status === 304 ) { 32923 statusText = "notmodified"; 32924 32925 // If we have data, let's convert it 32926 } else { 32927 statusText = response.state; 32928 success = response.data; 32929 error = response.error; 32930 isSuccess = !error; 32931 } 32932 } else { 32933 32934 // Extract error from statusText and normalize for non-aborts 32935 error = statusText; 32936 if ( status || !statusText ) { 32937 statusText = "error"; 32938 if ( status < 0 ) { 32939 status = 0; 32940 } 32941 } 32942 } 32943 32944 // Set data for the fake xhr object 32945 jqXHR.status = status; 32946 jqXHR.statusText = ( nativeStatusText || statusText ) + ""; 32947 32948 // Success/Error 32949 if ( isSuccess ) { 32950 deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); 32951 } else { 32952 deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); 32953 } 32954 32955 // Status-dependent callbacks 32956 jqXHR.statusCode( statusCode ); 32957 statusCode = undefined; 32958 32959 if ( fireGlobals ) { 32960 globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", 32961 [ jqXHR, s, isSuccess ? success : error ] ); 32962 } 32963 32964 // Complete 32965 completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); 32966 32967 if ( fireGlobals ) { 32968 globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); 32969 32970 // Handle the global AJAX counter 32971 if ( !( --jQuery.active ) ) { 32972 jQuery.event.trigger( "ajaxStop" ); 32973 } 32974 } 32975 } 32976 32977 return jqXHR; 32978 }, 32979 32980 getJSON: function( url, data, callback ) { 32981 return jQuery.get( url, data, callback, "json" ); 32982 }, 32983 32984 getScript: function( url, callback ) { 32985 return jQuery.get( url, undefined, callback, "script" ); 32986 } 32987} ); 32988 32989jQuery.each( [ "get", "post" ], function( _i, method ) { 32990 jQuery[ method ] = function( url, data, callback, type ) { 32991 32992 // Shift arguments if data argument was omitted 32993 if ( isFunction( data ) ) { 32994 type = type || callback; 32995 callback = data; 32996 data = undefined; 32997 } 32998 32999 // The url can be an options object (which then must have .url) 33000 return jQuery.ajax( jQuery.extend( { 33001 url: url, 33002 type: method, 33003 dataType: type, 33004 data: data, 33005 success: callback 33006 }, jQuery.isPlainObject( url ) && url ) ); 33007 }; 33008} ); 33009 33010jQuery.ajaxPrefilter( function( s ) { 33011 var i; 33012 for ( i in s.headers ) { 33013 if ( i.toLowerCase() === "content-type" ) { 33014 s.contentType = s.headers[ i ] || ""; 33015 } 33016 } 33017} ); 33018 33019 33020jQuery._evalUrl = function( url, options, doc ) { 33021 return jQuery.ajax( { 33022 url: url, 33023 33024 // Make this explicit, since user can override this through ajaxSetup (#11264) 33025 type: "GET", 33026 dataType: "script", 33027 cache: true, 33028 async: false, 33029 global: false, 33030 33031 // Only evaluate the response if it is successful (gh-4126) 33032 // dataFilter is not invoked for failure responses, so using it instead 33033 // of the default converter is kludgy but it works. 33034 converters: { 33035 "text script": function() {} 33036 }, 33037 dataFilter: function( response ) { 33038 jQuery.globalEval( response, options, doc ); 33039 } 33040 } ); 33041}; 33042 33043 33044jQuery.fn.extend( { 33045 wrapAll: function( html ) { 33046 var wrap; 33047 33048 if ( this[ 0 ] ) { 33049 if ( isFunction( html ) ) { 33050 html = html.call( this[ 0 ] ); 33051 } 33052 33053 // The elements to wrap the target around 33054 wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true ); 33055 33056 if ( this[ 0 ].parentNode ) { 33057 wrap.insertBefore( this[ 0 ] ); 33058 } 33059 33060 wrap.map( function() { 33061 var elem = this; 33062 33063 while ( elem.firstElementChild ) { 33064 elem = elem.firstElementChild; 33065 } 33066 33067 return elem; 33068 } ).append( this ); 33069 } 33070 33071 return this; 33072 }, 33073 33074 wrapInner: function( html ) { 33075 if ( isFunction( html ) ) { 33076 return this.each( function( i ) { 33077 jQuery( this ).wrapInner( html.call( this, i ) ); 33078 } ); 33079 } 33080 33081 return this.each( function() { 33082 var self = jQuery( this ), 33083 contents = self.contents(); 33084 33085 if ( contents.length ) { 33086 contents.wrapAll( html ); 33087 33088 } else { 33089 self.append( html ); 33090 } 33091 } ); 33092 }, 33093 33094 wrap: function( html ) { 33095 var htmlIsFunction = isFunction( html ); 33096 33097 return this.each( function( i ) { 33098 jQuery( this ).wrapAll( htmlIsFunction ? html.call( this, i ) : html ); 33099 } ); 33100 }, 33101 33102 unwrap: function( selector ) { 33103 this.parent( selector ).not( "body" ).each( function() { 33104 jQuery( this ).replaceWith( this.childNodes ); 33105 } ); 33106 return this; 33107 } 33108} ); 33109 33110 33111jQuery.expr.pseudos.hidden = function( elem ) { 33112 return !jQuery.expr.pseudos.visible( elem ); 33113}; 33114jQuery.expr.pseudos.visible = function( elem ) { 33115 return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length ); 33116}; 33117 33118 33119 33120 33121jQuery.ajaxSettings.xhr = function() { 33122 try { 33123 return new window.XMLHttpRequest(); 33124 } catch ( e ) {} 33125}; 33126 33127var xhrSuccessStatus = { 33128 33129 // File protocol always yields status code 0, assume 200 33130 0: 200, 33131 33132 // Support: IE <=9 only 33133 // #1450: sometimes IE returns 1223 when it should be 204 33134 1223: 204 33135 }, 33136 xhrSupported = jQuery.ajaxSettings.xhr(); 33137 33138support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); 33139support.ajax = xhrSupported = !!xhrSupported; 33140 33141jQuery.ajaxTransport( function( options ) { 33142 var callback, errorCallback; 33143 33144 // Cross domain only allowed if supported through XMLHttpRequest 33145 if ( support.cors || xhrSupported && !options.crossDomain ) { 33146 return { 33147 send: function( headers, complete ) { 33148 var i, 33149 xhr = options.xhr(); 33150 33151 xhr.open( 33152 options.type, 33153 options.url, 33154 options.async, 33155 options.username, 33156 options.password 33157 ); 33158 33159 // Apply custom fields if provided 33160 if ( options.xhrFields ) { 33161 for ( i in options.xhrFields ) { 33162 xhr[ i ] = options.xhrFields[ i ]; 33163 } 33164 } 33165 33166 // Override mime type if needed 33167 if ( options.mimeType && xhr.overrideMimeType ) { 33168 xhr.overrideMimeType( options.mimeType ); 33169 } 33170 33171 // X-Requested-With header 33172 // For cross-domain requests, seeing as conditions for a preflight are 33173 // akin to a jigsaw puzzle, we simply never set it to be sure. 33174 // (it can always be set on a per-request basis or even using ajaxSetup) 33175 // For same-domain requests, won't change header if already provided. 33176 if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) { 33177 headers[ "X-Requested-With" ] = "XMLHttpRequest"; 33178 } 33179 33180 // Set headers 33181 for ( i in headers ) { 33182 xhr.setRequestHeader( i, headers[ i ] ); 33183 } 33184 33185 // Callback 33186 callback = function( type ) { 33187 return function() { 33188 if ( callback ) { 33189 callback = errorCallback = xhr.onload = 33190 xhr.onerror = xhr.onabort = xhr.ontimeout = 33191 xhr.onreadystatechange = null; 33192 33193 if ( type === "abort" ) { 33194 xhr.abort(); 33195 } else if ( type === "error" ) { 33196 33197 // Support: IE <=9 only 33198 // On a manual native abort, IE9 throws 33199 // errors on any property access that is not readyState 33200 if ( typeof xhr.status !== "number" ) { 33201 complete( 0, "error" ); 33202 } else { 33203 complete( 33204 33205 // File: protocol always yields status 0; see #8605, #14207 33206 xhr.status, 33207 xhr.statusText 33208 ); 33209 } 33210 } else { 33211 complete( 33212 xhrSuccessStatus[ xhr.status ] || xhr.status, 33213 xhr.statusText, 33214 33215 // Support: IE <=9 only 33216 // IE9 has no XHR2 but throws on binary (trac-11426) 33217 // For XHR2 non-text, let the caller handle it (gh-2498) 33218 ( xhr.responseType || "text" ) !== "text" || 33219 typeof xhr.responseText !== "string" ? 33220 { binary: xhr.response } : 33221 { text: xhr.responseText }, 33222 xhr.getAllResponseHeaders() 33223 ); 33224 } 33225 } 33226 }; 33227 }; 33228 33229 // Listen to events 33230 xhr.onload = callback(); 33231 errorCallback = xhr.onerror = xhr.ontimeout = callback( "error" ); 33232 33233 // Support: IE 9 only 33234 // Use onreadystatechange to replace onabort 33235 // to handle uncaught aborts 33236 if ( xhr.onabort !== undefined ) { 33237 xhr.onabort = errorCallback; 33238 } else { 33239 xhr.onreadystatechange = function() { 33240 33241 // Check readyState before timeout as it changes 33242 if ( xhr.readyState === 4 ) { 33243 33244 // Allow onerror to be called first, 33245 // but that will not handle a native abort 33246 // Also, save errorCallback to a variable 33247 // as xhr.onerror cannot be accessed 33248 window.setTimeout( function() { 33249 if ( callback ) { 33250 errorCallback(); 33251 } 33252 } ); 33253 } 33254 }; 33255 } 33256 33257 // Create the abort callback 33258 callback = callback( "abort" ); 33259 33260 try { 33261 33262 // Do send the request (this may raise an exception) 33263 xhr.send( options.hasContent && options.data || null ); 33264 } catch ( e ) { 33265 33266 // #14683: Only rethrow if this hasn't been notified as an error yet 33267 if ( callback ) { 33268 throw e; 33269 } 33270 } 33271 }, 33272 33273 abort: function() { 33274 if ( callback ) { 33275 callback(); 33276 } 33277 } 33278 }; 33279 } 33280} ); 33281 33282 33283 33284 33285// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432) 33286jQuery.ajaxPrefilter( function( s ) { 33287 if ( s.crossDomain ) { 33288 s.contents.script = false; 33289 } 33290} ); 33291 33292// Install script dataType 33293jQuery.ajaxSetup( { 33294 accepts: { 33295 script: "text/javascript, application/javascript, " + 33296 "application/ecmascript, application/x-ecmascript" 33297 }, 33298 contents: { 33299 script: /\b(?:java|ecma)script\b/ 33300 }, 33301 converters: { 33302 "text script": function( text ) { 33303 jQuery.globalEval( text ); 33304 return text; 33305 } 33306 } 33307} ); 33308 33309// Handle cache's special case and crossDomain 33310jQuery.ajaxPrefilter( "script", function( s ) { 33311 if ( s.cache === undefined ) { 33312 s.cache = false; 33313 } 33314 if ( s.crossDomain ) { 33315 s.type = "GET"; 33316 } 33317} ); 33318 33319// Bind script tag hack transport 33320jQuery.ajaxTransport( "script", function( s ) { 33321 33322 // This transport only deals with cross domain or forced-by-attrs requests 33323 if ( s.crossDomain || s.scriptAttrs ) { 33324 var script, callback; 33325 return { 33326 send: function( _, complete ) { 33327 script = jQuery( "<script>" ) 33328 .attr( s.scriptAttrs || {} ) 33329 .prop( { charset: s.scriptCharset, src: s.url } ) 33330 .on( "load error", callback = function( evt ) { 33331 script.remove(); 33332 callback = null; 33333 if ( evt ) { 33334 complete( evt.type === "error" ? 404 : 200, evt.type ); 33335 } 33336 } ); 33337 33338 // Use native DOM manipulation to avoid our domManip AJAX trickery 33339 document.head.appendChild( script[ 0 ] ); 33340 }, 33341 abort: function() { 33342 if ( callback ) { 33343 callback(); 33344 } 33345 } 33346 }; 33347 } 33348} ); 33349 33350 33351 33352 33353var oldCallbacks = [], 33354 rjsonp = /(=)\?(?=&|$)|\?\?/; 33355 33356// Default jsonp settings 33357jQuery.ajaxSetup( { 33358 jsonp: "callback", 33359 jsonpCallback: function() { 33360 var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce.guid++ ) ); 33361 this[ callback ] = true; 33362 return callback; 33363 } 33364} ); 33365 33366// Detect, normalize options and install callbacks for jsonp requests 33367jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { 33368 33369 var callbackName, overwritten, responseContainer, 33370 jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? 33371 "url" : 33372 typeof s.data === "string" && 33373 ( s.contentType || "" ) 33374 .indexOf( "application/x-www-form-urlencoded" ) === 0 && 33375 rjsonp.test( s.data ) && "data" 33376 ); 33377 33378 // Handle iff the expected data type is "jsonp" or we have a parameter to set 33379 if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { 33380 33381 // Get callback name, remembering preexisting value associated with it 33382 callbackName = s.jsonpCallback = isFunction( s.jsonpCallback ) ? 33383 s.jsonpCallback() : 33384 s.jsonpCallback; 33385 33386 // Insert callback into url or form data 33387 if ( jsonProp ) { 33388 s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); 33389 } else if ( s.jsonp !== false ) { 33390 s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; 33391 } 33392 33393 // Use data converter to retrieve json after script execution 33394 s.converters[ "script json" ] = function() { 33395 if ( !responseContainer ) { 33396 jQuery.error( callbackName + " was not called" ); 33397 } 33398 return responseContainer[ 0 ]; 33399 }; 33400 33401 // Force json dataType 33402 s.dataTypes[ 0 ] = "json"; 33403 33404 // Install callback 33405 overwritten = window[ callbackName ]; 33406 window[ callbackName ] = function() { 33407 responseContainer = arguments; 33408 }; 33409 33410 // Clean-up function (fires after converters) 33411 jqXHR.always( function() { 33412 33413 // If previous value didn't exist - remove it 33414 if ( overwritten === undefined ) { 33415 jQuery( window ).removeProp( callbackName ); 33416 33417 // Otherwise restore preexisting value 33418 } else { 33419 window[ callbackName ] = overwritten; 33420 } 33421 33422 // Save back as free 33423 if ( s[ callbackName ] ) { 33424 33425 // Make sure that re-using the options doesn't screw things around 33426 s.jsonpCallback = originalSettings.jsonpCallback; 33427 33428 // Save the callback name for future use 33429 oldCallbacks.push( callbackName ); 33430 } 33431 33432 // Call if it was a function and we have a response 33433 if ( responseContainer && isFunction( overwritten ) ) { 33434 overwritten( responseContainer[ 0 ] ); 33435 } 33436 33437 responseContainer = overwritten = undefined; 33438 } ); 33439 33440 // Delegate to script 33441 return "script"; 33442 } 33443} ); 33444 33445 33446 33447 33448// Support: Safari 8 only 33449// In Safari 8 documents created via document.implementation.createHTMLDocument 33450// collapse sibling forms: the second one becomes a child of the first one. 33451// Because of that, this security measure has to be disabled in Safari 8. 33452// https://bugs.webkit.org/show_bug.cgi?id=137337 33453support.createHTMLDocument = ( function() { 33454 var body = document.implementation.createHTMLDocument( "" ).body; 33455 body.innerHTML = "<form></form><form></form>"; 33456 return body.childNodes.length === 2; 33457} )(); 33458 33459 33460// Argument "data" should be string of html 33461// context (optional): If specified, the fragment will be created in this context, 33462// defaults to document 33463// keepScripts (optional): If true, will include scripts passed in the html string 33464jQuery.parseHTML = function( data, context, keepScripts ) { 33465 if ( typeof data !== "string" ) { 33466 return []; 33467 } 33468 if ( typeof context === "boolean" ) { 33469 keepScripts = context; 33470 context = false; 33471 } 33472 33473 var base, parsed, scripts; 33474 33475 if ( !context ) { 33476 33477 // Stop scripts or inline event handlers from being executed immediately 33478 // by using document.implementation 33479 if ( support.createHTMLDocument ) { 33480 context = document.implementation.createHTMLDocument( "" ); 33481 33482 // Set the base href for the created document 33483 // so any parsed elements with URLs 33484 // are based on the document's URL (gh-2965) 33485 base = context.createElement( "base" ); 33486 base.href = document.location.href; 33487 context.head.appendChild( base ); 33488 } else { 33489 context = document; 33490 } 33491 } 33492 33493 parsed = rsingleTag.exec( data ); 33494 scripts = !keepScripts && []; 33495 33496 // Single tag 33497 if ( parsed ) { 33498 return [ context.createElement( parsed[ 1 ] ) ]; 33499 } 33500 33501 parsed = buildFragment( [ data ], context, scripts ); 33502 33503 if ( scripts && scripts.length ) { 33504 jQuery( scripts ).remove(); 33505 } 33506 33507 return jQuery.merge( [], parsed.childNodes ); 33508}; 33509 33510 33511/** 33512 * Load a url into a page 33513 */ 33514jQuery.fn.load = function( url, params, callback ) { 33515 var selector, type, response, 33516 self = this, 33517 off = url.indexOf( " " ); 33518 33519 if ( off > -1 ) { 33520 selector = stripAndCollapse( url.slice( off ) ); 33521 url = url.slice( 0, off ); 33522 } 33523 33524 // If it's a function 33525 if ( isFunction( params ) ) { 33526 33527 // We assume that it's the callback 33528 callback = params; 33529 params = undefined; 33530 33531 // Otherwise, build a param string 33532 } else if ( params && typeof params === "object" ) { 33533 type = "POST"; 33534 } 33535 33536 // If we have elements to modify, make the request 33537 if ( self.length > 0 ) { 33538 jQuery.ajax( { 33539 url: url, 33540 33541 // If "type" variable is undefined, then "GET" method will be used. 33542 // Make value of this field explicit since 33543 // user can override it through ajaxSetup method 33544 type: type || "GET", 33545 dataType: "html", 33546 data: params 33547 } ).done( function( responseText ) { 33548 33549 // Save response for use in complete callback 33550 response = arguments; 33551 33552 self.html( selector ? 33553 33554 // If a selector was specified, locate the right elements in a dummy div 33555 // Exclude scripts to avoid IE 'Permission Denied' errors 33556 jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) : 33557 33558 // Otherwise use the full result 33559 responseText ); 33560 33561 // If the request succeeds, this function gets "data", "status", "jqXHR" 33562 // but they are ignored because response was set above. 33563 // If it fails, this function gets "jqXHR", "status", "error" 33564 } ).always( callback && function( jqXHR, status ) { 33565 self.each( function() { 33566 callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] ); 33567 } ); 33568 } ); 33569 } 33570 33571 return this; 33572}; 33573 33574 33575 33576 33577jQuery.expr.pseudos.animated = function( elem ) { 33578 return jQuery.grep( jQuery.timers, function( fn ) { 33579 return elem === fn.elem; 33580 } ).length; 33581}; 33582 33583 33584 33585 33586jQuery.offset = { 33587 setOffset: function( elem, options, i ) { 33588 var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, 33589 position = jQuery.css( elem, "position" ), 33590 curElem = jQuery( elem ), 33591 props = {}; 33592 33593 // Set position first, in-case top/left are set even on static elem 33594 if ( position === "static" ) { 33595 elem.style.position = "relative"; 33596 } 33597 33598 curOffset = curElem.offset(); 33599 curCSSTop = jQuery.css( elem, "top" ); 33600 curCSSLeft = jQuery.css( elem, "left" ); 33601 calculatePosition = ( position === "absolute" || position === "fixed" ) && 33602 ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1; 33603 33604 // Need to be able to calculate position if either 33605 // top or left is auto and position is either absolute or fixed 33606 if ( calculatePosition ) { 33607 curPosition = curElem.position(); 33608 curTop = curPosition.top; 33609 curLeft = curPosition.left; 33610 33611 } else { 33612 curTop = parseFloat( curCSSTop ) || 0; 33613 curLeft = parseFloat( curCSSLeft ) || 0; 33614 } 33615 33616 if ( isFunction( options ) ) { 33617 33618 // Use jQuery.extend here to allow modification of coordinates argument (gh-1848) 33619 options = options.call( elem, i, jQuery.extend( {}, curOffset ) ); 33620 } 33621 33622 if ( options.top != null ) { 33623 props.top = ( options.top - curOffset.top ) + curTop; 33624 } 33625 if ( options.left != null ) { 33626 props.left = ( options.left - curOffset.left ) + curLeft; 33627 } 33628 33629 if ( "using" in options ) { 33630 options.using.call( elem, props ); 33631 33632 } else { 33633 if ( typeof props.top === "number" ) { 33634 props.top += "px"; 33635 } 33636 if ( typeof props.left === "number" ) { 33637 props.left += "px"; 33638 } 33639 curElem.css( props ); 33640 } 33641 } 33642}; 33643 33644jQuery.fn.extend( { 33645 33646 // offset() relates an element's border box to the document origin 33647 offset: function( options ) { 33648 33649 // Preserve chaining for setter 33650 if ( arguments.length ) { 33651 return options === undefined ? 33652 this : 33653 this.each( function( i ) { 33654 jQuery.offset.setOffset( this, options, i ); 33655 } ); 33656 } 33657 33658 var rect, win, 33659 elem = this[ 0 ]; 33660 33661 if ( !elem ) { 33662 return; 33663 } 33664 33665 // Return zeros for disconnected and hidden (display: none) elements (gh-2310) 33666 // Support: IE <=11 only 33667 // Running getBoundingClientRect on a 33668 // disconnected node in IE throws an error 33669 if ( !elem.getClientRects().length ) { 33670 return { top: 0, left: 0 }; 33671 } 33672 33673 // Get document-relative position by adding viewport scroll to viewport-relative gBCR 33674 rect = elem.getBoundingClientRect(); 33675 win = elem.ownerDocument.defaultView; 33676 return { 33677 top: rect.top + win.pageYOffset, 33678 left: rect.left + win.pageXOffset 33679 }; 33680 }, 33681 33682 // position() relates an element's margin box to its offset parent's padding box 33683 // This corresponds to the behavior of CSS absolute positioning 33684 position: function() { 33685 if ( !this[ 0 ] ) { 33686 return; 33687 } 33688 33689 var offsetParent, offset, doc, 33690 elem = this[ 0 ], 33691 parentOffset = { top: 0, left: 0 }; 33692 33693 // position:fixed elements are offset from the viewport, which itself always has zero offset 33694 if ( jQuery.css( elem, "position" ) === "fixed" ) { 33695 33696 // Assume position:fixed implies availability of getBoundingClientRect 33697 offset = elem.getBoundingClientRect(); 33698 33699 } else { 33700 offset = this.offset(); 33701 33702 // Account for the *real* offset parent, which can be the document or its root element 33703 // when a statically positioned element is identified 33704 doc = elem.ownerDocument; 33705 offsetParent = elem.offsetParent || doc.documentElement; 33706 while ( offsetParent && 33707 ( offsetParent === doc.body || offsetParent === doc.documentElement ) && 33708 jQuery.css( offsetParent, "position" ) === "static" ) { 33709 33710 offsetParent = offsetParent.parentNode; 33711 } 33712 if ( offsetParent && offsetParent !== elem && offsetParent.nodeType === 1 ) { 33713 33714 // Incorporate borders into its offset, since they are outside its content origin 33715 parentOffset = jQuery( offsetParent ).offset(); 33716 parentOffset.top += jQuery.css( offsetParent, "borderTopWidth", true ); 33717 parentOffset.left += jQuery.css( offsetParent, "borderLeftWidth", true ); 33718 } 33719 } 33720 33721 // Subtract parent offsets and element margins 33722 return { 33723 top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), 33724 left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true ) 33725 }; 33726 }, 33727 33728 // This method will return documentElement in the following cases: 33729 // 1) For the element inside the iframe without offsetParent, this method will return 33730 // documentElement of the parent window 33731 // 2) For the hidden or detached element 33732 // 3) For body or html element, i.e. in case of the html node - it will return itself 33733 // 33734 // but those exceptions were never presented as a real life use-cases 33735 // and might be considered as more preferable results. 33736 // 33737 // This logic, however, is not guaranteed and can change at any point in the future 33738 offsetParent: function() { 33739 return this.map( function() { 33740 var offsetParent = this.offsetParent; 33741 33742 while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) { 33743 offsetParent = offsetParent.offsetParent; 33744 } 33745 33746 return offsetParent || documentElement; 33747 } ); 33748 } 33749} ); 33750 33751// Create scrollLeft and scrollTop methods 33752jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { 33753 var top = "pageYOffset" === prop; 33754 33755 jQuery.fn[ method ] = function( val ) { 33756 return access( this, function( elem, method, val ) { 33757 33758 // Coalesce documents and windows 33759 var win; 33760 if ( isWindow( elem ) ) { 33761 win = elem; 33762 } else if ( elem.nodeType === 9 ) { 33763 win = elem.defaultView; 33764 } 33765 33766 if ( val === undefined ) { 33767 return win ? win[ prop ] : elem[ method ]; 33768 } 33769 33770 if ( win ) { 33771 win.scrollTo( 33772 !top ? val : win.pageXOffset, 33773 top ? val : win.pageYOffset 33774 ); 33775 33776 } else { 33777 elem[ method ] = val; 33778 } 33779 }, method, val, arguments.length ); 33780 }; 33781} ); 33782 33783// Support: Safari <=7 - 9.1, Chrome <=37 - 49 33784// Add the top/left cssHooks using jQuery.fn.position 33785// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 33786// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347 33787// getComputedStyle returns percent when specified for top/left/bottom/right; 33788// rather than make the css module depend on the offset module, just check for it here 33789jQuery.each( [ "top", "left" ], function( _i, prop ) { 33790 jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, 33791 function( elem, computed ) { 33792 if ( computed ) { 33793 computed = curCSS( elem, prop ); 33794 33795 // If curCSS returns percentage, fallback to offset 33796 return rnumnonpx.test( computed ) ? 33797 jQuery( elem ).position()[ prop ] + "px" : 33798 computed; 33799 } 33800 } 33801 ); 33802} ); 33803 33804 33805// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods 33806jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { 33807 jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, 33808 function( defaultExtra, funcName ) { 33809 33810 // Margin is only for outerHeight, outerWidth 33811 jQuery.fn[ funcName ] = function( margin, value ) { 33812 var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), 33813 extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); 33814 33815 return access( this, function( elem, type, value ) { 33816 var doc; 33817 33818 if ( isWindow( elem ) ) { 33819 33820 // $( window ).outerWidth/Height return w/h including scrollbars (gh-1729) 33821 return funcName.indexOf( "outer" ) === 0 ? 33822 elem[ "inner" + name ] : 33823 elem.document.documentElement[ "client" + name ]; 33824 } 33825 33826 // Get document width or height 33827 if ( elem.nodeType === 9 ) { 33828 doc = elem.documentElement; 33829 33830 // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], 33831 // whichever is greatest 33832 return Math.max( 33833 elem.body[ "scroll" + name ], doc[ "scroll" + name ], 33834 elem.body[ "offset" + name ], doc[ "offset" + name ], 33835 doc[ "client" + name ] 33836 ); 33837 } 33838 33839 return value === undefined ? 33840 33841 // Get width or height on the element, requesting but not forcing parseFloat 33842 jQuery.css( elem, type, extra ) : 33843 33844 // Set width or height on the element 33845 jQuery.style( elem, type, value, extra ); 33846 }, type, chainable ? margin : undefined, chainable ); 33847 }; 33848 } ); 33849} ); 33850 33851 33852jQuery.each( [ 33853 "ajaxStart", 33854 "ajaxStop", 33855 "ajaxComplete", 33856 "ajaxError", 33857 "ajaxSuccess", 33858 "ajaxSend" 33859], function( _i, type ) { 33860 jQuery.fn[ type ] = function( fn ) { 33861 return this.on( type, fn ); 33862 }; 33863} ); 33864 33865 33866 33867 33868jQuery.fn.extend( { 33869 33870 bind: function( types, data, fn ) { 33871 return this.on( types, null, data, fn ); 33872 }, 33873 unbind: function( types, fn ) { 33874 return this.off( types, null, fn ); 33875 }, 33876 33877 delegate: function( selector, types, data, fn ) { 33878 return this.on( types, selector, data, fn ); 33879 }, 33880 undelegate: function( selector, types, fn ) { 33881 33882 // ( namespace ) or ( selector, types [, fn] ) 33883 return arguments.length === 1 ? 33884 this.off( selector, "**" ) : 33885 this.off( types, selector || "**", fn ); 33886 }, 33887 33888 hover: function( fnOver, fnOut ) { 33889 return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); 33890 } 33891} ); 33892 33893jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " + 33894 "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + 33895 "change select submit keydown keypress keyup contextmenu" ).split( " " ), 33896 function( _i, name ) { 33897 33898 // Handle event binding 33899 jQuery.fn[ name ] = function( data, fn ) { 33900 return arguments.length > 0 ? 33901 this.on( name, null, data, fn ) : 33902 this.trigger( name ); 33903 }; 33904 } ); 33905 33906 33907 33908 33909// Support: Android <=4.0 only 33910// Make sure we trim BOM and NBSP 33911var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 33912 33913// Bind a function to a context, optionally partially applying any 33914// arguments. 33915// jQuery.proxy is deprecated to promote standards (specifically Function#bind) 33916// However, it is not slated for removal any time soon 33917jQuery.proxy = function( fn, context ) { 33918 var tmp, args, proxy; 33919 33920 if ( typeof context === "string" ) { 33921 tmp = fn[ context ]; 33922 context = fn; 33923 fn = tmp; 33924 } 33925 33926 // Quick check to determine if target is callable, in the spec 33927 // this throws a TypeError, but we will just return undefined. 33928 if ( !isFunction( fn ) ) { 33929 return undefined; 33930 } 33931 33932 // Simulated bind 33933 args = slice.call( arguments, 2 ); 33934 proxy = function() { 33935 return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); 33936 }; 33937 33938 // Set the guid of unique handler to the same of original handler, so it can be removed 33939 proxy.guid = fn.guid = fn.guid || jQuery.guid++; 33940 33941 return proxy; 33942}; 33943 33944jQuery.holdReady = function( hold ) { 33945 if ( hold ) { 33946 jQuery.readyWait++; 33947 } else { 33948 jQuery.ready( true ); 33949 } 33950}; 33951jQuery.isArray = Array.isArray; 33952jQuery.parseJSON = JSON.parse; 33953jQuery.nodeName = nodeName; 33954jQuery.isFunction = isFunction; 33955jQuery.isWindow = isWindow; 33956jQuery.camelCase = camelCase; 33957jQuery.type = toType; 33958 33959jQuery.now = Date.now; 33960 33961jQuery.isNumeric = function( obj ) { 33962 33963 // As of jQuery 3.0, isNumeric is limited to 33964 // strings and numbers (primitives or objects) 33965 // that can be coerced to finite numbers (gh-2662) 33966 var type = jQuery.type( obj ); 33967 return ( type === "number" || type === "string" ) && 33968 33969 // parseFloat NaNs numeric-cast false positives ("") 33970 // ...but misinterprets leading-number strings, particularly hex literals ("0x...") 33971 // subtraction forces infinities to NaN 33972 !isNaN( obj - parseFloat( obj ) ); 33973}; 33974 33975jQuery.trim = function( text ) { 33976 return text == null ? 33977 "" : 33978 ( text + "" ).replace( rtrim, "" ); 33979}; 33980 33981 33982 33983// Register as a named AMD module, since jQuery can be concatenated with other 33984// files that may use define, but not via a proper concatenation script that 33985// understands anonymous AMD modules. A named AMD is safest and most robust 33986// way to register. Lowercase jquery is used because AMD module names are 33987// derived from file names, and jQuery is normally delivered in a lowercase 33988// file name. Do this after creating the global so that if an AMD module wants 33989// to call noConflict to hide this version of jQuery, it will work. 33990 33991// Note that for maximum portability, libraries that are not jQuery should 33992// declare themselves as anonymous modules, and avoid setting a global if an 33993// AMD loader is present. jQuery is a special case. For more information, see 33994// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon 33995 33996if ( true ) { 33997 !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_RESULT__ = (function() { 33998 return jQuery; 33999 }).apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__), 34000 __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); 34001} 34002 34003 34004 34005 34006var 34007 34008 // Map over jQuery in case of overwrite 34009 _jQuery = window.jQuery, 34010 34011 // Map over the $ in case of overwrite 34012 _$ = window.$; 34013 34014jQuery.noConflict = function( deep ) { 34015 if ( window.$ === jQuery ) { 34016 window.$ = _$; 34017 } 34018 34019 if ( deep && window.jQuery === jQuery ) { 34020 window.jQuery = _jQuery; 34021 } 34022 34023 return jQuery; 34024}; 34025 34026// Expose jQuery and $ identifiers, even in AMD 34027// (#7102#comment:10, https://github.com/jquery/jquery/pull/557) 34028// and CommonJS for browser emulators (#13566) 34029if ( typeof noGlobal === "undefined" ) { 34030 window.jQuery = window.$ = jQuery; 34031} 34032 34033 34034 34035 34036return jQuery; 34037} ); 34038 34039 34040/***/ }), 34041
vendor: 353,058 bytes, lines 34042-44728
34042/***/ "./node_modules/mixitup/dist/mixitup.js": 34043/*!**********************************************!*\ 34044 !*** ./node_modules/mixitup/dist/mixitup.js ***! 34045 \**********************************************/ 34046/*! no static exports found */ 34047/***/ (function(module, exports, __webpack_require__) { 34048 34049/* WEBPACK VAR INJECTION */(function(__webpack_provided_window_dot_jQuery) {/**! 34050 * MixItUp v3.3.1 34051 * A high-performance, dependency-free library for animated filtering, sorting and more 34052 * Build 94e0fbf6-cd0b-4987-b3c0-14b59b67b8a0 34053 * 34054 * @copyright Copyright 2014-2018 KunkaLabs Limited. 34055 * @author KunkaLabs Limited. 34056 * @link https://www.kunkalabs.com/mixitup/ 34057 * 34058 * @license Commercial use requires a commercial license. 34059 * https://www.kunkalabs.com/mixitup/licenses/ 34060 * 34061 * Non-commercial use permitted under same terms as CC BY-NC 3.0 license. 34062 * http://creativecommons.org/licenses/by-nc/3.0/ 34063 */ 34064 34065(function(window) { 34066 'use strict'; 34067 34068 var mixitup = null, 34069 h = null; 34070 34071 (function() { 34072 var VENDORS = ['webkit', 'moz', 'o', 'ms'], 34073 canary = window.document.createElement('div'), 34074 i = -1; 34075 34076 // window.requestAnimationFrame 34077 34078 for (i = 0; i < VENDORS.length && !window.requestAnimationFrame; i++) { 34079 window.requestAnimationFrame = window[VENDORS[i] + 'RequestAnimationFrame']; 34080 } 34081 34082 // Element.nextElementSibling 34083 34084 if (typeof canary.nextElementSibling === 'undefined') { 34085 Object.defineProperty(window.Element.prototype, 'nextElementSibling', { 34086 get: function() { 34087 var el = this.nextSibling; 34088 34089 while (el) { 34090 if (el.nodeType === 1) { 34091 return el; 34092 } 34093 34094 el = el.nextSibling; 34095 } 34096 34097 return null; 34098 } 34099 }); 34100 } 34101 34102 // Element.matches 34103 34104 (function(ElementPrototype) { 34105 ElementPrototype.matches = 34106 ElementPrototype.matches || 34107 ElementPrototype.machesSelector || 34108 ElementPrototype.mozMatchesSelector || 34109 ElementPrototype.msMatchesSelector || 34110 ElementPrototype.oMatchesSelector || 34111 ElementPrototype.webkitMatchesSelector || 34112 function (selector) { 34113 return Array.prototype.indexOf.call(this.parentElement.querySelectorAll(selector), this) > -1; 34114 }; 34115 })(window.Element.prototype); 34116 34117 // Object.keys 34118 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys 34119 34120 if (!Object.keys) { 34121 Object.keys = (function() { 34122 var hasOwnProperty = Object.prototype.hasOwnProperty, 34123 hasDontEnumBug = false, 34124 dontEnums = [], 34125 dontEnumsLength = -1; 34126 34127 hasDontEnumBug = !({ 34128 toString: null 34129 }) 34130 .propertyIsEnumerable('toString'); 34131 34132 dontEnums = [ 34133 'toString', 34134 'toLocaleString', 34135 'valueOf', 34136 'hasOwnProperty', 34137 'isPrototypeOf', 34138 'propertyIsEnumerable', 34139 'constructor' 34140 ]; 34141 34142 dontEnumsLength = dontEnums.length; 34143 34144 return function(obj) { 34145 var result = [], 34146 prop = '', 34147 i = -1; 34148 34149 if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) { 34150 throw new TypeError('Object.keys called on non-object'); 34151 } 34152 34153 for (prop in obj) { 34154 if (hasOwnProperty.call(obj, prop)) { 34155 result.push(prop); 34156 } 34157 } 34158 34159 if (hasDontEnumBug) { 34160 for (i = 0; i < dontEnumsLength; i++) { 34161 if (hasOwnProperty.call(obj, dontEnums[i])) { 34162 result.push(dontEnums[i]); 34163 } 34164 } 34165 } 34166 34167 return result; 34168 }; 34169 }()); 34170 } 34171 34172 // Array.isArray 34173 // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray 34174 34175 if (!Array.isArray) { 34176 Array.isArray = function(arg) { 34177 return Object.prototype.toString.call(arg) === '[object Array]'; 34178 }; 34179 } 34180 34181 // Object.create 34182 // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/create 34183 34184 if (typeof Object.create !== 'function') { 34185 Object.create = (function(undefined) { 34186 var Temp = function() {}; 34187 34188 return function (prototype, propertiesObject) { 34189 if (prototype !== Object(prototype) && prototype !== null) { 34190 throw TypeError('Argument must be an object, or null'); 34191 } 34192 34193 Temp.prototype = prototype || {}; 34194 34195 var result = new Temp(); 34196 34197 Temp.prototype = null; 34198 34199 if (propertiesObject !== undefined) { 34200 Object.defineProperties(result, propertiesObject); 34201 } 34202 34203 if (prototype === null) { 34204 /* jshint ignore:start */ 34205 result.__proto__ = null; 34206 /* jshint ignore:end */ 34207 } 34208 34209 return result; 34210 }; 34211 })(); 34212 } 34213 34214 // String.prototyoe.trim 34215 34216 if (!String.prototype.trim) { 34217 String.prototype.trim = function() { 34218 return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, ''); 34219 }; 34220 } 34221 34222 // Array.prototype.indexOf 34223 // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf 34224 34225 if (!Array.prototype.indexOf) { 34226 Array.prototype.indexOf = function(searchElement) { 34227 var n, k, t, len; 34228 34229 if (this === null) { 34230 throw new TypeError(); 34231 } 34232 34233 t = Object(this); 34234 34235 len = t.length >>> 0; 34236 34237 if (len === 0) { 34238 return -1; 34239 } 34240 34241 n = 0; 34242 34243 if (arguments.length > 1) { 34244 n = Number(arguments[1]); 34245 34246 if (n !== n) { 34247 n = 0; 34248 } else if (n !== 0 && n !== Infinity && n !== -Infinity) { 34249 n = (n > 0 || -1) * Math.floor(Math.abs(n)); 34250 } 34251 } 34252 34253 if (n >= len) { 34254 return -1; 34255 } 34256 34257 for (k = n >= 0 ? n : Math.max(len - Math.abs(n), 0); k < len; k++) { 34258 if (k in t && t[k] === searchElement) { 34259 return k; 34260 } 34261 } 34262 34263 return -1; 34264 }; 34265 } 34266 34267 // Function.prototype.bind 34268 // https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_objects/Function/bind 34269 34270 if (!Function.prototype.bind) { 34271 Function.prototype.bind = function(oThis) { 34272 var aArgs, self, FNOP, fBound; 34273 34274 if (typeof this !== 'function') { 34275 throw new TypeError(); 34276 } 34277 34278 aArgs = Array.prototype.slice.call(arguments, 1); 34279 34280 self = this; 34281 34282 FNOP = function() {}; 34283 34284 fBound = function() { 34285 return self.apply(this instanceof FNOP ? this : oThis, aArgs.concat(Array.prototype.slice.call(arguments))); 34286 }; 34287 34288 if (this.prototype) { 34289 FNOP.prototype = this.prototype; 34290 } 34291 34292 fBound.prototype = new FNOP(); 34293 34294 return fBound; 34295 }; 34296 } 34297 34298 // Element.prototype.dispatchEvent 34299 34300 if (!window.Element.prototype.dispatchEvent) { 34301 window.Element.prototype.dispatchEvent = function(event) { 34302 try { 34303 return this.fireEvent('on' + event.type, event); 34304 } catch (err) {} 34305 }; 34306 } 34307 })(); 34308 34309 /** 34310 * The `mixitup()` "factory" function creates and returns individual instances 34311 * of MixItUp, known as "mixers", on which API methods can be called. 34312 * 34313 * When loading MixItUp via a script tag, the factory function is accessed 34314 * via the global variable `mixitup`. When using a module loading 34315 * system (e.g. ES2015, CommonJS, RequireJS), the factory function is 34316 * exported into your module when you require the MixItUp library. 34317 * 34318 * @example 34319 * mixitup(container [,config] [,foreignDoc]) 34320 * 34321 * @example <caption>Example 1: Creating a mixer instance with an element reference</caption> 34322 * var containerEl = document.querySelector('.container'); 34323 * 34324 * var mixer = mixitup(containerEl); 34325 * 34326 * @example <caption>Example 2: Creating a mixer instance with a selector string</caption> 34327 * var mixer = mixitup('.container'); 34328 * 34329 * @example <caption>Example 3: Passing a configuration object</caption> 34330 * var mixer = mixitup(containerEl, { 34331 * animation: { 34332 * effects: 'fade scale(0.5)' 34333 * } 34334 * }); 34335 * 34336 * @example <caption>Example 4: Passing an iframe reference</caption> 34337 * var mixer = mixitup(containerEl, config, foreignDocument); 34338 * 34339 * @global 34340 * @namespace 34341 * @public 34342 * @kind function 34343 * @since 3.0.0 34344 * @param {(Element|string)} container 34345 * A DOM element or selector string representing the container(s) on which to instantiate MixItUp. 34346 * @param {object} [config] 34347 * An optional "configuration object" used to customize the behavior of the MixItUp instance. 34348 * @param {object} [foreignDoc] 34349 * An optional reference to a `document`, which can be used to control a MixItUp instance in an iframe. 34350 * @return {mixitup.Mixer} 34351 * A "mixer" object holding the MixItUp instance. 34352 */ 34353 34354 mixitup = function(container, config, foreignDoc) { 34355 var el = null, 34356 returnCollection = false, 34357 instance = null, 34358 facade = null, 34359 doc = null, 34360 output = null, 34361 instances = [], 34362 id = '', 34363 elements = [], 34364 i = -1; 34365 34366 doc = foreignDoc || window.document; 34367 34368 if (returnCollection = arguments[3]) { 34369 // A non-documented 4th paramater enabling control of multiple instances 34370 34371 returnCollection = typeof returnCollection === 'boolean'; 34372 } 34373 34374 if (typeof container === 'string') { 34375 elements = doc.querySelectorAll(container); 34376 } else if (container && typeof container === 'object' && h.isElement(container, doc)) { 34377 elements = [container]; 34378 } else if (container && typeof container === 'object' && container.length) { 34379 // Although not documented, the container may also be an array-like list of 34380 // elements such as a NodeList or jQuery collection, is returnCollection is true 34381 34382 elements = container; 34383 } else { 34384 throw new Error(mixitup.messages.errorFactoryInvalidContainer()); 34385 } 34386 34387 if (elements.length < 1) { 34388 throw new Error(mixitup.messages.errorFactoryContainerNotFound()); 34389 } 34390 34391 for (i = 0; el = elements[i]; i++) { 34392 if (i > 0 && !returnCollection) break; 34393 34394 if (!el.id) { 34395 id = 'MixItUp' + h.randomHex(); 34396 34397 el.id = id; 34398 } else { 34399 id = el.id; 34400 } 34401 34402 if (mixitup.instances[id] instanceof mixitup.Mixer) { 34403 instance = mixitup.instances[id]; 34404 34405 if (!config || (config && config.debug && config.debug.showWarnings !== false)) { 34406 console.warn(mixitup.messages.warningFactoryPreexistingInstance()); 34407 } 34408 } else { 34409 instance = new mixitup.Mixer(); 34410 34411 instance.attach(el, doc, id, config); 34412 34413 mixitup.instances[id] = instance; 34414 } 34415 34416 facade = new mixitup.Facade(instance); 34417 34418 if (config && config.debug && config.debug.enable) { 34419 instances.push(instance); 34420 } else { 34421 instances.push(facade); 34422 } 34423 } 34424 34425 if (returnCollection) { 34426 output = new mixitup.Collection(instances); 34427 } else { 34428 // Return the first instance regardless 34429 34430 output = instances[0]; 34431 } 34432 34433 return output; 34434 }; 34435 34436 /** 34437 * The `.use()` static method is used to extend the functionality of mixitup with compatible 34438 * extensions and libraries in an environment with modular scoping e.g. ES2015, CommonJS, or RequireJS. 34439 * 34440 * You need only call the `.use()` function once per project, per extension, as module loaders 34441 * will cache a single reference to MixItUp inclusive of all changes made. 34442 * 34443 * @example 34444 * mixitup.use(extension) 34445 * 34446 * @example <caption>Example 1: Extending MixItUp with the Pagination Extension</caption> 34447 * 34448 * import mixitup from 'mixitup'; 34449 * import mixitupPagination from 'mixitup-pagination'; 34450 * 34451 * mixitup.use(mixitupPagination); 34452 * 34453 * // All mixers created by the factory function in all modules will now 34454 * // have pagination functionality 34455 * 34456 * var mixer = mixitup('.container'); 34457 * 34458 * @public 34459 * @name use 34460 * @memberof mixitup 34461 * @kind function 34462 * @static 34463 * @since 3.0.0 34464 * @param {*} extension A reference to the extension or library to be used. 34465 * @return {void} 34466 */ 34467 34468 mixitup.use = function(extension) { 34469 mixitup.Base.prototype.callActions.call(mixitup, 'beforeUse', arguments); 34470 34471 // Call the extension's factory function, passing 34472 // the mixitup factory as a paramater 34473 34474 if (typeof extension === 'function' && extension.TYPE === 'mixitup-extension') { 34475 // Mixitup extension 34476 34477 if (typeof mixitup.extensions[extension.NAME] === 'undefined') { 34478 extension(mixitup); 34479 34480 mixitup.extensions[extension.NAME] = extension; 34481 } 34482 } else if (extension.fn && extension.fn.jquery) { 34483 // jQuery 34484 34485 mixitup.libraries.$ = extension; 34486 } 34487 34488 mixitup.Base.prototype.callActions.call(mixitup, 'afterUse', arguments); 34489 }; 34490 34491 mixitup.instances = {}; 34492 mixitup.extensions = {}; 34493 mixitup.libraries = {}; 34494 34495 /** 34496 * @private 34497 */ 34498 34499 h = { 34500 34501 /** 34502 * @private 34503 * @param {HTMLElement} el 34504 * @param {string} cls 34505 * @return {boolean} 34506 */ 34507 34508 hasClass: function(el, cls) { 34509 return !!el.className.match(new RegExp('(\\s|^)' + cls + '(\\s|$)')); 34510 }, 34511 34512 /** 34513 * @private 34514 * @param {HTMLElement} el 34515 * @param {string} cls 34516 * @return {void} 34517 */ 34518 34519 addClass: function(el, cls) { 34520 if (!this.hasClass(el, cls)) el.className += el.className ? ' ' + cls : cls; 34521 }, 34522 34523 /** 34524 * @private 34525 * @param {HTMLElement} el 34526 * @param {string} cls 34527 * @return {void} 34528 */ 34529 34530 removeClass: function(el, cls) { 34531 if (this.hasClass(el, cls)) { 34532 var reg = new RegExp('(\\s|^)' + cls + '(\\s|$)'); 34533 34534 el.className = el.className.replace(reg, ' ').trim(); 34535 } 34536 }, 34537 34538 /** 34539 * Merges the properties of the source object onto the 34540 * target object. Alters the target object. 34541 * 34542 * @private 34543 * @param {object} destination 34544 * @param {object} source 34545 * @param {boolean} [deep=false] 34546 * @param {boolean} [handleErrors=false] 34547 * @return {void} 34548 */ 34549 34550 extend: function(destination, source, deep, handleErrors) { 34551 var sourceKeys = [], 34552 key = '', 34553 i = -1; 34554 34555 deep = deep || false; 34556 handleErrors = handleErrors || false; 34557 34558 try { 34559 if (Array.isArray(source)) { 34560 for (i = 0; i < source.length; i++) { 34561 sourceKeys.push(i); 34562 } 34563 } else if (source) { 34564 sourceKeys = Object.keys(source); 34565 } 34566 34567 for (i = 0; i < sourceKeys.length; i++) { 34568 key = sourceKeys[i]; 34569 34570 if (!deep || typeof source[key] !== 'object' || this.isElement(source[key])) { 34571 // All non-object properties, or all properties if shallow extend 34572 34573 destination[key] = source[key]; 34574 } else if (Array.isArray(source[key])) { 34575 // Arrays 34576 34577 if (!destination[key]) { 34578 destination[key] = []; 34579 } 34580 34581 this.extend(destination[key], source[key], deep, handleErrors); 34582 } else { 34583 // Objects 34584 34585 if (!destination[key]) { 34586 destination[key] = {}; 34587 } 34588 34589 this.extend(destination[key], source[key], deep, handleErrors); 34590 } 34591 } 34592 } catch(err) { 34593 if (handleErrors) { 34594 this.handleExtendError(err, destination); 34595 } else { 34596 throw err; 34597 } 34598 } 34599 34600 return destination; 34601 }, 34602 34603 /** 34604 * @private 34605 * @param {Error} err 34606 * @param {object} destination 34607 * @return {void} 34608 */ 34609 34610 handleExtendError: function(err, destination) { 34611 var re = /property "?(\w*)"?[,:] object/i, 34612 matches = null, 34613 erroneous = '', 34614 message = '', 34615 suggestion = '', 34616 probableMatch = '', 34617 key = '', 34618 mostMatchingChars = -1, 34619 i = -1; 34620 34621 if (err instanceof TypeError && (matches = re.exec(err.message))) { 34622 erroneous = matches[1]; 34623 34624 for (key in destination) { 34625 i = 0; 34626 34627 while (i < erroneous.length && erroneous.charAt(i) === key.charAt(i)) { 34628 i++; 34629 } 34630 34631 if (i > mostMatchingChars) { 34632 mostMatchingChars = i; 34633 probableMatch = key; 34634 } 34635 } 34636 34637 if (mostMatchingChars > 1) { 34638 suggestion = mixitup.messages.errorConfigInvalidPropertySuggestion({ 34639 probableMatch: probableMatch 34640 }); 34641 } 34642 34643 message = mixitup.messages.errorConfigInvalidProperty({ 34644 erroneous: erroneous, 34645 suggestion: suggestion 34646 }); 34647 34648 throw new TypeError(message); 34649 } 34650 34651 throw err; 34652 }, 34653 34654 /** 34655 * @private 34656 * @param {string} str 34657 * @return {function} 34658 */ 34659 34660 template: function(str) { 34661 var re = /\${([\w]*)}/g, 34662 dynamics = {}, 34663 matches = null; 34664 34665 while ((matches = re.exec(str))) { 34666 dynamics[matches[1]] = new RegExp('\\${' + matches[1] + '}', 'g'); 34667 } 34668 34669 return function(data) { 34670 var key = '', 34671 output = str; 34672 34673 data = data || {}; 34674 34675 for (key in dynamics) { 34676 output = output.replace(dynamics[key], typeof data[key] !== 'undefined' ? data[key] : ''); 34677 } 34678 34679 return output; 34680 }; 34681 }, 34682 34683 /** 34684 * @private 34685 * @param {HTMLElement} el 34686 * @param {string} type 34687 * @param {function} fn 34688 * @param {boolean} useCapture 34689 * @return {void} 34690 */ 34691 34692 on: function(el, type, fn, useCapture) { 34693 if (!el) return; 34694 34695 if (el.addEventListener) { 34696 el.addEventListener(type, fn, useCapture); 34697 } else if (el.attachEvent) { 34698 el['e' + type + fn] = fn; 34699 34700 el[type + fn] = function() { 34701 el['e' + type + fn](window.event); 34702 }; 34703 34704 el.attachEvent('on' + type, el[type + fn]); 34705 } 34706 }, 34707 34708 /** 34709 * @private 34710 * @param {HTMLElement} el 34711 * @param {string} type 34712 * @param {function} fn 34713 * @return {void} 34714 */ 34715 34716 off: function(el, type, fn) { 34717 if (!el) return; 34718 34719 if (el.removeEventListener) { 34720 el.removeEventListener(type, fn, false); 34721 } else if (el.detachEvent) { 34722 el.detachEvent('on' + type, el[type + fn]); 34723 el[type + fn] = null; 34724 } 34725 }, 34726 34727 /** 34728 * @private 34729 * @param {string} eventType 34730 * @param {object} detail 34731 * @param {Document} [doc] 34732 * @return {CustomEvent} 34733 */ 34734 34735 getCustomEvent: function(eventType, detail, doc) { 34736 var event = null; 34737 34738 doc = doc || window.document; 34739 34740 if (typeof window.CustomEvent === 'function') { 34741 event = new window.CustomEvent(eventType, { 34742 detail: detail, 34743 bubbles: true, 34744 cancelable: true 34745 }); 34746 } else if (typeof doc.createEvent === 'function') { 34747 event = doc.createEvent('CustomEvent'); 34748 event.initCustomEvent(eventType, true, true, detail); 34749 } else { 34750 event = doc.createEventObject(), 34751 event.type = eventType; 34752 34753 event.returnValue = false; 34754 event.cancelBubble = false; 34755 event.detail = detail; 34756 } 34757 34758 return event; 34759 }, 34760 34761 /** 34762 * @private 34763 * @param {Event} e 34764 * @return {Event} 34765 */ 34766 34767 getOriginalEvent: function(e) { 34768 if (e.touches && e.touches.length) { 34769 return e.touches[0]; 34770 } else if (e.changedTouches && e.changedTouches.length) { 34771 return e.changedTouches[0]; 34772 } else { 34773 return e; 34774 } 34775 }, 34776 34777 /** 34778 * @private 34779 * @param {HTMLElement} el 34780 * @param {string} selector 34781 * @return {Number} 34782 */ 34783 34784 index: function(el, selector) { 34785 var i = 0; 34786 34787 while ((el = el.previousElementSibling) !== null) { 34788 if (!selector || el.matches(selector)) { 34789 ++i; 34790 } 34791 } 34792 34793 return i; 34794 }, 34795 34796 /** 34797 * Converts a dash or snake-case string to camel case. 34798 * 34799 * @private 34800 * @param {string} str 34801 * @param {boolean} [isPascal] 34802 * @return {string} 34803 */ 34804 34805 camelCase: function(str) { 34806 return str.toLowerCase().replace(/([_-][a-z])/g, function($1) { 34807 return $1.toUpperCase().replace(/[_-]/, ''); 34808 }); 34809 }, 34810 34811 /** 34812 * Converts a dash or snake-case string to pascal case. 34813 * 34814 * @private 34815 * @param {string} str 34816 * @param {boolean} [isPascal] 34817 * @return {string} 34818 */ 34819 34820 pascalCase: function(str) { 34821 return (str = this.camelCase(str)).charAt(0).toUpperCase() + str.slice(1); 34822 }, 34823 34824 /** 34825 * Converts a camel or pascal-case string to dash case. 34826 * 34827 * @private 34828 * @param {string} str 34829 * @return {string} 34830 */ 34831 34832 dashCase: function(str) { 34833 return str.replace(/([A-Z])/g, '-$1').replace(/^-/, '').toLowerCase(); 34834 }, 34835 34836 /** 34837 * @private 34838 * @param {HTMLElement} el 34839 * @param {HTMLHtmlElement} [doc] 34840 * @return {boolean} 34841 */ 34842 34843 isElement: function(el, doc) { 34844 doc = doc || window.document; 34845 34846 if ( 34847 window.HTMLElement && 34848 el instanceof window.HTMLElement 34849 ) { 34850 return true; 34851 } else if ( 34852 doc.defaultView && 34853 doc.defaultView.HTMLElement && 34854 el instanceof doc.defaultView.HTMLElement 34855 ) { 34856 return true; 34857 } else { 34858 return ( 34859 el !== null && 34860 el.nodeType === 1 && 34861 typeof el.nodeName === 'string' 34862 ); 34863 } 34864 }, 34865 34866 /** 34867 * @private 34868 * @param {string} htmlString 34869 * @param {HTMLHtmlElement} [doc] 34870 * @return {DocumentFragment} 34871 */ 34872 34873 createElement: function(htmlString, doc) { 34874 var frag = null, 34875 temp = null; 34876 34877 doc = doc || window.document; 34878 34879 frag = doc.createDocumentFragment(); 34880 temp = doc.createElement('div'); 34881 34882 temp.innerHTML = htmlString.trim(); 34883 34884 while (temp.firstChild) { 34885 frag.appendChild(temp.firstChild); 34886 } 34887 34888 return frag; 34889 }, 34890 34891 /** 34892 * @private 34893 * @param {Node} node 34894 * @return {void} 34895 */ 34896 34897 removeWhitespace: function(node) { 34898 var deleting; 34899 34900 while (node && node.nodeName === '#text') { 34901 deleting = node; 34902 34903 node = node.previousSibling; 34904 34905 deleting.parentElement && deleting.parentElement.removeChild(deleting); 34906 } 34907 }, 34908 34909 /** 34910 * @private 34911 * @param {Array<*>} a 34912 * @param {Array<*>} b 34913 * @return {boolean} 34914 */ 34915 34916 isEqualArray: function(a, b) { 34917 var i = a.length; 34918 34919 if (i !== b.length) return false; 34920 34921 while (i--) { 34922 if (a[i] !== b[i]) return false; 34923 } 34924 34925 return true; 34926 }, 34927 34928 /** 34929 * @private 34930 * @param {object} a 34931 * @param {object} b 34932 * @return {boolean} 34933 */ 34934 34935 deepEquals: function(a, b) { 34936 var key; 34937 34938 if (typeof a === 'object' && a && typeof b === 'object' && b) { 34939 if (Object.keys(a).length !== Object.keys(b).length) return false; 34940 34941 for (key in a) { 34942 if (!b.hasOwnProperty(key) || !this.deepEquals(a[key], b[key])) return false; 34943 } 34944 } else if (a !== b) { 34945 return false; 34946 } 34947 34948 return true; 34949 }, 34950 34951 /** 34952 * @private 34953 * @param {Array<*>} oldArray 34954 * @return {Array<*>} 34955 */ 34956 34957 arrayShuffle: function(oldArray) { 34958 var newArray = oldArray.slice(), 34959 len = newArray.length, 34960 i = len, 34961 p = -1, 34962 t = []; 34963 34964 while (i--) { 34965 p = ~~(Math.random() * len); 34966 t = newArray[i]; 34967 34968 newArray[i] = newArray[p]; 34969 newArray[p] = t; 34970 } 34971 34972 return newArray; 34973 }, 34974 34975 /** 34976 * @private 34977 * @param {object} list 34978 */ 34979 34980 arrayFromList: function(list) { 34981 var output, i; 34982 34983 try { 34984 return Array.prototype.slice.call(list); 34985 } catch(err) { 34986 output = []; 34987 34988 for (i = 0; i < list.length; i++) { 34989 output.push(list[i]); 34990 } 34991 34992 return output; 34993 } 34994 }, 34995 34996 /** 34997 * @private 34998 * @param {function} func 34999 * @param {Number} wait 35000 * @param {boolean} immediate 35001 * @return {function} 35002 */ 35003 35004 debounce: function(func, wait, immediate) { 35005 var timeout; 35006 35007 return function() { 35008 var self = this, 35009 args = arguments, 35010 callNow = immediate && !timeout, 35011 later = null; 35012 35013 later = function() { 35014 timeout = null; 35015 35016 if (!immediate) { 35017 func.apply(self, args); 35018 } 35019 }; 35020 35021 clearTimeout(timeout); 35022 35023 timeout = setTimeout(later, wait); 35024 35025 if (callNow) func.apply(self, args); 35026 }; 35027 }, 35028 35029 /** 35030 * @private 35031 * @param {HTMLElement} element 35032 * @return {object} 35033 */ 35034 35035 position: function(element) { 35036 var xPosition = 0, 35037 yPosition = 0, 35038 offsetParent = element; 35039 35040 while (element) { 35041 xPosition -= element.scrollLeft; 35042 yPosition -= element.scrollTop; 35043 35044 if (element === offsetParent) { 35045 xPosition += element.offsetLeft; 35046 yPosition += element.offsetTop; 35047 35048 offsetParent = element.offsetParent; 35049 } 35050 35051 element = element.parentElement; 35052 } 35053 35054 return { 35055 x: xPosition, 35056 y: yPosition 35057 }; 35058 }, 35059 35060 /** 35061 * @private 35062 * @param {object} node1 35063 * @param {object} node2 35064 * @return {Number} 35065 */ 35066 35067 getHypotenuse: function(node1, node2) { 35068 var distanceX = node1.x - node2.x, 35069 distanceY = node1.y - node2.y; 35070 35071 distanceX = distanceX < 0 ? distanceX * -1 : distanceX, 35072 distanceY = distanceY < 0 ? distanceY * -1 : distanceY; 35073 35074 return Math.sqrt(Math.pow(distanceX, 2) + Math.pow(distanceY, 2)); 35075 }, 35076 35077 /** 35078 * Calcuates the area of intersection between two rectangles and expresses it as 35079 * a ratio in comparison to the area of the first rectangle. 35080 * 35081 * @private 35082 * @param {Rect} box1 35083 * @param {Rect} box2 35084 * @return {number} 35085 */ 35086 35087 getIntersectionRatio: function(box1, box2) { 35088 var controlArea = box1.width * box1.height, 35089 intersectionX = -1, 35090 intersectionY = -1, 35091 intersectionArea = -1, 35092 ratio = -1; 35093 35094 intersectionX = 35095 Math.max(0, Math.min(box1.left + box1.width, box2.left + box2.width) - Math.max(box1.left, box2.left)); 35096 35097 intersectionY = 35098 Math.max(0, Math.min(box1.top + box1.height, box2.top + box2.height) - Math.max(box1.top, box2.top)); 35099 35100 intersectionArea = intersectionY * intersectionX; 35101 35102 ratio = intersectionArea / controlArea; 35103 35104 return ratio; 35105 }, 35106 35107 /** 35108 * @private 35109 * @param {object} el 35110 * @param {string} selector 35111 * @param {boolean} [includeSelf] 35112 * @param {HTMLHtmlElement} [doc] 35113 * @return {Element|null} 35114 */ 35115 35116 closestParent: function(el, selector, includeSelf, doc) { 35117 var parent = el.parentNode; 35118 35119 doc = doc || window.document; 35120 35121 if (includeSelf && el.matches(selector)) { 35122 return el; 35123 } 35124 35125 while (parent && parent != doc.body) { 35126 if (parent.matches && parent.matches(selector)) { 35127 return parent; 35128 } else if (parent.parentNode) { 35129 parent = parent.parentNode; 35130 } else { 35131 return null; 35132 } 35133 } 35134 35135 return null; 35136 }, 35137 35138 /** 35139 * @private 35140 * @param {HTMLElement} el 35141 * @param {string} selector 35142 * @param {HTMLHtmlElement} [doc] 35143 * @return {NodeList} 35144 */ 35145 35146 children: function(el, selector, doc) { 35147 var children = [], 35148 tempId = ''; 35149 35150 doc = doc || window.doc; 35151 35152 if (el) { 35153 if (!el.id) { 35154 tempId = 'Temp' + this.randomHexKey(); 35155 35156 el.id = tempId; 35157 } 35158 35159 children = doc.querySelectorAll('#' + el.id + ' > ' + selector); 35160 35161 if (tempId) { 35162 el.removeAttribute('id'); 35163 } 35164 } 35165 35166 return children; 35167 }, 35168 35169 /** 35170 * Creates a clone of a provided array, with any empty strings removed. 35171 * 35172 * @private 35173 * @param {Array<*>} originalArray 35174 * @return {Array<*>} 35175 */ 35176 35177 clean: function(originalArray) { 35178 var cleanArray = [], 35179 i = -1; 35180 35181 for (i = 0; i < originalArray.length; i++) { 35182 if (originalArray[i] !== '') { 35183 cleanArray.push(originalArray[i]); 35184 } 35185 } 35186 35187 return cleanArray; 35188 }, 35189 35190 /** 35191 * Abstracts an ES6 promise into a q-like deferred interface for storage and deferred resolution. 35192 * 35193 * @private 35194 * @param {object} libraries 35195 * @return {h.Deferred} 35196 */ 35197 35198 defer: function(libraries) { 35199 var deferred = null, 35200 promiseWrapper = null, 35201 $ = null; 35202 35203 promiseWrapper = new this.Deferred(); 35204 35205 if (mixitup.features.has.promises) { 35206 // ES6 native promise or polyfill 35207 35208 promiseWrapper.promise = new Promise(function(resolve, reject) { 35209 promiseWrapper.resolve = resolve; 35210 promiseWrapper.reject = reject; 35211 }); 35212 } else if (($ = (__webpack_provided_window_dot_jQuery || libraries.$)) && typeof $.Deferred === 'function') { 35213 // jQuery 35214 35215 deferred = $.Deferred(); 35216 35217 promiseWrapper.promise = deferred.promise(); 35218 promiseWrapper.resolve = deferred.resolve; 35219 promiseWrapper.reject = deferred.reject; 35220 } else if (window.console) { 35221 // No implementation 35222 35223 console.warn(mixitup.messages.warningNoPromiseImplementation()); 35224 } 35225 35226 return promiseWrapper; 35227 }, 35228 35229 /** 35230 * @private 35231 * @param {Array<Promise>} tasks 35232 * @param {object} libraries 35233 * @return {Promise<Array>} 35234 */ 35235 35236 all: function(tasks, libraries) { 35237 var $ = null; 35238 35239 if (mixitup.features.has.promises) { 35240 return Promise.all(tasks); 35241 } else if (($ = (__webpack_provided_window_dot_jQuery || libraries.$)) && typeof $.when === 'function') { 35242 return $.when.apply($, tasks) 35243 .done(function() { 35244 // jQuery when returns spread arguments rather than an array or resolutions 35245 35246 return arguments; 35247 }); 35248 } 35249 35250 // No implementation 35251 35252 if (window.console) { 35253 console.warn(mixitup.messages.warningNoPromiseImplementation()); 35254 } 35255 35256 return []; 35257 }, 35258 35259 /** 35260 * @private 35261 * @param {HTMLElement} el 35262 * @param {string} property 35263 * @param {Array<string>} vendors 35264 * @return {string} 35265 */ 35266 35267 getPrefix: function(el, property, vendors) { 35268 var i = -1, 35269 prefix = ''; 35270 35271 if (h.dashCase(property) in el.style) return ''; 35272 35273 for (i = 0; prefix = vendors[i]; i++) { 35274 if (prefix + property in el.style) { 35275 return prefix.toLowerCase(); 35276 } 35277 } 35278 35279 return 'unsupported'; 35280 }, 35281 35282 /** 35283 * @private 35284 * @return {string} 35285 */ 35286 35287 randomHex: function() { 35288 return ('00000' + (Math.random() * 16777216 << 0).toString(16)).substr(-6).toUpperCase(); 35289 }, 35290 35291 /** 35292 * @private 35293 * @param {HTMLDocument} [doc] 35294 * @return {object} 35295 */ 35296 35297 getDocumentState: function(doc) { 35298 doc = typeof doc.body === 'object' ? doc : window.document; 35299 35300 return { 35301 scrollTop: window.pageYOffset, 35302 scrollLeft: window.pageXOffset, 35303 docHeight: doc.documentElement.scrollHeight, 35304 docWidth: doc.documentElement.scrollWidth, 35305 viewportHeight: doc.documentElement.clientHeight, 35306 viewportWidth: doc.documentElement.clientWidth 35307 }; 35308 }, 35309 35310 /** 35311 * @private 35312 * @param {object} obj 35313 * @param {function} fn 35314 * @return {function} 35315 */ 35316 35317 bind: function(obj, fn) { 35318 return function() { 35319 return fn.apply(obj, arguments); 35320 }; 35321 }, 35322 35323 /** 35324 * @private 35325 * @param {HTMLElement} el 35326 * @return {boolean} 35327 */ 35328 35329 isVisible: function(el) { 35330 var styles = null; 35331 35332 if (el.offsetParent) return true; 35333 35334 styles = window.getComputedStyle(el); 35335 35336 if ( 35337 styles.position === 'fixed' && 35338 styles.visibility !== 'hidden' && 35339 styles.opacity !== '0' 35340 ) { 35341 // Fixed elements report no offsetParent, 35342 // but may still be invisible 35343 35344 return true; 35345 } 35346 35347 return false; 35348 }, 35349 35350 /** 35351 * @private 35352 * @param {object} obj 35353 */ 35354 35355 seal: function(obj) { 35356 if (typeof Object.seal === 'function') { 35357 Object.seal(obj); 35358 } 35359 }, 35360 35361 /** 35362 * @private 35363 * @param {object} obj 35364 */ 35365 35366 freeze: function(obj) { 35367 if (typeof Object.freeze === 'function') { 35368 Object.freeze(obj); 35369 } 35370 }, 35371 35372 /** 35373 * @private 35374 * @param {string} control 35375 * @param {string} specimen 35376 * @return {boolean} 35377 */ 35378 35379 compareVersions: function(control, specimen) { 35380 var controlParts = control.split('.'), 35381 specimenParts = specimen.split('.'), 35382 controlPart = -1, 35383 specimenPart = -1, 35384 i = -1; 35385 35386 for (i = 0; i < controlParts.length; i++) { 35387 controlPart = parseInt(controlParts[i].replace(/[^\d.]/g, '')); 35388 specimenPart = parseInt(specimenParts[i].replace(/[^\d.]/g, '') || 0); 35389 35390 if (specimenPart < controlPart) { 35391 return false; 35392 } else if (specimenPart > controlPart) { 35393 return true; 35394 } 35395 } 35396 35397 return true; 35398 }, 35399 35400 /** 35401 * @private 35402 * @constructor 35403 */ 35404 35405 Deferred: function() { 35406 this.promise = null; 35407 this.resolve = null; 35408 this.reject = null; 35409 this.id = h.randomHex(); 35410 }, 35411 35412 /** 35413 * @private 35414 * @param {object} obj 35415 * @return {boolean} 35416 */ 35417 35418 isEmptyObject: function(obj) { 35419 var key = ''; 35420 35421 if (typeof Object.keys === 'function') { 35422 return Object.keys(obj).length === 0; 35423 } 35424 35425 for (key in obj) { 35426 if (obj.hasOwnProperty(key)) { 35427 return false; 35428 } 35429 } 35430 35431 return true; 35432 }, 35433 35434 /** 35435 * @param {mixitup.Config.ClassNames} classNames 35436 * @param {string} elementName 35437 * @param {string} [modifier] 35438 * @return {string} 35439 */ 35440 35441 getClassname: function(classNames, elementName, modifier) { 35442 var classname = ''; 35443 35444 classname += classNames.block; 35445 35446 if (classname.length) { 35447 classname += classNames.delineatorElement; 35448 } 35449 35450 classname += classNames['element' + this.pascalCase(elementName)]; 35451 35452 if (!modifier) return classname; 35453 35454 if (classname.length) { 35455 classname += classNames.delineatorModifier; 35456 } 35457 35458 classname += modifier; 35459 35460 return classname; 35461 }, 35462 35463 /** 35464 * Returns the value of a property on a given object via its string key. 35465 * 35466 * @param {object} obj 35467 * @param {string} stringKey 35468 * @return {*} value 35469 */ 35470 35471 getProperty: function(obj, stringKey) { 35472 var parts = stringKey.split('.'), 35473 returnCurrent = null, 35474 current = '', 35475 i = 0; 35476 35477 if (!stringKey) { 35478 return obj; 35479 } 35480 35481 returnCurrent = function(obj) { 35482 if (!obj) { 35483 return null; 35484 } else { 35485 return obj[current]; 35486 } 35487 }; 35488 35489 while (i < parts.length) { 35490 current = parts[i]; 35491 35492 obj = returnCurrent(obj); 35493 35494 i++; 35495 } 35496 35497 if (typeof obj !== 'undefined') { 35498 return obj; 35499 } else { 35500 return null; 35501 } 35502 } 35503 }; 35504 35505 mixitup.h = h; 35506 35507 /** 35508 * The Base class adds instance methods to all other extensible MixItUp classes, 35509 * enabling the calling of any registered hooks. 35510 * 35511 * @constructor 35512 * @namespace 35513 * @memberof mixitup 35514 * @private 35515 * @since 3.0.0 35516 */ 35517 35518 mixitup.Base = function() {}; 35519 35520 mixitup.Base.prototype = { 35521 constructor: mixitup.Base, 35522 35523 /** 35524 * Calls any registered hooks for the provided action. 35525 * 35526 * @memberof mixitup.Base 35527 * @private 35528 * @instance 35529 * @since 2.0.0 35530 * @param {string} actionName 35531 * @param {Array<*>} args 35532 * @return {void} 35533 */ 35534 35535 callActions: function(actionName, args) { 35536 var self = this, 35537 hooks = self.constructor.actions[actionName], 35538 extensionName = ''; 35539 35540 if (!hooks || h.isEmptyObject(hooks)) return; 35541 35542 for (extensionName in hooks) { 35543 hooks[extensionName].apply(self, args); 35544 } 35545 }, 35546 35547 /** 35548 * Calls any registered hooks for the provided filter. 35549 * 35550 * @memberof mixitup.Base 35551 * @private 35552 * @instance 35553 * @since 2.0.0 35554 * @param {string} filterName 35555 * @param {*} input 35556 * @param {Array<*>} args 35557 * @return {*} 35558 */ 35559 35560 callFilters: function(filterName, input, args) { 35561 var self = this, 35562 hooks = self.constructor.filters[filterName], 35563 output = input, 35564 extensionName = ''; 35565 35566 if (!hooks || h.isEmptyObject(hooks)) return output; 35567 35568 args = args || []; 35569 35570 for (extensionName in hooks) { 35571 args = h.arrayFromList(args); 35572 35573 args.unshift(output); 35574 35575 output = hooks[extensionName].apply(self, args); 35576 } 35577 35578 return output; 35579 } 35580 }; 35581 35582 /** 35583 * The BaseStatic class holds a set of static methods which are then added to all other 35584 * extensible MixItUp classes as a means of integrating extensions via the addition of new 35585 * methods and/or actions and hooks. 35586 * 35587 * @constructor 35588 * @namespace 35589 * @memberof mixitup 35590 * @private 35591 * @since 3.0.0 35592 */ 35593 35594 mixitup.BaseStatic = function() { 35595 this.actions = {}; 35596 this.filters = {}; 35597 35598 /** 35599 * Performs a shallow extend on the class's prototype, adding one or more new members to 35600 * the class in a single operation. 35601 * 35602 * @memberof mixitup.BaseStatic 35603 * @public 35604 * @static 35605 * @since 2.1.0 35606 * @param {object} extension 35607 * @return {void} 35608 */ 35609 35610 this.extend = function(extension) { 35611 h.extend(this.prototype, extension); 35612 }; 35613 35614 /** 35615 * Registers a function to be called on the action hook of the provided name. 35616 * 35617 * @memberof mixitup.BaseStatic 35618 * @public 35619 * @static 35620 * @since 2.1.0 35621 * @param {string} hookName 35622 * @param {string} extensionName 35623 * @param {function} func 35624 * @return {void} 35625 */ 35626 35627 this.registerAction = function(hookName, extensionName, func) { 35628 (this.actions[hookName] = this.actions[hookName] || {})[extensionName] = func; 35629 }; 35630 35631 /** 35632 * Registers a function to be called on the filter of the provided name. 35633 * 35634 * @memberof mixitup.BaseStatic 35635 * @public 35636 * @static 35637 * @since 2.1.0 35638 * @param {string} hookName 35639 * @param {string} extensionName 35640 * @param {function} func 35641 * @return {void} 35642 */ 35643 35644 this.registerFilter = function(hookName, extensionName, func) { 35645 (this.filters[hookName] = this.filters[hookName] || {})[extensionName] = func; 35646 }; 35647 }; 35648 35649 /** 35650 * The `mixitup.Features` class performs all feature and CSS prefix detection 35651 * neccessary for MixItUp to function correctly, as well as storing various 35652 * string and array constants. All feature decection is on evaluation of the 35653 * library and stored in a singleton instance for use by other internal classes. 35654 * 35655 * @constructor 35656 * @namespace 35657 * @memberof mixitup 35658 * @private 35659 * @since 3.0.0 35660 */ 35661 35662 mixitup.Features = function() { 35663 mixitup.Base.call(this); 35664 35665 this.callActions('beforeConstruct'); 35666 35667 this.boxSizingPrefix = ''; 35668 this.transformPrefix = ''; 35669 this.transitionPrefix = ''; 35670 35671 this.boxSizingPrefix = ''; 35672 this.transformProp = ''; 35673 this.transformRule = ''; 35674 this.transitionProp = ''; 35675 this.perspectiveProp = ''; 35676 this.perspectiveOriginProp = ''; 35677 35678 this.has = new mixitup.Has(); 35679 35680 this.canary = null; 35681 35682 this.BOX_SIZING_PROP = 'boxSizing'; 35683 this.TRANSITION_PROP = 'transition'; 35684 this.TRANSFORM_PROP = 'transform'; 35685 this.PERSPECTIVE_PROP = 'perspective'; 35686 this.PERSPECTIVE_ORIGIN_PROP = 'perspectiveOrigin'; 35687 this.VENDORS = ['Webkit', 'moz', 'O', 'ms']; 35688 35689 this.TWEENABLE = [ 35690 'opacity', 35691 'width', 'height', 35692 'marginRight', 'marginBottom', 35693 'x', 'y', 35694 'scale', 35695 'translateX', 'translateY', 'translateZ', 35696 'rotateX', 'rotateY', 'rotateZ' 35697 ]; 35698 35699 this.callActions('afterConstruct'); 35700 }; 35701 35702 mixitup.BaseStatic.call(mixitup.Features); 35703 35704 mixitup.Features.prototype = Object.create(mixitup.Base.prototype); 35705 35706 h.extend(mixitup.Features.prototype, 35707 /** @lends mixitup.Features */ 35708 { 35709 constructor: mixitup.Features, 35710 35711 /** 35712 * @private 35713 * @return {void} 35714 */ 35715 35716 init: function() { 35717 var self = this; 35718 35719 self.callActions('beforeInit', arguments); 35720 35721 self.canary = document.createElement('div'); 35722 35723 self.setPrefixes(); 35724 self.runTests(); 35725 35726 self.callActions('beforeInit', arguments); 35727 }, 35728 35729 /** 35730 * @private 35731 * @return {void} 35732 */ 35733 35734 runTests: function() { 35735 var self = this; 35736 35737 self.callActions('beforeRunTests', arguments); 35738 35739 self.has.promises = typeof window.Promise === 'function'; 35740 self.has.transitions = self.transitionPrefix !== 'unsupported'; 35741 35742 self.callActions('afterRunTests', arguments); 35743 35744 h.freeze(self.has); 35745 }, 35746 35747 /** 35748 * @private 35749 * @return {void} 35750 */ 35751 35752 setPrefixes: function() { 35753 var self = this; 35754 35755 self.callActions('beforeSetPrefixes', arguments); 35756 35757 self.transitionPrefix = h.getPrefix(self.canary, 'Transition', self.VENDORS); 35758 self.transformPrefix = h.getPrefix(self.canary, 'Transform', self.VENDORS); 35759 self.boxSizingPrefix = h.getPrefix(self.canary, 'BoxSizing', self.VENDORS); 35760 35761 self.boxSizingProp = self.boxSizingPrefix ? 35762 self.boxSizingPrefix + h.pascalCase(self.BOX_SIZING_PROP) : self.BOX_SIZING_PROP; 35763 35764 self.transitionProp = self.transitionPrefix ? 35765 self.transitionPrefix + h.pascalCase(self.TRANSITION_PROP) : self.TRANSITION_PROP; 35766 35767 self.transformProp = self.transformPrefix ? 35768 self.transformPrefix + h.pascalCase(self.TRANSFORM_PROP) : self.TRANSFORM_PROP; 35769 35770 self.transformRule = self.transformPrefix ? 35771 '-' + self.transformPrefix + '-' + self.TRANSFORM_PROP : self.TRANSFORM_PROP; 35772 35773 self.perspectiveProp = self.transformPrefix ? 35774 self.transformPrefix + h.pascalCase(self.PERSPECTIVE_PROP) : self.PERSPECTIVE_PROP; 35775 35776 self.perspectiveOriginProp = self.transformPrefix ? 35777 self.transformPrefix + h.pascalCase(self.PERSPECTIVE_ORIGIN_PROP) : 35778 self.PERSPECTIVE_ORIGIN_PROP; 35779 35780 self.callActions('afterSetPrefixes', arguments); 35781 } 35782 }); 35783 35784 /** 35785 * @constructor 35786 * @memberof mixitup 35787 * @private 35788 * @since 3.0.0 35789 */ 35790 35791 mixitup.Has = function() { 35792 this.transitions = false; 35793 this.promises = false; 35794 35795 h.seal(this); 35796 }; 35797 35798 // Assign a singleton instance to `mixitup.features` and initialise: 35799 35800 mixitup.features = new mixitup.Features(); 35801 35802 mixitup.features.init(); 35803 35804 /** 35805 * A group of properties defining the mixer's animation and effects settings. 35806 * 35807 * @constructor 35808 * @memberof mixitup.Config 35809 * @name animation 35810 * @namespace 35811 * @public 35812 * @since 2.0.0 35813 */ 35814 35815 mixitup.ConfigAnimation = function() { 35816 mixitup.Base.call(this); 35817 35818 this.callActions('beforeConstruct'); 35819 35820 /** 35821 * A boolean dictating whether or not animation should be enabled for the MixItUp instance. 35822 * If `false`, all operations will occur instantly and syncronously, although callback 35823 * functions and any returned promises will still be fulfilled. 35824 * 35825 * @example <caption>Example: Create a mixer with all animations disabled</caption> 35826 * var mixer = mixitup(containerEl, { 35827 * animation: { 35828 * enable: false 35829 * } 35830 * }); 35831 * 35832 * @name enable 35833 * @memberof mixitup.Config.animation 35834 * @instance 35835 * @type {boolean} 35836 * @default true 35837 */ 35838 35839 this.enable = true; 35840 35841 /** 35842 * A string of one or more space-seperated properties to which transitions will be 35843 * applied for all filtering animations. 35844 * 35845 * Properties can be listed any order or combination, although they will be applied in a specific 35846 * predefined order to produce consistent results. 35847 * 35848 * To learn more about available effects, experiment with our <a href="https://www.kunkalabs.com/mixitup/"> 35849 * sandbox demo</a> and try out the "Export config" button in the Animation options drop down. 35850 * 35851 * @example <caption>Example: Apply "fade" and "translateZ" effects to all animations</caption> 35852 * // As targets are filtered in and out, they will fade between 35853 * // opacity 1 and 0 and transform between translateZ(-100px) and 35854 * // translateZ(0). 35855 * 35856 * var mixer = mixitup(containerEl, { 35857 * animation: { 35858 * effects: 'fade translateZ(-100px)' 35859 * } 35860 * }); 35861 * 35862 * @name effects 35863 * @memberof mixitup.Config.animation 35864 * @instance 35865 * @type {string} 35866 * @default 'fade scale' 35867 */ 35868 35869 this.effects = 'fade scale'; 35870 35871 /** 35872 * A string of one or more space-seperated effects to be applied only to filter-in 35873 * animations, overriding `config.animation.effects` if set. 35874 * 35875 * @example <caption>Example: Apply downwards vertical translate to targets being filtered in</caption> 35876 * 35877 * var mixer = mixitup(containerEl, { 35878 * animation: { 35879 * effectsIn: 'fade translateY(-100%)' 35880 * } 35881 * }); 35882 * 35883 * @name effectsIn 35884 * @memberof mixitup.Config.animation 35885 * @instance 35886 * @type {string} 35887 * @default '' 35888 */ 35889 35890 this.effectsIn = ''; 35891 35892 /** 35893 * A string of one or more space-seperated effects to be applied only to filter-out 35894 * animations, overriding `config.animation.effects` if set. 35895 * 35896 * @example <caption>Example: Apply upwards vertical translate to targets being filtered out</caption> 35897 * 35898 * var mixer = mixitup(containerEl, { 35899 * animation: { 35900 * effectsOut: 'fade translateY(-100%)' 35901 * } 35902 * }); 35903 * 35904 * @name effectsOut 35905 * @memberof mixitup.Config.animation 35906 * @instance 35907 * @type {string} 35908 * @default '' 35909 */ 35910 35911 this.effectsOut = ''; 35912 35913 /** 35914 * An integer dictating the duration of all MixItUp animations in milliseconds, not 35915 * including any additional delay apllied via the `'stagger'` effect. 35916 * 35917 * @example <caption>Example: Apply an animation duration of 200ms to all mixitup animations</caption> 35918 * 35919 * var mixer = mixitup(containerEl, { 35920 * animation: { 35921 * duration: 200 35922 * } 35923 * }); 35924 * 35925 * @name duration 35926 * @memberof mixitup.Config.animation 35927 * @instance 35928 * @type {number} 35929 * @default 600 35930 */ 35931 35932 this.duration = 600; 35933 35934 /** 35935 * A valid CSS3 transition-timing function or shorthand. For a full list of accepted 35936 * values, visit <a href="http://easings.net" target="_blank">easings.net</a>. 35937 * 35938 * @example <caption>Example 1: Apply "ease-in-out" easing to all animations</caption> 35939 * 35940 * var mixer = mixitup(containerEl, { 35941 * animation: { 35942 * easing: 'ease-in-out' 35943 * } 35944 * }); 35945 * 35946 * @example <caption>Example 2: Apply a custom "cubic-bezier" easing function to all animations</caption> 35947 * var mixer = mixitup(containerEl, { 35948 * animation: { 35949 * easing: 'cubic-bezier(0.645, 0.045, 0.355, 1)' 35950 * } 35951 * }); 35952 * 35953 * @name easing 35954 * @memberof mixitup.Config.animation 35955 * @instance 35956 * @type {string} 35957 * @default 'ease' 35958 */ 35959 35960 this.easing = 'ease'; 35961 35962 /** 35963 * A boolean dictating whether or not to apply perspective to the MixItUp container 35964 * during animations. By default, perspective is always applied and creates the 35965 * illusion of three-dimensional space for effects such as `translateZ`, `rotateX`, 35966 * and `rotateY`. 35967 * 35968 * You may wish to disable this and define your own perspective settings via CSS. 35969 * 35970 * @example <caption>Example: Prevent perspective from being applied to any 3D transforms</caption> 35971 * var mixer = mixitup(containerEl, { 35972 * animation: { 35973 * applyPerspective: false 35974 * } 35975 * }); 35976 * 35977 * @name applyPerspective 35978 * @memberof mixitup.Config.animation 35979 * @instance 35980 * @type {bolean} 35981 * @default true 35982 */ 35983 35984 this.applyPerspective = true; 35985 35986 /** 35987 * The perspective distance value to be applied to the container during animations, 35988 * affecting any 3D-transform-based effects. 35989 * 35990 * @example <caption>Example: Set a perspective distance of 2000px</caption> 35991 * var mixer = mixitup(containerEl, { 35992 * animation: { 35993 * effects: 'rotateY(-25deg)', 35994 * perspectiveDistance: '2000px' 35995 * } 35996 * }); 35997 * 35998 * @name perspectiveDistance 35999 * @memberof mixitup.Config.animation 36000 * @instance 36001 * @type {string} 36002 * @default '3000px' 36003 */ 36004 36005 this.perspectiveDistance = '3000px'; 36006 36007 /** 36008 * The perspective-origin value to be applied to the container during animations, 36009 * affecting any 3D-transform-based effects. 36010 * 36011 * @example <caption>Example: Set a perspective origin in the top-right of the container</caption> 36012 * var mixer = mixitup(containerEl, { 36013 * animation: { 36014 * effects: 'transateZ(-200px)', 36015 * perspectiveOrigin: '100% 0' 36016 * } 36017 * }); 36018 * 36019 * @name perspectiveOrigin 36020 * @memberof mixitup.Config.animation 36021 * @instance 36022 * @type {string} 36023 * @default '50% 50%' 36024 */ 36025 36026 this.perspectiveOrigin = '50% 50%'; 36027 36028 /** 36029 * A boolean dictating whether or not to enable the queuing of operations. 36030 * 36031 * If `true` (default), and a control is clicked or an API call is made while another 36032 * operation is progress, the operation will go into the queue and will be automatically exectuted 36033 * when the previous operaitons is finished. 36034 * 36035 * If `false`, any requested operations will be ignored, and the `onMixBusy` callback and `mixBusy` 36036 * event will be fired. If `debug.showWarnings` is enabled, a console warning will also occur. 36037 * 36038 * @example <caption>Example: Disable queuing</caption> 36039 * var mixer = mixitup(containerEl, { 36040 * animation: { 36041 * queue: false 36042 * } 36043 * }); 36044 * 36045 * @name queue 36046 * @memberof mixitup.Config.animation 36047 * @instance 36048 * @type {boolean} 36049 * @default true 36050 */ 36051 36052 this.queue = true; 36053 36054 /** 36055 * An integer dictacting the maximum number of operations allowed in the queue at 36056 * any time, when queuing is enabled. 36057 * 36058 * @example <caption>Example: Allow a maximum of 5 operations in the queue at any time</caption> 36059 * var mixer = mixitup(containerEl, { 36060 * animation: { 36061 * queueLimit: 5 36062 * } 36063 * }); 36064 * 36065 * @name queueLimit 36066 * @memberof mixitup.Config.animation 36067 * @instance 36068 * @type {number} 36069 * @default 3 36070 */ 36071 36072 this.queueLimit = 3; 36073 36074 /** 36075 * A boolean dictating whether or not to transition the height and width of the 36076 * container as elements are filtered in and out. If disabled, the container height 36077 * will change abruptly. 36078 * 36079 * It may be desirable to disable this on mobile devices as the CSS `height` and 36080 * `width` properties do not receive GPU-acceleration and can therefore cause stuttering. 36081 * 36082 * @example <caption>Example 1: Disable the transitioning of the container height and/or width</caption> 36083 * var mixer = mixitup(containerEl, { 36084 * animation: { 36085 * animateResizeContainer: false 36086 * } 36087 * }); 36088 * 36089 * @example <caption>Example 2: Disable the transitioning of the container height and/or width for mobile devices only</caption> 36090 * var mixer = mixitup(containerEl, { 36091 * animation: { 36092 * animateResizeContainer: myFeatureTests.isMobile ? false : true 36093 * } 36094 * }); 36095 * 36096 * @name animateResizeContainer 36097 * @memberof mixitup.Config.animation 36098 * @instance 36099 * @type {boolean} 36100 * @default true 36101 */ 36102 36103 this.animateResizeContainer = true; 36104 36105 /** 36106 * A boolean dictating whether or not to transition the height and width of target 36107 * elements as they change throughout the course of an animation. 36108 * 36109 * This is often a must for flex-box grid layouts where the size of target elements may change 36110 * depending on final their position in relation to their siblings, or for `.changeLayout()` 36111 * operations where the size of targets change between layouts. 36112 * 36113 * NB: This feature requires additional calculations and manipulation to non-hardware-accelerated 36114 * properties which may adversely affect performance on slower devices, and is therefore 36115 * disabled by default. 36116 * 36117 * @example <caption>Example: Enable the transitioning of target widths and heights</caption> 36118 * var mixer = mixitup(containerEl, { 36119 * animation: { 36120 * animateResizeTargets: true 36121 * } 36122 * }); 36123 * 36124 * @name animateResizeTargets 36125 * @memberof mixitup.Config.animation 36126 * @instance 36127 * @type {boolean} 36128 * @default false 36129 */ 36130 36131 this.animateResizeTargets = false; 36132 36133 /** 36134 * A custom function used to manipulate the order in which the stagger delay is 36135 * incremented when using the ‘stagger’ effect. 36136 * 36137 * When using the 'stagger' effect, the delay applied to each target element is incremented 36138 * based on its index. You may create a custom function to manipulate the order in which the 36139 * delay is incremented and create engaging non-linear stagger effects. 36140 * 36141 * The function receives the index of the target element as a parameter, and must 36142 * return an integer which serves as the multiplier for the stagger delay. 36143 * 36144 * @example <caption>Example 1: Stagger target elements by column in a 3-column grid</caption> 36145 * var mixer = mixitup(containerEl, { 36146 * animation: { 36147 * effects: 'fade stagger(100ms)', 36148 * staggerSequence: function(i) { 36149 * return i % 3; 36150 * } 36151 * } 36152 * }); 36153 * 36154 * @example <caption>Example 2: Using an algorithm to produce a more complex sequence</caption> 36155 * var mixer = mixitup(containerEl, { 36156 * animation: { 36157 * effects: 'fade stagger(100ms)', 36158 * staggerSequence: function(i) { 36159 * return (2*i) - (5*((i/3) - ((1/3) * (i%3)))); 36160 * } 36161 * } 36162 * }); 36163 * 36164 * @name staggerSequence 36165 * @memberof mixitup.Config.animation 36166 * @instance 36167 * @type {function} 36168 * @default null 36169 */ 36170 36171 this.staggerSequence = null; 36172 36173 /** 36174 * A boolean dictating whether or not to reverse the direction of `translate` 36175 * and `rotate` transforms for elements being filtered out. 36176 * 36177 * It can be used to create carousel-like animations where elements enter and exit 36178 * from opposite directions. If enabled, the effect `translateX(-100%)` for elements 36179 * being filtered in would become `translateX(100%)` for targets being filtered out. 36180 * 36181 * This functionality can also be achieved by providing seperate effects 36182 * strings for `config.animation.effectsIn` and `config.animation.effectsOut`. 36183 * 36184 * @example <caption>Example: Reverse the desired direction on any translate/rotate effect for targets being filtered out</caption> 36185 * // Elements being filtered in will be translated from '100%' to '0' while 36186 * // elements being filtered out will be translated from 0 to '-100%' 36187 * 36188 * var mixer = mixitup(containerEl, { 36189 * animation: { 36190 * effects: 'fade translateX(100%)', 36191 * reverseOut: true, 36192 * nudge: false // Disable nudging to create a carousel-like effect 36193 * } 36194 * }); 36195 * 36196 * @name reverseOut 36197 * @memberof mixitup.Config.animation 36198 * @instance 36199 * @type {boolean} 36200 * @default false 36201 */ 36202 36203 this.reverseOut = false; 36204 36205 /** 36206 * A boolean dictating whether or not to "nudge" the animation path of targets 36207 * when they are being filtered in and out simulatenously. 36208 * 36209 * This has been the default behavior of MixItUp since version 1, but it 36210 * may be desirable to disable this effect when filtering directly from 36211 * one exclusive set of targets to a different exclusive set of targets, 36212 * to create a carousel-like effect, or a generally more subtle animation. 36213 * 36214 * @example <caption>Example: Disable the "nudging" of targets being filtered in and out simulatenously</caption> 36215 * 36216 * var mixer = mixitup(containerEl, { 36217 * animation: { 36218 * nudge: false 36219 * } 36220 * }); 36221 * 36222 * @name nudge 36223 * @memberof mixitup.Config.animation 36224 * @instance 36225 * @type {boolean} 36226 * @default true 36227 */ 36228 36229 this.nudge = true; 36230 36231 /** 36232 * A boolean dictating whether or not to clamp the height of the container while MixItUp's 36233 * geometry tests are carried out before an operation. 36234 * 36235 * To prevent scroll-bar flicker, clamping is turned on by default. But in the case where the 36236 * height of the container might affect its vertical positioning in the viewport 36237 * (e.g. a vertically-centered container), this should be turned off to ensure accurate 36238 * test results and a smooth animation. 36239 * 36240 * @example <caption>Example: Disable container height-clamping</caption> 36241 * 36242 * var mixer = mixitup(containerEl, { 36243 * animation: { 36244 * clampHeight: false 36245 * } 36246 * }); 36247 * 36248 * @name clampHeight 36249 * @memberof mixitup.Config.animation 36250 * @instance 36251 * @type {boolean} 36252 * @default true 36253 */ 36254 36255 this.clampHeight = true; 36256 36257 /** 36258 * A boolean dictating whether or not to clamp the width of the container while MixItUp's 36259 * geometry tests are carried out before an operation. 36260 * 36261 * To prevent scroll-bar flicker, clamping is turned on by default. But in the case where the 36262 * width of the container might affect its horitzontal positioning in the viewport 36263 * (e.g. a horizontall-centered container), this should be turned off to ensure accurate 36264 * test results and a smooth animation. 36265 * 36266 * @example <caption>Example: Disable container width-clamping</caption> 36267 * 36268 * var mixer = mixitup(containerEl, { 36269 * animation: { 36270 * clampWidth: false 36271 * } 36272 * }); 36273 * 36274 * @name clampWidth 36275 * @memberof mixitup.Config.animation 36276 * @instance 36277 * @type {boolean} 36278 * @default true 36279 */ 36280 36281 this.clampWidth = true; 36282 36283 this.callActions('afterConstruct'); 36284 36285 h.seal(this); 36286 }; 36287 36288 mixitup.BaseStatic.call(mixitup.ConfigAnimation); 36289 36290 mixitup.ConfigAnimation.prototype = Object.create(mixitup.Base.prototype); 36291 36292 mixitup.ConfigAnimation.prototype.constructor = mixitup.ConfigAnimation; 36293 36294 /** 36295 * A group of properties relating to the behavior of the Mixer. 36296 * 36297 * @constructor 36298 * @memberof mixitup.Config 36299 * @name behavior 36300 * @namespace 36301 * @public 36302 * @since 3.1.12 36303 */ 36304 36305 mixitup.ConfigBehavior = function() { 36306 mixitup.Base.call(this); 36307 36308 this.callActions('beforeConstruct'); 36309 36310 /** 36311 * A boolean dictating whether to allow "live" sorting of the mixer. 36312 * 36313 * Because of the expensive nature of sorting, MixItUp makes use of several 36314 * internal optimizations to skip redundant sorting operations, such as when 36315 * the newly requested sort command is the same as the active one. The caveat 36316 * to this optimization is that "live" edits to the value of a target's sorting 36317 * attribute will be ignored when requesting a re-sort by the same attribute. 36318 * 36319 * By setting to `behavior.liveSort` to `true`, the mixer will always re-sort 36320 * regardless of whether or not the sorting attribute and order have changed. 36321 * 36322 * @example <caption>Example: Enabling `liveSort` to allow for re-sorting</caption> 36323 * 36324 * var mixer = mixitup(containerEl, { 36325 * behavior: { 36326 * liveSort: true 36327 * }, 36328 * load: { 36329 * sort: 'edited:desc' 36330 * } 36331 * }); 36332 * 36333 * var target = containerEl.children[3]; 36334 * 36335 * console.log(target.getAttribute('data-edited')); // '2015-04-24' 36336 * 36337 * target.setAttribute('data-edited', '2017-08-10'); // Update the target's edited date 36338 * 36339 * mixer.sort('edited:desc') 36340 * .then(function(state) { 36341 * // The target is now at the top of the list 36342 * 36343 * console.log(state.targets[0] === target); // true 36344 * }); 36345 * 36346 * @name liveSort 36347 * @memberof mixitup.Config.behavior 36348 * @instance 36349 * @type {boolean} 36350 * @default false 36351 */ 36352 36353 this.liveSort = false; 36354 36355 this.callActions('afterConstruct'); 36356 36357 h.seal(this); 36358 }; 36359 36360 mixitup.BaseStatic.call(mixitup.ConfigBehavior); 36361 36362 mixitup.ConfigBehavior.prototype = Object.create(mixitup.Base.prototype); 36363 36364 mixitup.ConfigBehavior.prototype.constructor = mixitup.ConfigBehavior; 36365 36366 /** 36367 * A group of optional callback functions to be invoked at various 36368 * points within the lifecycle of a mixer operation. 36369 * 36370 * Each function is analogous to an event of the same name triggered from the 36371 * container element, and is invoked immediately after it. 36372 * 36373 * All callback functions receive the current `state` object as their first 36374 * argument, as well as other more specific arguments described below. 36375 * 36376 * @constructor 36377 * @memberof mixitup.Config 36378 * @name callbacks 36379 * @namespace 36380 * @public 36381 * @since 2.0.0 36382 */ 36383 36384 mixitup.ConfigCallbacks = function() { 36385 mixitup.Base.call(this); 36386 36387 this.callActions('beforeConstruct'); 36388 36389 /** 36390 * A callback function invoked immediately after any MixItUp operation is requested 36391 * and before animations have begun. 36392 * 36393 * A second `futureState` argument is passed to the function which represents the final 36394 * state of the mixer once the requested operation has completed. 36395 * 36396 * @example <caption>Example: Adding an `onMixStart` callback function</caption> 36397 * var mixer = mixitup(containerEl, { 36398 * callbacks: { 36399 * onMixStart: function(state, futureState) { 36400 * console.log('Starting operation...'); 36401 * } 36402 * } 36403 * }); 36404 * 36405 * @name onMixStart 36406 * @memberof mixitup.Config.callbacks 36407 * @instance 36408 * @type {function} 36409 * @default null 36410 */ 36411 36412 this.onMixStart = null; 36413 36414 /** 36415 * A callback function invoked when a MixItUp operation is requested while another 36416 * operation is in progress, and the animation queue is full, or queueing 36417 * is disabled. 36418 * 36419 * @example <caption>Example: Adding an `onMixBusy` callback function</caption> 36420 * var mixer = mixitup(containerEl, { 36421 * callbacks: { 36422 * onMixBusy: function(state) { 36423 * console.log('Mixer busy'); 36424 * } 36425 * } 36426 * }); 36427 * 36428 * @name onMixBusy 36429 * @memberof mixitup.Config.callbacks 36430 * @instance 36431 * @type {function} 36432 * @default null 36433 */ 36434 36435 this.onMixBusy = null; 36436 36437 /** 36438 * A callback function invoked after any MixItUp operation has completed, and the 36439 * state has been updated. 36440 * 36441 * @example <caption>Example: Adding an `onMixEnd` callback function</caption> 36442 * var mixer = mixitup(containerEl, { 36443 * callbacks: { 36444 * onMixEnd: function(state) { 36445 * console.log('Operation complete'); 36446 * } 36447 * } 36448 * }); 36449 * 36450 * @name onMixEnd 36451 * @memberof mixitup.Config.callbacks 36452 * @instance 36453 * @type {function} 36454 * @default null 36455 */ 36456 36457 this.onMixEnd = null; 36458 36459 /** 36460 * A callback function invoked whenever an operation "fails", i.e. no targets 36461 * could be found matching the requested filter. 36462 * 36463 * @example <caption>Example: Adding an `onMixFail` callback function</caption> 36464 * var mixer = mixitup(containerEl, { 36465 * callbacks: { 36466 * onMixFail: function(state) { 36467 * console.log('No items could be found matching the requested filter'); 36468 * } 36469 * } 36470 * }); 36471 * 36472 * @name onMixFail 36473 * @memberof mixitup.Config.callbacks 36474 * @instance 36475 * @type {function} 36476 * @default null 36477 */ 36478 36479 this.onMixFail = null; 36480 36481 /** 36482 * A callback function invoked whenever a MixItUp control is clicked, and before its 36483 * respective operation is requested. 36484 * 36485 * The clicked element is assigned to the `this` keyword within the function. The original 36486 * click event is passed to the function as the second argument, which can be useful if 36487 * using `<a>` tags as controls where the default behavior needs to be prevented. 36488 * 36489 * Returning `false` from the callback will prevent the control click from triggering 36490 * an operation. 36491 * 36492 * @example <caption>Example 1: Adding an `onMixClick` callback function</caption> 36493 * var mixer = mixitup(containerEl, { 36494 * callbacks: { 36495 * onMixClick: function(state, originalEvent) { 36496 * console.log('The control "' + this.innerText + '" was clicked'); 36497 * } 36498 * } 36499 * }); 36500 * 36501 * @example <caption>Example 2: Using `onMixClick` to manipulate the original click event</caption> 36502 * var mixer = mixitup(containerEl, { 36503 * callbacks: { 36504 * onMixClick: function(state, originalEvent) { 36505 * // Prevent original click event from bubbling up: 36506 * originalEvent.stopPropagation(); 36507 * 36508 * // Prevent default behavior of clicked element: 36509 * originalEvent.preventDefault(); 36510 * } 36511 * } 36512 * }); 36513 * 36514 * @example <caption>Example 3: Using `onMixClick` to conditionally cancel operations</caption> 36515 * var mixer = mixitup(containerEl, { 36516 * callbacks: { 36517 * onMixClick: function(state, originalEvent) { 36518 * // Perform some conditional check: 36519 * 36520 * if (myApp.isLoading) { 36521 * // By returning false, we can prevent the control click from triggering an operation. 36522 * 36523 * return false; 36524 * } 36525 * } 36526 * } 36527 * }); 36528 * 36529 * @name onMixClick 36530 * @memberof mixitup.Config.callbacks 36531 * @instance 36532 * @type {function} 36533 * @default null 36534 */ 36535 36536 this.onMixClick = null; 36537 36538 this.callActions('afterConstruct'); 36539 36540 h.seal(this); 36541 }; 36542 36543 mixitup.BaseStatic.call(mixitup.ConfigCallbacks); 36544 36545 mixitup.ConfigCallbacks.prototype = Object.create(mixitup.Base.prototype); 36546 36547 mixitup.ConfigCallbacks.prototype.constructor = mixitup.ConfigCallbacks; 36548 36549 /** 36550 * A group of properties relating to clickable control elements. 36551 * 36552 * @constructor 36553 * @memberof mixitup.Config 36554 * @name controls 36555 * @namespace 36556 * @public 36557 * @since 2.0.0 36558 */ 36559 36560 mixitup.ConfigControls = function() { 36561 mixitup.Base.call(this); 36562 36563 this.callActions('beforeConstruct'); 36564 36565 /** 36566 * A boolean dictating whether or not controls should be enabled for the mixer instance. 36567 * 36568 * If `true` (default behavior), MixItUp will search the DOM for any clickable elements with 36569 * `data-filter`, `data-sort` or `data-toggle` attributes, and bind them for click events. 36570 * 36571 * If `false`, no click handlers will be bound, and all functionality must therefore be performed 36572 * via the mixer's API methods. 36573 * 36574 * If you do not intend to use the default controls, setting this property to `false` will 36575 * marginally improve the startup time of your mixer instance, and will also prevent any other active 36576 * mixer instances in the DOM which are bound to controls from controlling the instance. 36577 * 36578 * @example <caption>Example: Disabling controls</caption> 36579 * var mixer = mixitup(containerEl, { 36580 * controls: { 36581 * enable: false 36582 * } 36583 * }); 36584 * 36585 * // With the default controls disabled, we can only control 36586 * // the mixer via its API methods, e.g.: 36587 * 36588 * mixer.filter('.cat-1'); 36589 * 36590 * @name enable 36591 * @memberof mixitup.Config.controls 36592 * @instance 36593 * @type {boolean} 36594 * @default true 36595 */ 36596 36597 this.enable = true; 36598 36599 /** 36600 * A boolean dictating whether or not to use event delegation when binding click events 36601 * to the default controls. 36602 * 36603 * If `false` (default behavior), each control button in the DOM will be found and 36604 * individually bound when a mixer is instantiated, with their corresponding actions 36605 * cached for performance. 36606 * 36607 * If `true`, a single click handler will be applied to the `window` (or container element - see 36608 * `config.controls.scope`), and any click events triggered by elements with `data-filter`, 36609 * `data-sort` or `data-toggle` attributes present will be handled as they propagate upwards. 36610 * 36611 * If you require a user interface where control buttons may be added, removed, or changed during the 36612 * lifetime of a mixer, `controls.live` should be set to `true`. There is a marginal but unavoidable 36613 * performance deficit when using live controls, as the value of each control button must be read 36614 * from the DOM in real time once the click event has propagated. 36615 * 36616 * @example <caption>Example: Setting live controls</caption> 36617 * var mixer = mixitup(containerEl, { 36618 * controls: { 36619 * live: true 36620 * } 36621 * }); 36622 * 36623 * // Control buttons can now be added, remove and changed without breaking 36624 * // the mixer's UI 36625 * 36626 * @name live 36627 * @memberof mixitup.Config.controls 36628 * @instance 36629 * @type {boolean} 36630 * @default true 36631 */ 36632 36633 this.live = false; 36634 36635 /** 36636 * A string dictating the "scope" to use when binding or querying the default controls. The available 36637 * values are `'global'` or `'local'`. 36638 * 36639 * When set to `'global'` (default behavior), MixItUp will query the entire document for control buttons 36640 * to bind, or delegate click events from (see `config.controls.live`). 36641 * 36642 * When set to `'local'`, MixItUp will only query (or bind click events to) its own container element. 36643 * This may be desireable if you require multiple active mixer instances within the same document, with 36644 * controls that would otherwise intefere with each other if scoped globally. 36645 * 36646 * Conversely, if you wish to control multiple instances with a single UI, you would create one 36647 * set of controls and keep the controls scope of each mixer set to `global`. 36648 * 36649 * @example <caption>Example: Setting 'local' scoped controls</caption> 36650 * var mixerOne = mixitup(containerOne, { 36651 * controls: { 36652 * scope: 'local' 36653 * } 36654 * }); 36655 * 36656 * var mixerTwo = mixitup(containerTwo, { 36657 * controls: { 36658 * scope: 'local' 36659 * } 36660 * }); 36661 * 36662 * // Both mixers can now exist within the same document with 36663 * // isolated controls placed within their container elements. 36664 * 36665 * @name scope 36666 * @memberof mixitup.Config.controls 36667 * @instance 36668 * @type {string} 36669 * @default 'global' 36670 */ 36671 36672 this.scope = 'global'; // enum: ['local' ,'global'] 36673 36674 /** 36675 * A string dictating the type of logic to apply when concatenating the filter selectors of 36676 * active toggle buttons (i.e. any clickable element with a `data-toggle` attribute). 36677 * 36678 * If set to `'or'` (default behavior), selectors will be concatenated together as 36679 * a comma-seperated list. For example: 36680 * 36681 * `'.cat-1, .cat-2'` (shows any elements matching `'.cat-1'` OR `'.cat-2'`) 36682 * 36683 * If set to `'and'`, selectors will be directly concatenated together. For example: 36684 * 36685 * `'.cat-1.cat-2'` (shows any elements which match both `'.cat-1'` AND `'.cat-2'`) 36686 * 36687 * @example <caption>Example: Setting "and" toggle logic</caption> 36688 * var mixer = mixitup(containerEl, { 36689 * controls: { 36690 * toggleLogic: 'and' 36691 * } 36692 * }); 36693 * 36694 * @name toggleLogic 36695 * @memberof mixitup.Config.controls 36696 * @instance 36697 * @type {string} 36698 * @default 'or' 36699 */ 36700 36701 this.toggleLogic = 'or'; // enum: ['or', 'and'] 36702 36703 /** 36704 * A string dictating the filter behavior when all toggles are inactive. 36705 * 36706 * When set to `'all'` (default behavior), *all* targets will be shown by default 36707 * when no toggles are active, or at the moment all active toggles are toggled off. 36708 * 36709 * When set to `'none'`, no targets will be shown by default when no toggles are 36710 * active, or at the moment all active toggles are toggled off. 36711 * 36712 * @example <caption>Example 1: Setting the default toggle behavior to `'all'`</caption> 36713 * var mixer = mixitup(containerEl, { 36714 * controls: { 36715 * toggleDefault: 'all' 36716 * } 36717 * }); 36718 * 36719 * mixer.toggleOn('.cat-2') 36720 * .then(function() { 36721 * // Deactivate all active toggles 36722 * 36723 * return mixer.toggleOff('.cat-2') 36724 * }) 36725 * .then(function(state) { 36726 * console.log(state.activeFilter.selector); // 'all' 36727 * console.log(state.totalShow); // 12 36728 * }); 36729 * 36730 * @example <caption>Example 2: Setting the default toggle behavior to `'none'`</caption> 36731 * var mixer = mixitup(containerEl, { 36732 * controls: { 36733 * toggleDefault: 'none' 36734 * } 36735 * }); 36736 * 36737 * mixer.toggleOn('.cat-2') 36738 * .then(function() { 36739 * // Deactivate all active toggles 36740 * 36741 * return mixer.toggleOff('.cat-2') 36742 * }) 36743 * .then(function(state) { 36744 * console.log(state.activeFilter.selector); // 'none' 36745 * console.log(state.totalShow); // 0 36746 * }); 36747 * 36748 * @name toggleDefault 36749 * @memberof mixitup.Config.controls 36750 * @instance 36751 * @type {string} 36752 * @default 'all' 36753 */ 36754 36755 this.toggleDefault = 'all'; // enum: ['all', 'none'] 36756 36757 this.callActions('afterConstruct'); 36758 36759 h.seal(this); 36760 }; 36761 36762 mixitup.BaseStatic.call(mixitup.ConfigControls); 36763 36764 mixitup.ConfigControls.prototype = Object.create(mixitup.Base.prototype); 36765 36766 mixitup.ConfigControls.prototype.constructor = mixitup.ConfigControls; 36767 36768 /** 36769 * A group of properties defining the output and structure of class names programmatically 36770 * added to controls and containers to reflect the state of the mixer. 36771 * 36772 * Most commonly, class names are added to controls by MixItUp to indicate that 36773 * the control is active so that it can be styled accordingly - `'mixitup-control-active'` by default. 36774 * 36775 * Using a "BEM" like structure, each classname is broken into the three parts: 36776 * a block namespace (`'mixitup'`), an element name (e.g. `'control'`), and an optional modifier 36777 * name (e.g. `'active'`) reflecting the state of the element. 36778 * 36779 * By default, each part of the classname is concatenated together using single hyphens as 36780 * delineators, but this can be easily customised to match the naming convention and style of 36781 * your project. 36782 * 36783 * @constructor 36784 * @memberof mixitup.Config 36785 * @name classNames 36786 * @namespace 36787 * @public 36788 * @since 3.0.0 36789 */ 36790 36791 mixitup.ConfigClassNames = function() { 36792 mixitup.Base.call(this); 36793 36794 this.callActions('beforeConstruct'); 36795 36796 /** 36797 * The "block" portion, or top-level namespace added to the start of any class names created by MixItUp. 36798 * 36799 * @example <caption>Example 1: changing the `config.classNames.block` value</caption> 36800 * var mixer = mixitup(containerEl, { 36801 * classNames: { 36802 * block: 'portfolio' 36803 * } 36804 * }); 36805 * 36806 * // Active control output: "portfolio-control-active" 36807 * 36808 * @example <caption>Example 2: Removing `config.classNames.block`</caption> 36809 * var mixer = mixitup(containerEl, { 36810 * classNames: { 36811 * block: '' 36812 * } 36813 * }); 36814 * 36815 * // Active control output: "control-active" 36816 * 36817 * @name block 36818 * @memberof mixitup.Config.classNames 36819 * @instance 36820 * @type {string} 36821 * @default 'mixitup' 36822 */ 36823 36824 this.block = 'mixitup'; 36825 36826 /** 36827 * The "element" portion of the class name added to container. 36828 * 36829 * @name elementContainer 36830 * @memberof mixitup.Config.classNames 36831 * @instance 36832 * @type {string} 36833 * @default 'container' 36834 */ 36835 36836 this.elementContainer = 'container'; 36837 36838 /** 36839 * The "element" portion of the class name added to filter controls. 36840 * 36841 * By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but 36842 * each type's element value can be individually overwritten to match the unique classNames of your controls as needed. 36843 * 36844 * @example <caption>Example 1: changing the `config.classNames.elementFilter` value</caption> 36845 * var mixer = mixitup(containerEl, { 36846 * classNames: { 36847 * elementFilter: 'filter' 36848 * } 36849 * }); 36850 * 36851 * // Active filter output: "mixitup-filter-active" 36852 * 36853 * @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementFilter` values</caption> 36854 * var mixer = mixitup(containerEl, { 36855 * classNames: { 36856 * block: 'portfolio', 36857 * elementFilter: 'filter' 36858 * } 36859 * }); 36860 * 36861 * // Active filter output: "portfolio-filter-active" 36862 * 36863 * @name elementFilter 36864 * @memberof mixitup.Config.classNames 36865 * @instance 36866 * @type {string} 36867 * @default 'control' 36868 */ 36869 36870 this.elementFilter = 'control'; 36871 36872 /** 36873 * The "element" portion of the class name added to sort controls. 36874 * 36875 * By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but 36876 * each type's element value can be individually overwritten to match the unique classNames of your controls as needed. 36877 * 36878 * @example <caption>Example 1: changing the `config.classNames.elementSort` value</caption> 36879 * var mixer = mixitup(containerEl, { 36880 * classNames: { 36881 * elementSort: 'sort' 36882 * } 36883 * }); 36884 * 36885 * // Active sort output: "mixitup-sort-active" 36886 * 36887 * @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementSort` values</caption> 36888 * var mixer = mixitup(containerEl, { 36889 * classNames: { 36890 * block: 'portfolio', 36891 * elementSort: 'sort' 36892 * } 36893 * }); 36894 * 36895 * // Active sort output: "portfolio-sort-active" 36896 * 36897 * @name elementSort 36898 * @memberof mixitup.Config.classNames 36899 * @instance 36900 * @type {string} 36901 * @default 'control' 36902 */ 36903 36904 this.elementSort = 'control'; 36905 36906 /** 36907 * The "element" portion of the class name added to multimix controls. 36908 * 36909 * By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but 36910 * each type's element value can be individually overwritten to match the unique classNames of your controls as needed. 36911 * 36912 * @example <caption>Example 1: changing the `config.classNames.elementMultimix` value</caption> 36913 * var mixer = mixitup(containerEl, { 36914 * classNames: { 36915 * elementMultimix: 'multimix' 36916 * } 36917 * }); 36918 * 36919 * // Active multimix output: "mixitup-multimix-active" 36920 * 36921 * @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementMultimix` values</caption> 36922 * var mixer = mixitup(containerEl, { 36923 * classNames: { 36924 * block: 'portfolio', 36925 * elementSort: 'multimix' 36926 * } 36927 * }); 36928 * 36929 * // Active multimix output: "portfolio-multimix-active" 36930 * 36931 * @name elementMultimix 36932 * @memberof mixitup.Config.classNames 36933 * @instance 36934 * @type {string} 36935 * @default 'control' 36936 */ 36937 36938 this.elementMultimix = 'control'; 36939 36940 /** 36941 * The "element" portion of the class name added to toggle controls. 36942 * 36943 * By default, all filter, sort, multimix and toggle controls take the same element value of `'control'`, but 36944 * each type's element value can be individually overwritten to match the unique classNames of your controls as needed. 36945 * 36946 * @example <caption>Example 1: changing the `config.classNames.elementToggle` value</caption> 36947 * var mixer = mixitup(containerEl, { 36948 * classNames: { 36949 * elementToggle: 'toggle' 36950 * } 36951 * }); 36952 * 36953 * // Active toggle output: "mixitup-toggle-active" 36954 * 36955 * @example <caption>Example 2: changing the `config.classNames.block` and `config.classNames.elementToggle` values</caption> 36956 * var mixer = mixitup(containerEl, { 36957 * classNames: { 36958 * block: 'portfolio', 36959 * elementToggle: 'toggle' 36960 * } 36961 * }); 36962 * 36963 * // Active toggle output: "portfolio-toggle-active" 36964 * 36965 * @name elementToggle 36966 * @memberof mixitup.Config.classNames 36967 * @instance 36968 * @type {string} 36969 * @default 'control' 36970 */ 36971 36972 this.elementToggle = 'control'; 36973 36974 /** 36975 * The "modifier" portion of the class name added to active controls. 36976 * @name modifierActive 36977 * @memberof mixitup.Config.classNames 36978 * @instance 36979 * @type {string} 36980 * @default 'active' 36981 */ 36982 36983 this.modifierActive = 'active'; 36984 36985 /** 36986 * The "modifier" portion of the class name added to disabled controls. 36987 * 36988 * @name modifierDisabled 36989 * @memberof mixitup.Config.classNames 36990 * @instance 36991 * @type {string} 36992 * @default 'disabled' 36993 */ 36994 36995 this.modifierDisabled = 'disabled'; 36996 36997 /** 36998 * The "modifier" portion of the class name added to the container when in a "failed" state. 36999 * 37000 * @name modifierFailed 37001 * @memberof mixitup.Config.classNames 37002 * @instance 37003 * @type {string} 37004 * @default 'failed' 37005 */ 37006 37007 this.modifierFailed = 'failed'; 37008 37009 /** 37010 * The delineator used between the "block" and "element" portions of any class name added by MixItUp. 37011 * 37012 * If the block portion is ommited by setting it to an empty string, no delineator will be added. 37013 * 37014 * @example <caption>Example: changing the delineator to match BEM convention</caption> 37015 * var mixer = mixitup(containerEl, { 37016 * classNames: { 37017 * delineatorElement: '__' 37018 * } 37019 * }); 37020 * 37021 * // example active control output: "mixitup__control-active" 37022 * 37023 * @name delineatorElement 37024 * @memberof mixitup.Config.classNames 37025 * @instance 37026 * @type {string} 37027 * @default '-' 37028 */ 37029 37030 this.delineatorElement = '-'; 37031 37032 /** 37033 * The delineator used between the "element" and "modifier" portions of any class name added by MixItUp. 37034 * 37035 * If the element portion is ommited by setting it to an empty string, no delineator will be added. 37036 * 37037 * @example <caption>Example: changing both delineators to match BEM convention</caption> 37038 * var mixer = mixitup(containerEl, { 37039 * classNames: { 37040 * delineatorElement: '__' 37041 * delineatorModifier: '--' 37042 * } 37043 * }); 37044 * 37045 * // Active control output: "mixitup__control--active" 37046 * 37047 * @name delineatorModifier 37048 * @memberof mixitup.Config.classNames 37049 * @instance 37050 * @type {string} 37051 * @default '-' 37052 */ 37053 37054 this.delineatorModifier = '-'; 37055 37056 this.callActions('afterConstruct'); 37057 37058 h.seal(this); 37059 }; 37060 37061 mixitup.BaseStatic.call(mixitup.ConfigClassNames); 37062 37063 mixitup.ConfigClassNames.prototype = Object.create(mixitup.Base.prototype); 37064 37065 mixitup.ConfigClassNames.prototype.constructor = mixitup.ConfigClassNames; 37066 37067 /** 37068 * A group of properties relating to MixItUp's dataset API. 37069 * 37070 * @constructor 37071 * @memberof mixitup.Config 37072 * @name data 37073 * @namespace 37074 * @public 37075 * @since 3.0.0 37076 */ 37077 37078 mixitup.ConfigData = function() { 37079 mixitup.Base.call(this); 37080 37081 this.callActions('beforeConstruct'); 37082 37083 /** 37084 * A string specifying the name of the key containing your data model's unique 37085 * identifier (UID). To use the dataset API, a UID key must be specified and 37086 * be present and unique on all objects in the dataset you provide to MixItUp. 37087 * 37088 * For example, if your dataset is made up of MongoDB documents, the UID 37089 * key would be `'id'` or `'_id'`. 37090 * 37091 * @example <caption>Example: Setting the UID to `'id'`</caption> 37092 * var mixer = mixitup(containerEl, { 37093 * data: { 37094 * uidKey: 'id' 37095 * } 37096 * }); 37097 * 37098 * @name uidKey 37099 * @memberof mixitup.Config.data 37100 * @instance 37101 * @type {string} 37102 * @default '' 37103 */ 37104 37105 this.uidKey = ''; 37106 37107 /** 37108 * A boolean dictating whether or not MixItUp should "dirty check" each object in 37109 * your dataset for changes whenever `.dataset()` is called, and re-render any targets 37110 * for which a change is found. 37111 * 37112 * Depending on the complexity of your data model, dirty checking can be expensive 37113 * and is therefore disabled by default. 37114 * 37115 * NB: For changes to be detected, a new immutable instance of the edited model must be 37116 * provided to mixitup, rather than manipulating properties on the existing instance. 37117 * If your changes are a result of a DB write and read, you will most likely be calling 37118 * `.dataset()` with a clean set of objects each time, so this will not be an issue. 37119 * 37120 * @example <caption>Example: Enabling dirty checking</caption> 37121 * 37122 * var myDataset = [ 37123 * { 37124 * id: 0, 37125 * title: "Blog Post Title 0" 37126 * ... 37127 * }, 37128 * { 37129 * id: 1, 37130 * title: "Blog Post Title 1" 37131 * ... 37132 * } 37133 * ]; 37134 * 37135 * // Instantiate a mixer with a pre-loaded dataset, and a target renderer 37136 * // function defined 37137 * 37138 * var mixer = mixitup(containerEl, { 37139 * data: { 37140 * uidKey: 'id', 37141 * dirtyCheck: true 37142 * }, 37143 * load: { 37144 * dataset: myDataset 37145 * }, 37146 * render: { 37147 * target: function() { ... } 37148 * } 37149 * }); 37150 * 37151 * // For illustration, we will clone and edit the second object in the dataset. 37152 * // NB: this would typically be done server-side in response to a DB update, 37153 * and then re-queried via an API. 37154 * 37155 * myDataset[1] = Object.assign({}, myDataset[1]); 37156 * 37157 * myDataset[1].title = 'Blog Post Title 11'; 37158 * 37159 * mixer.dataset(myDataset) 37160 * .then(function() { 37161 * // the target with ID "1", will be re-rendered reflecting its new title 37162 * }); 37163 * 37164 * @name dirtyCheck 37165 * @memberof mixitup.Config.data 37166 * @instance 37167 * @type {boolean} 37168 * @default false 37169 */ 37170 37171 this.dirtyCheck = false; 37172 37173 this.callActions('afterConstruct'); 37174 37175 h.seal(this); 37176 }; 37177 37178 mixitup.BaseStatic.call(mixitup.ConfigData); 37179 37180 mixitup.ConfigData.prototype = Object.create(mixitup.Base.prototype); 37181 37182 mixitup.ConfigData.prototype.constructor = mixitup.ConfigData; 37183 37184 /** 37185 * A group of properties allowing the toggling of various debug features. 37186 * 37187 * @constructor 37188 * @memberof mixitup.Config 37189 * @name debug 37190 * @namespace 37191 * @public 37192 * @since 3.0.0 37193 */ 37194 37195 mixitup.ConfigDebug = function() { 37196 mixitup.Base.call(this); 37197 37198 this.callActions('beforeConstruct'); 37199 37200 /** 37201 * A boolean dictating whether or not the mixer instance returned by the 37202 * `mixitup()` factory function should expose private properties and methods. 37203 * 37204 * By default, mixer instances only expose their public API, but enabling 37205 * debug mode will give you access to various mixer internals which may aid 37206 * in debugging, or the authoring of extensions. 37207 * 37208 * @example <caption>Example: Enabling debug mode</caption> 37209 * 37210 * var mixer = mixitup(containerEl, { 37211 * debug: { 37212 * enable: true 37213 * } 37214 * }); 37215 * 37216 * // Private properties and methods will now be visible on the mixer instance: 37217 * 37218 * console.log(mixer); 37219 * 37220 * @name enable 37221 * @memberof mixitup.Config.debug 37222 * @instance 37223 * @type {boolean} 37224 * @default false 37225 */ 37226 37227 this.enable = false; 37228 37229 /** 37230 * A boolean dictating whether or not warnings should be shown when various 37231 * common gotchas occur. 37232 * 37233 * Warnings are intended to provide insights during development when something 37234 * occurs that is not a fatal, but may indicate an issue with your integration, 37235 * and are therefore turned on by default. However, you may wish to disable 37236 * them in production. 37237 * 37238 * @example <caption>Example 1: Disabling warnings</caption> 37239 * 37240 * var mixer = mixitup(containerEl, { 37241 * debug: { 37242 * showWarnings: false 37243 * } 37244 * }); 37245 * 37246 * @example <caption>Example 2: Disabling warnings based on environment</caption> 37247 * 37248 * var showWarnings = myAppConfig.environment === 'development' ? true : false; 37249 * 37250 * var mixer = mixitup(containerEl, { 37251 * debug: { 37252 * showWarnings: showWarnings 37253 * } 37254 * }); 37255 * 37256 * @name showWarnings 37257 * @memberof mixitup.Config.debug 37258 * @instance 37259 * @type {boolean} 37260 * @default true 37261 */ 37262 37263 this.showWarnings = true; 37264 37265 /** 37266 * Used for server-side testing only. 37267 * 37268 * @private 37269 * @name fauxAsync 37270 * @memberof mixitup.Config.debug 37271 * @instance 37272 * @type {boolean} 37273 * @default false 37274 */ 37275 37276 this.fauxAsync = false; 37277 37278 this.callActions('afterConstruct'); 37279 37280 h.seal(this); 37281 }; 37282 37283 mixitup.BaseStatic.call(mixitup.ConfigDebug); 37284 37285 mixitup.ConfigDebug.prototype = Object.create(mixitup.Base.prototype); 37286 37287 mixitup.ConfigDebug.prototype.constructor = mixitup.ConfigDebug; 37288 37289 /** 37290 * A group of properties relating to the layout of the container. 37291 * 37292 * @constructor 37293 * @memberof mixitup.Config 37294 * @name layout 37295 * @namespace 37296 * @public 37297 * @since 3.0.0 37298 */ 37299 37300 mixitup.ConfigLayout = function() { 37301 mixitup.Base.call(this); 37302 37303 this.callActions('beforeConstruct'); 37304 37305 /** 37306 * A boolean dictating whether or not mixitup should query all descendants 37307 * of the container for targets, or only immediate children. 37308 * 37309 * By default, mixitup will query all descendants matching the 37310 * `selectors.target` selector when indexing targets upon instantiation. 37311 * This allows for targets to be nested inside a sub-container which is 37312 * useful when ring-fencing targets from locally scoped controls in your 37313 * markup (see `controls.scope`). 37314 * 37315 * However, if you are building a more complex UI requiring the nesting 37316 * of mixers within mixers, you will most likely want to limit targets to 37317 * immediate children of the container by setting this property to `false`. 37318 * 37319 * @example <caption>Example: Restricting targets to immediate children</caption> 37320 * 37321 * var mixer = mixitup(containerEl, { 37322 * layout: { 37323 * allowNestedTargets: false 37324 * } 37325 * }); 37326 * 37327 * @name allowNestedTargets 37328 * @memberof mixitup.Config.layout 37329 * @instance 37330 * @type {boolean} 37331 * @default true 37332 */ 37333 37334 this.allowNestedTargets = true; 37335 37336 /** 37337 * A string specifying an optional class name to apply to the container when in 37338 * its default state. 37339 * 37340 * By changing this class name or adding a class name to the container via the 37341 * `.changeLayout()` API method, the CSS layout of the container can be changed, 37342 * and MixItUp will attemp to gracefully animate the container and its targets 37343 * between states. 37344 * 37345 * @example <caption>Example 1: Specifying a container class name</caption> 37346 * 37347 * var mixer = mixitup(containerEl, { 37348 * layout: { 37349 * containerClassName: 'grid' 37350 * } 37351 * }); 37352 * 37353 * @example <caption>Example 2: Changing the default class name with `.changeLayout()`</caption> 37354 * 37355 * var mixer = mixitup(containerEl, { 37356 * layout: { 37357 * containerClassName: 'grid' 37358 * } 37359 * }); 37360 * 37361 * mixer.changeLayout('list') 37362 * .then(function(state) { 37363 * console.log(state.activeContainerClass); // "list" 37364 * }); 37365 * 37366 * @name containerClassName 37367 * @memberof mixitup.Config.layout 37368 * @instance 37369 * @type {string} 37370 * @default '' 37371 */ 37372 37373 this.containerClassName = ''; 37374 37375 /** 37376 * A reference to a non-target sibling element after which to insert targets 37377 * when there are no targets in the container. 37378 * 37379 * @example <caption>Example: Setting a `siblingBefore` reference element</caption> 37380 * 37381 * var addButton = containerEl.querySelector('button'); 37382 * 37383 * var mixer = mixitup(containerEl, { 37384 * layout: { 37385 * siblingBefore: addButton 37386 * } 37387 * }); 37388 * 37389 * @name siblingBefore 37390 * @memberof mixitup.Config.layout 37391 * @instance 37392 * @type {HTMLElement} 37393 * @default null 37394 */ 37395 37396 this.siblingBefore = null; 37397 37398 /** 37399 * A reference to a non-target sibling element before which to insert targets 37400 * when there are no targets in the container. 37401 * 37402 * @example <caption>Example: Setting an `siblingAfter` reference element</caption> 37403 * 37404 * var gap = containerEl.querySelector('.gap'); 37405 * 37406 * var mixer = mixitup(containerEl, { 37407 * layout: { 37408 * siblingAfter: gap 37409 * } 37410 * }); 37411 * 37412 * @name siblingAfter 37413 * @memberof mixitup.Config.layout 37414 * @instance 37415 * @type {HTMLElement} 37416 * @default null 37417 */ 37418 37419 this.siblingAfter = null; 37420 37421 this.callActions('afterConstruct'); 37422 37423 h.seal(this); 37424 }; 37425 37426 mixitup.BaseStatic.call(mixitup.ConfigLayout); 37427 37428 mixitup.ConfigLayout.prototype = Object.create(mixitup.Base.prototype); 37429 37430 mixitup.ConfigLayout.prototype.constructor = mixitup.ConfigLayout; 37431 37432 /** 37433 * A group of properties defining the initial state of the mixer on load (instantiation). 37434 * 37435 * @constructor 37436 * @memberof mixitup.Config 37437 * @name load 37438 * @namespace 37439 * @public 37440 * @since 2.0.0 37441 */ 37442 37443 mixitup.ConfigLoad = function() { 37444 mixitup.Base.call(this); 37445 37446 this.callActions('beforeConstruct'); 37447 37448 /** 37449 * A string defining any filtering to be statically applied to the mixer on load. 37450 * As per the `.filter()` API, this can be any valid selector string, or the 37451 * values `'all'` or `'none'`. 37452 * 37453 * @example <caption>Example 1: Defining an initial filter selector to be applied on load</caption> 37454 * 37455 * // The mixer will show only those targets matching '.category-a' on load. 37456 * 37457 * var mixer = mixitup(containerEl, { 37458 * load: { 37459 * filter: '.category-a' 37460 * } 37461 * }); 37462 * 37463 * @example <caption>Example 2: Hiding all targets on load</caption> 37464 * 37465 * // The mixer will show hide all targets on load. 37466 * 37467 * var mixer = mixitup(containerEl, { 37468 * load: { 37469 * filter: 'none' 37470 * } 37471 * }); 37472 * 37473 * @name filter 37474 * @memberof mixitup.Config.load 37475 * @instance 37476 * @type {string} 37477 * @default 'all' 37478 */ 37479 37480 this.filter = 'all'; 37481 37482 /** 37483 * A string defining any sorting to be statically applied to the mixer on load. 37484 * As per the `.sort()` API, this should be a valid "sort string" made up of 37485 * an attribute to sort by (or `'default'`) followed by an optional sorting 37486 * order, or the value `'random'`; 37487 * 37488 * @example <caption>Example: Defining sorting to be applied on load</caption> 37489 * 37490 * // The mixer will sort the container by the value of the `data-published-date` 37491 * // attribute, in descending order. 37492 * 37493 * var mixer = mixitup(containerEl, { 37494 * load: { 37495 * sort: 'published-date:desc' 37496 * } 37497 * }); 37498 * 37499 * @name sort 37500 * @memberof mixitup.Config.load 37501 * @instance 37502 * @type {string} 37503 * @default 'default:asc' 37504 */ 37505 37506 this.sort = 'default:asc'; 37507 37508 /** 37509 * An array of objects representing the underlying data of any pre-rendered targets, 37510 * when using the `.dataset()` API. 37511 * 37512 * NB: If targets are pre-rendered when the mixer is instantiated, this must be set. 37513 * 37514 * @example <caption>Example: Defining the initial underyling dataset</caption> 37515 * 37516 * var myDataset = [ 37517 * { 37518 * id: 0, 37519 * title: "Blog Post Title 0", 37520 * ... 37521 * }, 37522 * { 37523 * id: 1, 37524 * title: "Blog Post Title 1", 37525 * ... 37526 * } 37527 * ]; 37528 * 37529 * var mixer = mixitup(containerEl, { 37530 * data: { 37531 * uidKey: 'id' 37532 * }, 37533 * load: { 37534 * dataset: myDataset 37535 * } 37536 * }); 37537 * 37538 * @name dataset 37539 * @memberof mixitup.Config.load 37540 * @instance 37541 * @type {Array.<object>} 37542 * @default null 37543 */ 37544 37545 this.dataset = null; 37546 37547 this.callActions('afterConstruct'); 37548 37549 h.seal(this); 37550 }; 37551 37552 mixitup.BaseStatic.call(mixitup.ConfigLoad); 37553 37554 mixitup.ConfigLoad.prototype = Object.create(mixitup.Base.prototype); 37555 37556 mixitup.ConfigLoad.prototype.constructor = mixitup.ConfigLoad; 37557 37558 /** 37559 * A group of properties defining the selectors used to query elements within a mixitup container. 37560 * 37561 * @constructor 37562 * @memberof mixitup.Config 37563 * @name selectors 37564 * @namespace 37565 * @public 37566 * @since 3.0.0 37567 */ 37568 37569 mixitup.ConfigSelectors = function() { 37570 mixitup.Base.call(this); 37571 37572 this.callActions('beforeConstruct'); 37573 37574 /** 37575 * A selector string used to query and index target elements within the container. 37576 * 37577 * By default, the class selector `'.mix'` is used, but this can be changed to an 37578 * attribute or element selector to match the style of your project. 37579 * 37580 * @example <caption>Example 1: Changing the target selector</caption> 37581 * 37582 * var mixer = mixitup(containerEl, { 37583 * selectors: { 37584 * target: '.portfolio-item' 37585 * } 37586 * }); 37587 * 37588 * @example <caption>Example 2: Using an attribute selector as a target selector</caption> 37589 * 37590 * // The mixer will search for any children with the attribute `data-ref="mix"` 37591 * 37592 * var mixer = mixitup(containerEl, { 37593 * selectors: { 37594 * target: '[data-ref="mix"]' 37595 * } 37596 * }); 37597 * 37598 * @name target 37599 * @memberof mixitup.Config.selectors 37600 * @instance 37601 * @type {string} 37602 * @default '.mix' 37603 */ 37604 37605 this.target = '.mix'; 37606 37607 /** 37608 * A optional selector string used to add further specificity to the querying of control elements, 37609 * in addition to their mandatory data attribute (e.g. `data-filter`, `data-toggle`, `data-sort`). 37610 * 37611 * This can be used if other elements in your document must contain the above attributes 37612 * (e.g. for use in third-party scripts), and would otherwise interfere with MixItUp. Adding 37613 * an additional `control` selector of your choice allows MixItUp to restrict event handling 37614 * to only those elements matching the defined selector. 37615 * 37616 * @name control 37617 * @memberof mixitup.Config.selectors 37618 * @instance 37619 * @type {string} 37620 * @default '' 37621 * 37622 * @example <caption>Example 1: Adding a `selectors.control` selector</caption> 37623 * 37624 * var mixer = mixitup(containerEl, { 37625 * selectors: { 37626 * control: '.mixitup-control' 37627 * } 37628 * }); 37629 * 37630 * // Will not be handled: 37631 * // <button data-filter=".category-a"></button> 37632 * 37633 * // Will be handled: 37634 * // <button class="mixitup-control" data-filter=".category-a"></button> 37635 */ 37636 37637 this.control = ''; 37638 37639 this.callActions('afterConstruct'); 37640 37641 h.seal(this); 37642 }; 37643 37644 mixitup.BaseStatic.call(mixitup.ConfigSelectors); 37645 37646 mixitup.ConfigSelectors.prototype = Object.create(mixitup.Base.prototype); 37647 37648 mixitup.ConfigSelectors.prototype.constructor = mixitup.ConfigSelectors; 37649 37650 /** 37651 * A group of optional render functions for creating and updating elements. 37652 * 37653 * All render functions receive a data object, and should return a valid HTML string. 37654 * 37655 * @constructor 37656 * @memberof mixitup.Config 37657 * @name render 37658 * @namespace 37659 * @public 37660 * @since 3.0.0 37661 */ 37662 37663 mixitup.ConfigRender = function() { 37664 mixitup.Base.call(this); 37665 37666 this.callActions('beforeConstruct'); 37667 37668 /** 37669 * A function returning an HTML string representing a target element, or a reference to a 37670 * single DOM element. 37671 * 37672 * The function is invoked as part of the `.dataset()` API, whenever a new item is added 37673 * to the dataset, or an item in the dataset changes (if `dataset.dirtyCheck` is enabled). 37674 * 37675 * The function receives the relevant dataset item as its first parameter. 37676 * 37677 * @example <caption>Example 1: Using string concatenation</caption> 37678 * 37679 * var mixer = mixitup(containerEl, { 37680 * render: { 37681 * target: function(item) { 37682 * return ( 37683 * '<div class="mix">' + 37684 * '<h2>' + item.title + '</h2>' + 37685 * '</div>' 37686 * ); 37687 * } 37688 * } 37689 * }); 37690 * 37691 * @example <caption>Example 2: Using an ES2015 template literal</caption> 37692 * 37693 * var mixer = mixitup(containerEl, { 37694 * render: { 37695 * target: function(item) { 37696 * return ( 37697 * `<div class="mix"> 37698 * <h2>${item.title}</h2> 37699 * </div>` 37700 * ); 37701 * } 37702 * } 37703 * }); 37704 * 37705 * @example <caption>Example 3: Using a Handlebars template</caption> 37706 * 37707 * var targetTemplate = Handlebars.compile('<div class="mix"><h2>{{title}}</h2></div>'); 37708 * 37709 * var mixer = mixitup(containerEl, { 37710 * render: { 37711 * target: targetTemplate 37712 * } 37713 * }); 37714 * 37715 * @example <caption>Example 4: Returning a DOM element</caption> 37716 * 37717 * var mixer = mixitup(containerEl, { 37718 * render: { 37719 * target: function(item) { 37720 * // Create a single element using your framework's built-in renderer 37721 * 37722 * var el = ... 37723 * 37724 * return el; 37725 * } 37726 * } 37727 * }); 37728 * 37729 * @name target 37730 * @memberof mixitup.Config.render 37731 * @instance 37732 * @type {function} 37733 * @default 'null' 37734 */ 37735 37736 this.target = null; 37737 37738 this.callActions('afterConstruct'); 37739 37740 h.seal(this); 37741 }; 37742 37743 mixitup.BaseStatic.call(mixitup.ConfigRender); 37744 37745 mixitup.ConfigRender.prototype = Object.create(mixitup.Base.prototype); 37746 37747 mixitup.ConfigRender.prototype.constructor = mixitup.ConfigRender; 37748 37749 /** 37750 * @constructor 37751 * @memberof mixitup 37752 * @private 37753 * @since 3.0.0 37754 */ 37755 37756 mixitup.ConfigTemplates = function() { 37757 mixitup.Base.call(this); 37758 37759 this.callActions('beforeConstruct'); 37760 37761 this.callActions('afterConstruct'); 37762 37763 h.seal(this); 37764 }; 37765 37766 mixitup.BaseStatic.call(mixitup.ConfigTemplates); 37767 37768 mixitup.ConfigTemplates.prototype = Object.create(mixitup.Base.prototype); 37769 37770 mixitup.ConfigTemplates.prototype.constructor = mixitup.ConfigTemplates; 37771 37772 /** 37773 * `mixitup.Config` is an interface used for customising the functionality of a 37774 * mixer instance. It is organised into several semantically distinct sub-objects, 37775 * each one pertaining to a particular aspect of MixItUp functionality. 37776 * 37777 * An object literal containing any or all of the available properies, 37778 * known as the "configuration object", can be passed as the second parameter to 37779 * the `mixitup` factory function when creating a mixer instance to customise its 37780 * functionality as needed. 37781 * 37782 * If no configuration object is passed, the mixer instance will take on the default 37783 * configuration values detailed below. 37784 * 37785 * @example <caption>Example 1: Creating and passing the configuration object</caption> 37786 * // Create a configuration object with desired values 37787 * 37788 * var config = { 37789 * animation: { 37790 * enable: false 37791 * }, 37792 * selectors: { 37793 * target: '.item' 37794 * } 37795 * }; 37796 * 37797 * // Pass the configuration object to the mixitup factory function 37798 * 37799 * var mixer = mixitup(containerEl, config); 37800 * 37801 * @example <caption>Example 2: Passing the configuration object inline</caption> 37802 * // Typically, the configuration object is passed inline for brevity. 37803 * 37804 * var mixer = mixitup(containerEl, { 37805 * controls: { 37806 * live: true, 37807 * toggleLogic: 'and' 37808 * } 37809 * }); 37810 * 37811 * 37812 * @constructor 37813 * @memberof mixitup 37814 * @namespace 37815 * @public 37816 * @since 2.0.0 37817 */ 37818 37819 mixitup.Config = function() { 37820 mixitup.Base.call(this); 37821 37822 this.callActions('beforeConstruct'); 37823 37824 this.animation = new mixitup.ConfigAnimation(); 37825 this.behavior = new mixitup.ConfigBehavior(); 37826 this.callbacks = new mixitup.ConfigCallbacks(); 37827 this.controls = new mixitup.ConfigControls(); 37828 this.classNames = new mixitup.ConfigClassNames(); 37829 this.data = new mixitup.ConfigData(); 37830 this.debug = new mixitup.ConfigDebug(); 37831 this.layout = new mixitup.ConfigLayout(); 37832 this.load = new mixitup.ConfigLoad(); 37833 this.selectors = new mixitup.ConfigSelectors(); 37834 this.render = new mixitup.ConfigRender(); 37835 this.templates = new mixitup.ConfigTemplates(); 37836 37837 this.callActions('afterConstruct'); 37838 37839 h.seal(this); 37840 }; 37841 37842 mixitup.BaseStatic.call(mixitup.Config); 37843 37844 mixitup.Config.prototype = Object.create(mixitup.Base.prototype); 37845 37846 mixitup.Config.prototype.constructor = mixitup.Config; 37847 37848 /** 37849 * @constructor 37850 * @memberof mixitup 37851 * @private 37852 * @since 3.0.0 37853 */ 37854 37855 mixitup.MixerDom = function() { 37856 mixitup.Base.call(this); 37857 37858 this.callActions('beforeConstruct'); 37859 37860 this.document = null; 37861 this.body = null; 37862 this.container = null; 37863 this.parent = null; 37864 this.targets = []; 37865 37866 this.callActions('afterConstruct'); 37867 37868 h.seal(this); 37869 }; 37870 37871 mixitup.BaseStatic.call(mixitup.MixerDom); 37872 37873 mixitup.MixerDom.prototype = Object.create(mixitup.Base.prototype); 37874 37875 mixitup.MixerDom.prototype.constructor = mixitup.MixerDom; 37876 37877 /** 37878 * @constructor 37879 * @memberof mixitup 37880 * @private 37881 * @since 3.0.0 37882 */ 37883 37884 mixitup.UiClassNames = function() { 37885 mixitup.Base.call(this); 37886 37887 this.callActions('beforeConstruct'); 37888 37889 this.base = ''; 37890 this.active = ''; 37891 this.disabled = ''; 37892 37893 this.callActions('afterConstruct'); 37894 37895 h.seal(this); 37896 }; 37897 37898 mixitup.BaseStatic.call(mixitup.UiClassNames); 37899 37900 mixitup.UiClassNames.prototype = Object.create(mixitup.Base.prototype); 37901 37902 mixitup.UiClassNames.prototype.constructor = mixitup.UiClassNames; 37903 37904 /** 37905 * An object into which all arbitrary arguments sent to '.dataset()' are mapped. 37906 * 37907 * @constructor 37908 * @memberof mixitup 37909 * @private 37910 * @since 3.0.0 37911 */ 37912 37913 mixitup.CommandDataset = function() { 37914 mixitup.Base.call(this); 37915 37916 this.callActions('beforeConstruct'); 37917 37918 this.dataset = null; 37919 37920 this.callActions('afterConstruct'); 37921 37922 h.seal(this); 37923 }; 37924 37925 mixitup.BaseStatic.call(mixitup.CommandDataset); 37926 37927 mixitup.CommandDataset.prototype = Object.create(mixitup.Base.prototype); 37928 37929 mixitup.CommandDataset.prototype.constructor = mixitup.CommandDataset; 37930 37931 /** 37932 * An object into which all arbitrary arguments sent to '.multimix()' are mapped. 37933 * 37934 * @constructor 37935 * @memberof mixitup 37936 * @private 37937 * @since 3.0.0 37938 */ 37939 37940 mixitup.CommandMultimix = function() { 37941 mixitup.Base.call(this); 37942 37943 this.callActions('beforeConstruct'); 37944 37945 this.filter = null; 37946 this.sort = null; 37947 this.insert = null; 37948 this.remove = null; 37949 this.changeLayout = null; 37950 37951 this.callActions('afterConstruct'); 37952 37953 h.seal(this); 37954 }; 37955 37956 mixitup.BaseStatic.call(mixitup.CommandMultimix); 37957 37958 mixitup.CommandMultimix.prototype = Object.create(mixitup.Base.prototype); 37959 37960 mixitup.CommandMultimix.prototype.constructor = mixitup.CommandMultimix; 37961 37962 /** 37963 * An object into which all arbitrary arguments sent to '.filter()' are mapped. 37964 * 37965 * @constructor 37966 * @memberof mixitup 37967 * @private 37968 * @since 3.0.0 37969 */ 37970 37971 mixitup.CommandFilter = function() { 37972 mixitup.Base.call(this); 37973 37974 this.callActions('beforeConstruct'); 37975 37976 this.selector = ''; 37977 this.collection = null; 37978 this.action = 'show'; // enum: ['show', 'hide'] 37979 37980 this.callActions('afterConstruct'); 37981 37982 h.seal(this); 37983 }; 37984 37985 mixitup.BaseStatic.call(mixitup.CommandFilter); 37986 37987 mixitup.CommandFilter.prototype = Object.create(mixitup.Base.prototype); 37988 37989 mixitup.CommandFilter.prototype.constructor = mixitup.CommandFilter; 37990 37991 /** 37992 * An object into which all arbitrary arguments sent to '.sort()' are mapped. 37993 * 37994 * @constructor 37995 * @memberof mixitup 37996 * @private 37997 * @since 3.0.0 37998 */ 37999 38000 mixitup.CommandSort = function() { 38001 mixitup.Base.call(this); 38002 38003 this.callActions('beforeConstruct'); 38004 38005 this.sortString = ''; 38006 this.attribute = ''; 38007 this.order = 'asc'; 38008 this.collection = null; 38009 this.next = null; 38010 38011 this.callActions('afterConstruct'); 38012 38013 h.seal(this); 38014 }; 38015 38016 mixitup.BaseStatic.call(mixitup.CommandSort); 38017 38018 mixitup.CommandSort.prototype = Object.create(mixitup.Base.prototype); 38019 38020 mixitup.CommandSort.prototype.constructor = mixitup.CommandSort; 38021 38022 /** 38023 * An object into which all arbitrary arguments sent to '.insert()' are mapped. 38024 * 38025 * @constructor 38026 * @memberof mixitup 38027 * @private 38028 * @since 3.0.0 38029 */ 38030 38031 mixitup.CommandInsert = function() { 38032 mixitup.Base.call(this); 38033 38034 this.callActions('beforeConstruct'); 38035 38036 this.index = 0; 38037 this.collection = []; 38038 this.position = 'before'; // enum: ['before', 'after'] 38039 this.sibling = null; 38040 38041 this.callActions('afterConstruct'); 38042 38043 h.seal(this); 38044 }; 38045 38046 mixitup.BaseStatic.call(mixitup.CommandInsert); 38047 38048 mixitup.CommandInsert.prototype = Object.create(mixitup.Base.prototype); 38049 38050 mixitup.CommandInsert.prototype.constructor = mixitup.CommandInsert; 38051 38052 /** 38053 * An object into which all arbitrary arguments sent to '.remove()' are mapped. 38054 * 38055 * @constructor 38056 * @memberof mixitup 38057 * @private 38058 * @since 3.0.0 38059 */ 38060 38061 mixitup.CommandRemove = function() { 38062 mixitup.Base.call(this); 38063 38064 this.callActions('beforeConstruct'); 38065 38066 this.targets = []; 38067 this.collection = []; 38068 38069 this.callActions('afterConstruct'); 38070 38071 h.seal(this); 38072 }; 38073 38074 mixitup.BaseStatic.call(mixitup.CommandRemove); 38075 38076 mixitup.CommandRemove.prototype = Object.create(mixitup.Base.prototype); 38077 38078 mixitup.CommandRemove.prototype.constructor = mixitup.CommandRemove; 38079 38080 /** 38081 * An object into which all arbitrary arguments sent to '.changeLayout()' are mapped. 38082 * 38083 * @constructor 38084 * @memberof mixitup 38085 * @private 38086 * @since 3.0.0 38087 */ 38088 38089 mixitup.CommandChangeLayout = function() { 38090 mixitup.Base.call(this); 38091 38092 this.callActions('beforeConstruct'); 38093 38094 this.containerClassName = ''; 38095 38096 this.callActions('afterConstruct'); 38097 38098 h.seal(this); 38099 }; 38100 38101 mixitup.BaseStatic.call(mixitup.CommandChangeLayout); 38102 38103 mixitup.CommandChangeLayout.prototype = Object.create(mixitup.Base.prototype); 38104 38105 mixitup.CommandChangeLayout.prototype.constructor = mixitup.CommandChangeLayout; 38106 38107 /** 38108 * @constructor 38109 * @memberof mixitup 38110 * @private 38111 * @since 3.0.0 38112 * @param {string} type 38113 * @param {string} selector 38114 * @param {boolean} [live] 38115 * @param {string} [parent] 38116 * An optional string representing the name of the mixer.dom property containing a reference to a parent element. 38117 */ 38118 38119 mixitup.ControlDefinition = function(type, selector, live, parent) { 38120 mixitup.Base.call(this); 38121 38122 this.callActions('beforeConstruct'); 38123 38124 this.type = type; 38125 this.selector = selector; 38126 this.live = live || false; 38127 this.parent = parent || ''; 38128 38129 this.callActions('afterConstruct'); 38130 38131 h.freeze(this); 38132 h.seal(this); 38133 }; 38134 38135 mixitup.BaseStatic.call(mixitup.ControlDefinition); 38136 38137 mixitup.ControlDefinition.prototype = Object.create(mixitup.Base.prototype); 38138 38139 mixitup.ControlDefinition.prototype.constructor = mixitup.ControlDefinition; 38140 38141 mixitup.controlDefinitions = []; 38142 38143 mixitup.controlDefinitions.push(new mixitup.ControlDefinition('multimix', '[data-filter][data-sort]')); 38144 mixitup.controlDefinitions.push(new mixitup.ControlDefinition('filter', '[data-filter]')); 38145 mixitup.controlDefinitions.push(new mixitup.ControlDefinition('sort', '[data-sort]')); 38146 mixitup.controlDefinitions.push(new mixitup.ControlDefinition('toggle', '[data-toggle]')); 38147 38148 /** 38149 * @constructor 38150 * @memberof mixitup 38151 * @private 38152 * @since 3.0.0 38153 */ 38154 38155 mixitup.Control = function() { 38156 mixitup.Base.call(this); 38157 38158 this.callActions('beforeConstruct'); 38159 38160 this.el = null; 38161 this.selector = ''; 38162 this.bound = []; 38163 this.pending = -1; 38164 this.type = ''; 38165 this.status = 'inactive'; // enum: ['inactive', 'active', 'disabled', 'live'] 38166 this.filter = ''; 38167 this.sort = ''; 38168 this.canDisable = false; 38169 this.handler = null; 38170 this.classNames = new mixitup.UiClassNames(); 38171 38172 this.callActions('afterConstruct'); 38173 38174 h.seal(this); 38175 }; 38176 38177 mixitup.BaseStatic.call(mixitup.Control); 38178 38179 mixitup.Control.prototype = Object.create(mixitup.Base.prototype); 38180 38181 h.extend(mixitup.Control.prototype, 38182 /** @lends mixitup.Control */ 38183 { 38184 constructor: mixitup.Control, 38185 38186 /** 38187 * @private 38188 * @param {HTMLElement} el 38189 * @param {string} type 38190 * @param {string} selector 38191 */ 38192 38193 init: function(el, type, selector) { 38194 var self = this; 38195 38196 this.callActions('beforeInit', arguments); 38197 38198 self.el = el; 38199 self.type = type; 38200 self.selector = selector; 38201 38202 if (self.selector) { 38203 self.status = 'live'; 38204 } else { 38205 self.canDisable = typeof self.el.disable === 'boolean'; 38206 38207 switch (self.type) { 38208 case 'filter': 38209 self.filter = self.el.getAttribute('data-filter'); 38210 38211 break; 38212 case 'toggle': 38213 self.filter = self.el.getAttribute('data-toggle'); 38214 38215 break; 38216 case 'sort': 38217 self.sort = self.el.getAttribute('data-sort'); 38218 38219 break; 38220 case 'multimix': 38221 self.filter = self.el.getAttribute('data-filter'); 38222 self.sort = self.el.getAttribute('data-sort'); 38223 38224 break; 38225 } 38226 } 38227 38228 self.bindClick(); 38229 38230 mixitup.controls.push(self); 38231 38232 this.callActions('afterInit', arguments); 38233 }, 38234 38235 /** 38236 * @private 38237 * @param {mixitup.Mixer} mixer 38238 * @return {boolean} 38239 */ 38240 38241 isBound: function(mixer) { 38242 var self = this, 38243 isBound = false; 38244 38245 this.callActions('beforeIsBound', arguments); 38246 38247 isBound = self.bound.indexOf(mixer) > -1; 38248 38249 return self.callFilters('afterIsBound', isBound, arguments); 38250 }, 38251 38252 /** 38253 * @private 38254 * @param {mixitup.Mixer} mixer 38255 * @return {void} 38256 */ 38257 38258 addBinding: function(mixer) { 38259 var self = this; 38260 38261 this.callActions('beforeAddBinding', arguments); 38262 38263 if (!self.isBound()) { 38264 self.bound.push(mixer); 38265 } 38266 38267 this.callActions('afterAddBinding', arguments); 38268 }, 38269 38270 /** 38271 * @private 38272 * @param {mixitup.Mixer} mixer 38273 * @return {void} 38274 */ 38275 38276 removeBinding: function(mixer) { 38277 var self = this, 38278 removeIndex = -1; 38279 38280 this.callActions('beforeRemoveBinding', arguments); 38281 38282 if ((removeIndex = self.bound.indexOf(mixer)) > -1) { 38283 self.bound.splice(removeIndex, 1); 38284 } 38285 38286 if (self.bound.length < 1) { 38287 // No bindings exist, unbind event click handlers 38288 38289 self.unbindClick(); 38290 38291 // Remove from `mixitup.controls` list 38292 38293 removeIndex = mixitup.controls.indexOf(self); 38294 38295 mixitup.controls.splice(removeIndex, 1); 38296 38297 if (self.status === 'active') { 38298 self.renderStatus(self.el, 'inactive'); 38299 } 38300 } 38301 38302 this.callActions('afterRemoveBinding', arguments); 38303 }, 38304 38305 /** 38306 * @private 38307 * @return {void} 38308 */ 38309 38310 bindClick: function() { 38311 var self = this; 38312 38313 this.callActions('beforeBindClick', arguments); 38314 38315 self.handler = function(e) { 38316 self.handleClick(e); 38317 }; 38318 38319 h.on(self.el, 'click', self.handler); 38320 38321 this.callActions('afterBindClick', arguments); 38322 }, 38323 38324 /** 38325 * @private 38326 * @return {void} 38327 */ 38328 38329 unbindClick: function() { 38330 var self = this; 38331 38332 this.callActions('beforeUnbindClick', arguments); 38333 38334 h.off(self.el, 'click', self.handler); 38335 38336 self.handler = null; 38337 38338 this.callActions('afterUnbindClick', arguments); 38339 }, 38340 38341 /** 38342 * @private 38343 * @param {MouseEvent} e 38344 * @return {void} 38345 */ 38346 38347 handleClick: function(e) { 38348 var self = this, 38349 button = null, 38350 mixer = null, 38351 isActive = false, 38352 returnValue = void(0), 38353 command = {}, 38354 clone = null, 38355 commands = [], 38356 i = -1; 38357 38358 this.callActions('beforeHandleClick', arguments); 38359 38360 this.pending = 0; 38361 38362 mixer = self.bound[0]; 38363 38364 if (!self.selector) { 38365 button = self.el; 38366 } else { 38367 button = h.closestParent(e.target, mixer.config.selectors.control + self.selector, true, mixer.dom.document); 38368 } 38369 38370 if (!button) { 38371 self.callActions('afterHandleClick', arguments); 38372 38373 return; 38374 } 38375 38376 switch (self.type) { 38377 case 'filter': 38378 command.filter = self.filter || button.getAttribute('data-filter'); 38379 38380 break; 38381 case 'sort': 38382 command.sort = self.sort || button.getAttribute('data-sort'); 38383 38384 break; 38385 case 'multimix': 38386 command.filter = self.filter || button.getAttribute('data-filter'); 38387 command.sort = self.sort || button.getAttribute('data-sort'); 38388 38389 break; 38390 case 'toggle': 38391 command.filter = self.filter || button.getAttribute('data-toggle'); 38392 38393 if (self.status === 'live') { 38394 isActive = h.hasClass(button, self.classNames.active); 38395 } else { 38396 isActive = self.status === 'active'; 38397 } 38398 38399 break; 38400 } 38401 38402 for (i = 0; i < self.bound.length; i++) { 38403 // Create a clone of the command for each bound mixer instance 38404 38405 clone = new mixitup.CommandMultimix(); 38406 38407 h.extend(clone, command); 38408 38409 commands.push(clone); 38410 } 38411 38412 commands = self.callFilters('commandsHandleClick', commands, arguments); 38413 38414 self.pending = self.bound.length; 38415 38416 for (i = 0; mixer = self.bound[i]; i++) { 38417 command = commands[i]; 38418 38419 if (!command) { 38420 // An extension may set a command null to indicate that the click should not be handled 38421 38422 continue; 38423 } 38424 38425 if (!mixer.lastClicked) { 38426 mixer.lastClicked = button; 38427 } 38428 38429 mixitup.events.fire('mixClick', mixer.dom.container, { 38430 state: mixer.state, 38431 instance: mixer, 38432 originalEvent: e, 38433 control: mixer.lastClicked 38434 }, mixer.dom.document); 38435 38436 if (typeof mixer.config.callbacks.onMixClick === 'function') { 38437 returnValue = mixer.config.callbacks.onMixClick.call(mixer.lastClicked, mixer.state, e, mixer); 38438 38439 if (returnValue === false) { 38440 // User has returned `false` from the callback, so do not handle click 38441 38442 continue; 38443 } 38444 } 38445 38446 if (self.type === 'toggle') { 38447 isActive ? mixer.toggleOff(command.filter) : mixer.toggleOn(command.filter); 38448 } else { 38449 mixer.multimix(command); 38450 } 38451 } 38452 38453 this.callActions('afterHandleClick', arguments); 38454 }, 38455 38456 /** 38457 * @param {object} command 38458 * @param {Array<string>} toggleArray 38459 * @return {void} 38460 */ 38461 38462 update: function(command, toggleArray) { 38463 var self = this, 38464 actions = new mixitup.CommandMultimix(); 38465 38466 self.callActions('beforeUpdate', arguments); 38467 38468 self.pending--; 38469 38470 self.pending = Math.max(0, self.pending); 38471 38472 if (self.pending > 0) return; 38473 38474 if (self.status === 'live') { 38475 // Live control (status unknown) 38476 38477 self.updateLive(command, toggleArray); 38478 } else { 38479 // Static control 38480 38481 actions.sort = self.sort; 38482 actions.filter = self.filter; 38483 38484 self.callFilters('actionsUpdate', actions, arguments); 38485 38486 self.parseStatusChange(self.el, command, actions, toggleArray); 38487 } 38488 38489 self.callActions('afterUpdate', arguments); 38490 }, 38491 38492 /** 38493 * @param {mixitup.CommandMultimix} command 38494 * @param {Array<string>} toggleArray 38495 * @return {void} 38496 */ 38497 38498 updateLive: function(command, toggleArray) { 38499 var self = this, 38500 controlButtons = null, 38501 actions = null, 38502 button = null, 38503 i = -1; 38504 38505 self.callActions('beforeUpdateLive', arguments); 38506 38507 if (!self.el) return; 38508 38509 controlButtons = self.el.querySelectorAll(self.selector); 38510 38511 for (i = 0; button = controlButtons[i]; i++) { 38512 actions = new mixitup.CommandMultimix(); 38513 38514 switch (self.type) { 38515 case 'filter': 38516 actions.filter = button.getAttribute('data-filter'); 38517 38518 break; 38519 case 'sort': 38520 actions.sort = button.getAttribute('data-sort'); 38521 38522 break; 38523 case 'multimix': 38524 actions.filter = button.getAttribute('data-filter'); 38525 actions.sort = button.getAttribute('data-sort'); 38526 38527 break; 38528 case 'toggle': 38529 actions.filter = button.getAttribute('data-toggle'); 38530 38531 break; 38532 } 38533 38534 actions = self.callFilters('actionsUpdateLive', actions, arguments); 38535 38536 self.parseStatusChange(button, command, actions, toggleArray); 38537 } 38538 38539 self.callActions('afterUpdateLive', arguments); 38540 }, 38541 38542 /** 38543 * @param {HTMLElement} button 38544 * @param {mixitup.CommandMultimix} command 38545 * @param {mixitup.CommandMultimix} actions 38546 * @param {Array<string>} toggleArray 38547 * @return {void} 38548 */ 38549 38550 parseStatusChange: function(button, command, actions, toggleArray) { 38551 var self = this, 38552 alias = '', 38553 toggle = '', 38554 i = -1; 38555 38556 self.callActions('beforeParseStatusChange', arguments); 38557 38558 switch (self.type) { 38559 case 'filter': 38560 if (command.filter === actions.filter) { 38561 self.renderStatus(button, 'active'); 38562 } else { 38563 self.renderStatus(button, 'inactive'); 38564 } 38565 38566 break; 38567 case 'multimix': 38568 if (command.sort === actions.sort && command.filter === actions.filter) { 38569 self.renderStatus(button, 'active'); 38570 } else { 38571 self.renderStatus(button, 'inactive'); 38572 } 38573 38574 break; 38575 case 'sort': 38576 if (command.sort.match(/:asc/g)) { 38577 alias = command.sort.replace(/:asc/g, ''); 38578 } 38579 38580 if (command.sort === actions.sort || alias === actions.sort) { 38581 self.renderStatus(button, 'active'); 38582 } else { 38583 self.renderStatus(button, 'inactive'); 38584 } 38585 38586 break; 38587 case 'toggle': 38588 if (toggleArray.length < 1) self.renderStatus(button, 'inactive'); 38589 38590 if (command.filter === actions.filter) { 38591 self.renderStatus(button, 'active'); 38592 } 38593 38594 for (i = 0; i < toggleArray.length; i++) { 38595 toggle = toggleArray[i]; 38596 38597 if (toggle === actions.filter) { 38598 // Button matches one active toggle 38599 38600 self.renderStatus(button, 'active'); 38601 38602 break; 38603 } 38604 38605 self.renderStatus(button, 'inactive'); 38606 } 38607 38608 break; 38609 } 38610 38611 self.callActions('afterParseStatusChange', arguments); 38612 }, 38613 38614 /** 38615 * @param {HTMLElement} button 38616 * @param {string} status 38617 * @return {void} 38618 */ 38619 38620 renderStatus: function(button, status) { 38621 var self = this; 38622 38623 self.callActions('beforeRenderStatus', arguments); 38624 38625 switch (status) { 38626 case 'active': 38627 h.addClass(button, self.classNames.active); 38628 h.removeClass(button, self.classNames.disabled); 38629 38630 if (self.canDisable) self.el.disabled = false; 38631 38632 break; 38633 case 'inactive': 38634 h.removeClass(button, self.classNames.active); 38635 h.removeClass(button, self.classNames.disabled); 38636 38637 if (self.canDisable) self.el.disabled = false; 38638 38639 break; 38640 case 'disabled': 38641 if (self.canDisable) self.el.disabled = true; 38642 38643 h.addClass(button, self.classNames.disabled); 38644 h.removeClass(button, self.classNames.active); 38645 38646 break; 38647 } 38648 38649 if (self.status !== 'live') { 38650 // Update the control's status propery if not live 38651 38652 self.status = status; 38653 } 38654 38655 self.callActions('afterRenderStatus', arguments); 38656 } 38657 }); 38658 38659 mixitup.controls = []; 38660 38661 /** 38662 * @constructor 38663 * @memberof mixitup 38664 * @private 38665 * @since 3.0.0 38666 */ 38667 38668 mixitup.StyleData = function() { 38669 mixitup.Base.call(this); 38670 38671 this.callActions('beforeConstruct'); 38672 38673 this.x = 0; 38674 this.y = 0; 38675 this.top = 0; 38676 this.right = 0; 38677 this.bottom = 0; 38678 this.left = 0; 38679 this.width = 0; 38680 this.height = 0; 38681 this.marginRight = 0; 38682 this.marginBottom = 0; 38683 this.opacity = 0; 38684 this.scale = new mixitup.TransformData(); 38685 this.translateX = new mixitup.TransformData(); 38686 this.translateY = new mixitup.TransformData(); 38687 this.translateZ = new mixitup.TransformData(); 38688 this.rotateX = new mixitup.TransformData(); 38689 this.rotateY = new mixitup.TransformData(); 38690 this.rotateZ = new mixitup.TransformData(); 38691 38692 this.callActions('afterConstruct'); 38693 38694 h.seal(this); 38695 }; 38696 38697 mixitup.BaseStatic.call(mixitup.StyleData); 38698 38699 mixitup.StyleData.prototype = Object.create(mixitup.Base.prototype); 38700 38701 mixitup.StyleData.prototype.constructor = mixitup.StyleData; 38702 38703 /** 38704 * @constructor 38705 * @memberof mixitup 38706 * @private 38707 * @since 3.0.0 38708 */ 38709 38710 mixitup.TransformData = function() { 38711 mixitup.Base.call(this); 38712 38713 this.callActions('beforeConstruct'); 38714 38715 this.value = 0; 38716 this.unit = ''; 38717 38718 this.callActions('afterConstruct'); 38719 38720 h.seal(this); 38721 }; 38722 38723 mixitup.BaseStatic.call(mixitup.TransformData); 38724 38725 mixitup.TransformData.prototype = Object.create(mixitup.Base.prototype); 38726 38727 mixitup.TransformData.prototype.constructor = mixitup.TransformData; 38728 38729 /** 38730 * @constructor 38731 * @memberof mixitup 38732 * @private 38733 * @since 3.0.0 38734 */ 38735 38736 mixitup.TransformDefaults = function() { 38737 mixitup.StyleData.apply(this); 38738 38739 this.callActions('beforeConstruct'); 38740 38741 this.scale.value = 0.01; 38742 this.scale.unit = ''; 38743 38744 this.translateX.value = 20; 38745 this.translateX.unit = 'px'; 38746 38747 this.translateY.value = 20; 38748 this.translateY.unit = 'px'; 38749 38750 this.translateZ.value = 20; 38751 this.translateZ.unit = 'px'; 38752 38753 this.rotateX.value = 90; 38754 this.rotateX.unit = 'deg'; 38755 38756 this.rotateY.value = 90; 38757 this.rotateY.unit = 'deg'; 38758 38759 this.rotateX.value = 90; 38760 this.rotateX.unit = 'deg'; 38761 38762 this.rotateZ.value = 180; 38763 this.rotateZ.unit = 'deg'; 38764 38765 this.callActions('afterConstruct'); 38766 38767 h.seal(this); 38768 }; 38769 38770 mixitup.BaseStatic.call(mixitup.TransformDefaults); 38771 38772 mixitup.TransformDefaults.prototype = Object.create(mixitup.StyleData.prototype); 38773 38774 mixitup.TransformDefaults.prototype.constructor = mixitup.TransformDefaults; 38775 38776 /** 38777 * @private 38778 * @static 38779 * @since 3.0.0 38780 * @type {mixitup.TransformDefaults} 38781 */ 38782 38783 mixitup.transformDefaults = new mixitup.TransformDefaults(); 38784 38785 /** 38786 * @constructor 38787 * @memberof mixitup 38788 * @private 38789 * @since 3.0.0 38790 */ 38791 38792 mixitup.EventDetail = function() { 38793 this.state = null; 38794 this.futureState = null; 38795 this.instance = null; 38796 this.originalEvent = null; 38797 }; 38798 38799 /** 38800 * The `mixitup.Events` class contains all custom events dispatched by MixItUp at various 38801 * points within the lifecycle of a mixer operation. 38802 * 38803 * Each event is analogous to the callback function of the same name defined in 38804 * the `callbacks` configuration object, and is triggered immediately before it. 38805 * 38806 * Events are always triggered from the container element on which MixItUp is instantiated 38807 * upon. 38808 * 38809 * As with any event, registered event handlers receive the event object as a parameter 38810 * which includes a `detail` property containting references to the current `state`, 38811 * the `mixer` instance, and other event-specific properties described below. 38812 * 38813 * @constructor 38814 * @namespace 38815 * @memberof mixitup 38816 * @public 38817 * @since 3.0.0 38818 */ 38819 38820 mixitup.Events = function() { 38821 mixitup.Base.call(this); 38822 38823 this.callActions('beforeConstruct'); 38824 38825 /** 38826 * A custom event triggered immediately after any MixItUp operation is requested 38827 * and before animations have begun. 38828 * 38829 * The `mixStart` event also exposes a `futureState` property via the 38830 * `event.detail` object, which represents the final state of the mixer once 38831 * the requested operation has completed. 38832 * 38833 * @name mixStart 38834 * @memberof mixitup.Events 38835 * @static 38836 * @type {CustomEvent} 38837 */ 38838 38839 this.mixStart = null; 38840 38841 /** 38842 * A custom event triggered when a MixItUp operation is requested while another 38843 * operation is in progress, and the animation queue is full, or queueing 38844 * is disabled. 38845 * 38846 * @name mixBusy 38847 * @memberof mixitup.Events 38848 * @static 38849 * @type {CustomEvent} 38850 */ 38851 38852 this.mixBusy = null; 38853 38854 /** 38855 * A custom event triggered after any MixItUp operation has completed, and the 38856 * state has been updated. 38857 * 38858 * @name mixEnd 38859 * @memberof mixitup.Events 38860 * @static 38861 * @type {CustomEvent} 38862 */ 38863 38864 this.mixEnd = null; 38865 38866 /** 38867 * A custom event triggered whenever a filter operation "fails", i.e. no targets 38868 * could be found matching the requested filter. 38869 * 38870 * @name mixFail 38871 * @memberof mixitup.Events 38872 * @static 38873 * @type {CustomEvent} 38874 */ 38875 38876 this.mixFail = null; 38877 38878 /** 38879 * A custom event triggered whenever a MixItUp control is clicked, and before its 38880 * respective operation is requested. 38881 * 38882 * This event also exposes an `originalEvent` property via the `event.detail` 38883 * object, which holds a reference to the original click event. 38884 * 38885 * @name mixClick 38886 * @memberof mixitup.Events 38887 * @static 38888 * @type {CustomEvent} 38889 */ 38890 38891 this.mixClick = null; 38892 38893 this.callActions('afterConstruct'); 38894 38895 h.seal(this); 38896 }; 38897 38898 mixitup.BaseStatic.call(mixitup.Events); 38899 38900 mixitup.Events.prototype = Object.create(mixitup.Base.prototype); 38901 38902 mixitup.Events.prototype.constructor = mixitup.Events; 38903 38904 /** 38905 * @private 38906 * @param {string} eventType 38907 * @param {Element} el 38908 * @param {object} detail 38909 * @param {Document} [doc] 38910 */ 38911 38912 mixitup.Events.prototype.fire = function(eventType, el, detail, doc) { 38913 var self = this, 38914 event = null, 38915 eventDetail = new mixitup.EventDetail(); 38916 38917 self.callActions('beforeFire', arguments); 38918 38919 if (typeof self[eventType] === 'undefined') { 38920 throw new Error('Event type "' + eventType + '" not found.'); 38921 } 38922 38923 eventDetail.state = new mixitup.State(); 38924 38925 h.extend(eventDetail.state, detail.state); 38926 38927 if (detail.futureState) { 38928 eventDetail.futureState = new mixitup.State(); 38929 38930 h.extend(eventDetail.futureState, detail.futureState); 38931 } 38932 38933 eventDetail.instance = detail.instance; 38934 38935 if (detail.originalEvent) { 38936 eventDetail.originalEvent = detail.originalEvent; 38937 } 38938 38939 event = h.getCustomEvent(eventType, eventDetail, doc); 38940 38941 self.callFilters('eventFire', event, arguments); 38942 38943 el.dispatchEvent(event); 38944 }; 38945 38946 // Asign a singleton instance to `mixitup.events`: 38947 38948 mixitup.events = new mixitup.Events(); 38949 38950 /** 38951 * @constructor 38952 * @memberof mixitup 38953 * @private 38954 * @since 3.0.0 38955 */ 38956 38957 mixitup.QueueItem = function() { 38958 mixitup.Base.call(this); 38959 38960 this.callActions('beforeConstruct'); 38961 38962 this.args = []; 38963 this.instruction = null; 38964 this.triggerElement = null; 38965 this.deferred = null; 38966 this.isToggling = false; 38967 38968 this.callActions('afterConstruct'); 38969 38970 h.seal(this); 38971 }; 38972 38973 mixitup.BaseStatic.call(mixitup.QueueItem); 38974 38975 mixitup.QueueItem.prototype = Object.create(mixitup.Base.prototype); 38976 38977 mixitup.QueueItem.prototype.constructor = mixitup.QueueItem; 38978 38979 /** 38980 * The `mixitup.Mixer` class is used to hold discreet, user-configured 38981 * instances of MixItUp on a provided container element. 38982 * 38983 * Mixer instances are returned whenever the `mixitup()` factory function is called, 38984 * which expose a range of methods enabling API-based filtering, sorting, 38985 * insertion, removal and more. 38986 * 38987 * @constructor 38988 * @namespace 38989 * @memberof mixitup 38990 * @public 38991 * @since 3.0.0 38992 */ 38993 38994 mixitup.Mixer = function() { 38995 mixitup.Base.call(this); 38996 38997 this.callActions('beforeConstruct'); 38998 38999 this.config = new mixitup.Config(); 39000 39001 this.id = ''; 39002 39003 this.isBusy = false; 39004 this.isToggling = false; 39005 this.incPadding = true; 39006 39007 this.controls = []; 39008 this.targets = []; 39009 this.origOrder = []; 39010 this.cache = {}; 39011 39012 this.toggleArray = []; 39013 39014 this.targetsMoved = 0; 39015 this.targetsImmovable = 0; 39016 this.targetsBound = 0; 39017 this.targetsDone = 0; 39018 39019 this.staggerDuration = 0; 39020 this.effectsIn = null; 39021 this.effectsOut = null; 39022 this.transformIn = []; 39023 this.transformOut = []; 39024 this.queue = []; 39025 39026 this.state = null; 39027 this.lastOperation = null; 39028 this.lastClicked = null; 39029 this.userCallback = null; 39030 this.userDeferred = null; 39031 39032 this.dom = new mixitup.MixerDom(); 39033 39034 this.callActions('afterConstruct'); 39035 39036 h.seal(this); 39037 }; 39038 39039 mixitup.BaseStatic.call(mixitup.Mixer); 39040 39041 mixitup.Mixer.prototype = Object.create(mixitup.Base.prototype); 39042 39043 h.extend(mixitup.Mixer.prototype, 39044 /** @lends mixitup.Mixer */ 39045 { 39046 constructor: mixitup.Mixer, 39047 39048 /** 39049 * @private 39050 * @instance 39051 * @since 3.0.0 39052 * @param {HTMLElement} container 39053 * @param {HTMLElement} document 39054 * @param {string} id 39055 * @param {object} [config] 39056 */ 39057 39058 attach: function(container, document, id, config) { 39059 var self = this, 39060 target = null, 39061 i = -1; 39062 39063 self.callActions('beforeAttach', arguments); 39064 39065 self.id = id; 39066 39067 if (config) { 39068 h.extend(self.config, config, true, true); 39069 } 39070 39071 self.sanitizeConfig(); 39072 39073 self.cacheDom(container, document); 39074 39075 if (self.config.layout.containerClassName) { 39076 h.addClass(self.dom.container, self.config.layout.containerClassName); 39077 } 39078 39079 if (!mixitup.features.has.transitions) { 39080 self.config.animation.enable = false; 39081 } 39082 39083 if (typeof window.console === 'undefined') { 39084 self.config.debug.showWarnings = false; 39085 } 39086 39087 if (self.config.data.uidKey) { 39088 // If the dataset API is in use, force disable controls 39089 39090 self.config.controls.enable = false; 39091 } 39092 39093 self.indexTargets(); 39094 39095 self.state = self.getInitialState(); 39096 39097 for (i = 0; target = self.lastOperation.toHide[i]; i++) { 39098 target.hide(); 39099 } 39100 39101 if (self.config.controls.enable) { 39102 self.initControls(); 39103 39104 self.buildToggleArray(null, self.state); 39105 39106 self.updateControls({ 39107 filter: self.state.activeFilter, 39108 sort: self.state.activeSort 39109 }); 39110 } 39111 39112 self.parseEffects(); 39113 39114 self.callActions('afterAttach', arguments); 39115 }, 39116 39117 /** 39118 * @private 39119 * @instance 39120 * @since 3.0.0 39121 * @return {void} 39122 */ 39123 39124 sanitizeConfig: function() { 39125 var self = this; 39126 39127 self.callActions('beforeSanitizeConfig', arguments); 39128 39129 // Sanitize enum/string config options 39130 39131 self.config.controls.scope = self.config.controls.scope.toLowerCase().trim(); 39132 self.config.controls.toggleLogic = self.config.controls.toggleLogic.toLowerCase().trim(); 39133 self.config.controls.toggleDefault = self.config.controls.toggleDefault.toLowerCase().trim(); 39134 39135 self.config.animation.effects = self.config.animation.effects.trim(); 39136 39137 self.callActions('afterSanitizeConfig', arguments); 39138 }, 39139 39140 /** 39141 * @private 39142 * @instance 39143 * @since 3.0.0 39144 * @return {mixitup.State} 39145 */ 39146 39147 getInitialState: function() { 39148 var self = this, 39149 state = new mixitup.State(), 39150 operation = new mixitup.Operation(); 39151 39152 self.callActions('beforeGetInitialState', arguments); 39153 39154 // Map initial values into a mock state object in order to construct an operation 39155 39156 state.activeContainerClassName = self.config.layout.containerClassName; 39157 39158 if (self.config.load.dataset) { 39159 // Dataset API 39160 39161 if (!self.config.data.uidKey || typeof self.config.data.uidKey !== 'string') { 39162 throw new TypeError(mixitup.messages.errorConfigDataUidKeyNotSet()); 39163 } 39164 39165 operation.startDataset = operation.newDataset = state.activeDataset = self.config.load.dataset.slice(); 39166 operation.startContainerClassName = operation.newContainerClassName = state.activeContainerClassName; 39167 operation.show = self.targets.slice(); 39168 39169 state = self.callFilters('stateGetInitialState', state, arguments); 39170 } else { 39171 // DOM API 39172 39173 state.activeFilter = self.parseFilterArgs([self.config.load.filter]).command; 39174 state.activeSort = self.parseSortArgs([self.config.load.sort]).command; 39175 state.totalTargets = self.targets.length; 39176 39177 state = self.callFilters('stateGetInitialState', state, arguments); 39178 39179 if ( 39180 state.activeSort.collection || state.activeSort.attribute || 39181 state.activeSort.order === 'random' || state.activeSort.order === 'desc' 39182 ) { 39183 // Sorting on load 39184 39185 operation.newSort = state.activeSort; 39186 39187 self.sortOperation(operation); 39188 39189 self.printSort(false, operation); 39190 39191 self.targets = operation.newOrder; 39192 } else { 39193 operation.startOrder = operation.newOrder = self.targets; 39194 } 39195 39196 operation.startFilter = operation.newFilter = state.activeFilter; 39197 operation.startSort = operation.newSort = state.activeSort; 39198 operation.startContainerClassName = operation.newContainerClassName = state.activeContainerClassName; 39199 39200 if (operation.newFilter.selector === 'all') { 39201 operation.newFilter.selector = self.config.selectors.target; 39202 } else if (operation.newFilter.selector === 'none') { 39203 operation.newFilter.selector = ''; 39204 } 39205 } 39206 39207 operation = self.callFilters('operationGetInitialState', operation, [state]); 39208 39209 self.lastOperation = operation; 39210 39211 if (operation.newFilter) { 39212 self.filterOperation(operation); 39213 } 39214 39215 state = self.buildState(operation); 39216 39217 return state; 39218 }, 39219 39220 /** 39221 * Caches references of DOM elements neccessary for the mixer's functionality. 39222 * 39223 * @private 39224 * @instance 39225 * @since 3.0.0 39226 * @param {HTMLElement} el 39227 * @param {HTMLHtmlElement} document 39228 * @return {void} 39229 */ 39230 39231 cacheDom: function(el, document) { 39232 var self = this; 39233 39234 self.callActions('beforeCacheDom', arguments); 39235 39236 self.dom.document = document; 39237 self.dom.body = self.dom.document.querySelector('body'); 39238 self.dom.container = el; 39239 self.dom.parent = el; 39240 39241 self.callActions('afterCacheDom', arguments); 39242 }, 39243 39244 /** 39245 * Indexes all child elements of the mixer matching the `selectors.target` 39246 * selector, instantiating a mixitup.Target for each one. 39247 * 39248 * @private 39249 * @instance 39250 * @since 3.0.0 39251 * @return {void} 39252 */ 39253 39254 indexTargets: function() { 39255 var self = this, 39256 target = null, 39257 el = null, 39258 dataset = null, 39259 i = -1; 39260 39261 self.callActions('beforeIndexTargets', arguments); 39262 39263 self.dom.targets = self.config.layout.allowNestedTargets ? 39264 self.dom.container.querySelectorAll(self.config.selectors.target) : 39265 h.children(self.dom.container, self.config.selectors.target, self.dom.document); 39266 39267 self.dom.targets = h.arrayFromList(self.dom.targets); 39268 39269 self.targets = []; 39270 39271 if ((dataset = self.config.load.dataset) && dataset.length !== self.dom.targets.length) { 39272 throw new Error(mixitup.messages.errorDatasetPrerenderedMismatch()); 39273 } 39274 39275 if (self.dom.targets.length) { 39276 for (i = 0; el = self.dom.targets[i]; i++) { 39277 target = new mixitup.Target(); 39278 39279 target.init(el, self, dataset ? dataset[i] : void(0)); 39280 39281 target.isInDom = true; 39282 39283 self.targets.push(target); 39284 } 39285 39286 self.dom.parent = self.dom.targets[0].parentElement === self.dom.container ? 39287 self.dom.container : 39288 self.dom.targets[0].parentElement; 39289 } 39290 39291 self.origOrder = self.targets; 39292 39293 self.callActions('afterIndexTargets', arguments); 39294 }, 39295 39296 initControls: function() { 39297 var self = this, 39298 definition = '', 39299 controlElements = null, 39300 el = null, 39301 parent = null, 39302 delagators = null, 39303 control = null, 39304 i = -1, 39305 j = -1; 39306 39307 self.callActions('beforeInitControls', arguments); 39308 39309 switch (self.config.controls.scope) { 39310 case 'local': 39311 parent = self.dom.container; 39312 39313 break; 39314 case 'global': 39315 parent = self.dom.document; 39316 39317 break; 39318 default: 39319 throw new Error(mixitup.messages.errorConfigInvalidControlsScope()); 39320 } 39321 39322 for (i = 0; definition = mixitup.controlDefinitions[i]; i++) { 39323 if (self.config.controls.live || definition.live) { 39324 if (definition.parent) { 39325 delagators = self.dom[definition.parent]; 39326 39327 if (!delagators || delagators.length < 0) continue; 39328 39329 if (typeof delagators.length !== 'number') { 39330 delagators = [delagators]; 39331 } 39332 } else { 39333 delagators = [parent]; 39334 } 39335 39336 for (j = 0; (el = delagators[j]); j++) { 39337 control = self.getControl(el, definition.type, definition.selector); 39338 39339 self.controls.push(control); 39340 } 39341 } else { 39342 controlElements = parent.querySelectorAll(self.config.selectors.control + definition.selector); 39343 39344 for (j = 0; (el = controlElements[j]); j++) { 39345 control = self.getControl(el, definition.type, ''); 39346 39347 if (!control) continue; 39348 39349 self.controls.push(control); 39350 } 39351 } 39352 } 39353 39354 self.callActions('afterInitControls', arguments); 39355 }, 39356 39357 /** 39358 * @private 39359 * @instance 39360 * @since 3.0.0 39361 * @param {HTMLElement} el 39362 * @param {string} type 39363 * @param {string} selector 39364 * @return {mixitup.Control|null} 39365 */ 39366 39367 getControl: function(el, type, selector) { 39368 var self = this, 39369 control = null, 39370 i = -1; 39371 39372 self.callActions('beforeGetControl', arguments); 39373 39374 if (!selector) { 39375 // Static controls only 39376 39377 for (i = 0; control = mixitup.controls[i]; i++) { 39378 if (control.el === el && control.isBound(self)) { 39379 // Control already bound to this mixer (as another type). 39380 39381 // NB: This prevents duplicate controls from being registered where a selector 39382 // might collide, eg: "[data-filter]" and "[data-filter][data-sort]" 39383 39384 return self.callFilters('controlGetControl', null, arguments); 39385 } else if (control.el === el && control.type === type && control.selector === selector) { 39386 // Another mixer is already using this control, add this mixer as a binding 39387 39388 control.addBinding(self); 39389 39390 return self.callFilters('controlGetControl', control, arguments); 39391 } 39392 } 39393 } 39394 39395 // Create new control 39396 39397 control = new mixitup.Control(); 39398 39399 control.init(el, type, selector); 39400 39401 control.classNames.base = h.getClassname(self.config.classNames, type); 39402 control.classNames.active = h.getClassname(self.config.classNames, type, self.config.classNames.modifierActive); 39403 control.classNames.disabled = h.getClassname(self.config.classNames, type, self.config.classNames.modifierDisabled); 39404 39405 // Add a reference to this mixer as a binding 39406 39407 control.addBinding(self); 39408 39409 return self.callFilters('controlGetControl', control, arguments); 39410 }, 39411 39412 /** 39413 * Creates a compound selector by joining the `toggleArray` value as per the 39414 * defined toggle logic. 39415 * 39416 * @private 39417 * @instance 39418 * @since 3.0.0 39419 * @return {string} 39420 */ 39421 39422 getToggleSelector: function() { 39423 var self = this, 39424 delineator = self.config.controls.toggleLogic === 'or' ? ', ' : '', 39425 toggleSelector = ''; 39426 39427 self.callActions('beforeGetToggleSelector', arguments); 39428 39429 self.toggleArray = h.clean(self.toggleArray); 39430 39431 toggleSelector = self.toggleArray.join(delineator); 39432 39433 if (toggleSelector === '') { 39434 toggleSelector = self.config.controls.toggleDefault; 39435 } 39436 39437 return self.callFilters('selectorGetToggleSelector', toggleSelector, arguments); 39438 }, 39439 39440 /** 39441 * Breaks compound selector strings in an array of discreet selectors, 39442 * as per the active `controls.toggleLogic` configuration option. Accepts 39443 * either a dynamic command object, or a state object. 39444 * 39445 * @private 39446 * @instance 39447 * @since 2.0.0 39448 * @param {object} [command] 39449 * @param {mixitup.State} [state] 39450 * @return {void} 39451 */ 39452 39453 buildToggleArray: function(command, state) { 39454 var self = this, 39455 activeFilterSelector = ''; 39456 39457 self.callActions('beforeBuildToggleArray', arguments); 39458 39459 if (command && command.filter) { 39460 activeFilterSelector = command.filter.selector.replace(/\s/g, ''); 39461 } else if (state) { 39462 activeFilterSelector = state.activeFilter.selector.replace(/\s/g, ''); 39463 } else { 39464 return; 39465 } 39466 39467 if (activeFilterSelector === self.config.selectors.target || activeFilterSelector === 'all') { 39468 activeFilterSelector = ''; 39469 } 39470 39471 if (self.config.controls.toggleLogic === 'or') { 39472 self.toggleArray = activeFilterSelector.split(','); 39473 } else { 39474 self.toggleArray = self.splitCompoundSelector(activeFilterSelector); 39475 } 39476 39477 self.toggleArray = h.clean(self.toggleArray); 39478 39479 self.callActions('afterBuildToggleArray', arguments); 39480 }, 39481 39482 /** 39483 * Takes a compound selector (e.g. `.cat-1.cat-2`, `[data-cat="1"][data-cat="2"]`) 39484 * and breaks into its individual selectors. 39485 * 39486 * @private 39487 * @instance 39488 * @since 3.0.0 39489 * @param {string} compoundSelector 39490 * @return {string[]} 39491 */ 39492 39493 splitCompoundSelector: function(compoundSelector) { 39494 // Break at a `.` or `[`, capturing the delineator 39495 39496 var partials = compoundSelector.split(/([\.\[])/g), 39497 toggleArray = [], 39498 selector = '', 39499 i = -1; 39500 39501 if (partials[0] === '') { 39502 partials.shift(); 39503 } 39504 39505 for (i = 0; i < partials.length; i++) { 39506 if (i % 2 === 0) { 39507 selector = ''; 39508 } 39509 39510 selector += partials[i]; 39511 39512 if (i % 2 !== 0) { 39513 toggleArray.push(selector); 39514 } 39515 } 39516 39517 return toggleArray; 39518 }, 39519 39520 /** 39521 * Updates controls to their active/inactive state based on the command or 39522 * current state of the mixer. 39523 * 39524 * @private 39525 * @instance 39526 * @since 2.0.0 39527 * @param {object} command 39528 * @return {void} 39529 */ 39530 39531 updateControls: function(command) { 39532 var self = this, 39533 control = null, 39534 output = new mixitup.CommandMultimix(), 39535 i = -1; 39536 39537 self.callActions('beforeUpdateControls', arguments); 39538 39539 // Sanitise to defaults 39540 39541 if (command.filter) { 39542 output.filter = command.filter.selector; 39543 } else { 39544 output.filter = self.state.activeFilter.selector; 39545 } 39546 39547 if (command.sort) { 39548 output.sort = self.buildSortString(command.sort); 39549 } else { 39550 output.sort = self.buildSortString(self.state.activeSort); 39551 } 39552 39553 if (output.filter === self.config.selectors.target) { 39554 output.filter = 'all'; 39555 } 39556 39557 if (output.filter === '') { 39558 output.filter = 'none'; 39559 } 39560 39561 h.freeze(output); 39562 39563 for (i = 0; control = self.controls[i]; i++) { 39564 control.update(output, self.toggleArray); 39565 } 39566 39567 self.callActions('afterUpdateControls', arguments); 39568 }, 39569 39570 /** 39571 * @private 39572 * @instance 39573 * @since 3.0.0 39574 * @param {mixitup.CommandSort} command 39575 * @return {string} 39576 */ 39577 39578 buildSortString: function(command) { 39579 var self = this; 39580 var output = ''; 39581 39582 output += command.sortString; 39583 39584 if (command.next) { 39585 output += ' ' + self.buildSortString(command.next); 39586 } 39587 39588 return output; 39589 }, 39590 39591 /** 39592 * @private 39593 * @instance 39594 * @since 3.0.0 39595 * @param {object} command 39596 * @param {Operation} operation 39597 * @return {Promise.<mixitup.State>} 39598 */ 39599 39600 insertTargets: function(command, operation) { 39601 var self = this, 39602 nextSibling = null, 39603 insertionIndex = -1, 39604 frag = null, 39605 target = null, 39606 el = null, 39607 i = -1; 39608 39609 self.callActions('beforeInsertTargets', arguments); 39610 39611 if (typeof command.index === 'undefined') command.index = 0; 39612 39613 nextSibling = self.getNextSibling(command.index, command.sibling, command.position); 39614 frag = self.dom.document.createDocumentFragment(); 39615 39616 if (nextSibling) { 39617 insertionIndex = h.index(nextSibling, self.config.selectors.target); 39618 } else { 39619 insertionIndex = self.targets.length; 39620 } 39621 39622 if (command.collection) { 39623 for (i = 0; el = command.collection[i]; i++) { 39624 if (self.dom.targets.indexOf(el) > -1) { 39625 throw new Error(mixitup.messages.errorInsertPreexistingElement()); 39626 } 39627 39628 // Ensure elements are hidden when they are added to the DOM, so they can 39629 // be animated in gracefully 39630 39631 el.style.display = 'none'; 39632 39633 frag.appendChild(el); 39634 frag.appendChild(self.dom.document.createTextNode(' ')); 39635 39636 if (!h.isElement(el, self.dom.document) || !el.matches(self.config.selectors.target)) continue; 39637 39638 target = new mixitup.Target(); 39639 39640 target.init(el, self); 39641 39642 target.isInDom = true; 39643 39644 self.targets.splice(insertionIndex, 0, target); 39645 39646 insertionIndex++; 39647 } 39648 39649 self.dom.parent.insertBefore(frag, nextSibling); 39650 } 39651 39652 // Since targets have been added, the original order must be updated 39653 39654 operation.startOrder = self.origOrder = self.targets; 39655 39656 self.callActions('afterInsertTargets', arguments); 39657 }, 39658 39659 /** 39660 * @private 39661 * @instance 39662 * @since 3.0.0 39663 * @param {Number} [index] 39664 * @param {Element} [sibling] 39665 * @param {string} [position] 39666 * @return {Element} 39667 */ 39668 39669 getNextSibling: function(index, sibling, position) { 39670 var self = this, 39671 element = null; 39672 39673 index = Math.max(index, 0); 39674 39675 if (sibling && position === 'before') { 39676 // Explicit sibling 39677 39678 element = sibling; 39679 } else if (sibling && position === 'after') { 39680 // Explicit sibling 39681 39682 element = sibling.nextElementSibling || null; 39683 } else if (self.targets.length > 0 && typeof index !== 'undefined') { 39684 // Index and targets exist 39685 39686 element = (index < self.targets.length || !self.targets.length) ? 39687 self.targets[index].dom.el : 39688 self.targets[self.targets.length - 1].dom.el.nextElementSibling; 39689 } else if (self.targets.length === 0 && self.dom.parent.children.length > 0) { 39690 // No targets but other siblings 39691 39692 if (self.config.layout.siblingAfter) { 39693 element = self.config.layout.siblingAfter; 39694 } else if (self.config.layout.siblingBefore) { 39695 element = self.config.layout.siblingBefore.nextElementSibling; 39696 } else { 39697 self.dom.parent.children[0]; 39698 } 39699 } else { 39700 element === null; 39701 } 39702 39703 return self.callFilters('elementGetNextSibling', element, arguments); 39704 }, 39705 39706 /** 39707 * @private 39708 * @instance 39709 * @since 2.0.0 39710 * @param {Operation} operation 39711 * @return {void} 39712 */ 39713 39714 filterOperation: function(operation) { 39715 var self = this, 39716 testResult = false, 39717 index = -1, 39718 action = '', 39719 target = null, 39720 i = -1; 39721 39722 self.callActions('beforeFilterOperation', arguments); 39723 39724 action = operation.newFilter.action; 39725 39726 for (i = 0; target = operation.newOrder[i]; i++) { 39727 if (operation.newFilter.collection) { 39728 // show via collection 39729 39730 testResult = operation.newFilter.collection.indexOf(target.dom.el) > -1; 39731 } else { 39732 // show via selector 39733 39734 if (operation.newFilter.selector === '') { 39735 testResult = false; 39736 } else { 39737 testResult = target.dom.el.matches(operation.newFilter.selector); 39738 } 39739 } 39740 39741 self.evaluateHideShow(testResult, target, action, operation); 39742 } 39743 39744 if (operation.toRemove.length) { 39745 for (i = 0; target = operation.show[i]; i++) { 39746 if (operation.toRemove.indexOf(target) > -1) { 39747 // If any shown targets should be removed, move them into the toHide array 39748 39749 operation.show.splice(i, 1); 39750 39751 if ((index = operation.toShow.indexOf(target)) > -1) { 39752 operation.toShow.splice(index, 1); 39753 } 39754 39755 operation.toHide.push(target); 39756 operation.hide.push(target); 39757 39758 i--; 39759 } 39760 } 39761 } 39762 39763 operation.matching = operation.show.slice(); 39764 39765 if (operation.show.length === 0 && operation.newFilter.selector !== '' && self.targets.length !== 0) { 39766 operation.hasFailed = true; 39767 } 39768 39769 self.callActions('afterFilterOperation', arguments); 39770 }, 39771 39772 /** 39773 * @private 39774 * @instance 39775 * @since 3.0.0 39776 * @param {boolean} testResult 39777 * @param {Element} target 39778 * @param {string} action 39779 * @param {Operation} operation 39780 * @return {void} 39781 */ 39782 39783 evaluateHideShow: function(testResult, target, action, operation) { 39784 var self = this, 39785 filteredTestResult = false, 39786 args = Array.prototype.slice.call(arguments, 1); 39787 39788 filteredTestResult = self.callFilters('testResultEvaluateHideShow', testResult, args); 39789 39790 self.callActions('beforeEvaluateHideShow', arguments); 39791 39792 if ( 39793 filteredTestResult === true && action === 'show' || 39794 filteredTestResult === false && action === 'hide' 39795 ) { 39796 operation.show.push(target); 39797 39798 !target.isShown && operation.toShow.push(target); 39799 } else { 39800 operation.hide.push(target); 39801 39802 target.isShown && operation.toHide.push(target); 39803 } 39804 39805 self.callActions('afterEvaluateHideShow', arguments); 39806 }, 39807 39808 /** 39809 * @private 39810 * @instance 39811 * @since 2.0.0 39812 * @param {Operation} operation 39813 * @return {void} 39814 */ 39815 39816 sortOperation: function(operation) { 39817 var self = this, 39818 newOrder = [], 39819 target = null, 39820 el = null, 39821 i = -1; 39822 39823 self.callActions('beforeSortOperation', arguments); 39824 39825 operation.startOrder = self.targets; 39826 39827 if (operation.newSort.collection) { 39828 // Sort by collection 39829 39830 newOrder = []; 39831 39832 for (i = 0; (el = operation.newSort.collection[i]); i++) { 39833 if (self.dom.targets.indexOf(el) < 0) { 39834 throw new Error(mixitup.messages.errorSortNonExistentElement()); 39835 } 39836 39837 target = new mixitup.Target(); 39838 39839 target.init(el, self); 39840 39841 target.isInDom = true; 39842 39843 newOrder.push(target); 39844 } 39845 39846 operation.newOrder = newOrder; 39847 } else if (operation.newSort.order === 'random') { 39848 // Sort random 39849 39850 operation.newOrder = h.arrayShuffle(operation.startOrder); 39851 } else if (operation.newSort.attribute === '') { 39852 // Sort by default 39853 39854 operation.newOrder = self.origOrder.slice(); 39855 39856 if (operation.newSort.order === 'desc') { 39857 operation.newOrder.reverse(); 39858 } 39859 } else { 39860 // Sort by attribute 39861 39862 operation.newOrder = operation.startOrder.slice(); 39863 39864 operation.newOrder.sort(function(a, b) { 39865 return self.compare(a, b, operation.newSort); 39866 }); 39867 } 39868 39869 if (h.isEqualArray(operation.newOrder, operation.startOrder)) { 39870 operation.willSort = false; 39871 } 39872 39873 self.callActions('afterSortOperation', arguments); 39874 }, 39875 39876 /** 39877 * @private 39878 * @instance 39879 * @since 2.0.0 39880 * @param {mixitup.Target} a 39881 * @param {mixitup.Target} b 39882 * @param {mixitup.CommandSort} command 39883 * @return {Number} 39884 */ 39885 39886 compare: function(a, b, command) { 39887 var self = this, 39888 order = command.order, 39889 attrA = self.getAttributeValue(a, command.attribute), 39890 attrB = self.getAttributeValue(b, command.attribute); 39891 39892 if (isNaN(attrA * 1) || isNaN(attrB * 1)) { 39893 attrA = attrA.toLowerCase(); 39894 attrB = attrB.toLowerCase(); 39895 } else { 39896 attrA = attrA * 1; 39897 attrB = attrB * 1; 39898 } 39899 39900 if (attrA < attrB) { 39901 return order === 'asc' ? -1 : 1; 39902 } 39903 39904 if (attrA > attrB) { 39905 return order === 'asc' ? 1 : -1; 39906 } 39907 39908 if (attrA === attrB && command.next) { 39909 return self.compare(a, b, command.next); 39910 } 39911 39912 return 0; 39913 }, 39914 39915 /** 39916 * Reads the values of any data attributes present the provided target element 39917 * which match the current sort command. 39918 * 39919 * @private 39920 * @instance 39921 * @since 3.0.0 39922 * @param {mixitup.Target} target 39923 * @param {string} [attribute] 39924 * @return {(String|Number)} 39925 */ 39926 39927 getAttributeValue: function(target, attribute) { 39928 var self = this, 39929 value = ''; 39930 39931 value = target.dom.el.getAttribute('data-' + attribute); 39932 39933 if (value === null) { 39934 if (self.config.debug.showWarnings) { 39935 // Encourage users to assign values to all targets to avoid erroneous sorting 39936 // when types are mixed 39937 39938 console.warn(mixitup.messages.warningInconsistentSortingAttributes({ 39939 attribute: 'data-' + attribute 39940 })); 39941 } 39942 } 39943 39944 // If an attribute is not present, return 0 as a safety value 39945 39946 return self.callFilters('valueGetAttributeValue', value || 0, arguments); 39947 }, 39948 39949 /** 39950 * Inserts elements into the DOM in the appropriate 39951 * order using a document fragment for minimal 39952 * DOM thrashing 39953 * 39954 * @private 39955 * @instance 39956 * @since 2.0.0 39957 * @param {boolean} isResetting 39958 * @param {Operation} operation 39959 * @return {void} 39960 */ 39961 39962 printSort: function(isResetting, operation) { 39963 var self = this, 39964 startOrder = isResetting ? operation.newOrder : operation.startOrder, 39965 newOrder = isResetting ? operation.startOrder : operation.newOrder, 39966 nextSibling = startOrder.length ? startOrder[startOrder.length - 1].dom.el.nextElementSibling : null, 39967 frag = window.document.createDocumentFragment(), 39968 whitespace = null, 39969 target = null, 39970 el = null, 39971 i = -1; 39972 39973 self.callActions('beforePrintSort', arguments); 39974 39975 // Empty the container 39976 39977 for (i = 0; target = startOrder[i]; i++) { 39978 el = target.dom.el; 39979 39980 if (el.style.position === 'absolute') continue; 39981 39982 h.removeWhitespace(el.previousSibling); 39983 39984 el.parentElement.removeChild(el); 39985 } 39986 39987 whitespace = nextSibling ? nextSibling.previousSibling : self.dom.parent.lastChild; 39988 39989 if (whitespace && whitespace.nodeName === '#text') { 39990 h.removeWhitespace(whitespace); 39991 } 39992 39993 for (i = 0; target = newOrder[i]; i++) { 39994 // Add targets into a document fragment 39995 39996 el = target.dom.el; 39997 39998 if (h.isElement(frag.lastChild)) { 39999 frag.appendChild(window.document.createTextNode(' ')); 40000 } 40001 40002 frag.appendChild(el); 40003 } 40004 40005 // Insert the document fragment into the container 40006 // before any other non-target elements 40007 40008 if (self.dom.parent.firstChild && self.dom.parent.firstChild !== nextSibling) { 40009 frag.insertBefore(window.document.createTextNode(' '), frag.childNodes[0]); 40010 } 40011 40012 if (nextSibling) { 40013 frag.appendChild(window.document.createTextNode(' ')); 40014 40015 self.dom.parent.insertBefore(frag, nextSibling); 40016 } else { 40017 self.dom.parent.appendChild(frag); 40018 } 40019 40020 self.callActions('afterPrintSort', arguments); 40021 }, 40022 40023 /** 40024 * Parses user-defined sort strings (i.e. `default:asc`) into sort commands objects. 40025 * 40026 * @private 40027 * @instance 40028 * @since 3.0.0 40029 * @param {string} sortString 40030 * @param {mixitup.CommandSort} command 40031 * @return {mixitup.CommandSort} 40032 */ 40033 40034 parseSortString: function(sortString, command) { 40035 var self = this, 40036 rules = sortString.split(' '), 40037 current = command, 40038 rule = [], 40039 i = -1; 40040 40041 // command.sortString = sortString; 40042 40043 for (i = 0; i < rules.length; i++) { 40044 rule = rules[i].split(':'); 40045 40046 current.sortString = rules[i]; 40047 current.attribute = h.dashCase(rule[0]); 40048 current.order = rule[1] || 'asc'; 40049 40050 switch (current.attribute) { 40051 case 'default': 40052 // treat "default" as sorting by no attribute 40053 40054 current.attribute = ''; 40055 40056 break; 40057 case 'random': 40058 // treat "random" as an order not an attribute 40059 40060 current.attribute = ''; 40061 current.order = 'random'; 40062 40063 break; 40064 } 40065 40066 if (!current.attribute || current.order === 'random') break; 40067 40068 if (i < rules.length - 1) { 40069 // Embed reference to the next command 40070 40071 current.next = new mixitup.CommandSort(); 40072 40073 h.freeze(current); 40074 40075 current = current.next; 40076 } 40077 } 40078 40079 return self.callFilters('commandsParseSort', command, arguments); 40080 }, 40081 40082 /** 40083 * Parses all effects out of the user-defined `animation.effects` string into 40084 * their respective properties and units. 40085 * 40086 * @private 40087 * @instance 40088 * @since 2.0.0 40089 * @return {void} 40090 */ 40091 40092 parseEffects: function() { 40093 var self = this, 40094 transformName = '', 40095 effectsIn = self.config.animation.effectsIn || self.config.animation.effects, 40096 effectsOut = self.config.animation.effectsOut || self.config.animation.effects; 40097 40098 self.callActions('beforeParseEffects', arguments); 40099 40100 self.effectsIn = new mixitup.StyleData(); 40101 self.effectsOut = new mixitup.StyleData(); 40102 self.transformIn = []; 40103 self.transformOut = []; 40104 40105 self.effectsIn.opacity = self.effectsOut.opacity = 1; 40106 40107 self.parseEffect('fade', effectsIn, self.effectsIn, self.transformIn); 40108 self.parseEffect('fade', effectsOut, self.effectsOut, self.transformOut, true); 40109 40110 for (transformName in mixitup.transformDefaults) { 40111 if (!(mixitup.transformDefaults[transformName] instanceof mixitup.TransformData)) { 40112 continue; 40113 } 40114 40115 self.parseEffect(transformName, effectsIn, self.effectsIn, self.transformIn); 40116 self.parseEffect(transformName, effectsOut, self.effectsOut, self.transformOut, true); 40117 } 40118 40119 self.parseEffect('stagger', effectsIn, self.effectsIn, self.transformIn); 40120 self.parseEffect('stagger', effectsOut, self.effectsOut, self.transformOut, true); 40121 40122 self.callActions('afterParseEffects', arguments); 40123 }, 40124 40125 /** 40126 * @private 40127 * @instance 40128 * @since 2.0.0 40129 * @param {string} effectName 40130 * @param {string} effectString 40131 * @param {StyleData} effects 40132 * @param {String[]} transform 40133 * @param {boolean} [isOut] 40134 */ 40135 40136 parseEffect: function(effectName, effectString, effects, transform, isOut) { 40137 var self = this, 40138 re = /\(([^)]+)\)/, 40139 propIndex = -1, 40140 str = '', 40141 match = [], 40142 val = '', 40143 units = ['%', 'px', 'em', 'rem', 'vh', 'vw', 'deg'], 40144 unit = '', 40145 i = -1; 40146 40147 self.callActions('beforeParseEffect', arguments); 40148 40149 if (typeof effectString !== 'string') { 40150 throw new TypeError(mixitup.messages.errorConfigInvalidAnimationEffects()); 40151 } 40152 40153 if (effectString.indexOf(effectName) < 0) { 40154 // The effect is not present in the effects string 40155 40156 if (effectName === 'stagger') { 40157 // Reset stagger to 0 40158 40159 self.staggerDuration = 0; 40160 } 40161 40162 return; 40163 } 40164 40165 // The effect is present 40166 40167 propIndex = effectString.indexOf(effectName + '('); 40168 40169 if (propIndex > -1) { 40170 // The effect has a user defined value in parentheses 40171 40172 // Extract from the first parenthesis to the end of string 40173 40174 str = effectString.substring(propIndex); 40175 40176 // Match any number of characters between "(" and ")" 40177 40178 match = re.exec(str); 40179 40180 val = match[1]; 40181 } 40182 40183 switch (effectName) { 40184 case 'fade': 40185 effects.opacity = val ? parseFloat(val) : 0; 40186 40187 break; 40188 case 'stagger': 40189 self.staggerDuration = val ? parseFloat(val) : 100; 40190 40191 // TODO: Currently stagger must be applied globally, but 40192 // if seperate values are specified for in/out, this should 40193 // be respected 40194 40195 break; 40196 default: 40197 // All other effects are transforms following the same structure 40198 40199 if (isOut && self.config.animation.reverseOut && effectName !== 'scale') { 40200 effects[effectName].value = 40201 (val ? parseFloat(val) : mixitup.transformDefaults[effectName].value) * -1; 40202 } else { 40203 effects[effectName].value = 40204 (val ? parseFloat(val) : mixitup.transformDefaults[effectName].value); 40205 } 40206 40207 if (val) { 40208 for (i = 0; unit = units[i]; i++) { 40209 if (val.indexOf(unit) > -1) { 40210 effects[effectName].unit = unit; 40211 40212 break; 40213 } 40214 } 40215 } else { 40216 effects[effectName].unit = mixitup.transformDefaults[effectName].unit; 40217 } 40218 40219 transform.push( 40220 effectName + 40221 '(' + 40222 effects[effectName].value + 40223 effects[effectName].unit + 40224 ')' 40225 ); 40226 } 40227 40228 self.callActions('afterParseEffect', arguments); 40229 }, 40230 40231 /** 40232 * @private 40233 * @instance 40234 * @since 2.0.0 40235 * @param {Operation} operation 40236 * @return {State} 40237 */ 40238 40239 buildState: function(operation) { 40240 var self = this, 40241 state = new mixitup.State(), 40242 target = null, 40243 i = -1; 40244 40245 self.callActions('beforeBuildState', arguments); 40246 40247 // Map target elements into state arrays. 40248 // the real target objects should never be exposed 40249 40250 for (i = 0; target = self.targets[i]; i++) { 40251 if (!operation.toRemove.length || operation.toRemove.indexOf(target) < 0) { 40252 state.targets.push(target.dom.el); 40253 } 40254 } 40255 40256 for (i = 0; target = operation.matching[i]; i++) { 40257 state.matching.push(target.dom.el); 40258 } 40259 40260 for (i = 0; target = operation.show[i]; i++) { 40261 state.show.push(target.dom.el); 40262 } 40263 40264 for (i = 0; target = operation.hide[i]; i++) { 40265 if (!operation.toRemove.length || operation.toRemove.indexOf(target) < 0) { 40266 state.hide.push(target.dom.el); 40267 } 40268 } 40269 40270 state.id = self.id; 40271 state.container = self.dom.container; 40272 state.activeFilter = operation.newFilter; 40273 state.activeSort = operation.newSort; 40274 state.activeDataset = operation.newDataset; 40275 state.activeContainerClassName = operation.newContainerClassName; 40276 state.hasFailed = operation.hasFailed; 40277 state.totalTargets = self.targets.length; 40278 state.totalShow = operation.show.length; 40279 state.totalHide = operation.hide.length; 40280 state.totalMatching = operation.matching.length; 40281 state.triggerElement = operation.triggerElement; 40282 40283 return self.callFilters('stateBuildState', state, arguments); 40284 }, 40285 40286 /** 40287 * @private 40288 * @instance 40289 * @since 2.0.0 40290 * @param {boolean} shouldAnimate 40291 * @param {Operation} operation 40292 * @return {void} 40293 */ 40294 40295 goMix: function(shouldAnimate, operation) { 40296 var self = this, 40297 deferred = null; 40298 40299 self.callActions('beforeGoMix', arguments); 40300 40301 // If the animation duration is set to 0ms, 40302 // or no effects specified, 40303 // or the container is hidden 40304 // then abort animation 40305 40306 if ( 40307 !self.config.animation.duration || !self.config.animation.effects || !h.isVisible(self.dom.container) 40308 ) { 40309 shouldAnimate = false; 40310 } 40311 40312 if ( 40313 !operation.toShow.length && 40314 !operation.toHide.length && 40315 !operation.willSort && 40316 !operation.willChangeLayout 40317 ) { 40318 // If nothing to show or hide, and not sorting or 40319 // changing layout 40320 40321 shouldAnimate = false; 40322 } 40323 40324 if ( 40325 !operation.startState.show.length && 40326 !operation.show.length 40327 ) { 40328 // If nothing currently shown, nothing to show 40329 40330 shouldAnimate = false; 40331 } 40332 40333 mixitup.events.fire('mixStart', self.dom.container, { 40334 state: operation.startState, 40335 futureState: operation.newState, 40336 instance: self 40337 }, self.dom.document); 40338 40339 if (typeof self.config.callbacks.onMixStart === 'function') { 40340 self.config.callbacks.onMixStart.call( 40341 self.dom.container, 40342 operation.startState, 40343 operation.newState, 40344 self 40345 ); 40346 } 40347 40348 h.removeClass(self.dom.container, h.getClassname(self.config.classNames, 'container', self.config.classNames.modifierFailed)); 40349 40350 if (!self.userDeferred) { 40351 // Queue empty, no pending operations 40352 40353 deferred = self.userDeferred = h.defer(mixitup.libraries); 40354 } else { 40355 // Use existing deferred 40356 40357 deferred = self.userDeferred; 40358 } 40359 40360 self.isBusy = true; 40361 40362 if (!shouldAnimate || !mixitup.features.has.transitions) { 40363 // Abort 40364 40365 if (self.config.debug.fauxAsync) { 40366 setTimeout(function() { 40367 self.cleanUp(operation); 40368 }, self.config.animation.duration); 40369 } else { 40370 self.cleanUp(operation); 40371 } 40372 40373 return self.callFilters('promiseGoMix', deferred.promise, arguments); 40374 } 40375 40376 // If we should animate and the platform supports transitions, go for it 40377 40378 if (window.pageYOffset !== operation.docState.scrollTop) { 40379 window.scrollTo(operation.docState.scrollLeft, operation.docState.scrollTop); 40380 } 40381 40382 if (self.config.animation.applyPerspective) { 40383 self.dom.parent.style[mixitup.features.perspectiveProp] = 40384 self.config.animation.perspectiveDistance; 40385 40386 self.dom.parent.style[mixitup.features.perspectiveOriginProp] = 40387 self.config.animation.perspectiveOrigin; 40388 } 40389 40390 if ( 40391 self.config.animation.animateResizeContainer && 40392 operation.startHeight !== operation.newHeight && 40393 operation.viewportDeltaY !== operation.startHeight - operation.newHeight 40394 ) { 40395 self.dom.parent.style.height = operation.startHeight + 'px'; 40396 } 40397 40398 if ( 40399 self.config.animation.animateResizeContainer && 40400 operation.startWidth !== operation.newWidth && 40401 operation.viewportDeltaX !== operation.startWidth - operation.newWidth 40402 ) { 40403 self.dom.parent.style.width = operation.startWidth + 'px'; 40404 } 40405 40406 if (operation.startHeight === operation.newHeight) { 40407 self.dom.parent.style.height = operation.startHeight + 'px'; 40408 } 40409 40410 if (operation.startWidth === operation.newWidth) { 40411 self.dom.parent.style.width = operation.startWidth + 'px'; 40412 } 40413 40414 if (operation.startHeight === operation.newHeight && operation.startWidth === operation.newWidth) { 40415 self.dom.parent.style.overflow = 'hidden'; 40416 } 40417 40418 requestAnimationFrame(function() { 40419 self.moveTargets(operation); 40420 }); 40421 40422 return self.callFilters('promiseGoMix', deferred.promise, arguments); 40423 }, 40424 40425 /** 40426 * @private 40427 * @instance 40428 * @since 2.0.0 40429 * @param {Operation} operation 40430 * @return {void} 40431 */ 40432 40433 getStartMixData: function(operation) { 40434 var self = this, 40435 parentStyle = window.getComputedStyle(self.dom.parent), 40436 parentRect = self.dom.parent.getBoundingClientRect(), 40437 target = null, 40438 data = {}, 40439 i = -1, 40440 boxSizing = parentStyle[mixitup.features.boxSizingProp]; 40441 40442 self.incPadding = (boxSizing === 'border-box'); 40443 40444 self.callActions('beforeGetStartMixData', arguments); 40445 40446 for (i = 0; target = operation.show[i]; i++) { 40447 data = target.getPosData(); 40448 40449 operation.showPosData[i] = { 40450 startPosData: data 40451 }; 40452 } 40453 40454 for (i = 0; target = operation.toHide[i]; i++) { 40455 data = target.getPosData(); 40456 40457 operation.toHidePosData[i] = { 40458 startPosData: data 40459 }; 40460 } 40461 40462 operation.startX = parentRect.left; 40463 operation.startY = parentRect.top; 40464 40465 operation.startHeight = self.incPadding ? 40466 parentRect.height : 40467 parentRect.height - 40468 parseFloat(parentStyle.paddingTop) - 40469 parseFloat(parentStyle.paddingBottom) - 40470 parseFloat(parentStyle.borderTop) - 40471 parseFloat(parentStyle.borderBottom); 40472 40473 operation.startWidth = self.incPadding ? 40474 parentRect.width : 40475 parentRect.width - 40476 parseFloat(parentStyle.paddingLeft) - 40477 parseFloat(parentStyle.paddingRight) - 40478 parseFloat(parentStyle.borderLeft) - 40479 parseFloat(parentStyle.borderRight); 40480 40481 self.callActions('afterGetStartMixData', arguments); 40482 }, 40483 40484 /** 40485 * @private 40486 * @instance 40487 * @since 2.0.0 40488 * @param {Operation} operation 40489 * @return {void} 40490 */ 40491 40492 setInter: function(operation) { 40493 var self = this, 40494 target = null, 40495 i = -1; 40496 40497 self.callActions('beforeSetInter', arguments); 40498 40499 // Prevent scrollbar flicker on non-inertial scroll platforms by clamping height/width 40500 40501 if (self.config.animation.clampHeight) { 40502 self.dom.parent.style.height = operation.startHeight + 'px'; 40503 self.dom.parent.style.overflow = 'hidden'; 40504 } 40505 40506 if (self.config.animation.clampWidth) { 40507 self.dom.parent.style.width = operation.startWidth + 'px'; 40508 self.dom.parent.style.overflow = 'hidden'; 40509 } 40510 40511 for (i = 0; target = operation.toShow[i]; i++) { 40512 target.show(); 40513 } 40514 40515 if (operation.willChangeLayout) { 40516 h.removeClass(self.dom.container, operation.startContainerClassName); 40517 h.addClass(self.dom.container, operation.newContainerClassName); 40518 } 40519 40520 self.callActions('afterSetInter', arguments); 40521 }, 40522 40523 /** 40524 * @private 40525 * @instance 40526 * @since 2.0.0 40527 * @param {Operation} operation 40528 * @return {void} 40529 */ 40530 40531 getInterMixData: function(operation) { 40532 var self = this, 40533 target = null, 40534 i = -1; 40535 40536 self.callActions('beforeGetInterMixData', arguments); 40537 40538 for (i = 0; target = operation.show[i]; i++) { 40539 operation.showPosData[i].interPosData = target.getPosData(); 40540 } 40541 40542 for (i = 0; target = operation.toHide[i]; i++) { 40543 operation.toHidePosData[i].interPosData = target.getPosData(); 40544 } 40545 40546 self.callActions('afterGetInterMixData', arguments); 40547 }, 40548 40549 /** 40550 * @private 40551 * @instance 40552 * @since 2.0.0 40553 * @param {Operation} operation 40554 * @return {void} 40555 */ 40556 40557 setFinal: function(operation) { 40558 var self = this, 40559 target = null, 40560 i = -1; 40561 40562 self.callActions('beforeSetFinal', arguments); 40563 40564 operation.willSort && self.printSort(false, operation); 40565 40566 for (i = 0; target = operation.toHide[i]; i++) { 40567 target.hide(); 40568 } 40569 40570 self.callActions('afterSetFinal', arguments); 40571 }, 40572 40573 /** 40574 * @private 40575 * @instance 40576 * @since 2.0.0 40577 * @param {Operation} operation 40578 * @return {void} 40579 */ 40580 40581 getFinalMixData: function(operation) { 40582 var self = this, 40583 parentStyle = null, 40584 parentRect = null, 40585 target = null, 40586 i = -1; 40587 40588 self.callActions('beforeGetFinalMixData', arguments); 40589 40590 for (i = 0; target = operation.show[i]; i++) { 40591 operation.showPosData[i].finalPosData = target.getPosData(); 40592 } 40593 40594 for (i = 0; target = operation.toHide[i]; i++) { 40595 operation.toHidePosData[i].finalPosData = target.getPosData(); 40596 } 40597 40598 // Remove clamping 40599 40600 if (self.config.animation.clampHeight || self.config.animation.clampWidth) { 40601 self.dom.parent.style.height = 40602 self.dom.parent.style.width = 40603 self.dom.parent.style.overflow = ''; 40604 } 40605 40606 if (!self.incPadding) { 40607 parentStyle = window.getComputedStyle(self.dom.parent); 40608 } 40609 40610 parentRect = self.dom.parent.getBoundingClientRect(); 40611 40612 operation.newX = parentRect.left; 40613 operation.newY = parentRect.top; 40614 40615 operation.newHeight = self.incPadding ? 40616 parentRect.height : 40617 parentRect.height - 40618 parseFloat(parentStyle.paddingTop) - 40619 parseFloat(parentStyle.paddingBottom) - 40620 parseFloat(parentStyle.borderTop) - 40621 parseFloat(parentStyle.borderBottom); 40622 40623 operation.newWidth = self.incPadding ? 40624 parentRect.width : 40625 parentRect.width - 40626 parseFloat(parentStyle.paddingLeft) - 40627 parseFloat(parentStyle.paddingRight) - 40628 parseFloat(parentStyle.borderLeft) - 40629 parseFloat(parentStyle.borderRight); 40630 40631 operation.viewportDeltaX = operation.docState.viewportWidth - this.dom.document.documentElement.clientWidth; 40632 operation.viewportDeltaY = operation.docState.viewportHeight - this.dom.document.documentElement.clientHeight; 40633 40634 if (operation.willSort) { 40635 self.printSort(true, operation); 40636 } 40637 40638 for (i = 0; target = operation.toShow[i]; i++) { 40639 target.hide(); 40640 } 40641 40642 for (i = 0; target = operation.toHide[i]; i++) { 40643 target.show(); 40644 } 40645 40646 if (operation.willChangeLayout) { 40647 h.removeClass(self.dom.container, operation.newContainerClassName); 40648 h.addClass(self.dom.container, self.config.layout.containerClassName); 40649 } 40650 40651 self.callActions('afterGetFinalMixData', arguments); 40652 }, 40653 40654 /** 40655 * @private 40656 * @instance 40657 * @since 3.0.0 40658 * @param {Operation} operation 40659 */ 40660 40661 getTweenData: function(operation) { 40662 var self = this, 40663 target = null, 40664 posData = null, 40665 effectNames = Object.getOwnPropertyNames(self.effectsIn), 40666 effectName = '', 40667 effect = null, 40668 widthChange = -1, 40669 heightChange = -1, 40670 i = -1, 40671 j = -1; 40672 40673 self.callActions('beforeGetTweenData', arguments); 40674 40675 for (i = 0; target = operation.show[i]; i++) { 40676 posData = operation.showPosData[i]; 40677 posData.posIn = new mixitup.StyleData(); 40678 posData.posOut = new mixitup.StyleData(); 40679 posData.tweenData = new mixitup.StyleData(); 40680 40681 // Process x and y 40682 40683 if (target.isShown) { 40684 posData.posIn.x = posData.startPosData.x - posData.interPosData.x; 40685 posData.posIn.y = posData.startPosData.y - posData.interPosData.y; 40686 } else { 40687 posData.posIn.x = posData.posIn.y = 0; 40688 } 40689 40690 posData.posOut.x = posData.finalPosData.x - posData.interPosData.x; 40691 posData.posOut.y = posData.finalPosData.y - posData.interPosData.y; 40692 40693 // Process opacity 40694 40695 posData.posIn.opacity = target.isShown ? 1 : self.effectsIn.opacity; 40696 posData.posOut.opacity = 1; 40697 posData.tweenData.opacity = posData.posOut.opacity - posData.posIn.opacity; 40698 40699 // Adjust x and y if not nudging 40700 40701 if (!target.isShown && !self.config.animation.nudge) { 40702 posData.posIn.x = posData.posOut.x; 40703 posData.posIn.y = posData.posOut.y; 40704 } 40705 40706 posData.tweenData.x = posData.posOut.x - posData.posIn.x; 40707 posData.tweenData.y = posData.posOut.y - posData.posIn.y; 40708 40709 // Process width, height, and margins 40710 40711 if (self.config.animation.animateResizeTargets) { 40712 posData.posIn.width = posData.startPosData.width; 40713 posData.posIn.height = posData.startPosData.height; 40714 40715 // "||" Prevents width/height change from including 0 width/height if hiding or showing 40716 40717 widthChange = (posData.startPosData.width || posData.finalPosData.width) - posData.interPosData.width; 40718 40719 posData.posIn.marginRight = posData.startPosData.marginRight - widthChange; 40720 40721 heightChange = (posData.startPosData.height || posData.finalPosData.height) - posData.interPosData.height; 40722 40723 posData.posIn.marginBottom = posData.startPosData.marginBottom - heightChange; 40724 40725 posData.posOut.width = posData.finalPosData.width; 40726 posData.posOut.height = posData.finalPosData.height; 40727 40728 widthChange = (posData.finalPosData.width || posData.startPosData.width) - posData.interPosData.width; 40729 40730 posData.posOut.marginRight = posData.finalPosData.marginRight - widthChange; 40731 40732 heightChange = (posData.finalPosData.height || posData.startPosData.height) - posData.interPosData.height; 40733 40734 posData.posOut.marginBottom = posData.finalPosData.marginBottom - heightChange; 40735 40736 posData.tweenData.width = posData.posOut.width - posData.posIn.width; 40737 posData.tweenData.height = posData.posOut.height - posData.posIn.height; 40738 posData.tweenData.marginRight = posData.posOut.marginRight - posData.posIn.marginRight; 40739 posData.tweenData.marginBottom = posData.posOut.marginBottom - posData.posIn.marginBottom; 40740 } 40741 40742 // Process transforms 40743 40744 for (j = 0; effectName = effectNames[j]; j++) { 40745 effect = self.effectsIn[effectName]; 40746 40747 if (!(effect instanceof mixitup.TransformData) || !effect.value) continue; 40748 40749 posData.posIn[effectName].value = effect.value; 40750 posData.posOut[effectName].value = 0; 40751 40752 posData.tweenData[effectName].value = 40753 posData.posOut[effectName].value - posData.posIn[effectName].value; 40754 40755 posData.posIn[effectName].unit = 40756 posData.posOut[effectName].unit = 40757 posData.tweenData[effectName].unit = 40758 effect.unit; 40759 } 40760 } 40761 40762 for (i = 0; target = operation.toHide[i]; i++) { 40763 posData = operation.toHidePosData[i]; 40764 posData.posIn = new mixitup.StyleData(); 40765 posData.posOut = new mixitup.StyleData(); 40766 posData.tweenData = new mixitup.StyleData(); 40767 40768 // Process x and y 40769 40770 posData.posIn.x = target.isShown ? posData.startPosData.x - posData.interPosData.x : 0; 40771 posData.posIn.y = target.isShown ? posData.startPosData.y - posData.interPosData.y : 0; 40772 posData.posOut.x = self.config.animation.nudge ? 0 : posData.posIn.x; 40773 posData.posOut.y = self.config.animation.nudge ? 0 : posData.posIn.y; 40774 posData.tweenData.x = posData.posOut.x - posData.posIn.x; 40775 posData.tweenData.y = posData.posOut.y - posData.posIn.y; 40776 40777 // Process width, height, and margins 40778 40779 if (self.config.animation.animateResizeTargets) { 40780 posData.posIn.width = posData.startPosData.width; 40781 posData.posIn.height = posData.startPosData.height; 40782 40783 widthChange = posData.startPosData.width - posData.interPosData.width; 40784 40785 posData.posIn.marginRight = posData.startPosData.marginRight - widthChange; 40786 40787 heightChange = posData.startPosData.height - posData.interPosData.height; 40788 40789 posData.posIn.marginBottom = posData.startPosData.marginBottom - heightChange; 40790 } 40791 40792 // Process opacity 40793 40794 posData.posIn.opacity = 1; 40795 posData.posOut.opacity = self.effectsOut.opacity; 40796 posData.tweenData.opacity = posData.posOut.opacity - posData.posIn.opacity; 40797 40798 // Process transforms 40799 40800 for (j = 0; effectName = effectNames[j]; j++) { 40801 effect = self.effectsOut[effectName]; 40802 40803 if (!(effect instanceof mixitup.TransformData) || !effect.value) continue; 40804 40805 posData.posIn[effectName].value = 0; 40806 posData.posOut[effectName].value = effect.value; 40807 40808 posData.tweenData[effectName].value = 40809 posData.posOut[effectName].value - posData.posIn[effectName].value; 40810 40811 posData.posIn[effectName].unit = 40812 posData.posOut[effectName].unit = 40813 posData.tweenData[effectName].unit = 40814 effect.unit; 40815 } 40816 } 40817 40818 self.callActions('afterGetTweenData', arguments); 40819 }, 40820 40821 /** 40822 * @private 40823 * @instance 40824 * @since 3.0.0 40825 * @param {Operation} operation 40826 * @return {void} 40827 */ 40828 40829 moveTargets: function(operation) { 40830 var self = this, 40831 target = null, 40832 moveData = null, 40833 posData = null, 40834 statusChange = '', 40835 willTransition = false, 40836 staggerIndex = -1, 40837 i = -1, 40838 checkProgress = self.checkProgress.bind(self); 40839 40840 self.callActions('beforeMoveTargets', arguments); 40841 40842 // TODO: this is an extra loop in addition to the calcs 40843 // done in getOperation, could some of this be done there? 40844 40845 for (i = 0; target = operation.show[i]; i++) { 40846 moveData = new mixitup.IMoveData(); 40847 posData = operation.showPosData[i]; 40848 40849 statusChange = target.isShown ? 'none' : 'show'; 40850 40851 willTransition = self.willTransition( 40852 statusChange, 40853 operation.hasEffect, 40854 posData.posIn, 40855 posData.posOut 40856 ); 40857 40858 if (willTransition) { 40859 // Prevent non-transitioning targets from incrementing the staggerIndex 40860 40861 staggerIndex++; 40862 } 40863 40864 target.show(); 40865 40866 moveData.posIn = posData.posIn; 40867 moveData.posOut = posData.posOut; 40868 moveData.statusChange = statusChange; 40869 moveData.staggerIndex = staggerIndex; 40870 moveData.operation = operation; 40871 moveData.callback = willTransition ? checkProgress : null; 40872 40873 target.move(moveData); 40874 } 40875 40876 for (i = 0; target = operation.toHide[i]; i++) { 40877 posData = operation.toHidePosData[i]; 40878 moveData = new mixitup.IMoveData(); 40879 40880 statusChange = 'hide'; 40881 40882 willTransition = self.willTransition(statusChange, posData.posIn, posData.posOut); 40883 40884 moveData.posIn = posData.posIn; 40885 moveData.posOut = posData.posOut; 40886 moveData.statusChange = statusChange; 40887 moveData.staggerIndex = i; 40888 moveData.operation = operation; 40889 moveData.callback = willTransition ? checkProgress : null; 40890 40891 target.move(moveData); 40892 } 40893 40894 if (self.config.animation.animateResizeContainer) { 40895 self.dom.parent.style[mixitup.features.transitionProp] = 40896 'height ' + self.config.animation.duration + 'ms ease, ' + 40897 'width ' + self.config.animation.duration + 'ms ease '; 40898 40899 requestAnimationFrame(function() { 40900 if ( 40901 operation.startHeight !== operation.newHeight && 40902 operation.viewportDeltaY !== operation.startHeight - operation.newHeight 40903 ) { 40904 self.dom.parent.style.height = operation.newHeight + 'px'; 40905 } 40906 40907 if ( 40908 operation.startWidth !== operation.newWidth && 40909 operation.viewportDeltaX !== operation.startWidth - operation.newWidth 40910 ) { 40911 self.dom.parent.style.width = operation.newWidth + 'px'; 40912 } 40913 }); 40914 } 40915 40916 if (operation.willChangeLayout) { 40917 h.removeClass(self.dom.container, self.config.layout.ContainerClassName); 40918 h.addClass(self.dom.container, operation.newContainerClassName); 40919 } 40920 40921 self.callActions('afterMoveTargets', arguments); 40922 }, 40923 40924 /** 40925 * @private 40926 * @instance 40927 * @return {boolean} 40928 */ 40929 40930 hasEffect: function() { 40931 var self = this, 40932 EFFECTABLES = [ 40933 'scale', 40934 'translateX', 'translateY', 'translateZ', 40935 'rotateX', 'rotateY', 'rotateZ' 40936 ], 40937 effectName = '', 40938 effect = null, 40939 result = false, 40940 value = -1, 40941 i = -1; 40942 40943 if (self.effectsIn.opacity !== 1) { 40944 return self.callFilters('resultHasEffect', true, arguments); 40945 } 40946 40947 for (i = 0; effectName = EFFECTABLES[i]; i++) { 40948 effect = self.effectsIn[effectName]; 40949 value = (typeof effect && effect.value !== 'undefined') ? 40950 effect.value : effect; 40951 40952 if (value !== 0) { 40953 result = true; 40954 40955 break; 40956 } 40957 } 40958 40959 return self.callFilters('resultHasEffect', result, arguments); 40960 }, 40961 40962 /** 40963 * Determines if a target element will transition in 40964 * some fasion and therefore requires binding of 40965 * transitionEnd 40966 * 40967 * @private 40968 * @instance 40969 * @since 3.0.0 40970 * @param {string} statusChange 40971 * @param {boolean} hasEffect 40972 * @param {StyleData} posIn 40973 * @param {StyleData} posOut 40974 * @return {boolean} 40975 */ 40976 40977 willTransition: function(statusChange, hasEffect, posIn, posOut) { 40978 var self = this, 40979 result = false; 40980 40981 if (!h.isVisible(self.dom.container)) { 40982 // If the container is not visible, the transitionEnd 40983 // event will not occur and MixItUp will hang 40984 40985 result = false; 40986 } else if ( 40987 (statusChange !== 'none' && hasEffect) || 40988 posIn.x !== posOut.x || 40989 posIn.y !== posOut.y 40990 ) { 40991 // If opacity and/or translate will change 40992 40993 result = true; 40994 } else if (self.config.animation.animateResizeTargets) { 40995 // Check if width, height or margins will change 40996 40997 result = ( 40998 posIn.width !== posOut.width || 40999 posIn.height !== posOut.height || 41000 posIn.marginRight !== posOut.marginRight || 41001 posIn.marginTop !== posOut.marginTop 41002 ); 41003 } else { 41004 result = false; 41005 } 41006 41007 return self.callFilters('resultWillTransition', result, arguments); 41008 }, 41009 41010 /** 41011 * @private 41012 * @instance 41013 * @since 2.0.0 41014 * @param {Operation} operation 41015 * @return {void} 41016 */ 41017 41018 checkProgress: function(operation) { 41019 var self = this; 41020 41021 self.targetsDone++; 41022 41023 if (self.targetsBound === self.targetsDone) { 41024 self.cleanUp(operation); 41025 } 41026 }, 41027 41028 /** 41029 * @private 41030 * @instance 41031 * @since 2.0.0 41032 * @param {Operation} operation 41033 * @return {void} 41034 */ 41035 41036 cleanUp: function(operation) { 41037 var self = this, 41038 target = null, 41039 whitespaceBefore = null, 41040 whitespaceAfter = null, 41041 nextInQueue = null, 41042 i = -1; 41043 41044 self.callActions('beforeCleanUp', arguments); 41045 41046 self.targetsMoved = 41047 self.targetsImmovable = 41048 self.targetsBound = 41049 self.targetsDone = 0; 41050 41051 for (i = 0; target = operation.show[i]; i++) { 41052 target.cleanUp(); 41053 41054 target.show(); 41055 } 41056 41057 for (i = 0; target = operation.toHide[i]; i++) { 41058 target.cleanUp(); 41059 41060 target.hide(); 41061 } 41062 41063 if (operation.willSort) { 41064 self.printSort(false, operation); 41065 } 41066 41067 // Remove any styles applied to the parent container 41068 41069 self.dom.parent.style[mixitup.features.transitionProp] = 41070 self.dom.parent.style.height = 41071 self.dom.parent.style.width = 41072 self.dom.parent.style.overflow = 41073 self.dom.parent.style[mixitup.features.perspectiveProp] = 41074 self.dom.parent.style[mixitup.features.perspectiveOriginProp] = ''; 41075 41076 if (operation.willChangeLayout) { 41077 h.removeClass(self.dom.container, operation.startContainerClassName); 41078 h.addClass(self.dom.container, operation.newContainerClassName); 41079 } 41080 41081 if (operation.toRemove.length) { 41082 for (i = 0; target = self.targets[i]; i++) { 41083 if (operation.toRemove.indexOf(target) > -1) { 41084 if ( 41085 (whitespaceBefore = target.dom.el.previousSibling) && whitespaceBefore.nodeName === '#text' && 41086 (whitespaceAfter = target.dom.el.nextSibling) && whitespaceAfter.nodeName === '#text' 41087 ) { 41088 h.removeWhitespace(whitespaceBefore); 41089 } 41090 41091 if (!operation.willSort) { 41092 // NB: Sorting will remove targets as a bi-product of `printSort()` 41093 41094 self.dom.parent.removeChild(target.dom.el); 41095 } 41096 41097 self.targets.splice(i, 1); 41098 41099 target.isInDom = false; 41100 41101 i--; 41102 } 41103 } 41104 41105 // Since targets have been removed, the original order must be updated 41106 41107 self.origOrder = self.targets; 41108 } 41109 41110 if (operation.willSort) { 41111 self.targets = operation.newOrder; 41112 } 41113 41114 self.state = operation.newState; 41115 self.lastOperation = operation; 41116 41117 self.dom.targets = self.state.targets; 41118 41119 // mixEnd 41120 41121 mixitup.events.fire('mixEnd', self.dom.container, { 41122 state: self.state, 41123 instance: self 41124 }, self.dom.document); 41125 41126 if (typeof self.config.callbacks.onMixEnd === 'function') { 41127 self.config.callbacks.onMixEnd.call(self.dom.container, self.state, self); 41128 } 41129 41130 if (operation.hasFailed) { 41131 // mixFail 41132 41133 mixitup.events.fire('mixFail', self.dom.container, { 41134 state: self.state, 41135 instance: self 41136 }, self.dom.document); 41137 41138 if (typeof self.config.callbacks.onMixFail === 'function') { 41139 self.config.callbacks.onMixFail.call(self.dom.container, self.state, self); 41140 } 41141 41142 h.addClass(self.dom.container, h.getClassname(self.config.classNames, 'container', self.config.classNames.modifierFailed)); 41143 } 41144 41145 // User-defined callback function 41146 41147 if (typeof self.userCallback === 'function') { 41148 self.userCallback.call(self.dom.container, self.state, self); 41149 } 41150 41151 if (typeof self.userDeferred.resolve === 'function') { 41152 self.userDeferred.resolve(self.state); 41153 } 41154 41155 self.userCallback = null; 41156 self.userDeferred = null; 41157 self.lastClicked = null; 41158 self.isToggling = false; 41159 self.isBusy = false; 41160 41161 if (self.queue.length) { 41162 self.callActions('beforeReadQueueCleanUp', arguments); 41163 41164 nextInQueue = self.queue.shift(); 41165 41166 // Update non-public API properties stored in queue 41167 41168 self.userDeferred = nextInQueue.deferred; 41169 self.isToggling = nextInQueue.isToggling; 41170 self.lastClicked = nextInQueue.triggerElement; 41171 41172 if (nextInQueue.instruction.command instanceof mixitup.CommandMultimix) { 41173 self.multimix.apply(self, nextInQueue.args); 41174 } else { 41175 self.dataset.apply(self, nextInQueue.args); 41176 } 41177 } 41178 41179 self.callActions('afterCleanUp', arguments); 41180 }, 41181 41182 /** 41183 * @private 41184 * @instance 41185 * @since 2.0.0 41186 * @param {Array<*>} args 41187 * @return {mixitup.UserInstruction} 41188 */ 41189 41190 parseMultimixArgs: function(args) { 41191 var self = this, 41192 instruction = new mixitup.UserInstruction(), 41193 arg = null, 41194 i = -1; 41195 41196 instruction.animate = self.config.animation.enable; 41197 instruction.command = new mixitup.CommandMultimix(); 41198 41199 for (i = 0; i < args.length; i++) { 41200 arg = args[i]; 41201 41202 if (arg === null) continue; 41203 41204 if (typeof arg === 'object') { 41205 h.extend(instruction.command, arg); 41206 } else if (typeof arg === 'boolean') { 41207 instruction.animate = arg; 41208 } else if (typeof arg === 'function') { 41209 instruction.callback = arg; 41210 } 41211 } 41212 41213 // Coerce arbitrary command arguments into typed command objects 41214 41215 if (instruction.command.insert && !(instruction.command.insert instanceof mixitup.CommandInsert)) { 41216 instruction.command.insert = self.parseInsertArgs([instruction.command.insert]).command; 41217 } 41218 41219 if (instruction.command.remove && !(instruction.command.remove instanceof mixitup.CommandRemove)) { 41220 instruction.command.remove = self.parseRemoveArgs([instruction.command.remove]).command; 41221 } 41222 41223 if (instruction.command.filter && !(instruction.command.filter instanceof mixitup.CommandFilter)) { 41224 instruction.command.filter = self.parseFilterArgs([instruction.command.filter]).command; 41225 } 41226 41227 if (instruction.command.sort && !(instruction.command.sort instanceof mixitup.CommandSort)) { 41228 instruction.command.sort = self.parseSortArgs([instruction.command.sort]).command; 41229 } 41230 41231 if (instruction.command.changeLayout && !(instruction.command.changeLayout instanceof mixitup.CommandChangeLayout)) { 41232 instruction.command.changeLayout = self.parseChangeLayoutArgs([instruction.command.changeLayout]).command; 41233 } 41234 41235 instruction = self.callFilters('instructionParseMultimixArgs', instruction, arguments); 41236 41237 h.freeze(instruction); 41238 41239 return instruction; 41240 }, 41241 41242 /** 41243 * @private 41244 * @instance 41245 * @since 2.0.0 41246 * @param {Array<*>} args 41247 * @return {mixitup.UserInstruction} 41248 */ 41249 41250 parseFilterArgs: function(args) { 41251 var self = this, 41252 instruction = new mixitup.UserInstruction(), 41253 arg = null, 41254 i = -1; 41255 41256 instruction.animate = self.config.animation.enable; 41257 instruction.command = new mixitup.CommandFilter(); 41258 41259 for (i = 0; i < args.length; i++) { 41260 arg = args[i]; 41261 41262 if (typeof arg === 'string') { 41263 // Selector 41264 41265 instruction.command.selector = arg; 41266 } else if (arg === null) { 41267 instruction.command.collection = []; 41268 } else if (typeof arg === 'object' && h.isElement(arg, self.dom.document)) { 41269 // Single element 41270 41271 instruction.command.collection = [arg]; 41272 } else if (typeof arg === 'object' && typeof arg.length !== 'undefined') { 41273 // Multiple elements in array, NodeList or jQuery collection 41274 41275 instruction.command.collection = h.arrayFromList(arg); 41276 } else if (typeof arg === 'object') { 41277 // Filter command 41278 41279 h.extend(instruction.command, arg); 41280 } else if (typeof arg === 'boolean') { 41281 instruction.animate = arg; 41282 } else if (typeof arg === 'function') { 41283 instruction.callback = arg; 41284 } 41285 } 41286 41287 if (instruction.command.selector && instruction.command.collection) { 41288 throw new Error(mixitup.messages.errorFilterInvalidArguments()); 41289 } 41290 41291 instruction = self.callFilters('instructionParseFilterArgs', instruction, arguments); 41292 41293 h.freeze(instruction); 41294 41295 return instruction; 41296 }, 41297 41298 parseSortArgs: function(args) { 41299 var self = this, 41300 instruction = new mixitup.UserInstruction(), 41301 arg = null, 41302 sortString = '', 41303 i = -1; 41304 41305 instruction.animate = self.config.animation.enable; 41306 instruction.command = new mixitup.CommandSort(); 41307 41308 for (i = 0; i < args.length; i++) { 41309 arg = args[i]; 41310 41311 if (arg === null) continue; 41312 41313 switch (typeof arg) { 41314 case 'string': 41315 // Sort string 41316 41317 sortString = arg; 41318 41319 break; 41320 case 'object': 41321 // Array of element references 41322 41323 if (arg.length) { 41324 instruction.command.collection = h.arrayFromList(arg); 41325 } 41326 41327 break; 41328 case 'boolean': 41329 instruction.animate = arg; 41330 41331 break; 41332 case 'function': 41333 instruction.callback = arg; 41334 41335 break; 41336 } 41337 } 41338 41339 if (sortString) { 41340 instruction.command = self.parseSortString(sortString, instruction.command); 41341 } 41342 41343 instruction = self.callFilters('instructionParseSortArgs', instruction, arguments); 41344 41345 h.freeze(instruction); 41346 41347 return instruction; 41348 }, 41349 41350 /** 41351 * @private 41352 * @instance 41353 * @since 2.0.0 41354 * @param {Array<*>} args 41355 * @return {mixitup.UserInstruction} 41356 */ 41357 41358 parseInsertArgs: function(args) { 41359 var self = this, 41360 instruction = new mixitup.UserInstruction(), 41361 arg = null, 41362 i = -1; 41363 41364 instruction.animate = self.config.animation.enable; 41365 instruction.command = new mixitup.CommandInsert(); 41366 41367 for (i = 0; i < args.length; i++) { 41368 arg = args[i]; 41369 41370 if (arg === null) continue; 41371 41372 if (typeof arg === 'number') { 41373 // Insert index 41374 41375 instruction.command.index = arg; 41376 } else if (typeof arg === 'string' && ['before', 'after'].indexOf(arg) > -1) { 41377 // 'before'/'after' 41378 41379 instruction.command.position = arg; 41380 } else if (typeof arg === 'string') { 41381 // Markup 41382 41383 instruction.command.collection = 41384 h.arrayFromList(h.createElement(arg).childNodes); 41385 } else if (typeof arg === 'object' && h.isElement(arg, self.dom.document)) { 41386 // Single element 41387 41388 !instruction.command.collection.length ? 41389 (instruction.command.collection = [arg]) : 41390 (instruction.command.sibling = arg); 41391 } else if (typeof arg === 'object' && arg.length) { 41392 // Multiple elements in array or jQuery collection 41393 41394 !instruction.command.collection.length ? 41395 (instruction.command.collection = arg) : 41396 instruction.command.sibling = arg[0]; 41397 } else if (typeof arg === 'object' && arg.childNodes && arg.childNodes.length) { 41398 // Document fragment 41399 41400 !instruction.command.collection.length ? 41401 instruction.command.collection = h.arrayFromList(arg.childNodes) : 41402 instruction.command.sibling = arg.childNodes[0]; 41403 } else if (typeof arg === 'object') { 41404 // Insert command 41405 41406 h.extend(instruction.command, arg); 41407 } else if (typeof arg === 'boolean') { 41408 instruction.animate = arg; 41409 } else if (typeof arg === 'function') { 41410 instruction.callback = arg; 41411 } 41412 } 41413 41414 if (instruction.command.index && instruction.command.sibling) { 41415 throw new Error(mixitup.messages.errorInsertInvalidArguments()); 41416 } 41417 41418 if (!instruction.command.collection.length && self.config.debug.showWarnings) { 41419 console.warn(mixitup.messages.warningInsertNoElements()); 41420 } 41421 41422 instruction = self.callFilters('instructionParseInsertArgs', instruction, arguments); 41423 41424 h.freeze(instruction); 41425 41426 return instruction; 41427 }, 41428 41429 /** 41430 * @private 41431 * @instance 41432 * @since 3.0.0 41433 * @param {Array<*>} args 41434 * @return {mixitup.UserInstruction} 41435 */ 41436 41437 parseRemoveArgs: function(args) { 41438 var self = this, 41439 instruction = new mixitup.UserInstruction(), 41440 target = null, 41441 arg = null, 41442 i = -1; 41443 41444 instruction.animate = self.config.animation.enable; 41445 instruction.command = new mixitup.CommandRemove(); 41446 41447 for (i = 0; i < args.length; i++) { 41448 arg = args[i]; 41449 41450 if (arg === null) continue; 41451 41452 switch (typeof arg) { 41453 case 'number': 41454 if (self.targets[arg]) { 41455 instruction.command.targets[0] = self.targets[arg]; 41456 } 41457 41458 break; 41459 case 'string': 41460 instruction.command.collection = h.arrayFromList(self.dom.parent.querySelectorAll(arg)); 41461 41462 break; 41463 case 'object': 41464 if (arg && arg.length) { 41465 instruction.command.collection = arg; 41466 } else if (h.isElement(arg, self.dom.document)) { 41467 instruction.command.collection = [arg]; 41468 } else { 41469 // Remove command 41470 41471 h.extend(instruction.command, arg); 41472 } 41473 41474 break; 41475 case 'boolean': 41476 instruction.animate = arg; 41477 41478 break; 41479 case 'function': 41480 instruction.callback = arg; 41481 41482 break; 41483 } 41484 } 41485 41486 if (instruction.command.collection.length) { 41487 for (i = 0; target = self.targets[i]; i++) { 41488 if (instruction.command.collection.indexOf(target.dom.el) > -1) { 41489 instruction.command.targets.push(target); 41490 } 41491 } 41492 } 41493 41494 if (!instruction.command.targets.length && self.config.debug.showWarnings) { 41495 console.warn(mixitup.messages.warningRemoveNoElements()); 41496 } 41497 41498 h.freeze(instruction); 41499 41500 return instruction; 41501 }, 41502 41503 /** 41504 * @private 41505 * @instance 41506 * @since 3.0.0 41507 * @param {Array<*>} args 41508 * @return {mixitup.UserInstruction} 41509 */ 41510 41511 parseDatasetArgs: function(args) { 41512 var self = this, 41513 instruction = new mixitup.UserInstruction(), 41514 arg = null, 41515 i = -1; 41516 41517 instruction.animate = self.config.animation.enable; 41518 instruction.command = new mixitup.CommandDataset(); 41519 41520 for (i = 0; i < args.length; i++) { 41521 arg = args[i]; 41522 41523 if (arg === null) continue; 41524 41525 switch (typeof arg) { 41526 case 'object': 41527 if (Array.isArray(arg) || typeof arg.length === 'number') { 41528 instruction.command.dataset = arg; 41529 } else { 41530 // Change layout command 41531 41532 h.extend(instruction.command, arg); 41533 } 41534 41535 break; 41536 case 'boolean': 41537 instruction.animate = arg; 41538 41539 break; 41540 case 'function': 41541 instruction.callback = arg; 41542 41543 break; 41544 } 41545 } 41546 41547 h.freeze(instruction); 41548 41549 return instruction; 41550 }, 41551 41552 /** 41553 * @private 41554 * @instance 41555 * @since 3.0.0 41556 * @param {Array<*>} args 41557 * @return {mixitup.UserInstruction} 41558 */ 41559 41560 parseChangeLayoutArgs: function(args) { 41561 var self = this, 41562 instruction = new mixitup.UserInstruction(), 41563 arg = null, 41564 i = -1; 41565 41566 instruction.animate = self.config.animation.enable; 41567 instruction.command = new mixitup.CommandChangeLayout(); 41568 41569 for (i = 0; i < args.length; i++) { 41570 arg = args[i]; 41571 41572 if (arg === null) continue; 41573 41574 switch (typeof arg) { 41575 case 'string': 41576 instruction.command.containerClassName = arg; 41577 41578 break; 41579 case 'object': 41580 // Change layout command 41581 41582 h.extend(instruction.command, arg); 41583 41584 break; 41585 case 'boolean': 41586 instruction.animate = arg; 41587 41588 break; 41589 case 'function': 41590 instruction.callback = arg; 41591 41592 break; 41593 } 41594 } 41595 41596 h.freeze(instruction); 41597 41598 return instruction; 41599 }, 41600 41601 /** 41602 * @private 41603 * @instance 41604 * @since 3.0.0 41605 * @param {mixitup.QueueItem} queueItem 41606 * @return {Promise.<mixitup.State>} 41607 */ 41608 41609 queueMix: function(queueItem) { 41610 var self = this, 41611 deferred = null, 41612 toggleSelector = ''; 41613 41614 self.callActions('beforeQueueMix', arguments); 41615 41616 deferred = h.defer(mixitup.libraries); 41617 41618 if (self.config.animation.queue && self.queue.length < self.config.animation.queueLimit) { 41619 queueItem.deferred = deferred; 41620 41621 self.queue.push(queueItem); 41622 41623 // Keep controls in sync with user interactions. Mixer will catch up as it drains the queue. 41624 41625 if (self.config.controls.enable) { 41626 if (self.isToggling) { 41627 self.buildToggleArray(queueItem.instruction.command); 41628 41629 toggleSelector = self.getToggleSelector(); 41630 41631 self.updateControls({ 41632 filter: { 41633 selector: toggleSelector 41634 } 41635 }); 41636 } else { 41637 self.updateControls(queueItem.instruction.command); 41638 } 41639 } 41640 } else { 41641 if (self.config.debug.showWarnings) { 41642 console.warn(mixitup.messages.warningMultimixInstanceQueueFull()); 41643 } 41644 41645 deferred.resolve(self.state); 41646 41647 mixitup.events.fire('mixBusy', self.dom.container, { 41648 state: self.state, 41649 instance: self 41650 }, self.dom.document); 41651 41652 if (typeof self.config.callbacks.onMixBusy === 'function') { 41653 self.config.callbacks.onMixBusy.call(self.dom.container, self.state, self); 41654 } 41655 } 41656 41657 return self.callFilters('promiseQueueMix', deferred.promise, arguments); 41658 }, 41659 41660 /** 41661 * @private 41662 * @instance 41663 * @since 3.0.0 41664 * @param {Array.<object>} newDataset 41665 * @return {Operation} 41666 */ 41667 41668 getDataOperation: function(newDataset) { 41669 var self = this, 41670 operation = new mixitup.Operation(), 41671 startDataset = []; 41672 41673 operation = self.callFilters('operationUnmappedGetDataOperation', operation, arguments); 41674 41675 if (self.dom.targets.length && !(startDataset = (self.state.activeDataset || [])).length) { 41676 throw new Error(mixitup.messages.errorDatasetNotSet()); 41677 } 41678 41679 operation.id = h.randomHex(); 41680 operation.startState = self.state; 41681 operation.startDataset = startDataset; 41682 operation.newDataset = newDataset.slice(); 41683 41684 self.diffDatasets(operation); 41685 41686 operation.startOrder = self.targets; 41687 operation.newOrder = operation.show; 41688 41689 if (self.config.animation.enable) { 41690 self.getStartMixData(operation); 41691 self.setInter(operation); 41692 41693 operation.docState = h.getDocumentState(self.dom.document); 41694 41695 self.getInterMixData(operation); 41696 self.setFinal(operation); 41697 self.getFinalMixData(operation); 41698 41699 self.parseEffects(); 41700 41701 operation.hasEffect = self.hasEffect(); 41702 41703 self.getTweenData(operation); 41704 } 41705 41706 self.targets = operation.show.slice(); 41707 41708 operation.newState = self.buildState(operation); 41709 41710 // NB: Targets to be removed must be included in `self.targets` for removal during clean up, 41711 // but are added after state is built so that state is accurate 41712 41713 Array.prototype.push.apply(self.targets, operation.toRemove); 41714 41715 operation = self.callFilters('operationMappedGetDataOperation', operation, arguments); 41716 41717 return operation; 41718 }, 41719 41720 /** 41721 * @private 41722 * @instance 41723 * @since 3.0.0 41724 * @param {mixitup.Operation} operation 41725 * @return {void} 41726 */ 41727 41728 diffDatasets: function(operation) { 41729 var self = this, 41730 persistantStartIds = [], 41731 persistantNewIds = [], 41732 insertedTargets = [], 41733 data = null, 41734 target = null, 41735 el = null, 41736 frag = null, 41737 nextEl = null, 41738 uids = {}, 41739 id = '', 41740 i = -1; 41741 41742 self.callActions('beforeDiffDatasets', arguments); 41743 41744 for (i = 0; data = operation.newDataset[i]; i++) { 41745 if (typeof (id = data[self.config.data.uidKey]) === 'undefined' || id.toString().length < 1) { 41746 throw new TypeError(mixitup.messages.errorDatasetInvalidUidKey({ 41747 uidKey: self.config.data.uidKey 41748 })); 41749 } 41750 41751 if (!uids[id]) { 41752 uids[id] = true; 41753 } else { 41754 throw new Error(mixitup.messages.errorDatasetDuplicateUid({ 41755 uid: id 41756 })); 41757 } 41758 41759 if ((target = self.cache[id]) instanceof mixitup.Target) { 41760 // Already in cache 41761 41762 if (self.config.data.dirtyCheck && !h.deepEquals(data, target.data)) { 41763 // change detected 41764 41765 el = target.render(data); 41766 41767 target.data = data; 41768 41769 if (el !== target.dom.el) { 41770 // Update target element reference 41771 41772 if (target.isInDom) { 41773 target.unbindEvents(); 41774 41775 self.dom.parent.replaceChild(el, target.dom.el); 41776 } 41777 41778 if (!target.isShown) { 41779 el.style.display = 'none'; 41780 } 41781 41782 target.dom.el = el; 41783 41784 if (target.isInDom) { 41785 target.bindEvents(); 41786 } 41787 } 41788 } 41789 41790 el = target.dom.el; 41791 } else { 41792 // New target 41793 41794 target = new mixitup.Target(); 41795 41796 target.init(null, self, data); 41797 41798 target.hide(); 41799 } 41800 41801 if (!target.isInDom) { 41802 // Adding to DOM 41803 41804 if (!frag) { 41805 // Open frag 41806 41807 frag = self.dom.document.createDocumentFragment(); 41808 } 41809 41810 if (frag.lastElementChild) { 41811 frag.appendChild(self.dom.document.createTextNode(' ')); 41812 } 41813 41814 frag.appendChild(target.dom.el); 41815 41816 target.isInDom = true; 41817 41818 target.unbindEvents(); 41819 target.bindEvents(); 41820 target.hide(); 41821 41822 operation.toShow.push(target); 41823 41824 insertedTargets.push(target); 41825 } else { 41826 // Already in DOM 41827 41828 nextEl = target.dom.el.nextElementSibling; 41829 41830 persistantNewIds.push(id); 41831 41832 if (frag) { 41833 // Close and insert previously opened frag 41834 41835 if (frag.lastElementChild) { 41836 frag.appendChild(self.dom.document.createTextNode(' ')); 41837 } 41838 41839 self.insertDatasetFrag(frag, target.dom.el, insertedTargets); 41840 41841 frag = null; 41842 } 41843 } 41844 41845 operation.show.push(target); 41846 } 41847 41848 if (frag) { 41849 // Unclosed frag remaining 41850 41851 nextEl = nextEl || self.config.layout.siblingAfter; 41852 41853 if (nextEl) { 41854 frag.appendChild(self.dom.document.createTextNode(' ')); 41855 } 41856 41857 self.insertDatasetFrag(frag, nextEl, insertedTargets); 41858 } 41859 41860 for (i = 0; data = operation.startDataset[i]; i++) { 41861 id = data[self.config.data.uidKey]; 41862 41863 target = self.cache[id]; 41864 41865 if (operation.show.indexOf(target) < 0) { 41866 // Previously shown but now absent 41867 41868 operation.hide.push(target); 41869 operation.toHide.push(target); 41870 operation.toRemove.push(target); 41871 } else { 41872 persistantStartIds.push(id); 41873 } 41874 } 41875 41876 if (!h.isEqualArray(persistantStartIds, persistantNewIds)) { 41877 operation.willSort = true; 41878 } 41879 41880 self.callActions('afterDiffDatasets', arguments); 41881 }, 41882 41883 /** 41884 * @private 41885 * @instance 41886 * @since 3.1.5 41887 * @param {DocumentFragment} frag 41888 * @param {(HTMLElement|null)} nextEl 41889 * @param {Array.<mixitup.Target>} targets 41890 * @return {void} 41891 */ 41892 41893 insertDatasetFrag: function(frag, nextEl, targets) { 41894 var self = this; 41895 var insertAt = nextEl ? h.arrayFromList(self.dom.parent.children).indexOf(nextEl) : self.targets.length; 41896 41897 self.dom.parent.insertBefore(frag, nextEl); 41898 41899 while (targets.length) { 41900 self.targets.splice(insertAt, 0, targets.shift()); 41901 41902 insertAt++; 41903 } 41904 }, 41905 41906 /** 41907 * @private 41908 * @instance 41909 * @since 3.0.0 41910 * @param {mixitup.CommandSort} sortCommandA 41911 * @param {mixitup.CommandSort} sortCommandB 41912 * @return {boolean} 41913 */ 41914 41915 willSort: function(sortCommandA, sortCommandB) { 41916 var self = this, 41917 result = false; 41918 41919 if ( 41920 self.config.behavior.liveSort || 41921 sortCommandA.order === 'random' || 41922 sortCommandA.attribute !== sortCommandB.attribute || 41923 sortCommandA.order !== sortCommandB.order || 41924 sortCommandA.collection !== sortCommandB.collection || 41925 (sortCommandA.next === null && sortCommandB.next) || 41926 (sortCommandA.next && sortCommandB.next === null) 41927 ) { 41928 result = true; 41929 } else if (sortCommandA.next && sortCommandB.next) { 41930 result = self.willSort(sortCommandA.next, sortCommandB.next); 41931 } else { 41932 result = false; 41933 } 41934 41935 return self.callFilters('resultWillSort', result, arguments); 41936 }, 41937 41938 /** 41939 * A shorthand method for `.filter('all')`. Shows all targets in the container. 41940 * 41941 * @example 41942 * 41943 * .show() 41944 * 41945 * @example <caption>Example: Showing all targets</caption> 41946 * 41947 * mixer.show() 41948 * .then(function(state) { 41949 * console.log(state.totalShow === state.totalTargets); // true 41950 * }); 41951 * 41952 * @public 41953 * @instance 41954 * @since 3.0.0 41955 * @return {Promise.<mixitup.State>} 41956 */ 41957 41958 show: function() { 41959 var self = this; 41960 41961 return self.filter('all'); 41962 }, 41963 41964 /** 41965 * A shorthand method for `.filter('none')`. Hides all targets in the container. 41966 * 41967 * @example 41968 * 41969 * .hide() 41970 * 41971 * @example <caption>Example: Hiding all targets</caption> 41972 * 41973 * mixer.hide() 41974 * .then(function(state) { 41975 * console.log(state.totalShow === 0); // true 41976 * console.log(state.totalHide === state.totalTargets); // true 41977 * }); 41978 * 41979 * @public 41980 * @instance 41981 * @since 3.0.0 41982 * @return {Promise.<mixitup.State>} 41983 */ 41984 41985 hide: function() { 41986 var self = this; 41987 41988 return self.filter('none'); 41989 }, 41990 41991 /** 41992 * Returns a boolean indicating whether or not a MixItUp operation is 41993 * currently in progress. 41994 * 41995 * @example 41996 * 41997 * .isMixing() 41998 * 41999 * @example <caption>Example: Checking the status of a mixer</caption> 42000 * 42001 * mixer.sort('random', function() { 42002 * console.log(mixer.isMixing()) // false 42003 * }); 42004 * 42005 * console.log(mixer.isMixing()) // true 42006 * 42007 * @public 42008 * @instance 42009 * @since 2.0.0 42010 * @return {boolean} 42011 */ 42012 42013 isMixing: function() { 42014 var self = this; 42015 42016 return self.isBusy; 42017 }, 42018 42019 /** 42020 * Filters all targets in the container by a provided selector string, or the values `'all'` 42021 * or `'none'`. Only targets matching the selector will be shown. 42022 * 42023 * @example 42024 * 42025 * .filter(selector [, animate] [, callback]) 42026 * 42027 * @example <caption>Example 1: Filtering targets by a class selector</caption> 42028 * 42029 * mixer.filter('.category-a') 42030 * .then(function(state) { 42031 * console.log(state.totalShow === containerEl.querySelectorAll('.category-a').length); // true 42032 * }); 42033 * 42034 * @example <caption>Example 2: Filtering targets by an attribute selector</caption> 42035 * 42036 * mixer.filter('[data-category~="a"]') 42037 * .then(function(state) { 42038 * console.log(state.totalShow === containerEl.querySelectorAll('[data-category~="a"]').length); // true 42039 * }); 42040 * 42041 * @example <caption>Example 3: Filtering targets by a compound selector</caption> 42042 * 42043 * // Show only those targets with the classes 'category-a' AND 'category-b' 42044 * 42045 * mixer.filter('.category-a.category-c') 42046 * .then(function(state) { 42047 * console.log(state.totalShow === containerEl.querySelectorAll('.category-a.category-c').length); // true 42048 * }); 42049 * 42050 * @example <caption>Example 4: Filtering via an element collection</caption> 42051 * 42052 * var collection = Array.from(container.querySelectorAll('.mix')); 42053 * 42054 * console.log(collection.length); // 34 42055 * 42056 * // Filter the collection manually using Array.prototype.filter 42057 * 42058 * var filtered = collection.filter(function(target) { 42059 * return parseInt(target.getAttribute('data-price')) > 10; 42060 * }); 42061 * 42062 * console.log(filtered.length); // 22 42063 * 42064 * // Pass the filtered collection to MixItUp 42065 * 42066 * mixer.filter(filtered) 42067 * .then(function(state) { 42068 * console.log(state.activeFilter.collection.length === 22); // true 42069 * }); 42070 * 42071 * @public 42072 * @instance 42073 * @since 2.0.0 42074 * @param {(string|HTMLElement|Array.<HTMLElement>)} selector 42075 * Any valid CSS selector (i.e. `'.category-a'`), or the values `'all'` or `'none'`. The filter method also accepts a reference to single target element or a collection of target elements to show. 42076 * @param {boolean} [animate=true] 42077 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42078 * @param {function} [callback=null] 42079 * An optional callback function to be invoked after the operation has completed. 42080 * @return {Promise.<mixitup.State>} 42081 * A promise resolving with the current state object. 42082 */ 42083 42084 filter: function() { 42085 var self = this, 42086 instruction = self.parseFilterArgs(arguments); 42087 42088 return self.multimix({ 42089 filter: instruction.command 42090 }, instruction.animate, instruction.callback); 42091 }, 42092 42093 /** 42094 * Adds an additional selector to the currently active filter selector, concatenating 42095 * as per the logic defined in `controls.toggleLogic`. 42096 * 42097 * @example 42098 * 42099 * .toggleOn(selector [, animate] [, callback]) 42100 * 42101 * @example <caption>Example: Toggling on a filter selector</caption> 42102 * 42103 * console.log(mixer.getState().activeFilter.selector); // '.category-a' 42104 * 42105 * mixer.toggleOn('.category-b') 42106 * .then(function(state) { 42107 * console.log(state.activeFilter.selector); // '.category-a, .category-b' 42108 * }); 42109 * 42110 * @public 42111 * @instance 42112 * @since 3.0.0 42113 * @param {string} selector 42114 * Any valid CSS selector (i.e. `'.category-a'`) 42115 * @param {boolean} [animate=true] 42116 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42117 * @param {function} [callback=null] 42118 * An optional callback function to be invoked after the operation has completed. 42119 * @return {Promise.<mixitup.State>} 42120 * A promise resolving with the current state object. 42121 */ 42122 42123 toggleOn: function() { 42124 var self = this, 42125 instruction = self.parseFilterArgs(arguments), 42126 selector = instruction.command.selector, 42127 toggleSelector = ''; 42128 42129 self.isToggling = true; 42130 42131 if (self.toggleArray.indexOf(selector) < 0) { 42132 self.toggleArray.push(selector); 42133 } 42134 42135 toggleSelector = self.getToggleSelector(); 42136 42137 return self.multimix({ 42138 filter: toggleSelector 42139 }, instruction.animate, instruction.callback); 42140 }, 42141 42142 /** 42143 * Removes a selector from the active filter selector. 42144 * 42145 * @example 42146 * 42147 * .toggleOff(selector [, animate] [, callback]) 42148 * 42149 * @example <caption>Example: Toggling off a filter selector</caption> 42150 * 42151 * console.log(mixer.getState().activeFilter.selector); // '.category-a, .category-b' 42152 * 42153 * mixer.toggleOff('.category-b') 42154 * .then(function(state) { 42155 * console.log(state.activeFilter.selector); // '.category-a' 42156 * }); 42157 * 42158 * @public 42159 * @instance 42160 * @since 3.0.0 42161 * @param {string} selector 42162 * Any valid CSS selector (i.e. `'.category-a'`) 42163 * @param {boolean} [animate=true] 42164 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42165 * @param {function} [callback=null] 42166 * An optional callback function to be invoked after the operation has completed. 42167 * @return {Promise.<mixitup.State>} 42168 * A promise resolving with the current state object. 42169 */ 42170 42171 toggleOff: function() { 42172 var self = this, 42173 instruction = self.parseFilterArgs(arguments), 42174 selector = instruction.command.selector, 42175 selectorIndex = self.toggleArray.indexOf(selector), 42176 toggleSelector = ''; 42177 42178 self.isToggling = true; 42179 42180 if (selectorIndex > -1) { 42181 self.toggleArray.splice(selectorIndex, 1); 42182 } 42183 42184 toggleSelector = self.getToggleSelector(); 42185 42186 return self.multimix({ 42187 filter: toggleSelector 42188 }, instruction.animate, instruction.callback); 42189 }, 42190 42191 /** 42192 * Sorts all targets in the container according to a provided sort string. 42193 * 42194 * @example 42195 * 42196 * .sort(sortString [, animate] [, callback]) 42197 * 42198 * @example <caption>Example 1: Sorting by the default DOM order</caption> 42199 * 42200 * // Reverse the default order of the targets 42201 * 42202 * mixer.sort('default:desc') 42203 * .then(function(state) { 42204 * console.log(state.activeSort.attribute === 'default'); // true 42205 * console.log(state.activeSort.order === 'desc'); // true 42206 * }); 42207 * 42208 * @example <caption>Example 2: Sorting by a custom data-attribute</caption> 42209 * 42210 * // Sort the targets by the value of a `data-published-date` attribute 42211 * 42212 * mixer.sort('published-date:asc') 42213 * .then(function(state) { 42214 * console.log(state.activeSort.attribute === 'published-date'); // true 42215 * console.log(state.activeSort.order === 'asc'); // true 42216 * }); 42217 * 42218 * @example <caption>Example 3: Sorting by multiple attributes</caption> 42219 * 42220 * // Sort the targets by the value of a `data-published-date` attribute, then by `data-title` 42221 * 42222 * mixer.sort('published-date:desc data-title:asc') 42223 * .then(function(state) { 42224 * console.log(state.activeSort.attribute === 'published-date'); // true 42225 * console.log(state.activeSort.order === 'desc'); // true 42226 * 42227 * console.log(state.activeSort.next.attribute === 'title'); // true 42228 * console.log(state.activeSort.next.order === 'asc'); // true 42229 * }); 42230 * 42231 * @example <caption>Example 4: Sorting by random</caption> 42232 * 42233 * mixer.sort('random') 42234 * .then(function(state) { 42235 * console.log(state.activeSort.order === 'random') // true 42236 * }); 42237 * 42238 * @example <caption>Example 5: Sorting via an element collection</caption> 42239 * 42240 * var collection = Array.from(container.querySelectorAll('.mix')); 42241 * 42242 * // Swap the position of two elements in the collection: 42243 * 42244 * var temp = collection[1]; 42245 * 42246 * collection[1] = collection[0]; 42247 * collection[0] = temp; 42248 * 42249 * // Pass the sorted collection to MixItUp 42250 * 42251 * mixer.sort(collection) 42252 * .then(function(state) { 42253 * console.log(state.targets[0] === collection[0]); // true 42254 * }); 42255 * 42256 * @public 42257 * @instance 42258 * @since 2.0.0 42259 * @param {(string|Array.<HTMLElement>)} sortString 42260 * A valid sort string (e.g. `'default'`, `'published-date:asc'`, or `'random'`). The sort method also accepts an array of all target elements in a user-defined order. 42261 * @param {boolean} [animate=true] 42262 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42263 * @param {function} [callback=null] 42264 * An optional callback function to be invoked after the operation has completed. 42265 * @return {Promise.<mixitup.State>} 42266 * A promise resolving with the current state object. 42267 */ 42268 42269 sort: function() { 42270 var self = this, 42271 instruction = self.parseSortArgs(arguments); 42272 42273 return self.multimix({ 42274 sort: instruction.command 42275 }, instruction.animate, instruction.callback); 42276 }, 42277 42278 /** 42279 * Changes the layout of the container by adding, removing or updating a 42280 * layout-specific class name. If `animation.animateResizetargets` is 42281 * enabled, MixItUp will attempt to gracefully animate the width, height, 42282 * and position of targets between layout states. 42283 * 42284 * @example 42285 * 42286 * .changeLayout(containerClassName [, animate] [, callback]) 42287 * 42288 * @example <caption>Example 1: Adding a new class name to the container</caption> 42289 * 42290 * mixer.changeLayout('container-list') 42291 * .then(function(state) { 42292 * console.log(state.activeContainerClass === 'container-list'); // true 42293 * }); 42294 * 42295 * @example <caption>Example 2: Removing a previously added class name from the container</caption> 42296 * 42297 * mixer.changeLayout('') 42298 * .then(function(state) { 42299 * console.log(state.activeContainerClass === ''); // true 42300 * }); 42301 * 42302 * @public 42303 * @instance 42304 * @since 2.0.0 42305 * @param {string} containerClassName 42306 * A layout-specific class name to add to the container. 42307 * @param {boolean} [animate=true] 42308 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42309 * @param {function} [callback=null] 42310 * An optional callback function to be invoked after the operation has completed. 42311 * @return {Promise.<mixitup.State>} 42312 * A promise resolving with the current state object. 42313 */ 42314 42315 changeLayout: function() { 42316 var self = this, 42317 instruction = self.parseChangeLayoutArgs(arguments); 42318 42319 return self.multimix({ 42320 changeLayout: instruction.command 42321 }, instruction.animate, instruction.callback); 42322 }, 42323 42324 /** 42325 * Updates the contents and order of the container to reflect the provided dataset, 42326 * if the dataset API is in use. 42327 * 42328 * The dataset API is designed for use in API-driven JavaScript applications, and 42329 * can be used instead of DOM-based methods such as `.filter()`, `.sort()`, 42330 * `.insert()`, etc. When used, insertion, removal, sorting and pagination can be 42331 * achieved purely via changes to your data model, without the uglyness of having 42332 * to interact with or query the DOM directly. 42333 * 42334 * @example 42335 * 42336 * .dataset(dataset [, animate] [, callback]) 42337 * 42338 * @example <caption>Example 1: Rendering a dataset</caption> 42339 * 42340 * var myDataset = [ 42341 * {id: 1, ...}, 42342 * {id: 2, ...}, 42343 * {id: 3, ...} 42344 * ]; 42345 * 42346 * mixer.dataset(myDataset) 42347 * .then(function(state) { 42348 * console.log(state.totalShow === 3); // true 42349 * }); 42350 * 42351 * @example <caption>Example 2: Sorting a dataset</caption> 42352 * 42353 * // Create a new dataset in reverse order 42354 * 42355 * var newDataset = myDataset.slice().reverse(); 42356 * 42357 * mixer.dataset(newDataset) 42358 * .then(function(state) { 42359 * console.log(state.activeDataset[0] === myDataset[2]); // true 42360 * }); 42361 * 42362 * @example <caption>Example 3: Removing an item from the dataset</caption> 42363 * 42364 * console.log(myDataset.length); // 3 42365 * 42366 * // Create a new dataset with the last item removed. 42367 * 42368 * var newDataset = myDataset.slice().pop(); 42369 * 42370 * mixer.dataset(newDataset) 42371 * .then(function(state) { 42372 * console.log(state.totalShow === 2); // true 42373 * }); 42374 * 42375 * @public 42376 * @instance 42377 * @since 3.0.0 42378 * @param {Array.<object>} dataset 42379 * An array of objects, each one representing the underlying data model of a target to be rendered. 42380 * @param {boolean} [animate=true] 42381 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42382 * @param {function} [callback=null] 42383 * An optional callback function to be invoked after the operation has completed. 42384 * @return {Promise.<mixitup.State>} 42385 * A promise resolving with the current state object. 42386 */ 42387 42388 dataset: function() { 42389 var self = this, 42390 instruction = self.parseDatasetArgs(arguments), 42391 operation = null, 42392 queueItem = null, 42393 animate = false; 42394 42395 self.callActions('beforeDataset', arguments); 42396 42397 if (!self.isBusy) { 42398 if (instruction.callback) self.userCallback = instruction.callback; 42399 42400 animate = (instruction.animate ^ self.config.animation.enable) ? instruction.animate : self.config.animation.enable; 42401 42402 operation = self.getDataOperation(instruction.command.dataset); 42403 42404 return self.goMix(animate, operation); 42405 } else { 42406 queueItem = new mixitup.QueueItem(); 42407 42408 queueItem.args = arguments; 42409 queueItem.instruction = instruction; 42410 42411 return self.queueMix(queueItem); 42412 } 42413 }, 42414 42415 /** 42416 * Performs simultaneous `filter`, `sort`, `insert`, `remove` and `changeLayout` 42417 * operations as requested. 42418 * 42419 * @example 42420 * 42421 * .multimix(multimixCommand [, animate] [, callback]) 42422 * 42423 * @example <caption>Example 1: Performing simultaneous filtering and sorting</caption> 42424 * 42425 * mixer.multimix({ 42426 * filter: '.category-b', 42427 * sort: 'published-date:desc' 42428 * }) 42429 * .then(function(state) { 42430 * console.log(state.activeFilter.selector === '.category-b'); // true 42431 * console.log(state.activeSort.attribute === 'published-date'); // true 42432 * }); 42433 * 42434 * @example <caption>Example 2: Performing simultaneous sorting, insertion, and removal</caption> 42435 * 42436 * console.log(mixer.getState().totalShow); // 6 42437 * 42438 * // NB: When inserting via `multimix()`, an object should be provided as the value 42439 * // for the `insert` portion of the command, allowing for a collection of elements 42440 * // and an insertion index to be specified. 42441 * 42442 * mixer.multimix({ 42443 * sort: 'published-date:desc', // Sort the container, including any new elements 42444 * insert: { 42445 * collection: [newElementReferenceA, newElementReferenceB], // Add 2 new elements at index 5 42446 * index: 5 42447 * }, 42448 * remove: existingElementReference // Remove 1 existing element 42449 * }) 42450 * .then(function(state) { 42451 * console.log(state.activeSort.attribute === 'published-date'); // true 42452 * console.log(state.totalShow === 7); // true 42453 * }); 42454 * 42455 * @public 42456 * @instance 42457 * @since 2.0.0 42458 * @param {object} multimixCommand 42459 * An object containing one or more things to do 42460 * @param {boolean} [animate=true] 42461 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42462 * @param {function} [callback=null] 42463 * An optional callback function to be invoked after the operation has completed. 42464 * @return {Promise.<mixitup.State>} 42465 * A promise resolving with the current state object. 42466 */ 42467 42468 multimix: function() { 42469 var self = this, 42470 operation = null, 42471 animate = false, 42472 queueItem = null, 42473 instruction = self.parseMultimixArgs(arguments); 42474 42475 self.callActions('beforeMultimix', arguments); 42476 42477 if (!self.isBusy) { 42478 operation = self.getOperation(instruction.command); 42479 42480 if (self.config.controls.enable) { 42481 // Update controls for API calls 42482 42483 if (instruction.command.filter && !self.isToggling) { 42484 // As we are not toggling, reset the toggle array 42485 // so new filter overrides existing toggles 42486 42487 self.toggleArray.length = 0; 42488 self.buildToggleArray(operation.command); 42489 } 42490 42491 if (self.queue.length < 1) { 42492 self.updateControls(operation.command); 42493 } 42494 } 42495 42496 if (instruction.callback) self.userCallback = instruction.callback; 42497 42498 // Always allow the instruction to override the instance setting 42499 42500 animate = (instruction.animate ^ self.config.animation.enable) ? 42501 instruction.animate : 42502 self.config.animation.enable; 42503 42504 self.callFilters('operationMultimix', operation, arguments); 42505 42506 return self.goMix(animate, operation); 42507 } else { 42508 queueItem = new mixitup.QueueItem(); 42509 42510 queueItem.args = arguments; 42511 queueItem.instruction = instruction; 42512 queueItem.triggerElement = self.lastClicked; 42513 queueItem.isToggling = self.isToggling; 42514 42515 return self.queueMix(queueItem); 42516 } 42517 }, 42518 42519 /** 42520 * @private 42521 * @instance 42522 * @since 3.0.0 42523 * @param {object} multimixCommand 42524 * @param {boolean} [isPreFetch] 42525 * An optional boolean indicating that the operation is being pre-fetched for execution at a later time. 42526 * @return {Operation|null} 42527 */ 42528 42529 getOperation: function(multimixCommand) { 42530 var self = this, 42531 sortCommand = multimixCommand.sort, 42532 filterCommand = multimixCommand.filter, 42533 changeLayoutCommand = multimixCommand.changeLayout, 42534 removeCommand = multimixCommand.remove, 42535 insertCommand = multimixCommand.insert, 42536 operation = new mixitup.Operation(); 42537 42538 operation = self.callFilters('operationUnmappedGetOperation', operation, arguments); 42539 42540 operation.id = h.randomHex(); 42541 operation.command = multimixCommand; 42542 operation.startState = self.state; 42543 operation.triggerElement = self.lastClicked; 42544 42545 if (self.isBusy) { 42546 if (self.config.debug.showWarnings) { 42547 console.warn(mixitup.messages.warningGetOperationInstanceBusy()); 42548 } 42549 42550 return null; 42551 } 42552 42553 if (insertCommand) { 42554 self.insertTargets(insertCommand, operation); 42555 } 42556 42557 if (removeCommand) { 42558 operation.toRemove = removeCommand.targets; 42559 } 42560 42561 operation.startSort = operation.newSort = operation.startState.activeSort; 42562 operation.startOrder = operation.newOrder = self.targets; 42563 42564 if (sortCommand) { 42565 operation.startSort = operation.startState.activeSort; 42566 operation.newSort = sortCommand; 42567 42568 operation.willSort = self.willSort(sortCommand, operation.startState.activeSort); 42569 42570 if (operation.willSort) { 42571 self.sortOperation(operation); 42572 } 42573 } 42574 42575 operation.startFilter = operation.startState.activeFilter; 42576 42577 if (filterCommand) { 42578 operation.newFilter = filterCommand; 42579 } else { 42580 operation.newFilter = h.extend(new mixitup.CommandFilter(), operation.startFilter); 42581 } 42582 42583 if (operation.newFilter.selector === 'all') { 42584 operation.newFilter.selector = self.config.selectors.target; 42585 } else if (operation.newFilter.selector === 'none') { 42586 operation.newFilter.selector = ''; 42587 } 42588 42589 self.filterOperation(operation); 42590 42591 operation.startContainerClassName = operation.startState.activeContainerClassName; 42592 42593 if (changeLayoutCommand) { 42594 operation.newContainerClassName = changeLayoutCommand.containerClassName; 42595 42596 if (operation.newContainerClassName !== operation.startContainerClassName) { 42597 operation.willChangeLayout = true; 42598 } 42599 } else { 42600 operation.newContainerClassName = operation.startContainerClassName; 42601 } 42602 42603 if (self.config.animation.enable) { 42604 // Populate the operation's position data 42605 42606 self.getStartMixData(operation); 42607 self.setInter(operation); 42608 42609 operation.docState = h.getDocumentState(self.dom.document); 42610 42611 self.getInterMixData(operation); 42612 self.setFinal(operation); 42613 self.getFinalMixData(operation); 42614 42615 self.parseEffects(); 42616 42617 operation.hasEffect = self.hasEffect(); 42618 42619 self.getTweenData(operation); 42620 } 42621 42622 if (operation.willSort) { 42623 self.targets = operation.newOrder; 42624 } 42625 42626 operation.newState = self.buildState(operation); 42627 42628 return self.callFilters('operationMappedGetOperation', operation, arguments); 42629 }, 42630 42631 /** 42632 * Renders a previously created operation at a specific point in its path, as 42633 * determined by a multiplier between 0 and 1. 42634 * 42635 * @example 42636 * .tween(operation, multiplier) 42637 * 42638 * @private 42639 * @instance 42640 * @since 3.0.0 42641 * @param {mixitup.Operation} operation 42642 * An operation object created via the `getOperation` method 42643 * 42644 * @param {Float} multiplier 42645 * Any number between 0 and 1 representing the percentage complete of the operation 42646 * @return {void} 42647 */ 42648 42649 tween: function(operation, multiplier) { 42650 var target = null, 42651 posData = null, 42652 toHideIndex = -1, 42653 i = -1; 42654 42655 multiplier = Math.min(multiplier, 1); 42656 multiplier = Math.max(multiplier, 0); 42657 42658 for (i = 0; target = operation.show[i]; i++) { 42659 posData = operation.showPosData[i]; 42660 42661 target.applyTween(posData, multiplier); 42662 } 42663 42664 for (i = 0; target = operation.hide[i]; i++) { 42665 if (target.isShown) { 42666 target.hide(); 42667 } 42668 42669 if ((toHideIndex = operation.toHide.indexOf(target)) > -1) { 42670 posData = operation.toHidePosData[toHideIndex]; 42671 42672 if (!target.isShown) { 42673 target.show(); 42674 } 42675 42676 target.applyTween(posData, multiplier); 42677 } 42678 } 42679 }, 42680 42681 /** 42682 * Inserts one or more new target elements into the container at a specified 42683 * index. 42684 * 42685 * To be indexed as targets, new elements must match the `selectors.target` 42686 * selector (`'.mix'` by default). 42687 * 42688 * @example 42689 * 42690 * .insert(newElements [, index] [, animate], [, callback]) 42691 * 42692 * @example <caption>Example 1: Inserting a single element via reference</caption> 42693 * 42694 * console.log(mixer.getState().totalShow); // 0 42695 * 42696 * // Create a new element 42697 * 42698 * var newElement = document.createElement('div'); 42699 * newElement.classList.add('mix'); 42700 * 42701 * mixer.insert(newElement) 42702 * .then(function(state) { 42703 * console.log(state.totalShow === 1); // true 42704 * }); 42705 * 42706 * @example <caption>Example 2: Inserting a single element via HTML string</caption> 42707 * 42708 * console.log(mixer.getState().totalShow); // 1 42709 * 42710 * // Create a new element via reference 42711 * 42712 * var newElementHtml = '<div class="mix"></div>'; 42713 * 42714 * // Create and insert the new element at index 1 42715 * 42716 * mixer.insert(newElementHtml, 1) 42717 * .then(function(state) { 42718 * console.log(state.totalShow === 2); // true 42719 * console.log(state.show[1].outerHTML === newElementHtml); // true 42720 * }); 42721 * 42722 * @example <caption>Example 3: Inserting multiple elements via reference</caption> 42723 * 42724 * console.log(mixer.getState().totalShow); // 2 42725 * 42726 * // Create an array of new elements to insert. 42727 * 42728 * var newElement1 = document.createElement('div'); 42729 * var newElement2 = document.createElement('div'); 42730 * 42731 * newElement1.classList.add('mix'); 42732 * newElement2.classList.add('mix'); 42733 * 42734 * var newElementsCollection = [newElement1, newElement2]; 42735 * 42736 * // Insert the new elements starting at index 1 42737 * 42738 * mixer.insert(newElementsCollection, 1) 42739 * .then(function(state) { 42740 * console.log(state.totalShow === 4); // true 42741 * console.log(state.show[1] === newElement1); // true 42742 * console.log(state.show[2] === newElement2); // true 42743 * }); 42744 * 42745 * @example <caption>Example 4: Inserting a jQuery collection object containing one or more elements</caption> 42746 * 42747 * console.log(mixer.getState().totalShow); // 4 42748 * 42749 * var $newElement = $('<div class="mix"></div>'); 42750 * 42751 * // Insert the new elements starting at index 3 42752 * 42753 * mixer.insert($newElement, 3) 42754 * .then(function(state) { 42755 * console.log(state.totalShow === 5); // true 42756 * console.log(state.show[3] === $newElement[0]); // true 42757 * }); 42758 * 42759 * @public 42760 * @instance 42761 * @since 2.0.0 42762 * @param {(HTMLElement|Array.<HTMLElement>|string)} newElements 42763 * A reference to a single element to insert, an array-like collection of elements, or an HTML string representing a single element. 42764 * @param {number} index=0 42765 * The index at which to insert the new element(s). `0` by default. 42766 * @param {boolean} [animate=true] 42767 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42768 * @param {function} [callback=null] 42769 * An optional callback function to be invoked after the operation has completed. 42770 * @return {Promise.<mixitup.State>} 42771 * A promise resolving with the current state object. 42772 */ 42773 42774 insert: function() { 42775 var self = this, 42776 args = self.parseInsertArgs(arguments); 42777 42778 return self.multimix({ 42779 insert: args.command 42780 }, args.animate, args.callback); 42781 }, 42782 42783 /** 42784 * Inserts one or more new elements before a provided reference element. 42785 * 42786 * @example 42787 * 42788 * .insertBefore(newElements, referenceElement [, animate] [, callback]) 42789 * 42790 * @example <caption>Example: Inserting a new element before a reference element</caption> 42791 * 42792 * // An existing reference element is chosen at index 2 42793 * 42794 * var referenceElement = mixer.getState().show[2]; 42795 * 42796 * // Create a new element 42797 * 42798 * var newElement = document.createElement('div'); 42799 * newElement.classList.add('mix'); 42800 * 42801 * mixer.insertBefore(newElement, referenceElement) 42802 * .then(function(state) { 42803 * // The new element is inserted into the container at index 2, before the reference element 42804 * 42805 * console.log(state.show[2] === newElement); // true 42806 * 42807 * // The reference element is now at index 3 42808 * 42809 * console.log(state.show[3] === referenceElement); // true 42810 * }); 42811 * 42812 * @public 42813 * @instance 42814 * @since 3.0.0 42815 * @param {(HTMLElement|Array.<HTMLElement>|string)} newElements 42816 * A reference to a single element to insert, an array-like collection of elements, or an HTML string representing a single element. 42817 * @param {HTMLElement} referenceElement 42818 * A reference to an existing element in the container to insert new elements before. 42819 *@param {boolean} [animate=true] 42820 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42821 * @param {function} [callback=null] 42822 * An optional callback function to be invoked after the operation has completed. 42823 * @return {Promise.<mixitup.State>} 42824 * A promise resolving with the current state object. 42825 */ 42826 42827 insertBefore: function() { 42828 var self = this, 42829 args = self.parseInsertArgs(arguments); 42830 42831 return self.insert(args.command.collection, 'before', args.command.sibling, args.animate, args.callback); 42832 }, 42833 42834 /** 42835 * Inserts one or more new elements after a provided reference element. 42836 * 42837 * @example 42838 * 42839 * .insertAfter(newElements, referenceElement [, animate] [, callback]) 42840 * 42841 * @example <caption>Example: Inserting a new element after a reference element</caption> 42842 * 42843 * // An existing reference element is chosen at index 2 42844 * 42845 * var referenceElement = mixer.getState().show[2]; 42846 * 42847 * // Create a new element 42848 * 42849 * var newElement = document.createElement('div'); 42850 * newElement.classList.add('mix'); 42851 * 42852 * mixer.insertAfter(newElement, referenceElement) 42853 * .then(function(state) { 42854 * // The new element is inserted into the container at index 3, after the reference element 42855 * 42856 * console.log(state.show[3] === newElement); // true 42857 * }); 42858 * 42859 * @public 42860 * @instance 42861 * @since 3.0.0 42862 * @param {(HTMLElement|Array.<HTMLElement>|string)} newElements 42863 * A reference to a single element to insert, an array-like collection of elements, or an HTML string representing a single element. 42864 * @param {HTMLElement} referenceElement 42865 * A reference to an existing element in the container to insert new elements after. 42866 * @param {boolean} [animate=true] 42867 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42868 * @param {function} [callback=null] 42869 * An optional callback function to be invoked after the operation has completed. 42870 * @return {Promise.<mixitup.State>} 42871 * A promise resolving with the current state object. 42872 */ 42873 42874 insertAfter: function() { 42875 var self = this, 42876 args = self.parseInsertArgs(arguments); 42877 42878 return self.insert(args.command.collection, 'after', args.command.sibling, args.animate, args.callback); 42879 }, 42880 42881 /** 42882 * Inserts one or more new elements into the container before all existing targets. 42883 * 42884 * @example 42885 * 42886 * .prepend(newElements [,animate] [,callback]) 42887 * 42888 * @example <caption>Example: Prepending a new element</caption> 42889 * 42890 * // Create a new element 42891 * 42892 * var newElement = document.createElement('div'); 42893 * newElement.classList.add('mix'); 42894 * 42895 * // Insert the element into the container 42896 * 42897 * mixer.prepend(newElement) 42898 * .then(function(state) { 42899 * console.log(state.show[0] === newElement); // true 42900 * }); 42901 * 42902 * @public 42903 * @instance 42904 * @since 3.0.0 42905 * @param {(HTMLElement|Array.<HTMLElement>|string)} newElements 42906 * A reference to a single element to insert, an array-like collection of elements, or an HTML string representing a single element. 42907 * @param {boolean} [animate=true] 42908 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42909 * @param {function} [callback=null] 42910 * An optional callback function to be invoked after the operation has completed. 42911 * @return {Promise.<mixitup.State>} 42912 * A promise resolving with the current state object. 42913 */ 42914 42915 prepend: function() { 42916 var self = this, 42917 args = self.parseInsertArgs(arguments); 42918 42919 return self.insert(0, args.command.collection, args.animate, args.callback); 42920 }, 42921 42922 /** 42923 * Inserts one or more new elements into the container after all existing targets. 42924 * 42925 * @example 42926 * 42927 * .append(newElements [,animate] [,callback]) 42928 * 42929 * @example <caption>Example: Appending a new element</caption> 42930 * 42931 * // Create a new element 42932 * 42933 * var newElement = document.createElement('div'); 42934 * newElement.classList.add('mix'); 42935 * 42936 * // Insert the element into the container 42937 * 42938 * mixer.append(newElement) 42939 * .then(function(state) { 42940 * console.log(state.show[state.show.length - 1] === newElement); // true 42941 * }); 42942 * 42943 * @public 42944 * @instance 42945 * @since 3.0.0 42946 * @param {(HTMLElement|Array.<HTMLElement>|string)} newElements 42947 * A reference to a single element to insert, an array-like collection of elements, or an HTML string representing a single element. 42948 * @param {boolean} [animate=true] 42949 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 42950 * @param {function} [callback=null] 42951 * An optional callback function to be invoked after the operation has completed. 42952 * @return {Promise.<mixitup.State>} 42953 * A promise resolving with the current state object. 42954 */ 42955 42956 append: function() { 42957 var self = this, 42958 args = self.parseInsertArgs(arguments); 42959 42960 return self.insert(self.state.totalTargets, args.command.collection, args.animate, args.callback); 42961 }, 42962 42963 /** 42964 * Removes one or more existing target elements from the container. 42965 * 42966 * @example 42967 * 42968 * .remove(elements [, animate] [, callback]) 42969 * 42970 * @example <caption>Example 1: Removing an element by reference</caption> 42971 * 42972 * var elementToRemove = containerEl.firstElementChild; 42973 * 42974 * mixer.remove(elementToRemove) 42975 * .then(function(state) { 42976 * console.log(state.targets.indexOf(elementToRemove) === -1); // true 42977 * }); 42978 * 42979 * @example <caption>Example 2: Removing a collection of elements by reference</caption> 42980 * 42981 * var elementsToRemove = containerEl.querySelectorAll('.category-a'); 42982 * 42983 * console.log(elementsToRemove.length) // 3 42984 * 42985 * mixer.remove(elementsToRemove) 42986 * .then(function() { 42987 * console.log(containerEl.querySelectorAll('.category-a').length); // 0 42988 * }); 42989 * 42990 * @example <caption>Example 3: Removing one or more elements by selector</caption> 42991 * 42992 * mixer.remove('.category-a') 42993 * .then(function() { 42994 * console.log(containerEl.querySelectorAll('.category-a').length); // 0 42995 * }); 42996 * 42997 * @example <caption>Example 4: Removing an element by index</caption> 42998 * 42999 * console.log(mixer.getState.totalShow); // 4 43000 * 43001 * // Remove the element at index 3 43002 * 43003 * mixer.remove(3) 43004 * .then(function(state) { 43005 * console.log(state.totalShow); // 3 43006 * console.log(state.show[3]); // undefined 43007 * }); 43008 * 43009 * 43010 * @public 43011 * @instance 43012 * @since 3.0.0 43013 * @param {(HTMLElement|Array.<HTMLElement>|string|number)} elements 43014 * A reference to a single element to remove, an array-like collection of elements, a selector string, or the index of an element to remove. 43015 * @param {boolean} [animate=true] 43016 * An optional boolean dictating whether the operation should animate, or occur syncronously with no animation. `true` by default. 43017 * @param {function} [callback=null] 43018 * An optional callback function to be invoked after the operation has completed. 43019 * @return {Promise.<mixitup.State>} 43020 * A promise resolving with the current state object. 43021 */ 43022 43023 remove: function() { 43024 var self = this, 43025 args = self.parseRemoveArgs(arguments); 43026 43027 return self.multimix({ 43028 remove: args.command 43029 }, args.animate, args.callback); 43030 }, 43031 43032 /** 43033 * Retrieves the the value of any property or sub-object within the current 43034 * mixitup configuration, or the whole configuration object. 43035 * 43036 * @example 43037 * 43038 * .getConfig([stringKey]) 43039 * 43040 * @example <caption>Example 1: retrieve the entire configuration object</caption> 43041 * 43042 * var config = mixer.getConfig(); // Config { ... } 43043 * 43044 * @example <caption>Example 2: retrieve a named sub-object of configuration object</caption> 43045 * 43046 * var animation = mixer.getConfig('animation'); // ConfigAnimation { ... } 43047 * 43048 * @example <caption>Example 3: retrieve a value of configuration object via a dot-notation string key</caption> 43049 * 43050 * var effects = mixer.getConfig('animation.effects'); // 'fade scale' 43051 * 43052 * @public 43053 * @instance 43054 * @since 2.0.0 43055 * @param {string} [stringKey] A "dot-notation" string key 43056 * @return {*} 43057 */ 43058 43059 getConfig: function(stringKey) { 43060 var self = this, 43061 value = null; 43062 43063 if (!stringKey) { 43064 value = self.config; 43065 } else { 43066 value = h.getProperty(self.config, stringKey); 43067 } 43068 43069 return self.callFilters('valueGetConfig', value, arguments); 43070 }, 43071 43072 /** 43073 * Updates the configuration of the mixer, after it has been instantiated. 43074 * 43075 * See the Configuration Object documentation for a full list of avilable 43076 * configuration options. 43077 * 43078 * @example 43079 * 43080 * .configure(config) 43081 * 43082 * @example <caption>Example 1: Updating animation options</caption> 43083 * 43084 * mixer.configure({ 43085 * animation: { 43086 * effects: 'fade translateX(-100%)', 43087 * duration: 300 43088 * } 43089 * }); 43090 * 43091 * @example <caption>Example 2: Removing a callback after it has been set</caption> 43092 * 43093 * var mixer; 43094 * 43095 * function handleMixEndOnce() { 43096 * // Do something .. 43097 * 43098 * // Then nullify the callback 43099 * 43100 * mixer.configure({ 43101 * callbacks: { 43102 * onMixEnd: null 43103 * } 43104 * }); 43105 * }; 43106 * 43107 * // Instantiate a mixer with a callback defined 43108 * 43109 * mixer = mixitup(containerEl, { 43110 * callbacks: { 43111 * onMixEnd: handleMixEndOnce 43112 * } 43113 * }); 43114 * 43115 * @public 43116 * @instance 43117 * @since 3.0.0 43118 * @param {object} config 43119 * An object containing one of more configuration options. 43120 * @return {void} 43121 */ 43122 43123 configure: function(config) { 43124 var self = this; 43125 43126 self.callActions('beforeConfigure', arguments); 43127 43128 h.extend(self.config, config, true, true); 43129 43130 self.callActions('afterConfigure', arguments); 43131 }, 43132 43133 /** 43134 * Returns an object containing information about the current state of the 43135 * mixer. See the State Object documentation for more information. 43136 * 43137 * NB: State objects are immutable and should therefore be regenerated 43138 * after any operation. 43139 * 43140 * @example 43141 * 43142 * .getState(); 43143 * 43144 * @example <caption>Example: Retrieving a state object</caption> 43145 * 43146 * var state = mixer.getState(); 43147 * 43148 * console.log(state.totalShow + 'targets are currently shown'); 43149 * 43150 * @public 43151 * @instance 43152 * @since 2.0.0 43153 * @return {mixitup.State} An object reflecting the current state of the mixer. 43154 */ 43155 43156 getState: function() { 43157 var self = this, 43158 state = null; 43159 43160 state = new mixitup.State(); 43161 43162 h.extend(state, self.state); 43163 43164 h.freeze(state); 43165 43166 return self.callFilters('stateGetState', state, arguments); 43167 }, 43168 43169 /** 43170 * Forces the re-indexing all targets within the container. 43171 * 43172 * This should only be used if some other piece of code in your application 43173 * has manipulated the contents of your container, which should be avoided. 43174 * 43175 * If you need to add or remove target elements from the container, use 43176 * the built-in `.insert()` or `.remove()` methods, and MixItUp will keep 43177 * itself up to date. 43178 * 43179 * @example 43180 * 43181 * .forceRefresh() 43182 * 43183 * @example <caption>Example: Force refreshing the mixer after external DOM manipulation</caption> 43184 * 43185 * console.log(mixer.getState().totalShow); // 3 43186 * 43187 * // An element is removed from the container via some external DOM manipulation code: 43188 * 43189 * containerEl.removeChild(containerEl.firstElementChild); 43190 * 43191 * // The mixer does not know that the number of targets has changed: 43192 * 43193 * console.log(mixer.getState().totalShow); // 3 43194 * 43195 * mixer.forceRefresh(); 43196 * 43197 * // After forceRefresh, the mixer is in sync again: 43198 * 43199 * console.log(mixer.getState().totalShow); // 2 43200 * 43201 * @public 43202 * @instance 43203 * @since 2.1.2 43204 * @return {void} 43205 */ 43206 43207 forceRefresh: function() { 43208 var self = this; 43209 43210 self.indexTargets(); 43211 }, 43212 43213 /** 43214 * Forces the re-rendering of all targets when using the Dataset API. 43215 * 43216 * By default, targets are only re-rendered when `data.dirtyCheck` is 43217 * enabled, and an item's data has changed when `dataset()` is called. 43218 * 43219 * The `forceRender()` method allows for the re-rendering of all targets 43220 * in response to some arbitrary event, such as the changing of the target 43221 * render function. 43222 * 43223 * Targets are rendered against their existing data. 43224 * 43225 * @example 43226 * 43227 * .forceRender() 43228 * 43229 * @example <caption>Example: Force render targets after changing the target render function</caption> 43230 * 43231 * console.log(container.innerHTML); // ... <span class="mix">Foo</span> ... 43232 * 43233 * mixer.configure({ 43234 * render: { 43235 * target: (item) => `<a href="/${item.slug}/" class="mix">${item.title}</a>` 43236 * } 43237 * }); 43238 * 43239 * mixer.forceRender(); 43240 * 43241 * console.log(container.innerHTML); // ... <a href="/foo/" class="mix">Foo</a> ... 43242 * 43243 * @public 43244 * @instance 43245 * @since 3.2.1 43246 * @return {void} 43247 */ 43248 43249 forceRender: function() { 43250 var self = this, 43251 target = null, 43252 el = null, 43253 id = ''; 43254 43255 for (id in self.cache) { 43256 target = self.cache[id]; 43257 43258 el = target.render(target.data); 43259 43260 if (el !== target.dom.el) { 43261 // Update target element reference 43262 43263 if (target.isInDom) { 43264 target.unbindEvents(); 43265 43266 self.dom.parent.replaceChild(el, target.dom.el); 43267 } 43268 43269 if (!target.isShown) { 43270 el.style.display = 'none'; 43271 } 43272 43273 target.dom.el = el; 43274 43275 if (target.isInDom) { 43276 target.bindEvents(); 43277 } 43278 } 43279 } 43280 43281 self.state = self.buildState(self.lastOperation); 43282 }, 43283 43284 /** 43285 * Removes mixitup functionality from the container, unbinds all control 43286 * event handlers, and deletes the mixer instance from MixItUp's internal 43287 * cache. 43288 * 43289 * This should be performed whenever a mixer's container is removed from 43290 * the DOM, such as during a page change in a single page application, 43291 * or React's `componentWillUnmount()`. 43292 * 43293 * @example 43294 * 43295 * .destroy([cleanUp]) 43296 * 43297 * @example <caption>Example: Destroying the mixer before removing its container element</caption> 43298 * 43299 * mixer.destroy(); 43300 * 43301 * containerEl.parentElement.removeChild(containerEl); 43302 * 43303 * @public 43304 * @instance 43305 * @since 2.0.0 43306 * @param {boolean} [cleanUp=false] 43307 * An optional boolean dictating whether or not to clean up any inline `display: none;` styling applied to hidden targets. 43308 * @return {void} 43309 */ 43310 43311 destroy: function(cleanUp) { 43312 var self = this, 43313 control = null, 43314 target = null, 43315 i = 0; 43316 43317 self.callActions('beforeDestroy', arguments); 43318 43319 for (i = 0; control = self.controls[i]; i++) { 43320 control.removeBinding(self); 43321 } 43322 43323 for (i = 0; target = self.targets[i]; i++) { 43324 if (cleanUp) { 43325 target.show(); 43326 } 43327 43328 target.unbindEvents(); 43329 } 43330 43331 if (self.dom.container.id.match(/^MixItUp/)) { 43332 self.dom.container.removeAttribute('id'); 43333 } 43334 43335 delete mixitup.instances[self.id]; 43336 43337 self.callActions('afterDestroy', arguments); 43338 } 43339 }); 43340 43341 /** 43342 * @constructor 43343 * @memberof mixitup 43344 * @private 43345 * @since 3.0.0 43346 */ 43347 43348 mixitup.IMoveData = function() { 43349 mixitup.Base.call(this); 43350 43351 this.callActions('beforeConstruct'); 43352 43353 this.posIn = null; 43354 this.posOut = null; 43355 this.operation = null; 43356 this.callback = null; 43357 this.statusChange = ''; 43358 this.duration = -1; 43359 this.staggerIndex = -1; 43360 43361 this.callActions('afterConstruct'); 43362 43363 h.seal(this); 43364 }; 43365 43366 mixitup.BaseStatic.call(mixitup.IMoveData); 43367 43368 mixitup.IMoveData.prototype = Object.create(mixitup.Base.prototype); 43369 43370 mixitup.IMoveData.prototype.constructor = mixitup.IMoveData; 43371 43372 /** 43373 * @constructor 43374 * @memberof mixitup 43375 * @private 43376 * @since 3.0.0 43377 */ 43378 43379 mixitup.TargetDom = function() { 43380 mixitup.Base.call(this); 43381 43382 this.callActions('beforeConstruct'); 43383 43384 this.el = null; 43385 43386 this.callActions('afterConstruct'); 43387 43388 h.seal(this); 43389 }; 43390 43391 mixitup.BaseStatic.call(mixitup.TargetDom); 43392 43393 mixitup.TargetDom.prototype = Object.create(mixitup.Base.prototype); 43394 43395 mixitup.TargetDom.prototype.constructor = mixitup.TargetDom; 43396 43397 /** 43398 * @constructor 43399 * @namespace 43400 * @memberof mixitup 43401 * @private 43402 * @since 3.0.0 43403 */ 43404 43405 mixitup.Target = function() { 43406 mixitup.Base.call(this); 43407 43408 this.callActions('beforeConstruct'); 43409 43410 this.id = ''; 43411 this.sortString = ''; 43412 this.mixer = null; 43413 this.callback = null; 43414 this.isShown = false; 43415 this.isBound = false; 43416 this.isExcluded = false; 43417 this.isInDom = false; 43418 this.handler = null; 43419 this.operation = null; 43420 this.data = null; 43421 this.dom = new mixitup.TargetDom(); 43422 43423 this.callActions('afterConstruct'); 43424 43425 h.seal(this); 43426 }; 43427 43428 mixitup.BaseStatic.call(mixitup.Target); 43429 43430 mixitup.Target.prototype = Object.create(mixitup.Base.prototype); 43431 43432 h.extend(mixitup.Target.prototype, { 43433 constructor: mixitup.Target, 43434 43435 /** 43436 * Initialises a newly instantiated Target. 43437 * 43438 * @private 43439 * @instance 43440 * @since 3.0.0 43441 * @param {(Element|null)} el 43442 * @param {object} mixer 43443 * @param {object} [data] 43444 * @return {void} 43445 */ 43446 43447 init: function(el, mixer, data) { 43448 var self = this, 43449 id = ''; 43450 43451 self.callActions('beforeInit', arguments); 43452 43453 self.mixer = mixer; 43454 43455 if (!el) { 43456 // If no element is provided, render it 43457 43458 el = self.render(data); 43459 } 43460 43461 self.cacheDom(el); 43462 43463 self.bindEvents(); 43464 43465 if (self.dom.el.style.display !== 'none') { 43466 self.isShown = true; 43467 } 43468 43469 if (data && mixer.config.data.uidKey) { 43470 if (typeof (id = data[mixer.config.data.uidKey]) === 'undefined' || id.toString().length < 1) { 43471 throw new TypeError(mixitup.messages.errorDatasetInvalidUidKey({ 43472 uidKey: mixer.config.data.uidKey 43473 })); 43474 } 43475 43476 self.id = id; 43477 self.data = data; 43478 43479 mixer.cache[id] = self; 43480 } 43481 43482 self.callActions('afterInit', arguments); 43483 }, 43484 43485 /** 43486 * Renders the target element using a user-defined renderer function. 43487 * 43488 * @private 43489 * @instance 43490 * @since 3.1.4 43491 * @param {object} data 43492 * @return {void} 43493 */ 43494 43495 render: function(data) { 43496 var self = this, 43497 render = null, 43498 el = null, 43499 temp = null, 43500 output = ''; 43501 43502 self.callActions('beforeRender', arguments); 43503 43504 render = self.callFilters('renderRender', self.mixer.config.render.target, arguments); 43505 43506 if (typeof render !== 'function') { 43507 throw new TypeError(mixitup.messages.errorDatasetRendererNotSet()); 43508 } 43509 43510 output = render(data); 43511 43512 if (output && typeof output === 'object' && h.isElement(output)) { 43513 el = output; 43514 } else if (typeof output === 'string') { 43515 temp = document.createElement('div'); 43516 temp.innerHTML = output; 43517 43518 el = temp.firstElementChild; 43519 } 43520 43521 return self.callFilters('elRender', el, arguments); 43522 }, 43523 43524 /** 43525 * Caches references of DOM elements neccessary for the target's functionality. 43526 * 43527 * @private 43528 * @instance 43529 * @since 3.0.0 43530 * @param {Element} el 43531 * @return {void} 43532 */ 43533 43534 cacheDom: function(el) { 43535 var self = this; 43536 43537 self.callActions('beforeCacheDom', arguments); 43538 43539 self.dom.el = el; 43540 43541 self.callActions('afterCacheDom', arguments); 43542 }, 43543 43544 /** 43545 * @private 43546 * @instance 43547 * @since 3.0.0 43548 * @param {string} attributeName 43549 * @return {void} 43550 */ 43551 43552 getSortString: function(attributeName) { 43553 var self = this, 43554 value = self.dom.el.getAttribute('data-' + attributeName) || ''; 43555 43556 self.callActions('beforeGetSortString', arguments); 43557 43558 value = isNaN(value * 1) ? 43559 value.toLowerCase() : 43560 value * 1; 43561 43562 self.sortString = value; 43563 43564 self.callActions('afterGetSortString', arguments); 43565 }, 43566 43567 /** 43568 * @private 43569 * @instance 43570 * @since 3.0.0 43571 * @return {void} 43572 */ 43573 43574 show: function() { 43575 var self = this; 43576 43577 self.callActions('beforeShow', arguments); 43578 43579 if (!self.isShown) { 43580 self.dom.el.style.display = ''; 43581 43582 self.isShown = true; 43583 } 43584 43585 self.callActions('afterShow', arguments); 43586 }, 43587 43588 /** 43589 * @private 43590 * @instance 43591 * @since 3.0.0 43592 * @return {void} 43593 */ 43594 43595 hide: function() { 43596 var self = this; 43597 43598 self.callActions('beforeHide', arguments); 43599 43600 if (self.isShown) { 43601 self.dom.el.style.display = 'none'; 43602 43603 self.isShown = false; 43604 } 43605 43606 self.callActions('afterHide', arguments); 43607 }, 43608 43609 /** 43610 * @private 43611 * @instance 43612 * @since 3.0.0 43613 * @param {mixitup.IMoveData} moveData 43614 * @return {void} 43615 */ 43616 43617 move: function(moveData) { 43618 var self = this; 43619 43620 self.callActions('beforeMove', arguments); 43621 43622 if (!self.isExcluded) { 43623 self.mixer.targetsMoved++; 43624 } 43625 43626 self.applyStylesIn(moveData); 43627 43628 requestAnimationFrame(function() { 43629 self.applyStylesOut(moveData); 43630 }); 43631 43632 self.callActions('afterMove', arguments); 43633 }, 43634 43635 /** 43636 * @private 43637 * @instance 43638 * @since 3.0.0 43639 * @param {object} posData 43640 * @param {number} multiplier 43641 * @return {void} 43642 */ 43643 43644 applyTween: function(posData, multiplier) { 43645 var self = this, 43646 propertyName = '', 43647 tweenData = null, 43648 posIn = posData.posIn, 43649 currentTransformValues = [], 43650 currentValues = new mixitup.StyleData(), 43651 i = -1; 43652 43653 self.callActions('beforeApplyTween', arguments); 43654 43655 currentValues.x = posIn.x; 43656 currentValues.y = posIn.y; 43657 43658 if (multiplier === 0) { 43659 self.hide(); 43660 } else if (!self.isShown) { 43661 self.show(); 43662 } 43663 43664 for (i = 0; propertyName = mixitup.features.TWEENABLE[i]; i++) { 43665 tweenData = posData.tweenData[propertyName]; 43666 43667 if (propertyName === 'x') { 43668 if (!tweenData) continue; 43669 43670 currentValues.x = posIn.x + (tweenData * multiplier); 43671 } else if (propertyName === 'y') { 43672 if (!tweenData) continue; 43673 43674 currentValues.y = posIn.y + (tweenData * multiplier); 43675 } else if (tweenData instanceof mixitup.TransformData) { 43676 if (!tweenData.value) continue; 43677 43678 currentValues[propertyName].value = 43679 posIn[propertyName].value + (tweenData.value * multiplier); 43680 43681 currentValues[propertyName].unit = tweenData.unit; 43682 43683 currentTransformValues.push( 43684 propertyName + '(' + currentValues[propertyName].value + tweenData.unit + ')' 43685 ); 43686 } else { 43687 if (!tweenData) continue; 43688 43689 currentValues[propertyName] = posIn[propertyName] + (tweenData * multiplier); 43690 43691 self.dom.el.style[propertyName] = currentValues[propertyName]; 43692 } 43693 } 43694 43695 if (currentValues.x || currentValues.y) { 43696 currentTransformValues.unshift('translate(' + currentValues.x + 'px, ' + currentValues.y + 'px)'); 43697 } 43698 43699 if (currentTransformValues.length) { 43700 self.dom.el.style[mixitup.features.transformProp] = currentTransformValues.join(' '); 43701 } 43702 43703 self.callActions('afterApplyTween', arguments); 43704 }, 43705 43706 /** 43707 * Applies the initial styling to a target element before any transition 43708 * is applied. 43709 * 43710 * @private 43711 * @instance 43712 * @param {mixitup.IMoveData} moveData 43713 * @return {void} 43714 */ 43715 43716 applyStylesIn: function(moveData) { 43717 var self = this, 43718 posIn = moveData.posIn, 43719 isFading = self.mixer.effectsIn.opacity !== 1, 43720 transformValues = []; 43721 43722 self.callActions('beforeApplyStylesIn', arguments); 43723 43724 transformValues.push('translate(' + posIn.x + 'px, ' + posIn.y + 'px)'); 43725 43726 if (self.mixer.config.animation.animateResizeTargets) { 43727 if (moveData.statusChange !== 'show') { 43728 // Don't apply posIn width or height or showing, as will be 0 43729 43730 self.dom.el.style.width = posIn.width + 'px'; 43731 self.dom.el.style.height = posIn.height + 'px'; 43732 } 43733 43734 self.dom.el.style.marginRight = posIn.marginRight + 'px'; 43735 self.dom.el.style.marginBottom = posIn.marginBottom + 'px'; 43736 } 43737 43738 isFading && (self.dom.el.style.opacity = posIn.opacity); 43739 43740 if (moveData.statusChange === 'show') { 43741 transformValues = transformValues.concat(self.mixer.transformIn); 43742 } 43743 43744 self.dom.el.style[mixitup.features.transformProp] = transformValues.join(' '); 43745 43746 self.callActions('afterApplyStylesIn', arguments); 43747 }, 43748 43749 /** 43750 * Applies a transition followed by the final styles for the element to 43751 * transition towards. 43752 * 43753 * @private 43754 * @instance 43755 * @param {mixitup.IMoveData} moveData 43756 * @return {void} 43757 */ 43758 43759 applyStylesOut: function(moveData) { 43760 var self = this, 43761 transitionRules = [], 43762 transformValues = [], 43763 isResizing = self.mixer.config.animation.animateResizeTargets, 43764 isFading = typeof self.mixer.effectsIn.opacity !== 'undefined'; 43765 43766 self.callActions('beforeApplyStylesOut', arguments); 43767 43768 // Build the transition rules 43769 43770 transitionRules.push(self.writeTransitionRule( 43771 mixitup.features.transformRule, 43772 moveData.staggerIndex 43773 )); 43774 43775 if (moveData.statusChange !== 'none') { 43776 transitionRules.push(self.writeTransitionRule( 43777 'opacity', 43778 moveData.staggerIndex, 43779 moveData.duration 43780 )); 43781 } 43782 43783 if (isResizing) { 43784 transitionRules.push(self.writeTransitionRule( 43785 'width', 43786 moveData.staggerIndex, 43787 moveData.duration 43788 )); 43789 43790 transitionRules.push(self.writeTransitionRule( 43791 'height', 43792 moveData.staggerIndex, 43793 moveData.duration 43794 )); 43795 43796 transitionRules.push(self.writeTransitionRule( 43797 'margin', 43798 moveData.staggerIndex, 43799 moveData.duration 43800 )); 43801 } 43802 43803 // If no callback was provided, the element will 43804 // not transition in any way so tag it as "immovable" 43805 43806 if (!moveData.callback) { 43807 self.mixer.targetsImmovable++; 43808 43809 if (self.mixer.targetsMoved === self.mixer.targetsImmovable) { 43810 // If the total targets moved is equal to the 43811 // number of immovable targets, the operation 43812 // should be considered finished 43813 43814 self.mixer.cleanUp(moveData.operation); 43815 } 43816 43817 return; 43818 } 43819 43820 // If the target will transition in some fasion, 43821 // assign a callback function 43822 43823 self.operation = moveData.operation; 43824 self.callback = moveData.callback; 43825 43826 // As long as the target is not excluded, increment 43827 // the total number of targets bound 43828 43829 !self.isExcluded && self.mixer.targetsBound++; 43830 43831 // Tag the target as bound to differentiate from transitionEnd 43832 // events that may come from stylesheet driven effects 43833 43834 self.isBound = true; 43835 43836 // Apply the transition 43837 43838 self.applyTransition(transitionRules); 43839 43840 // Apply width, height and margin negation 43841 43842 if (isResizing && moveData.posOut.width > 0 && moveData.posOut.height > 0) { 43843 self.dom.el.style.width = moveData.posOut.width + 'px'; 43844 self.dom.el.style.height = moveData.posOut.height + 'px'; 43845 self.dom.el.style.marginRight = moveData.posOut.marginRight + 'px'; 43846 self.dom.el.style.marginBottom = moveData.posOut.marginBottom + 'px'; 43847 } 43848 43849 if (!self.mixer.config.animation.nudge && moveData.statusChange === 'hide') { 43850 // If we're not nudging, the translation should be 43851 // applied before any other transforms to prevent 43852 // lateral movement 43853 43854 transformValues.push('translate(' + moveData.posOut.x + 'px, ' + moveData.posOut.y + 'px)'); 43855 } 43856 43857 // Apply fade 43858 43859 switch (moveData.statusChange) { 43860 case 'hide': 43861 isFading && (self.dom.el.style.opacity = self.mixer.effectsOut.opacity); 43862 43863 transformValues = transformValues.concat(self.mixer.transformOut); 43864 43865 break; 43866 case 'show': 43867 isFading && (self.dom.el.style.opacity = 1); 43868 } 43869 43870 if ( 43871 self.mixer.config.animation.nudge || 43872 (!self.mixer.config.animation.nudge && moveData.statusChange !== 'hide') 43873 ) { 43874 // Opposite of above - apply translate after 43875 // other transform 43876 43877 transformValues.push('translate(' + moveData.posOut.x + 'px, ' + moveData.posOut.y + 'px)'); 43878 } 43879 43880 // Apply transforms 43881 43882 self.dom.el.style[mixitup.features.transformProp] = transformValues.join(' '); 43883 43884 self.callActions('afterApplyStylesOut', arguments); 43885 }, 43886 43887 /** 43888 * Combines the name of a CSS property with the appropriate duration and delay 43889 * values to created a valid transition rule. 43890 * 43891 * @private 43892 * @instance 43893 * @since 3.0.0 43894 * @param {string} property 43895 * @param {number} staggerIndex 43896 * @param {number} duration 43897 * @return {string} 43898 */ 43899 43900 writeTransitionRule: function(property, staggerIndex, duration) { 43901 var self = this, 43902 delay = self.getDelay(staggerIndex), 43903 rule = ''; 43904 43905 rule = property + ' ' + 43906 (duration > 0 ? duration : self.mixer.config.animation.duration) + 'ms ' + 43907 delay + 'ms ' + 43908 (property === 'opacity' ? 'linear' : self.mixer.config.animation.easing); 43909 43910 return self.callFilters('ruleWriteTransitionRule', rule, arguments); 43911 }, 43912 43913 /** 43914 * Calculates the transition delay for each target element based on its index, if 43915 * staggering is applied. If defined, A custom `animation.staggerSeqeuence` 43916 * function can be used to manipulate the order of indices to produce custom 43917 * stagger effects (e.g. for use in a grid with irregular row lengths). 43918 * 43919 * @private 43920 * @instance 43921 * @since 2.0.0 43922 * @param {number} index 43923 * @return {number} 43924 */ 43925 43926 getDelay: function(index) { 43927 var self = this, 43928 delay = -1; 43929 43930 if (typeof self.mixer.config.animation.staggerSequence === 'function') { 43931 index = self.mixer.config.animation.staggerSequence.call(self, index, self.state); 43932 } 43933 43934 delay = !!self.mixer.staggerDuration ? index * self.mixer.staggerDuration : 0; 43935 43936 return self.callFilters('delayGetDelay', delay, arguments); 43937 }, 43938 43939 /** 43940 * @private 43941 * @instance 43942 * @since 3.0.0 43943 * @param {string[]} rules 43944 * @return {void} 43945 */ 43946 43947 applyTransition: function(rules) { 43948 var self = this, 43949 transitionString = rules.join(', '); 43950 43951 self.callActions('beforeApplyTransition', arguments); 43952 43953 self.dom.el.style[mixitup.features.transitionProp] = transitionString; 43954 43955 self.callActions('afterApplyTransition', arguments); 43956 }, 43957 43958 /** 43959 * @private 43960 * @instance 43961 * @since 3.0.0 43962 * @param {Event} e 43963 * @return {void} 43964 */ 43965 43966 handleTransitionEnd: function(e) { 43967 var self = this, 43968 propName = e.propertyName, 43969 canResize = self.mixer.config.animation.animateResizeTargets; 43970 43971 self.callActions('beforeHandleTransitionEnd', arguments); 43972 43973 if ( 43974 self.isBound && 43975 e.target.matches(self.mixer.config.selectors.target) && 43976 ( 43977 propName.indexOf('transform') > -1 || 43978 propName.indexOf('opacity') > -1 || 43979 canResize && propName.indexOf('height') > -1 || 43980 canResize && propName.indexOf('width') > -1 || 43981 canResize && propName.indexOf('margin') > -1 43982 ) 43983 ) { 43984 self.callback.call(self, self.operation); 43985 43986 self.isBound = false; 43987 self.callback = null; 43988 self.operation = null; 43989 } 43990 43991 self.callActions('afterHandleTransitionEnd', arguments); 43992 }, 43993 43994 /** 43995 * @private 43996 * @instance 43997 * @since 3.0.0 43998 * @param {Event} e 43999 * @return {void} 44000 */ 44001 44002 eventBus: function(e) { 44003 var self = this; 44004 44005 self.callActions('beforeEventBus', arguments); 44006 44007 switch (e.type) { 44008 case 'webkitTransitionEnd': 44009 case 'transitionend': 44010 self.handleTransitionEnd(e); 44011 } 44012 44013 self.callActions('afterEventBus', arguments); 44014 }, 44015 44016 /** 44017 * @private 44018 * @instance 44019 * @since 3.0.0 44020 * @return {void} 44021 */ 44022 44023 unbindEvents: function() { 44024 var self = this; 44025 44026 self.callActions('beforeUnbindEvents', arguments); 44027 44028 h.off(self.dom.el, 'webkitTransitionEnd', self.handler); 44029 h.off(self.dom.el, 'transitionend', self.handler); 44030 44031 self.callActions('afterUnbindEvents', arguments); 44032 }, 44033 44034 /** 44035 * @private 44036 * @instance 44037 * @since 3.0.0 44038 * @return {void} 44039 */ 44040 44041 bindEvents: function() { 44042 var self = this, 44043 transitionEndEvent = ''; 44044 44045 self.callActions('beforeBindEvents', arguments); 44046 44047 transitionEndEvent = mixitup.features.transitionPrefix === 'webkit' ? 'webkitTransitionEnd' : 'transitionend'; 44048 44049 self.handler = function(e) { 44050 return self.eventBus(e); 44051 }; 44052 44053 h.on(self.dom.el, transitionEndEvent, self.handler); 44054 44055 self.callActions('afterBindEvents', arguments); 44056 }, 44057 44058 /** 44059 * @private 44060 * @instance 44061 * @since 3.0.0 44062 * @param {boolean} [getBox] 44063 * @return {PosData} 44064 */ 44065 44066 getPosData: function(getBox) { 44067 var self = this, 44068 styles = {}, 44069 rect = null, 44070 posData = new mixitup.StyleData(); 44071 44072 self.callActions('beforeGetPosData', arguments); 44073 44074 posData.x = self.dom.el.offsetLeft; 44075 posData.y = self.dom.el.offsetTop; 44076 44077 if (self.mixer.config.animation.animateResizeTargets || getBox) { 44078 rect = self.dom.el.getBoundingClientRect(); 44079 44080 posData.top = rect.top; 44081 posData.right = rect.right; 44082 posData.bottom = rect.bottom; 44083 posData.left = rect.left; 44084 44085 posData.width = rect.width; 44086 posData.height = rect.height; 44087 } 44088 44089 if (self.mixer.config.animation.animateResizeTargets) { 44090 styles = window.getComputedStyle(self.dom.el); 44091 44092 posData.marginBottom = parseFloat(styles.marginBottom); 44093 posData.marginRight = parseFloat(styles.marginRight); 44094 } 44095 44096 return self.callFilters('posDataGetPosData', posData, arguments); 44097 }, 44098 44099 /** 44100 * @private 44101 * @instance 44102 * @since 3.0.0 44103 * @return {void} 44104 */ 44105 44106 cleanUp: function() { 44107 var self = this; 44108 44109 self.callActions('beforeCleanUp', arguments); 44110 44111 self.dom.el.style[mixitup.features.transformProp] = ''; 44112 self.dom.el.style[mixitup.features.transitionProp] = ''; 44113 self.dom.el.style.opacity = ''; 44114 44115 if (self.mixer.config.animation.animateResizeTargets) { 44116 self.dom.el.style.width = ''; 44117 self.dom.el.style.height = ''; 44118 self.dom.el.style.marginRight = ''; 44119 self.dom.el.style.marginBottom = ''; 44120 } 44121 44122 self.callActions('afterCleanUp', arguments); 44123 } 44124 }); 44125 44126 /** 44127 * A jQuery-collection-like wrapper around one or more `mixitup.Mixer` instances 44128 * allowing simultaneous control of said instances similar to the MixItUp 2 API. 44129 * 44130 * @example 44131 * new mixitup.Collection(instances) 44132 * 44133 * @constructor 44134 * @namespace 44135 * @memberof mixitup 44136 * @private 44137 * @since 3.0.0 44138 * @param {mixitup.Mixer[]} instances 44139 */ 44140 44141 mixitup.Collection = function(instances) { 44142 var instance = null, 44143 i = -1; 44144 44145 this.callActions('beforeConstruct'); 44146 44147 for (i = 0; instance = instances[i]; i++) { 44148 this[i] = instance; 44149 } 44150 44151 this.length = instances.length; 44152 44153 this.callActions('afterConstruct'); 44154 44155 h.freeze(this); 44156 }; 44157 44158 mixitup.BaseStatic.call(mixitup.Collection); 44159 44160 mixitup.Collection.prototype = Object.create(mixitup.Base.prototype); 44161 44162 h.extend(mixitup.Collection.prototype, 44163 /** @lends mixitup.Collection */ 44164 { 44165 constructor: mixitup.Collection, 44166 44167 /** 44168 * Calls a method on all instances in the collection by passing the method 44169 * name as a string followed by any applicable parameters to be curried into 44170 * to the method. 44171 * 44172 * @example 44173 * .mixitup(methodName[,arg1][,arg2..]); 44174 * 44175 * @example 44176 * var collection = new Collection([mixer1, mixer2]); 44177 * 44178 * return collection.mixitup('filter', '.category-a') 44179 * .then(function(states) { 44180 * state.forEach(function(state) { 44181 * console.log(state.activeFilter.selector); // .category-a 44182 * }); 44183 * }); 44184 * 44185 * @public 44186 * @instance 44187 * @since 3.0.0 44188 * @param {string} methodName 44189 * @return {Promise<Array<mixitup.State>>} 44190 */ 44191 44192 mixitup: function(methodName) { 44193 var self = this, 44194 instance = null, 44195 args = Array.prototype.slice.call(arguments), 44196 tasks = [], 44197 i = -1; 44198 44199 this.callActions('beforeMixitup'); 44200 44201 args.shift(); 44202 44203 for (i = 0; instance = self[i]; i++) { 44204 tasks.push(instance[methodName].apply(instance, args)); 44205 } 44206 44207 return self.callFilters('promiseMixitup', h.all(tasks, mixitup.libraries), arguments); 44208 } 44209 }); 44210 44211 /** 44212 * `mixitup.Operation` objects contain all data neccessary to describe the full 44213 * lifecycle of any MixItUp operation. They can be used to compute and store an 44214 * operation for use at a later time (e.g. programmatic tweening). 44215 * 44216 * @constructor 44217 * @namespace 44218 * @memberof mixitup 44219 * @private 44220 * @since 3.0.0 44221 */ 44222 44223 mixitup.Operation = function() { 44224 mixitup.Base.call(this); 44225 44226 this.callActions('beforeConstruct'); 44227 44228 this.id = ''; 44229 44230 this.args = []; 44231 this.command = null; 44232 this.showPosData = []; 44233 this.toHidePosData = []; 44234 44235 this.startState = null; 44236 this.newState = null; 44237 this.docState = null; 44238 44239 this.willSort = false; 44240 this.willChangeLayout = false; 44241 this.hasEffect = false; 44242 this.hasFailed = false; 44243 44244 this.triggerElement = null; 44245 44246 this.show = []; 44247 this.hide = []; 44248 this.matching = []; 44249 this.toShow = []; 44250 this.toHide = []; 44251 this.toMove = []; 44252 this.toRemove = []; 44253 this.startOrder = []; 44254 this.newOrder = []; 44255 this.startSort = null; 44256 this.newSort = null; 44257 this.startFilter = null; 44258 this.newFilter = null; 44259 this.startDataset = null; 44260 this.newDataset = null; 44261 this.viewportDeltaX = 0; 44262 this.viewportDeltaY = 0; 44263 this.startX = 0; 44264 this.startY = 0; 44265 this.startHeight = 0; 44266 this.startWidth = 0; 44267 this.newX = 0; 44268 this.newY = 0; 44269 this.newHeight = 0; 44270 this.newWidth = 0; 44271 this.startContainerClassName = ''; 44272 this.startDisplay = ''; 44273 this.newContainerClassName = ''; 44274 this.newDisplay = ''; 44275 44276 this.callActions('afterConstruct'); 44277 44278 h.seal(this); 44279 }; 44280 44281 mixitup.BaseStatic.call(mixitup.Operation); 44282 44283 mixitup.Operation.prototype = Object.create(mixitup.Base.prototype); 44284 44285 mixitup.Operation.prototype.constructor = mixitup.Operation; 44286 44287 /** 44288 * `mixitup.State` objects expose various pieces of data detailing the state of 44289 * a MixItUp instance. They are provided at the start and end of any operation via 44290 * callbacks and events, with the most recent state stored between operations 44291 * for retrieval at any time via the API. 44292 * 44293 * @constructor 44294 * @namespace 44295 * @memberof mixitup 44296 * @public 44297 * @since 3.0.0 44298 */ 44299 44300 mixitup.State = function() { 44301 mixitup.Base.call(this); 44302 44303 this.callActions('beforeConstruct'); 44304 44305 /** 44306 * The ID of the mixer instance. 44307 * 44308 * @name id 44309 * @memberof mixitup.State 44310 * @instance 44311 * @type {string} 44312 * @default '' 44313 */ 44314 44315 this.id = ''; 44316 44317 /** 44318 * The currently active filter command as set by a control click or API call. 44319 * 44320 * @name activeFilter 44321 * @memberof mixitup.State 44322 * @instance 44323 * @type {mixitup.CommandFilter} 44324 * @default null 44325 */ 44326 44327 this.activeFilter = null; 44328 44329 /** 44330 * The currently active sort command as set by a control click or API call. 44331 * 44332 * @name activeSort 44333 * @memberof mixitup.State 44334 * @instance 44335 * @type {mixitup.CommandSort} 44336 * @default null 44337 */ 44338 44339 this.activeSort = null; 44340 44341 /** 44342 * The current layout-specific container class name, if applied. 44343 * 44344 * @name activeContainerClassName 44345 * @memberof mixitup.State 44346 * @instance 44347 * @type {string} 44348 * @default '' 44349 */ 44350 44351 this.activeContainerClassName = ''; 44352 44353 /** 44354 * A reference to the container element that the mixer is instantiated on. 44355 * 44356 * @name container 44357 * @memberof mixitup.State 44358 * @instance 44359 * @type {Element} 44360 * @default null 44361 */ 44362 44363 this.container = null; 44364 44365 /** 44366 * An array of all target elements indexed by the mixer. 44367 * 44368 * @name targets 44369 * @memberof mixitup.State 44370 * @instance 44371 * @type {Array.<Element>} 44372 * @default [] 44373 */ 44374 44375 this.targets = []; 44376 44377 /** 44378 * An array of all target elements not matching the current filter. 44379 * 44380 * @name hide 44381 * @memberof mixitup.State 44382 * @instance 44383 * @type {Array.<Element>} 44384 * @default [] 44385 */ 44386 44387 this.hide = []; 44388 44389 /** 44390 * An array of all target elements matching the current filter and any additional 44391 * limits applied such as pagination. 44392 * 44393 * @name show 44394 * @memberof mixitup.State 44395 * @instance 44396 * @type {Array.<Element>} 44397 * @default [] 44398 */ 44399 44400 this.show = []; 44401 44402 /** 44403 * An array of all target elements matching the current filter irrespective of 44404 * any additional limits applied such as pagination. 44405 * 44406 * @name matching 44407 * @memberof mixitup.State 44408 * @instance 44409 * @type {Array.<Element>} 44410 * @default [] 44411 */ 44412 44413 this.matching = []; 44414 44415 /** 44416 * An integer representing the total number of target elements indexed by the 44417 * mixer. Equivalent to `state.targets.length`. 44418 * 44419 * @name totalTargets 44420 * @memberof mixitup.State 44421 * @instance 44422 * @type {number} 44423 * @default -1 44424 */ 44425 44426 this.totalTargets = -1; 44427 44428 /** 44429 * An integer representing the total number of target elements matching the 44430 * current filter and any additional limits applied such as pagination. 44431 * Equivalent to `state.show.length`. 44432 * 44433 * @name totalShow 44434 * @memberof mixitup.State 44435 * @instance 44436 * @type {number} 44437 * @default -1 44438 */ 44439 44440 this.totalShow = -1; 44441 44442 /** 44443 * An integer representing the total number of target elements not matching 44444 * the current filter. Equivalent to `state.hide.length`. 44445 * 44446 * @name totalHide 44447 * @memberof mixitup.State 44448 * @instance 44449 * @type {number} 44450 * @default -1 44451 */ 44452 44453 this.totalHide = -1; 44454 44455 /** 44456 * An integer representing the total number of target elements matching the 44457 * current filter irrespective of any other limits applied such as pagination. 44458 * Equivalent to `state.matching.length`. 44459 * 44460 * @name totalMatching 44461 * @memberof mixitup.State 44462 * @instance 44463 * @type {number} 44464 * @default -1 44465 */ 44466 44467 this.totalMatching = -1; 44468 44469 /** 44470 * A boolean indicating whether the last operation "failed", i.e. no targets 44471 * could be found matching the filter. 44472 * 44473 * @name hasFailed 44474 * @memberof mixitup.State 44475 * @instance 44476 * @type {boolean} 44477 * @default false 44478 */ 44479 44480 this.hasFailed = false; 44481 44482 /** 44483 * The DOM element that was clicked if the last operation was triggered by the 44484 * clicking of a control and not an API call. 44485 * 44486 * @name triggerElement 44487 * @memberof mixitup.State 44488 * @instance 44489 * @type {Element|null} 44490 * @default null 44491 */ 44492 44493 this.triggerElement = null; 44494 44495 /** 44496 * The currently active dataset underlying the rendered targets, if the 44497 * dataset API is in use. 44498 * 44499 * @name activeDataset 44500 * @memberof mixitup.State 44501 * @instance 44502 * @type {Array.<object>} 44503 * @default null 44504 */ 44505 44506 this.activeDataset = null; 44507 44508 this.callActions('afterConstruct'); 44509 44510 h.seal(this); 44511 }; 44512 44513 mixitup.BaseStatic.call(mixitup.State); 44514 44515 mixitup.State.prototype = Object.create(mixitup.Base.prototype); 44516 44517 mixitup.State.prototype.constructor = mixitup.State; 44518 44519 /** 44520 * @constructor 44521 * @memberof mixitup 44522 * @private 44523 * @since 3.0.0 44524 */ 44525 44526 mixitup.UserInstruction = function() { 44527 mixitup.Base.call(this); 44528 44529 this.callActions('beforeConstruct'); 44530 44531 this.command = {}; 44532 this.animate = false; 44533 this.callback = null; 44534 44535 this.callActions('afterConstruct'); 44536 44537 h.seal(this); 44538 }; 44539 44540 mixitup.BaseStatic.call(mixitup.UserInstruction); 44541 44542 mixitup.UserInstruction.prototype = Object.create(mixitup.Base.prototype); 44543 44544 mixitup.UserInstruction.prototype.constructor = mixitup.UserInstruction; 44545 44546 /** 44547 * @constructor 44548 * @memberof mixitup 44549 * @private 44550 * @since 3.0.0 44551 */ 44552 44553 mixitup.Messages = function() { 44554 mixitup.Base.call(this); 44555 44556 this.callActions('beforeConstruct'); 44557 44558 /* Errors 44559 ----------------------------------------------------------------------------- */ 44560 44561 this.ERROR_FACTORY_INVALID_CONTAINER = 44562 '[MixItUp] An invalid selector or element reference was passed to the mixitup factory function'; 44563 44564 this.ERROR_FACTORY_CONTAINER_NOT_FOUND = 44565 '[MixItUp] The provided selector yielded no container element'; 44566 44567 this.ERROR_CONFIG_INVALID_ANIMATION_EFFECTS = 44568 '[MixItUp] Invalid value for `animation.effects`'; 44569 44570 this.ERROR_CONFIG_INVALID_CONTROLS_SCOPE = 44571 '[MixItUp] Invalid value for `controls.scope`'; 44572 44573 this.ERROR_CONFIG_INVALID_PROPERTY = 44574 '[MixitUp] Invalid configuration object property "${erroneous}"${suggestion}'; 44575 44576 this.ERROR_CONFIG_INVALID_PROPERTY_SUGGESTION = 44577 '. Did you mean "${probableMatch}"?'; 44578 44579 this.ERROR_CONFIG_DATA_UID_KEY_NOT_SET = 44580 '[MixItUp] To use the dataset API, a UID key must be specified using `data.uidKey`'; 44581 44582 this.ERROR_DATASET_INVALID_UID_KEY = 44583 '[MixItUp] The specified UID key "${uidKey}" is not present on one or more dataset items'; 44584 44585 this.ERROR_DATASET_DUPLICATE_UID = 44586 '[MixItUp] The UID "${uid}" was found on two or more dataset items. UIDs must be unique.'; 44587 44588 this.ERROR_INSERT_INVALID_ARGUMENTS = 44589 '[MixItUp] Please provider either an index or a sibling and position to insert, not both'; 44590 44591 this.ERROR_INSERT_PREEXISTING_ELEMENT = 44592 '[MixItUp] An element to be inserted already exists in the container'; 44593 44594 this.ERROR_FILTER_INVALID_ARGUMENTS = 44595 '[MixItUp] Please provide either a selector or collection `.filter()`, not both'; 44596 44597 this.ERROR_DATASET_NOT_SET = 44598 '[MixItUp] To use the dataset API with pre-rendered targets, a starting dataset must be set using `load.dataset`'; 44599 44600 this.ERROR_DATASET_PRERENDERED_MISMATCH = 44601 '[MixItUp] `load.dataset` does not match pre-rendered targets'; 44602 44603 this.ERROR_DATASET_RENDERER_NOT_SET = 44604 '[MixItUp] To insert an element via the dataset API, a target renderer function must be provided to `render.target`'; 44605 44606 this.ERROR_SORT_NON_EXISTENT_ELEMENT = 44607 '[MixItUp] An element to be sorted does not already exist in the container'; 44608 44609 /* Warnings 44610 ----------------------------------------------------------------------------- */ 44611 44612 this.WARNING_FACTORY_PREEXISTING_INSTANCE = 44613 '[MixItUp] WARNING: This element already has an active MixItUp instance. The provided configuration object will be ignored.' + 44614 ' If you wish to perform additional methods on this instance, please create a reference.'; 44615 44616 this.WARNING_INSERT_NO_ELEMENTS = 44617 '[MixItUp] WARNING: No valid elements were passed to `.insert()`'; 44618 44619 this.WARNING_REMOVE_NO_ELEMENTS = 44620 '[MixItUp] WARNING: No valid elements were passed to `.remove()`'; 44621 44622 this.WARNING_MULTIMIX_INSTANCE_QUEUE_FULL = 44623 '[MixItUp] WARNING: An operation was requested but the MixItUp instance was busy. The operation was rejected because the ' + 44624 'queue is full or queuing is disabled.'; 44625 44626 this.WARNING_GET_OPERATION_INSTANCE_BUSY = 44627 '[MixItUp] WARNING: Operations can be be created while the MixItUp instance is busy.'; 44628 44629 this.WARNING_NO_PROMISE_IMPLEMENTATION = 44630 '[MixItUp] WARNING: No Promise implementations could be found. If you wish to use promises with MixItUp please install' + 44631 ' an ES6 Promise polyfill.'; 44632 44633 this.WARNING_INCONSISTENT_SORTING_ATTRIBUTES = 44634 '[MixItUp] WARNING: The requested sorting data attribute "${attribute}" was not present on one or more target elements' + 44635 ' which may product unexpected sort output'; 44636 44637 this.callActions('afterConstruct'); 44638 44639 this.compileTemplates(); 44640 44641 h.seal(this); 44642 }; 44643 44644 mixitup.BaseStatic.call(mixitup.Messages); 44645 44646 mixitup.Messages.prototype = Object.create(mixitup.Base.prototype); 44647 44648 mixitup.Messages.prototype.constructor = mixitup.Messages; 44649 44650 /** 44651 * @return {void} 44652 */ 44653 44654 mixitup.Messages.prototype.compileTemplates = function() { 44655 var errorKey = ''; 44656 var errorMessage = ''; 44657 44658 for (errorKey in this) { 44659 if (typeof (errorMessage = this[errorKey]) !== 'string') continue; 44660 44661 this[h.camelCase(errorKey)] = h.template(errorMessage); 44662 } 44663 }; 44664 44665 mixitup.messages = new mixitup.Messages(); 44666 44667 /** 44668 * @constructor 44669 * @memberof mixitup 44670 * @private 44671 * @since 3.0.0 44672 * @param {mixitup.Mixer} mixer 44673 */ 44674 44675 mixitup.Facade = function Mixer(mixer) { 44676 mixitup.Base.call(this); 44677 44678 this.callActions('beforeConstruct', arguments); 44679 44680 this.configure = mixer.configure.bind(mixer); 44681 this.show = mixer.show.bind(mixer); 44682 this.hide = mixer.hide.bind(mixer); 44683 this.filter = mixer.filter.bind(mixer); 44684 this.toggleOn = mixer.toggleOn.bind(mixer); 44685 this.toggleOff = mixer.toggleOff.bind(mixer); 44686 this.sort = mixer.sort.bind(mixer); 44687 this.changeLayout = mixer.changeLayout.bind(mixer); 44688 this.multimix = mixer.multimix.bind(mixer); 44689 this.dataset = mixer.dataset.bind(mixer); 44690 this.tween = mixer.tween.bind(mixer); 44691 this.insert = mixer.insert.bind(mixer); 44692 this.insertBefore = mixer.insertBefore.bind(mixer); 44693 this.insertAfter = mixer.insertAfter.bind(mixer); 44694 this.prepend = mixer.prepend.bind(mixer); 44695 this.append = mixer.append.bind(mixer); 44696 this.remove = mixer.remove.bind(mixer); 44697 this.destroy = mixer.destroy.bind(mixer); 44698 this.forceRefresh = mixer.forceRefresh.bind(mixer); 44699 this.forceRender = mixer.forceRender.bind(mixer); 44700 this.isMixing = mixer.isMixing.bind(mixer); 44701 this.getOperation = mixer.getOperation.bind(mixer); 44702 this.getConfig = mixer.getConfig.bind(mixer); 44703 this.getState = mixer.getState.bind(mixer); 44704 44705 this.callActions('afterConstruct', arguments); 44706 44707 h.freeze(this); 44708 h.seal(this); 44709 }; 44710 44711 mixitup.BaseStatic.call(mixitup.Facade); 44712 44713 mixitup.Facade.prototype = Object.create(mixitup.Base.prototype); 44714 44715 mixitup.Facade.prototype.constructor = mixitup.Facade; 44716 44717 if (true) { 44718 module.exports = mixitup; 44719 } else {} 44720 mixitup.BaseStatic.call(mixitup.constructor); 44721 44722 mixitup.NAME = 'mixitup'; 44723 mixitup.CORE_VERSION = '3.3.1'; 44724})(window); 44725/* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(/*! jquery */ "./node_modules/jquery/dist/jquery.js"))) 44726 44727/***/ }), 44728
vendor: 746 bytes, lines 44729-44760
44729/***/ "./node_modules/webpack/buildin/module.js": 44730/*!***********************************!*\ 44731 !*** (webpack)/buildin/module.js ***! 44732 \***********************************/ 44733/*! no static exports found */ 44734/***/ (function(module, exports) { 44735 44736module.exports = function(module) { 44737 if (!module.webpackPolyfill) { 44738 module.deprecate = function() {}; 44739 module.paths = []; 44740 // module.parent = undefined by default 44741 if (!module.children) module.children = []; 44742 Object.defineProperty(module, "loaded", { 44743 enumerable: true, 44744 get: function() { 44745 return module.l; 44746 } 44747 }); 44748 Object.defineProperty(module, "id", { 44749 enumerable: true, 44750 get: function() { 44751 return module.i; 44752 } 44753 }); 44754 module.webpackPolyfill = 1; 44755 } 44756 return module; 44757}; 44758 44759 44760/***/ })
44760 44761 44762}]); 44763//# sourceMappingURL=vendors~bundle.js.map
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.