vendor: 115 bytes, lines 1-5
1/******/ (() => { // webpackBootstrap 2/******/ "use strict"; 3/******/ var __webpack_modules__ = ({ 4 5/***/ "./src/
5base/AppBase.ts": 6/*!*****************************!*\ 7 !*** ./src/base/AppBase.ts ***! 8 \*****************************/ 9/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 10 11__webpack_require__.r(__webpack_exports__); 12/* harmony export */ __webpack_require__.d(__webpack_exports__, { 13/* harmony export */ "default": () => (/* binding */ AppBase) 14/* harmony export */ }); 15const $ = window.jQuery; 16class AppBase { 17 constructor() { 18 Object.defineProperty(this, "scriptLoaded", { 19 enumerable: true, 20 configurable: true, 21 writable: true, 22 value: false 23 }); 24 jQuery(this.init.bind(this)); 25 jQuery(this.loadThirdPartyScript.bind(this)); 26 } 27 loadAfterFCP() { 28 if (!this.scriptLoaded) { 29 const $content = $('#lazyload-scripts').html(); 30 $(document.head).append($content); 31 this.scriptLoaded = true; 32 } 33 } 34 loadThirdPartyScript() { 35 if (scrollY > 0) { 36 this.loadAfterFCP(); 37 } 38 // on mousemove 39 document.addEventListener('mousemove', this.loadAfterFCP.bind(this), { 40 once: true 41 }); 42 // on scroll 43 document.addEventListener('scroll', this.loadAfterFCP.bind(this), { 44 once: true 45 }); 46 // on timeout 47 setTimeout(this.loadAfterFCP.bind(this), 5000); 48 } 49} 50 51/***/ }), 52
53/***/ "./src/base/Helper.ts": 54/*!****************************!*\ 55 !*** ./src/base/Helper.ts ***! 56 \****************************/ 57/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 58 59__webpack_require__.r(__webpack_exports__); 60/* harmony export */ __webpack_require__.d(__webpack_exports__, { 61/* harmony export */ "default": () => (/* binding */ Helper) 62/* harmony export */ }); 63const $ = jQuery; 64/** 65 * The intersection observer 66 */ 67const intersectionObserver = (element, callback) => { 68 const observer = new IntersectionObserver(entries => { 69 entries.forEach(callback); 70 }); 71 observer.observe(element); 72}; 73/** 74 * The helper class 75 * @class Helper 76 * @version 1.0.0 77 * @since 1.0.0 78 * 79 * Helper class contains the helper functions 80 */ 81class Helper { 82 /** 83 * The intersection observer 84 * Observe the element and call the callback when the element is in the viewport 85 */ 86 static intersectionObserver($element, callback) { 87 if ($element.length && $element[0]) { 88 return intersectionObserver($element[0], callback); 89 } 90 } 91 /** 92 * Scroll any html element into view 93 */ 94 static scrollIntoView(selector, duration = 1000) { 95 var _a; 96 const $targetEl = $(selector); 97 if ($targetEl.length) { 98 $('html, body').animate({ 99 scrollTop: (_a = $targetEl.offset()) === null || _a === void 0 ? void 0 : _a.top 100 }, duration); 101 } 102 } 103 /** 104 * Check if the element is in the viewport 105 */ 106 static isInViewport($element) { 107 var _a; 108 if ($element.length === 0) return false; 109 const elementTop = ((_a = $element.offset()) === null || _a === void 0 ? void 0 : _a.top) || 0; 110 const elementBottom = elementTop + $element.outerHeight() || 0; 111 const viewportTop = $(window).scrollTop(); 112 const viewportBottom = viewportTop + $(window).height(); 113 return elementBottom > viewportTop && elementTop < viewportBottom; 114 } 115 /** 116 * slick carousel exists 117 */ 118 static slickExists($element) { 119 return 'slick' in $element; 120 } 121} 122 123/***/ }), 124
125/***/ "./src/decorators/lib-exists.ts": 126/*!**************************************!*\ 127 !*** ./src/decorators/lib-exists.ts ***! 128 \**************************************/ 129/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 130 131__webpack_require__.r(__webpack_exports__); 132/* harmony export */ __webpack_require__.d(__webpack_exports__, { 133/* harmony export */ "default": () => (/* binding */ LibExists) 134/* harmony export */ }); 135/** 136 * this decorators is used to check if any external library exists in window object 137 */ 138function LibExists(libName) { 139 return (_target, _propertyKey, descriptor) => { 140 const originalMethod = descriptor.value; 141 descriptor.value = function (...arg) { 142 if (libName in window) { 143 originalMethod.apply(this, arg); 144 } 145 }; 146 }; 147} 148 149/***/ }), 150
151/***/ "./src/inc/chatway-widget-support.ts": 152/*!*******************************************!*\ 153 !*** ./src/inc/chatway-widget-support.ts ***! 154 \*******************************************/ 155/***/ (() => { 156 157 158 159// @ts-nocheck 160// Open the chatway widget when the button is clicked 161document.addEventListener('click', event => { 162 const trigger = event.target.closest('[data-open-chatway-widget]'); 163 if (!trigger) { 164 return; 165 } 166 event.preventDefault(); 167 if (window.$chatway && typeof window.$chatway.openChatwayWidget === 'function') { 168 window.$chatway.openChatwayWidget(); 169 } 170}); 171// Rewrite the widget cookie after conversation started 172window.$chatwayConversationStarted = function () { 173 const cookies = document.cookie.split(';'); 174 cookies.forEach(cookie => { 175 const [rawName, ...rawValue] = cookie.trim().split('='); 176 const name = rawName; 177 if (!name.startsWith('ch_cw')) return; 178 const value = rawValue.join('='); 179 const d = new Date(); 180 d.setTime(d.getTime() + 365 * 24 * 60 * 60 * 1000); 181 let expires = 'expires=' + d.toUTCString(); 182 document.cookie = `${name}=${value}; ${expires}; path=/; domain=.chatway.app; Secure; SameSite=None`; 183 }); 184}; 185 186/***/ }), 187
188/***/ "./src/modules/comparison-table.ts": 189/*!*****************************************!*\ 190 !*** ./src/modules/comparison-table.ts ***! 191 \*****************************************/ 192/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 193 194__webpack_require__.r(__webpack_exports__); 195/* harmony export */ __webpack_require__.d(__webpack_exports__, { 196/* harmony export */ "default": () => (/* binding */ ComparisonTable) 197/* harmony export */ }); 198/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ "./node_modules/gsap/index.js"); 199/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/ScrollTrigger */ "./node_modules/gsap/ScrollTrigger.js"); 200 201 202const $ = window.jQuery; 203class ComparisonTable { 204 constructor() { 205 Object.defineProperty(this, "primaryHeaderOffset", { 206 enumerable: true, 207 configurable: true, 208 writable: true, 209 value: 0 210 }); 211 Object.defineProperty(this, "scrollTrigger", { 212 enumerable: true, 213 configurable: true, 214 writable: true, 215 value: void 0 216 }); 217 if (!this.isElementsReady) return; 218 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__.ScrollTrigger); 219 this.events(); 220 } 221 events() { 222 const self = this; 223 const elements = self.elements; 224 self.sticky(false); 225 elements.$primaryHeader.on('sticky-header:show', () => { 226 const rect = elements.$primaryHeader.position(); 227 const height = elements.$primaryHeader.outerHeight(); 228 self.primaryHeaderOffset = rect.top + height; 229 self.scrollTrigger.refresh(); 230 }); 231 elements.$primaryHeader.on('sticky-header:hide', () => { 232 const rect = elements.$primaryHeader.position(); 233 const height = elements.$primaryHeader.outerHeight(); 234 self.primaryHeaderOffset = rect.top + height; 235 self.scrollTrigger.refresh(); 236 }); 237 self.scrollTrigger = gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__.ScrollTrigger.create({ 238 trigger: elements.$body[0], 239 start() { 240 return `top ${self.primaryHeaderOffset}`; 241 }, 242 end() { 243 return `bottom ${self.primaryHeaderOffset}`; 244 }, 245 onToggle() { 246 self.sticky(self.scrollTrigger.isActive); 247 } 248 }); 249 } 250 sticky(status) { 251 this.elements.$sticky.css({ 252 top: `${this.primaryHeaderOffset}px`, 253 display: status ? 'block' : 'none' 254 }); 255 this.elements.$primaryHeader.toggleClass('no-shadow', status); 256 } 257 get selectors() { 258 return { 259 scope: '.comparison-table-sticky', 260 sticky: '.comparison-table-sticky__scope', 261 header: '.comparison-table-sticky__header', 262 body: '.comparison-table-sticky__body', 263 primaryHeader: '#chatway-theme-header' 264 }; 265 } 266 get elements() { 267 const selectors = this.selectors; 268 const $scope = $(selectors.scope); 269 return { 270 $scope, 271 $sticky: $scope.find(selectors.sticky), 272 $header: $scope.find(selectors.header), 273 $body: $scope.find(selectors.body), 274 $primaryHeader: $(selectors.primaryHeader) 275 }; 276 } 277 get isElementsReady() { 278 const { 279 $scope, 280 $sticky, 281 $header, 282 $body 283 } = this.elements; 284 return $scope.length && $sticky.length && $header.length && $body.length; 285 } 286} 287 288/***/ }), 289
290/***/ "./src/modules/feature-slide.ts": 291/*!**************************************!*\ 292 !*** ./src/modules/feature-slide.ts ***! 293 \**************************************/ 294/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 295 296__webpack_require__.r(__webpack_exports__); 297/* harmony export */ __webpack_require__.d(__webpack_exports__, { 298/* harmony export */ "default": () => (/* binding */ FeatureSlide) 299/* harmony export */ }); 300/* harmony import */ var _base_Helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/base/Helper */ "./src/base/Helper.ts"); 301const $ = window.jQuery; 302 303class FeatureSlide { 304 constructor() { 305 this.init(); 306 } 307 get selectors() { 308 return { 309 scope: '.feature-slide', 310 header: '.feature-slide__header', 311 body: '.feature-slide__body', 312 prev: '.feature-slide__prev', 313 next: '.feature-slide__next' 314 }; 315 } 316 slickSettings() { 317 return { 318 header: { 319 slidesToShow: 5, 320 slidesToScroll: 1, 321 asNavFor: this.selectors.body, 322 focusOnSelect: true, 323 variableWidth: true, 324 arrows: false, 325 infinite: false, 326 accessibility: false, 327 // autoplay: true, 328 // autoplaySpeed: 3000, 329 cssEase: 'linear', 330 // add responsive settings 331 responsive: [{ 332 breakpoint: 700, 333 settings: { 334 slidesToShow: 2, 335 slidesToScroll: 1, 336 swipeToSlide: true 337 } 338 }] 339 }, 340 body: { 341 slidesToShow: 1, 342 slidesToScroll: 1, 343 arrows: false, 344 fade: true, 345 swipeToSlide: true, 346 accessibility: false, 347 // autoplay: true, 348 // autoplaySpeed: 3000, 349 asNavFor: this.selectors.header, 350 infinite: false, 351 cssEase: 'linear' 352 } 353 }; 354 } 355 get elements() { 356 const $scope = $(this.selectors.scope); 357 return { 358 $scope, 359 $header: $scope.find(this.selectors.header), 360 $body: $scope.find(this.selectors.body), 361 $prev: $scope.find(this.selectors.prev), 362 $next: $scope.find(this.selectors.next) 363 }; 364 } 365 setupTablist() { 366 const { 367 $header 368 } = this.elements; 369 const $track = $header.find('.slick-track'); 370 if (!$track.length) { 371 return; 372 } 373 const label = $header.attr('aria-label') || 'Product features'; 374 // Slick wraps tabs in .slick-track; tablist must be the direct parent of role="tab". 375 $header.removeAttr('role aria-label'); 376 $track.attr('role', 'tablist'); 377 $track.attr('aria-label', label); 378 } 379 syncTabSelection(currentSlide) { 380 const { 381 $header, 382 $body 383 } = this.elements; 384 $header.find('.slick-track .slick-slide[role="tab"]').each((index, tab) => { 385 const isSelected = index === currentSlide; 386 const $tab = $(tab); 387 $tab.attr('aria-selected', isSelected ? 'true' : 'false'); 388 $tab.attr('tabindex', isSelected ? '0' : '-1'); 389 }); 390 $body.find('.slick-track .slick-slide[role="tabpanel"]').each((index, panel) => { 391 const isSelected = index === currentSlide; 392 $(panel).attr('aria-hidden', isSelected ? 'false' : 'true'); 393 }); 394 } 395 init() { 396 const { 397 $header, 398 $body, 399 $prev, 400 $next 401 } = this.elements; 402 const settings = this.slickSettings(); 403 const toggleArrows = (currentSlide, slideCount) => { 404 $prev.prop('disabled', currentSlide === 0); 405 $next.prop('disabled', currentSlide === slideCount - 1); 406 this.syncTabSelection(currentSlide); 407 }; 408 if (_base_Helper__WEBPACK_IMPORTED_MODULE_0__["default"].slickExists($header)) { 409 $header.on('init reInit', (_event, slick) => { 410 this.setupTablist(); 411 this.syncTabSelection(slick.currentSlide); 412 }); 413 $header.slick(settings.header); 414 this.setupTablist(); 415 } 416 if (_base_Helper__WEBPACK_IMPORTED_MODULE_0__["default"].slickExists($body)) { 417 $body.on('init', (_event, slick) => { 418 toggleArrows(slick.currentSlide, slick.slideCount); 419 }); 420 $body.on('beforeChange', (_event, slick, _currentSlide, nextSlide) => { 421 toggleArrows(nextSlide, slick.slideCount); 422 }); 423 $body.slick(settings.body); 424 } 425 $prev.on('click', () => { 426 $header.slick('slickPrev'); 427 }); 428 $next.on('click', () => { 429 $header.slick('slickNext'); 430 }); 431 } 432} 433 434/***/ }), 435
436/***/ "./src/modules/glossary-scroll-pagination.ts": 437/*!***************************************************!*\ 438 !*** ./src/modules/glossary-scroll-pagination.ts ***! 439 \***************************************************/ 440/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 441 442__webpack_require__.r(__webpack_exports__); 443/* harmony export */ __webpack_require__.d(__webpack_exports__, { 444/* harmony export */ "default": () => (/* binding */ GlossaryInfiniteScroll) 445/* harmony export */ }); 446// import { LibExists } from "@/helper/decorators"; 447// import DomHandlerAbstract from "@/abstracts/domHandlerAbstract"; 448const $ = jQuery; 449class GlossaryInfiniteScroll { 450 constructor() { 451 Object.defineProperty(this, "isLoading", { 452 enumerable: true, 453 configurable: true, 454 writable: true, 455 value: false 456 }); 457 Object.defineProperty(this, "page", { 458 enumerable: true, 459 configurable: true, 460 writable: true, 461 value: 2 462 }); 463 Object.defineProperty(this, "hasMore", { 464 enumerable: true, 465 configurable: true, 466 writable: true, 467 value: true 468 }); 469 Object.defineProperty(this, "context", { 470 enumerable: true, 471 configurable: true, 472 writable: true, 473 value: '' 474 }); 475 Object.defineProperty(this, "termSlug", { 476 enumerable: true, 477 configurable: true, 478 writable: true, 479 value: '' 480 }); 481 Object.defineProperty(this, "searchQuery", { 482 enumerable: true, 483 configurable: true, 484 writable: true, 485 value: '' 486 }); 487 this.domReady(); // <== ADD THIS 488 } 489 get selectors() { 490 return { 491 container: '.tab-content', 492 itemsContainer: '.tab-content-inner', 493 loadingIndicator: '#glossary-loading' 494 }; 495 } 496 get elements() { 497 return { 498 $container: $(this.selectors.container), 499 $itemsContainer: $(this.selectors.itemsContainer), 500 $loadingIndicator: $(this.selectors.loadingIndicator) 501 }; 502 } 503 domReady() { 504 // if dom is exisits 505 if (this.elements.$container.length) { 506 if (this.elements.$container.find('.no-result-page').length > 0) { 507 return; 508 } 509 $(window).on('load', () => { 510 $(window).scrollTop(0); 511 }); 512 this.initContext(); 513 this.setupScrollListener(); 514 // set time out for 500 515 } 516 } 517 initContext() { 518 if (this.elements.$container.data('is-tax')) { 519 this.context = 'term'; 520 this.termSlug = this.elements.$container.data('term-slug') || ''; 521 } else if (this.elements.$container.data('is-search')) { 522 this.context = 'search'; 523 this.searchQuery = this.elements.$container.data('search-query') || ''; 524 } else { 525 this.context = 'archive'; 526 } 527 } 528 createLoadingIndicator() { 529 this.elements.$container.append(` 530 <div id="glossary-loading" class="hidden py-8 flex justify-center text-center mx-auto"> 531 <svg xmlns="http://www.w3.org/2000/svg" width="38" height="38" viewBox="0 0 38 38" fill="none"> 532 <g clip-path="url(#paint0_angular_62543_71575_clip_path)" data-figma-skip-parse="true"><g transform="matrix(0.016 -6.99382e-10 6.99382e-10 0.016 19 19)"><foreignObject x="-1375" y="-1375" width="2750" height="2750"><div xmlns="http://www.w3.org/1999/xhtml" style="background:conic-gradient(from 90deg,rgba(197, 152, 151, 1) 0deg,rgba(119, 97, 223, 1) 39.8444deg,rgba(81, 219, 238, 1) 131.25deg,rgba(239, 156, 219, 1) 198.75deg,rgba(255, 99, 118, 1) 253.125deg,rgba(255, 193, 99, 1) 330.628deg,rgba(197, 152, 151, 1) 360deg);height:100%;width:100%;opacity:1"></div></foreignObject></g></g><path d="M19 3L19 6C26.1797 6 32 11.8203 32 19L35 19L38 19C38 8.50659 29.4934 -1.15806e-06 19 -6.99382e-07L19 3ZM35 19L32 19C32 26.1797 26.1797 32 19 32L19 35L19 38C29.4934 38 38 29.4934 38 19L35 19ZM19 35L19 32C11.8203 32 6 26.1797 6 19L3 19L-6.99382e-07 19C-2.40701e-07 29.4934 8.50659 38 19 38L19 35ZM3 19L6 19C6 11.8203 11.8203 6 19 6L19 3L19 -6.99382e-07C8.50659 -2.40701e-07 -1.15806e-06 8.50659 -6.99382e-07 19L3 19Z" data-figma-gradient-fill="{"type":"GRADIENT_ANGULAR","stops":[{"color":{"r":0.46666666865348816,"g":0.38039216399192810,"b":0.87450981140136719,"a":1.0},"position":0.11067881435155869},{"color":{"r":0.31764706969261169,"g":0.85882353782653809,"b":0.93333333730697632,"a":1.0},"position":0.36458334326744080},{"color":{"r":0.93750,"g":0.613281250,"b":0.86136698722839355,"a":1.0},"position":0.55208331346511841},{"color":{"r":1.0,"g":0.38823530077934265,"b":0.46274510025978088,"a":1.0},"position":0.7031250},{"color":{"r":1.0,"g":0.75686275959014893,"b":0.38823530077934265,"a":1.0},"position":0.91841232776641846}],"stopsVar":[{"color":{"r":0.46666666865348816,"g":0.38039216399192810,"b":0.87450981140136719,"a":1.0},"position":0.11067881435155869},{"color":{"r":0.31764706969261169,"g":0.85882353782653809,"b":0.93333333730697632,"a":1.0},"position":0.36458334326744080},{"color":{"r":0.93750,"g":0.613281250,"b":0.86136698722839355,"a":1.0},"position":0.55208331346511841},{"color":{"r":1.0,"g":0.38823530077934265,"b":0.46274510025978088,"a":1.0},"position":0.7031250},{"color":{"r":1.0,"g":0.75686275959014893,"b":0.38823530077934265,"a":1.0},"position":0.91841232776641846}],"transform":{"m00":32.0,"m01":1.3987645388624514e-06,"m02":2.9999985694885254,"m10":-1.3987645388624514e-06,"m11":32.0,"m12":3.0},"opacity":1.0,"blendMode":"NORMAL","visible":true}"/> 533 <animateTransform xmlns="http://www.w3.org/2000/svg" attributeName="transform" type="rotate" values="0 0 0;
533360 0 0" dur="0.9s" repeatCount="indefinite"/> 534 <defs xmlns="http://www.w3.org/2000/svg"> 535 <clipPath id="paint0_angular_62543_71575_clip_path"><path d="M19 3L19 6C26.1797 6 32 11.8203 32 19L35 19L38 19C38 8.50659 29.4934 -1.15806e-06 19 -6.99382e-07L19 3ZM35 19L32 19C32 26.1797 26.1797 32 19 32L19 35L19 38C29.4934 38 38 29.4934 38 19L35 19ZM19 35L19 32C11.8203 32 6 26.1797 6 19L3 19L-6.99382e-07 19C-2.40701e-07 29.4934 8.50659 38 19 38L19 35ZM3 19L6 19C6 11.8203 11.8203 6 19 6L19 3L19 -6.99382e-07C8.50659 -2.40701e-07 -1.15806e-06 8.50659 -6.99382e-07 19L3 19Z"/></clipPath></defs> 536 </svg> 537 </div> 538 `); 539 } 540 // @LibExists('jQuery') 541 setupScrollListener() { 542 const scrollThreshold = 800; // Distance from the bottom to trigger loading 543 const $window = $(window); 544 const checkScroll = () => { 545 if (this.isLoading || !this.hasMore) return; 546 const scrollTop = $window.scrollTop() || 0; 547 const windowHeight = $window.height() || 0; 548 const documentHeight = $(document).height() || 0; 549 // Check if the scroll is near the bottom 550 if (scrollTop + windowHeight >= documentHeight - scrollThreshold) { 551 this.createLoadingIndicator(); 552 // Introduce a 1-second delay before loading more posts 553 this.loadMorePosts(); 554 } 555 }; 556 // Bind scroll event to the checkScroll function 557 $window.on('scroll', checkScroll); 558 // Initial check in case the page content is not tall enough to fill the viewport 559 // setTimeout(checkScroll, 0); 560 } 561 loadMorePosts() { 562 this.isLoading = true; 563 this.elements.$loadingIndicator.removeClass('hidden'); 564 const requestData = { 565 action: 'chatway_glossary_infinite_scroll', 566 page: this.page, 567 context: this.context, 568 term_slug: this.termSlug, 569 search_query: this.searchQuery, 570 _wpnonce: Chatway_Ajax.nonce 571 }; 572 $.ajax({ 573 url: Chatway_Ajax.ajax_url, 574 type: 'POST', 575 dataType: 'json', 576 data: requestData 577 }).done(response => { 578 if (response.data.success) { 579 const data = response.data.data; 580 if (!data.length) { 581 this.hasMore = false; 582 this.elements.$loadingIndicator.remove(); 583 this.showNoResultsMessage(); 584 return; 585 } 586 this.appendPosts(data, response.data.context); 587 this.page++; // Increment only if data is present 588 this.isLoading = false; 589 this.elements.$loadingIndicator.remove(); 590 } else { 591 this.hasMore = false; 592 this.showNoResultsMessage(); 593 } 594 }).fail(error => { 595 console.error('Error loading more posts:', error); 596 this.elements.$loadingIndicator.remove(); 597 }).always(() => { 598 // this.isLoading = false; 599 // this.elements.$loadingIndicator.addClass('hidden'); 600 this.elements.$loadingIndicator.remove(); 601 }); 602 } 603 appendPosts(termsData, context) { 604 termsData.forEach(termData => { 605 if (context === 'archive') { 606 const termHtml = ` 607 <div class="single-tab-content flex flex-col sm:flex-row justify-start gap-6 py-6"> 608 <div class="tab-title w-full sm:w-[40px]"> 609 <h2 class="text-[#0C1D36] font-poppins text-2xl font-semibold leading-[38.4px]">${termData.term_name}</h2> 610 </div> 611 <div class="tab-content-inner flex flex-col gap-4 w-full"> 612 ${this.generatePostsHtml(termData.posts)} 613 </div> 614 </div> 615 `; 616 this.elements.$container.append(termHtml); 617 } else if (context === 'search') { 618 // Check if .single-tab-content is available or not 619 let $tabContent = this.elements.$container.find('.single-tab-content'); 620 if ($tabContent.length === 0) { 621 // If not found, append a new .single-tab-content container 622 this.elements.$container.append(` 623 <div class="single-tab-content flex flex-col sm:flex-row justify-start gap-6 py-6"> 624 <div class="tab-content-inner flex flex-col gap-4 w-full"> 625 ${this.generatePostsHtml(termData.posts)} 626 </div> 627 </div> 628 `); 629 } else { 630 // If found, just append to the existing container 631 $tabContent.find('.tab-content-inner').append(this.generatePostsHtml(termData.posts)); 632 } 633 } else if (context === 'term') { 634 // Check if .single-tab-content is available or not 635 let $tabContent = this.elements.$container.find('.single-tab-content'); 636 if ($tabContent.length === 0) { 637 // If not found, append a new .single-tab-content container 638 this.elements.$container.append(` 639 <div class="single-tab-content flex flex-col sm:flex-row justify-start gap-6 py-6"> 640 <div class="tab-title w-full sm:w-[40px]"> 641 <h2 class="text-[#0C1D36] font-poppins text-2xl font-semibold leading-[38.4px]">${termData.term_name}</h2> 642 </div> 643 <div class="tab-content-inner flex flex-col gap-4 w-full"> 644 ${this.generatePostsHtml(termData.posts)} 645 </div> 646 </div> 647 `); 648 } else { 649 // If found, just append to the existing container 650 $tabContent.find('.tab-content-inner').append(this.generatePostsHtml(termData.posts)); 651 } 652 } 653 }); 654 } 655 generatePostsHtml(posts) { 656 console.log(posts); 657 return posts.map(post => `
658 <a href="${post.permalink}" class="rounded-[8px] border border-[#E6E6F0] bg-white p-4 hover:shadow-[0_4px_8px_-2px_rgba(10,13,18,0.10),_0_2px_4px_-2px_rgba(10,13,18,0.06)] transition-shadow"> 659 <h4 class="text-black py-[0px] mb-2 text-base font-semibold leading-[25.2px] hover:text-[#0446DE]">${post.title}</h4> 660 ${post.excerpt ? `<p class="text-[#5A6185] font-poppins text-sm font-normal leading-[19.6px]">${post.excerpt}</p>` : ''} 661 </a> 662 `).join(''); 663 } 664 showNoResultsMessage() { 665 if (!this.elements.$container.find('.no-more-posts').length) { 666 this.elements.$container.append(` 667 <div class="no-more-posts py-6 text-center text-[#5A6185] font-poppins text-sm"> 668 No more terms were found. 669 </div> 670 `); 671 } 672 } 673} 674 675/***/ }), 676
677/***/ "./src/modules/glossary-search.ts": 678/*!****************************************!*\ 679 !*** ./src/modules/glossary-search.ts ***! 680 \****************************************/ 681/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 682 683__webpack_require__.r(__webpack_exports__); 684/* harmony export */ __webpack_require__.d(__webpack_exports__, { 685/* harmony export */ "default": () => (/* binding */ AcademySearch) 686/* harmony export */ }); 687const $ = window.jQuery; 688const searchIcon = `<svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 689 <path d="M9.16667 15.8333C12.8486 15.8333 15.8333 12.8486 15.8333 9.16667C15.8333 5.48477 12.8486 2.5 9.16667 2.5C5.48477 2.5 2.5 5.48477 2.5 9.16667C2.5 12.8486 5.48477 15.8333 9.16667 15.8333Z" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 690 <path d="M17.5 17.5L13.875 13.875" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 691 </svg>`; 692const recentSearchIcon = `<svg aria-hidden="true" focusable="false" width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"> 693 <path d="M1.5 4.875L2.37393 8.29754L5.79648 7.42361" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 694 <path d="M2.92504 12.5C3.46537 14.0337 4.48949 15.3502 5.84309 16.2512C7.19669 17.1522 8.80644 17.5889 10.4298 17.4954C12.0532 17.402 13.6022 16.7835 14.8435 15.7332C16.0848 14.6828 16.9511 13.2575 17.3119 11.672C17.6727 10.0865 17.5084 8.42667 16.8439 6.94262C16.1793 5.45858 15.0505 4.2307 13.6274 3.44401C12.2043 2.65732 10.5641 2.35442 8.95394 2.58097C7.34375 2.80751 5.8508 3.55122 4.70004 4.70004C4.70004 4.70004 3.00012 6.5 2.50012 7.75" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 695 <path d="M9.5 7.5V11H12.5" stroke="#374151" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/> 696 </svg>`; 697class AcademySearch { 698 constructor() { 699 Object.defineProperty(this, "recentSearchesKey", { 700 enumerable: true, 701 configurable: true, 702 writable: true, 703 value: 'recentSearches' 704 }); 705 this.domReady(); // <== ADD THIS 706 } 707 get selectors() { 708 return { 709 searchInput: '#popt-glossary-search', 710 suggestionBox: '.popt-glossary-serach-suggestions' 711 }; 712 } 713 get elements() { 714 const { 715 searchInput, 716 suggestionBox 717 } = this.selectors; 718 return { 719 $searchInput: $(searchInput), 720 $suggestionBox: $(suggestionBox) 721 }; 722 } 723 domReady() { 724 this.elements.$searchInput.attr('autocomplete', 'off').attr('autocorrect', 'off').attr('autocapitalize', 'off').attr('spellcheck', 'false'); 725 this.bindSearch(); 726 this.bindFocusEvent(); 727 } 728 bindSearch() { 729 const { 730 $searchInput 731 } = this.elements; // Removed unused $suggestionBox 732 $searchInput.on('keyup', () => { 733 const keyword = $searchInput.val().trim(); 734 if (keyword.length < 2) { 735 this.showRecentSearches(); 736 this.elements.$suggestionBox.hide(); 737 return; 738 } 739 if (keyword.length > 0) { 740 // remove class visible 741 this.elements.$suggestionBox.removeClass('hidden'); 742 } 743 this.fetchSuggestions(keyword).then(results => { 744 this.renderSuggestions(results, keyword); 745 this.elements.$suggestionBox.show(); 746 }).catch(error => console.error('Search AJAX error:', error)); 747 }); 748 // on enter key 749 $searchInput.on('keydown', e => { 750 if (e.key === 'Enter') { 751 const keyword = $searchInput.val().trim(); 752 this.storeRecentSearch(keyword); 753 } 754 }); 755 } 756 bindFocusEvent() { 757 const { 758 $searchInput 759 } = this.elements; 760 $searchInput.on('focus', () => { 761 const keyword = $searchInput.val().trim(); 762 if (keyword.length < 2) { 763 this.showRecentSearches(); 764 } 765 }); 766 } 767 showRecentSearches() { 768 const { 769 $suggestionBox 770 } = this.elements; 771 const recentSearches = this.getRecentSearches(); 772 if (recentSearches.length === 0) { 773 $suggestionBox.html('<div class="no-recent-searches flex items-center p-2 px-3 gap-2 self
773-stretch roundeds">No recent searches</div>'); 774 // return; 775 } else { 776 let html = '<div class="flex text-[#5A6185] text-[12px] leading-[1.4] font-normal items-center p-2 px-3 gap-2 self-stretch rounded">Recent Searches</div>'; 777 recentSearches.forEach(search => { 778 html += ` 779 <button type="button" class="recent-search-btn flex items-center p-2 px-3 gap-2 self-stretch rounded text-[16px] text-[#0C1D36] font-normal w-full text-left"> 780 <span aria-hidden="true">${recentSearchIcon}</span>${search} 781 </button>`; 782 }); 783 $suggestionBox.html(html); 784 // Add click handler for recent search buttons 785 $suggestionBox.find('.recent-search-btn').on('click', e => { 786 e.preventDefault(); 787 const searchText = $(e.currentTarget).text().trim(); 788 this.elements.$searchInput.val(searchText).trigger('keyup'); 789 }); 790 } 791 } 792 getRecentSearches() { 793 return JSON.parse(localStorage.getItem(this.recentSearchesKey) || '[]'); 794 } 795 storeRecentSearch(keyword) { 796 if (keyword.length < 2) return; 797 let recentSearches = this.getRecentSearches(); 798 recentSearches = [keyword, ...recentSearches.filter(search => search !== keyword)]; 799 if (recentSearches.length > 5) { 800 recentSearches = recentSearches.slice(0, 5); 801 } 802 localStorage.setItem(this.recentSearchesKey, JSON.stringify(recentSearches)); 803 } 804 fetchSuggestions(keyword) { 805 return new Promise((resolve, reject) => { 806 $.ajax({ 807 url: Chatway_Ajax.ajax_url, 808 type: 'POST', 809 dataType: 'json', 810 data: { 811 action: 'popt_search_suggestions', 812 keyword, 813 _wpnonce: Chatway_Ajax.nonce 814 } 815 }).done(response => { 816 if (response && response.success && Array.isArray(response.data)) { 817 resolve(response.data); 818 } else if (Array.isArray(response)) { 819 resolve(response); 820 } else { 821 resolve([]); 822 } 823 }).fail(errorThrown => { 824 reject(errorThrown); 825 }); 826 }); 827 } 828 renderSuggestions(results, keyword) { 829 const { 830 $suggestionBox 831 } = this.elements; 832 const recentSearches = this.getRecentSearches(); 833 const matchingRecentSearches = recentSearches.filter(search => search.toLowerCase().includes(keyword.toLowerCase())); 834 let html = ''; 835 // Add regular search results 836 if (results.length > 0) { 837 if (matchingRecentSearches.length > 0) { 838 html += ''; 839 } 840 results.forEach(item => { 841 html += ` 842 <a href="${item.url}" class="flex items-center p-2 px-3 gap-2 self-stretch roundeds"> 843 <span aria-hidden="true">${searchIcon}</span><span>${this.highlightMatch(item.title, keyword)}</span> 844 </a>`; 845 }); 846 } 847 // Add matching recent searches first 848 if (matchingRecentSearches.length > 0) { 849 html += '<div class="flex text-[#5A6185] text-[12px] leading-[1.4] font-normal items-center p-2 px-3 gap-2 self-stretch rounded">Recent Searches</div>'; 850 matchingRecentSearches.forEach(search => { 851 html += ` 852 <button type="button" class="recent-search-btn flex items-center p-2 px-3 gap-2 self-stretch roundeds"> 853 <span aria-hidden="true">${recentSearchIcon}</span><span>${this.highlightMatch(search, keyword)}</span> 854 </button>`; 855 }); 856 } else if (matchingRecentSearches.length === 0 && results.length === 0) { 857 html = '<div class="flex items-center p-4 px-3 gap-2 self-stretch roundeds">No results found!</div>'; 858 } 859 $suggestionBox.html(html); 860 // add class to visibile suggestion box 861 $suggestionBox.addClass('visible'); 862 // Add click handler for recent search buttons 863 $suggestionBox.find('.recent-search-btn').on('click', e => { 864 e.preventDefault(); 865 const searchText = $(e.currentTarget).text().replace(/(<([^>]+)>)/gi, '').trim(); 866 this.elements.$searchInput.val(searchText).trigger('keyup'); 867 }); 868 } 869 highlightMatch(text, keyword) { 870 const regex = new RegExp(`(${keyword})`, 'gi'); 871 return text.replace(regex, '<strong>$1</strong>'); 872 } 873} 874 875/***/ }), 876
877/***/ "./src/modules/header/base.ts": 878/*!************************************!*\ 879 !*** ./src/modules/header/base.ts ***! 880 \************************************/ 881/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 882 883__webpack_require__.r(__webpack_exports__); 884/* harmony export */ __webpack_require__.d(__webpack_exports__, { 885/* harmony export */ "default": () => (/* binding */ Base) 886/* harmony export */ }); 887const $ = window.jQuery; 888class Base { 889 constructor() { 890 Object.defineProperty(this, "breakpoint", { 891 enumerable: true, 892 configurable: true, 893 writable: true, 894 value: 1200 895 }); 896 if (this.elements.$header.length > 0) { 897 this.init(); 898 } 899 } 900 get selectors() { 901 return { 902 body: 'body', 903 wpAdminBar: '#wpadminbar', 904 header: '#chatway-theme-header', 905 desktopMegaMenuPlaceholder: '.desktop-mega-menu-placeholder', 906 hamburger: '.breadcrumb-btn', 907 line: '#last-hamburger-line', 908 overlay: '.header-overlay', 909 menu: '.chatway-nav', 910 desktopNav: '.desktop-nav', 911 responsiveNav: '.responsive-nav', 912 megamenu: '.mega-menu.menu-item' 913 }; 914 } 915 get elements() { 916 const { 917 body, 918 wpAdminBar, 919 header, 920 desktopMegaMenuPlaceholder, 921 overlay, 922 hamburger, 923 line, 924 menu, 925 desktopNav, 926 responsiveNav, 927 megamenu 928 } = this.selectors; 929 return { 930 $body: $(body), 931 $wpAdminBar: $(wpAdminBar), 932 $header: $(header), 933 $desktopMegaMenuPlaceholder: $(desktopMegaMenuPlaceholder), 934 $overlay: $(overlay), 935 get $hamburger() { 936 return this.$header.find(hamburger); 937 }, 938 get $line() { 939 return this.$hamburger.find(line); 940 }, 941 get $menu() { 942 return this.$header.find(menu); 943 }, 944 get $megamenu() { 945 return this.$menu.find(megamenu); 946 }, 947 get $desktopNav() { 948 return this.$header.find(desktopNav); 949 }, 950 get $responsiveNav() { 951 return this.$header.find(responsiveNav); 952 } 953 }; 954 } 955 closeOtherMobileNavItems($current) { 956 const { 957 megamenu 958 } = this.selectors; 959 const { 960 $responsiveNav 961 } = this.elements; 962 if (!$responsiveNav.length) { 963 return; 964 } 965 $responsiveNav.find(`${megamenu} > a`).each((_i, el) => { 966 const $btn = $(el); 967 const $dropdown = $btn.next('.mega-menu-dropdown'); 968 if ($btn.is($current) || !$dropdown.is(':visible')) { 969 return; 970 } 971 $btn.removeClass('open').attr('aria-expanded', 'false'); 972 $btn.find('.caret').removeClass('open'); 973 $dropdown.slideUp(200); 974 }); 975 $responsiveNav.find('.dropdown-toggle').each((_i, el) => { 976 const $btn = $(el); 977 const $dropdown = $btn.next('.dropdown'); 978 if ($btn.is($current) || !$dropdown.is(':visible')) { 979 return; 980 } 981 $btn.removeClass('open').attr('aria-expanded', 'false'); 982 $btn.find('.caret').removeClass('open'); 983 $dropdown.slideUp(200); 984 }); 985 } 986} 987 988/***/ }), 989
990/***/ "./src/modules/header/index.ts": 991/*!*************************************!*\ 992 !*** ./src/modules/header/index.ts ***! 993 \*************************************/ 994/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 995 996__webpack_require__.r(__webpack_exports__); 997/* harmony export */ __webpack_require__.d(__webpack_exports__, { 998/* harmony export */ "default": () => (/* binding */ Header) 999/* harmony export */ }); 1000/* harmony import */ var _base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base */ "./src/modules/header/base.ts"); 1001 1002const $ = window.jQuery; 1003class Header extends _base__WEBPACK_IMPORTED_MODULE_0__["default"] { 1004 constructor() { 1005 super(); 1006 } 1007 init() { 1008 this.events(); 1009 this.sticky(); 1010 this.hashRouteHandler(); 1011 this.dropdownHandler(); 1012 } 1013 events() { 1014 const { 1015 $wpAdminBar, 1016 $overlay, 1017 $hamburger, 1018 $body 1019 } = this.elements; 1020 if ($wpAdminBar.length > 0) { 1021 this.resizeOrScroll(); 1022 $(window).on('resize scroll', this.resizeOrScroll.bind(this)); 1023 } else { 1024 this.headerTopGap({ 1025 height: 0, 1026 top: 0 1027 }); 1028 } 1029 $(window).on('scroll', this.sticky.bind(this)); 1030 $hamburger.on('click', () => { 1031 if ($body.hasClass('mobile-menu-opened')) { 1032 this.hideNavigation(); 1033 } else { 1034 this.showNavigation(); 1035 } 1036 }); 1037 $overlay.on('click', this.hideNavigation.bind(this)); 1038 /** 1039 * When Viewport is changed 1040 */ 1041 const mql = window.matchMedia('(max-width: 1200px)'); 1042 const onMediaChange = event => { 1043 if (!event.matches) { 1044 this.hideNavigation(); 1045 } 1046 }; 1047 mql.addListener(onMediaChange); 1048 } 1049 resizeOrScroll() { 1050 const { 1051 $wpAdminBar 1052 } = this.elements; 1053 const rect = $wpAdminBar[0].getBoundingClientRect(); 1054 if (rect) { 1055 this.headerTopGap(rect); 1056 } 1057 } 1058 headerTopGap(adminBarRect) { 1059 const { 1060 $header, 1061 $desktopMegaMenuPlaceholder 1062 } = this.elements; 1063 const y = adminBarRect.top + adminBarRect.height; 1064 const headerHeight = $header.outerHeight(); 1065 const yOffset = y > 0 ? y : 0; 1066 $header.removeClass('top-0'); 1067 $header.css('top', `${yOffset}px`); 1068 $desktopMegaMenuPlaceholder.css('top', `${headerHeight + yOffset}px`); 1069 } 1070 sticky() { 1071 const { 1072 $body, 1073 $header 1074 } = this.elements; 1075 const y = window.scrollY; 1076 if (!$body.hasClass('mobile-menu-opened')) { 1077 $header.toggleClass('sticky-header', y > 0); 1078 this.dispatchStickyEvent(y > 0); 1079 } 1080 } 1081 showNavigation() { 1082 const { 1083 $body, 1084 $header, 1085 $menu, 1086 $overlay, 1087 $line, 1088 $hamburger 1089 } = this.elements; 1090 if (innerWidth > this.breakpoint) return; 1091 $hamburger.attr('aria-expanded', 'true').attr('aria-label', 'Close menu'); 1092 $line.animate({ 1093 x: '0', 1094 width: '100%' 1095 }); 1096 $overlay.fadeIn(); 1097 $header.addClass('sticky-header'); 1098 $header.trigger('mobile-menu:open'); 1099 $body.addClass('mobile-menu-opening'); 1100 $menu.slideDown(400, function () { 1101 $body.removeClass('mobile-menu-opening').addClass('mobile-menu-opened'); 1102 }); 1103 this.dispatchStickyEvent(true); 1104 } 1105 hideNavigation() { 1106 const { 1107 $line, 1108 $menu, 1109 $overlay, 1110 $body, 1111 $hamburger 1112 } = this.elements; 1113 const self = this; 1114 $hamburger.attr('aria-expanded', 'false').attr('aria-label', 'Open menu'); 1115 $line.animate({ 1116 x: '8' 1117 }); 1118 $menu.slideUp(400, function () { 1119 $overlay.fadeOut(); 1120 $body.removeClass('mobile-menu-opened').removeClass('mobile-menu-opening'); 1121 $menu.removeAttr('style'); 1122 self.sticky(); 1123 }); 1124 // close 1125 } 1126 hashRouteHandler() { 1127 const self = this; 1128 const { 1129 $menu 1130 } = this.elements; 1131 const btns = $menu.find('li:not(.mega-menu) a:not(.dropdown-toggle) a:not(.chatway-headwayapp)'); 1132 btns.on('click', ev => { 1133 ev.stopPropagation(); 1134 self.hideNavigation(); 1135 }); 1136 } 1137 dropdownHandler() { 1138 const self = this; 1139 const { 1140 $menu 1141 } = this.elements; 1142 const btns = $menu.find('.dropdown-toggle'); 1143 btns.on('click', function (ev) { 1144 ev.preventDefault(); 1145 ev.stopPropagation(); 1146 const $target = $(this); 1147 const isVisible = $target.next().is(':visible'); 1148 if (!isVisible && innerWidth <= self.breakpoint) { 1149 self.closeOtherMobileNavItems($target); 1150 } 1151 $target.attr('aria-expanded', isVisible ? 'false' : 'true'); 1152 $target.find('.caret').toggleClass('open', !isVisible); 1153 $target.toggleClass('open', !isVisible); 1154 $target.next().slideToggle(200); 1155 }); 1156 } 1157 dispatchStickyEvent(status) { 1158 const { 1159 $header 1160 } = this.elements; 1161 if (status) { 1162 $header.trigger('sticky-header:show'); 1163 } else { 1164 $header.trigger('sticky-header:hide'); 1165 } 1166 } 1167} 1168 1169/***/ }), 1170
1171/***/ "./src/modules/header/megamenu.ts": 1172/*!****************************************!*\ 1173 !*** ./src/modules/header/megamenu.ts ***! 1174 \****************************************/ 1175/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1176 1177__webpack_require__.r(__webpack_exports__); 1178/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1179/* harmony export */ "default": () => (/* binding */ Megamenu) 1180/* harmony export */ }); 1181/* harmony import */ var _base__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./base */ "./src/modules/header/base.ts"); 1182 1183const $ = window.jQuery; 1184class Megamenu extends _base__WEBPACK_IMPORTED_MODULE_0__["default"] { 1185 constructor() { 1186 super(); 1187 } 1188 init() { 1189 this.prepareMobileDropdown(); 1190 this.events(); 1191 } 1192 events() { 1193 const { 1194 megamenu 1195 } = this.selectors; 1196 const { 1197 $desktopMegaMenuPlaceholder, 1198 $desktopNav, 1199 $responsiveNav 1200 } = this.elements; 1201 const $megamenuDesktop = $desktopNav.find(megamenu); 1202 const $megamenuResponsive = $responsiveNav.find(megamenu); 1203 $megamenuDesktop.on('mouseenter', this.showMenu.bind(this)); 1204 $megamenuDesktop.on('mouseleave', this.hideMenu.bind(this)); 1205 $desktopMegaMenuPlaceholder.on('mouseenter', this.showMenu.bind(this)); 1206 $desktopMegaMenuPlaceholder.on('mouseleave', this.hideMenu.bind(this)); 1207 $.each($megamenuResponsive, (_i, el) => { 1208 const $el = $(el); 1209 const $btn = $el.find('a').first(); 1210 $btn.on('click', this.toggleMobileDropdown.bind(this)); 1211 }); 1212 } 1213 prepareMobileDropdown() { 1214 const { 1215 megamenu 1216 } = this.selectors; 1217 const { 1218 $responsiveNav 1219 } = this.elements; 1220 const $megamenu = $responsiveNav.find(megamenu); 1221 $megamenu.each((_i, el) => { 1222 const $el = $(el); 1223 const { 1224 $contentMarkup 1225 } = this.elementsFactory(el); 1226 $el.append(` 1227 <div class="mega-menu-dropdown hidden will-change-transform"> 1228 ${$contentMarkup} 1229 </div> 1230 `); 1231 }); 1232 } 1233 toggleMobileDropdown(ev) { 1234 ev.preventDefault(); 1235 ev.stopPropagation(); 1236 const $target = $(ev.currentTarget); 1237 const isVisible = $target.next().is(':visible'); 1238 if (!isVisible) { 1239 this.closeOtherMobileNavItems($target); 1240 } 1241 $target.attr('aria-expanded', !isVisible ? 'true' : 'false'); 1242 $target.find('.caret').toggleClass('open', !isVisible); 1243 $target.toggleClass('open', !isVisible); 1244 $target.next().slideToggle(200); 1245 } 1246 showMenu(ev) { 1247 ev.preventDefault(); 1248 ev.stopPropagation(); 1249 const elemenets = this.elementsFactory(ev.currentTarget); 1250 const { 1251 $desktopMegaMenuPlaceholder, 1252 $body 1253 } = this.elements; 1254 $desktopMegaMenuPlaceholder.html(elemenets.$contentMarkup); 1255 if (!$body.hasClass('desktop-mega-menu-opened')) { 1256 $body.removeClass('desktop-mega-menu-closing'); 1257 $body.addClass('desktop-mega-menu-opened'); 1258 const spaceLeft = (innerWidth - $desktopMegaMenuPlaceholder.outerWidth()) / 2; 1259 $desktopMegaMenuPlaceholder.css('left', spaceLeft + 'px'); 1260 } 1261 } 1262 hideMenu() { 1263 const { 1264 $body 1265 } = this.elements; 1266 if (!$body.hasClass('desktop-mega-menu-opened') || $body.hasClass('desktop-mega-menu-over') || $body.hasClass('desktop-mega-menu-closing')) return; 1267 $body.removeClass('desktop-mega-menu-opened'); 1268 $body.addClass('desktop-mega-menu-closing'); 1269 setTimeout(() => { 1270 $body.removeClass('desktop-mega-menu-closing'); 1271 }, 300); 1272 } 1273 elementsFactory(el) { 1274 const { 1275 $menu 1276 } = this.elements; 1277 let id = null; 1278 // Loop through all classes of the element 1279 el.classList.forEach(cls => { 1280 const template = document.querySelector(`template.chatway-mega-menu-content[data-menu-for="${cls}"]`); 1281 if (template) { 1282 id = `#${template.id}`; 1283 } 1284 }); 1285 return { 1286 $target: $menu.find(el), 1287 $contentMarkup: $(id).html() 1288 }; 1289 } 1290} 1291 1292/***/ }), 1293
1294/***/ "./src/modules/header/product-megamenu.ts": 1295/*!************************************************!*\ 1296 !*** ./src/modules/header/product-megamenu.ts ***! 1297 \************************************************/ 1298/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1299 1300__webpack_require__.r(__webpack_exports__); 1301/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1302/* harmony export */ "default": () => (/* binding */ ProductMegamenu) 1303/* harmony export */ }); 1304/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ "./node_modules/gsap/index.js"); 1305 1306const $ = window.jQuery; 1307class ProductMegamenu { 1308 constructor() { 1309 Object.defineProperty(this, "animationDuration", { 1310 enumerable: true, 1311 configurable: true, 1312 writable: true, 1313 value: 0.2 1314 }); 1315 Object.defineProperty(this, "desktopBreakpoint", { 1316 enumerable: true, 1317 configurable: true, 1318 writable: true, 1319 value: 1200 1320 }); 1321 Object.defineProperty(this, "panelSwitchDelay", { 1322 enumerable: true, 1323 configurable: true, 1324 writable: true, 1325 value: 50 1326 }); 1327 Object.defineProperty(this, "tabHoverTimeout", { 1328 enumerable: true, 1329 configurable: true, 1330 writable: true, 1331 value: null 1332 }); 1333 Object.defineProperty(this, "pendingTab", { 1334 enumerable: true, 1335 configurable: true, 1336 writable: true, 1337 value: null 1338 }); 1339 Object.defineProperty(this, "panelTimeline", { 1340 enumerable: true, 1341 configurable: true, 1342 writable: true, 1343 value: null 1344 }); 1345 this.init(); 1346 } 1347 init() { 1348 this.events(); 1349 } 1350 get selectors() { 1351 return { 1352 body: 'body', 1353 root: '.product-megamenu', 1354 tab: '.product-megamenu-tab', 1355 panels: '.product-megamenu-panels', 1356 desktop: '.product-megamenu-desktop', 1357 panel: '.product-megamenu-panel', 1358 panelsTrack: '.product-megamenu-panels-track', 1359 accordionTrigger: '.product-megamenu-accordion-trigger', 1360 accordionPanel: '.product-megamenu-accordion-panel', 1361 activeClass: 'active', 1362 hiddenClass: 'hidden', 1363 animatingClass: 'is-animating', 1364 openClass: 'open' 1365 }; 1366 } 1367 get elements() { 1368 const { 1369 body 1370 } = this.selectors; 1371 return { 1372 $body: $(body) 1373 }; 1374 } 1375 isDesktop() { 1376 return window.matchMedia(`(min-width: ${this.desktopBreakpoint}px)`).matches; 1377 } 1378 events() { 1379 const { 1380 $body 1381 } = this.elements; 1382 const { 1383 tab, 1384 panels, 1385 desktop, 1386 accordionTrigger 1387 } = this.selectors; 1388 $body.on('mouseenter', tab, this.onTabHover.bind(this)); 1389 $body.on('mouseenter', panels, this.onPanelsEnter.bind(this)); 1390 $body.on('mouseleave', desktop, this.onDesktopLeave.bind(this)); 1391 $body.on('click', accordionTrigger, this.onAccordionClick.bind(this)); 1392 } 1393 clearTabHoverTimeout() { 1394 if (this.tabHoverTimeout) { 1395 clearTimeout(this.tabHoverTimeout); 1396 this.tabHoverTimeout = null; 1397 } 1398 } 1399 schedulePanelSwitch($tab) { 1400 this.pendingTab = $tab; 1401 this.clearTabHoverTimeout(); 1402 this.tabHoverTimeout = setTimeout(() => { 1403 this.tabHoverTimeout = null; 1404 this.flushPendingTabHover(); 1405 }, this.panelSwitchDelay); 1406 } 1407 flushPendingTabHover() { 1408 this.clearTabHoverTimeout(); 1409 const $tab = this.pendingTab; 1410 this.pendingTab = null; 1411 if ($tab === null || $tab === void 0 ? void 0 : $tab.length) { 1412 this.activatePanel($tab); 1413 } 1414 } 1415 onPanelsEnter() { 1416 if (!this.isDesktop()) { 1417 return; 1418 } 1419 this.flushPendingTabHover(); 1420 } 1421 onDesktopLeave(ev) { 1422 if (!this.isDesktop()) { 1423 return; 1424 } 1425 this.clearTabHoverTimeout(); 1426 this.pendingTab = null; 1427 const { 1428 root 1429 } = this.selectors; 1430 const $menu = $(ev.currentTarget).closest(root); 1431 if ($menu.length) { 1432 this.resetPanelAnimation($menu); 1433 } 1434 } 1435 onAccordionClick(ev) { 1436 ev.preventDefault(); 1437 ev.stopPropagation(); 1438 if (this.isDesktop()) { 1439 return; 1440 } 1441 const { 1442 root, 1443 accordionTrigger, 1444 accordionPanel, 1445 openClass 1446 } = this.selectors; 1447 const $trigger = $(ev.currentTarget); 1448 const $menu = $trigger.closest(root); 1449 if (!$menu.length) { 1450 return; 1451 } 1452 const targetId = $trigger.data('target'); 1453 if (!targetId) { 1454 return; 1455 } 1456 const $panel = this.findById($menu, targetId); 1457 if (!$panel.length) { 1458 return; 1459 } 1460 const isVisible = $panel.is(':visible'); 1461 if (!isVisible) {
1462 $menu.find(accordionPanel).slideUp(200); 1463 $menu.find(accordionTrigger).removeClass(openClass).attr('aria-expanded', 'false').find('.caret').removeClass(openClass); 1464 } 1465 $trigger.toggleClass(openClass, !isVisible).attr('aria-expanded', !isVisible ? 'true' : 'false'); 1466 $trigger.find('.caret').toggleClass(openClass, !isVisible); 1467 $panel.slideToggle(200); 1468 } 1469 onTabHover(ev) { 1470 if (!this.isDesktop()) { 1471 return; 1472 } 1473 const $tab = $(ev.currentTarget); 1474 const { 1475 root 1476 } = this.selectors; 1477 const $menu = $tab.closest(root); 1478 if (!$menu.length) { 1479 return; 1480 } 1481 this.setActiveTabState($tab, $menu); 1482 const { 1483 animatingClass 1484 } = this.selectors; 1485 if ($menu.hasClass(animatingClass) || this.panelTimeline) { 1486 this.pendingTab = $tab; 1487 this.clearTabHoverTimeout(); 1488 this.activatePanel($tab, true); 1489 return; 1490 } 1491 this.schedulePanelSwitch($tab); 1492 } 1493 setActiveTabState($tab, $menu) { 1494 const { 1495 tab, 1496 activeClass 1497 } = this.selectors; 1498 $menu.find(tab).removeClass(activeClass).attr('aria-selected', 'false'); 1499 $tab.addClass(activeClass).attr('aria-selected', 'true'); 1500 } 1501 findById(scope, id) { 1502 if (!scope || !id) { 1503 return $(); 1504 } 1505 const root = 'querySelector' in scope ? scope : scope.get(0); 1506 if (!root) { 1507 return $(); 1508 } 1509 const match = root.querySelector(`[id="${id}"]`); 1510 return match ? $(match) : $(); 1511 } 1512 findDesktopPanel($menu, id) { 1513 var _a; 1514 const { 1515 desktop 1516 } = this.selectors; 1517 const desktopEl = (_a = $menu.get(0)) === null || _a === void 0 ? void 0 : _a.querySelector(desktop); 1518 return this.findById(desktopEl, id); 1519 } 1520 activatePanel($tab, instant = false) { 1521 var _a; 1522 const { 1523 root, 1524 tab, 1525 panel, 1526 panelsTrack, 1527 desktop, 1528 activeClass, 1529 hiddenClass, 1530 animatingClass 1531 } = this.selectors; 1532 if (!((_a = $tab.get(0)) === null || _a === void 0 ? void 0 : _a.isConnected)) { 1533 return; 1534 } 1535 const $menu = $tab.closest(root); 1536 if (!$menu.length) { 1537 return; 1538 } 1539 const targetId = $tab.data('target'); 1540 if (!targetId) { 1541 return; 1542 } 1543 const $panel = this.findDesktopPanel($menu, targetId); 1544 if (!$panel.length) { 1545 return; 1546 } 1547 this.resetPanelAnimation($menu); 1548 const $desktop = $menu.find(desktop); 1549 const $activePanel = $desktop.find(`${panel}.${activeClass}`).first(); 1550 const $panelsTrack = $menu.find(panelsTrack); 1551 if ($panel.is($activePanel)) { 1552 return; 1553 } 1554 const activePanelId = $activePanel.attr('id'); 1555 const $previousTab = activePanelId ? $desktop.find(`${tab}[data-target="${activePanelId}"]`) : $(); 1556 const oldIndex = $desktop.find(tab).index($previousTab); 1557 const newIndex = $desktop.find(tab).index($tab); 1558 const goingDown = newIndex > oldIndex; 1559 if (instant || !$activePanel.length || window.matchMedia('(prefers-reduced-motion: reduce)').matches) { 1560 this.switchPanelInstant($activePanel, $panel, activeClass, hiddenClass); 1561 return; 1562 } 1563 this.switchPanelAnimated($menu, $activePanel, $panel, $panelsTrack, goingDown, activeClass, hiddenClass, animatingClass); 1564 } 1565 switchPanelInstant($activePanel, $panel, activeClass, hiddenClass) { 1566 $activePanel.removeClass(activeClass).addClass(hiddenClass); 1567 $panel.removeClass(hiddenClass).addClass(activeClass); 1568 } 1569 measurePanelHeight($panel, hiddenClass) { 1570 var _a; 1571 const panelEl = $panel.get(0); 1572 if (!panelEl) { 1573 return 0; 1574 } 1575 const wasHidden = $panel.hasClass(hiddenClass); 1576 if (wasHidden) { 1577 $panel.removeClass(hiddenClass); 1578 } 1579 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelEl, { 1580 position: 'absolute', 1581 visibility: 'hidden', 1582 pointerEvents: 'none', 1583 width: '100%', 1584 left: 0, 1585 top: 0 1586 }); 1587 const height = (_a = $panel.outerHeight()) !== null && _a !== void 0 ? _a : 0; 1588 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelEl, { 1589 clearProps: 'position,visibility,pointerEvents,width,left,top' 1590 }); 1591 if (wasHidden) { 1592 $panel.addClass(hiddenClass); 1593 } 1594 return height; 1595 } 1596 resetPanelAnimation($menu) { 1597 const { 1598 desktop, 1599 panel, 1600 panelsTrack, 1601 activeClass, 1602 hiddenClass, 1603 animatingClass 1604 } = this.selectors; 1605 if (this.panelTimeline) { 1606 this.panelTimeline.kill(); 1607 this.panelTimeline = null; 1608 } 1609 const $desktop = $menu.find(desktop); 1610 const $panels = $desktop.find(panel); 1611 const $track = $desktop.find(panelsTrack); 1612 const panels = $panels.get(); 1613 const track = $track.get(); 1614 if (panels.length) { 1615 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.killTweensOf(panels); 1616 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panels, { 1617 clearProps: 'all' 1618 }); 1619 } 1620 if (track.length) { 1621 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.killTweensOf(track); 1622 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(track, { 1623 clearProps: 'all' 1624 }); 1625 } 1626 $panels.each((_i, el) => { 1627 const $el = $(el); 1628 if ($el.hasClass(activeClass)) { 1629 $el.removeClass(hiddenClass); 1630 } else { 1631 $el.addClass(hiddenClass); 1632 } 1633 }); 1634 $menu.removeClass(animatingClass); 1635 } 1636 switchPanelAnimated($menu, $activePanel, $panel, $panelsTrack, goingDown, activeClass, hiddenClass, animatingClass) { 1637 var _a; 1638 const activePanelEl = $activePanel.get(0); 1639 const panelEl = $panel.get(0); 1640 const panelsTrackEl = $panelsTrack.get(0); 1641 if (!activePanelEl || !panelEl || !panelsTrackEl) { 1642 this.switchPanelInstant($activePanel, $panel, activeClass, hiddenClass); 1643 return; 1644 } 1645 const exitY = goingDown ? -20 : 20; 1646 const enterY = goingDown ? 20 : -20; 1647 const currentHeight = (_a = $activePanel.outerHeight()) !== null && _a !== void 0 ? _a : 0; 1648 const nextHeight = this.measurePanelHeight($panel, hiddenClass); 1649 const duration = this.animationDuration; 1650 const swapAt = duration * 0.5; 1651 $menu.addClass(animatingClass); 1652 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelsTrackEl, { 1653 height: currentHeight, 1654 overflow: 'hidden' 1655 }); 1656 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(activePanelEl, { 1657 position: 'absolute', 1658 top: 0, 1659 left: 0, 1660 width: '100%' 1661 }); 1662 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelEl, { 1663 position: 'absolute', 1664 top: 0, 1665 left: 0, 1666 width: '100%', 1667 autoAlpha: 0, 1668 y: enterY 1669 }); 1670 this.panelTimeline = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline({ 1671 onComplete: () => { 1672 $activePanel.removeClass(activeClass).addClass(hiddenClass); 1673 $panel.removeClass(hiddenClass).addClass(activeClass); 1674 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set([activePanelEl, panelEl], { 1675 clearProps: 'all' 1676 }); 1677 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelsTrackEl, { 1678 clearProps: 'all' 1679 }); 1680 $menu.removeClass(animatingClass); 1681 this.panelTimeline = null; 1682 } 1683 }); 1684 this.panelTimeline.to(panelsTrackEl, { 1685 height: nextHeight, 1686 duration, 1687 ease: 'power2.inOut' 1688 }, 0); 1689 this.panelTimeline.to(activePanelEl, { 1690 y: exitY, 1691 autoAlpha: 0, 1692 duration: swapAt, 1693 ease: 'power2.in' 1694 }, 0); 1695 this.panelTimeline.add(() => { 1696 $activePanel.addClass(hiddenClass); 1697 $panel.removeClass(hiddenClass); 1698 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(panelEl, { 1699 position: 'absolute', 1700 top: 0, 1701 left: 0, 1702 width: '100%', 1703 autoAlpha: 0, 1704 y: enterY 1705 }); 1706 }, swapAt); 1707 this.panelTimeline.to(panelEl, { 1708 y: 0, 1709 autoAlpha: 1, 1710 duration: duration - swapAt, 1711 ease: 'power2.out' 1712 }, swapAt); 1713 } 1714} 1715 1716/***/ }), 1717
1718/***/ "./src/modules/headway.ts": 1719/*!********************************!*\ 1720 !*** ./src/modules/headway.ts ***! 1721 \********************************/ 1722/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1723 1724__webpack_require__.r(__webpack_exports__); 1725/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1726/* harmony export */ "default": () => (/* binding */ Headway) 1727/* harmony export */ }); 1728const $ = window.jQuery; 1729class Headway { 1730 constructor() { 1731 this.init(); 1732 } 1733 init() { 1734 const { 1735 $whatsNewLink 1736 } = this.elements; 1737 $whatsNewLink.on('click', function (ev) { 1738 ev.preventDefault(); 1739 ev.stopPropagation(); 1740 // @ts-ignore 1741 window.Headway.toggle(); 1742 return false; 1743 }); 1744 } 1745 get selectors() { 1746 return { 1747 scope: '.chatway-headwayapp' 1748 }; 1749 } 1750 get elements() { 1751 const { 1752 scope 1753 } = this.selectors; 1754 return { 1755 $scope: $(scope), 1756 get $whatsNewLink() { 1757 return this.$scope.find('a').first(); 1758 } 1759 }; 1760 } 1761} 1762 1763/***/ }), 1764
1765/***/ "./src/modules/loadMorePosts.ts": 1766/*!**************************************!*\ 1767 !*** ./src/modules/loadMorePosts.ts ***! 1768 \**************************************/ 1769/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1770 1771__webpack_require__.r(__webpack_exports__); 1772/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1773/* harmony export */ "default": () => (/* binding */ LoadMorePosts) 1774/* harmony export */ }); 1775const $ = window.jQuery; 1776class LoadMorePosts { 1777 constructor() { 1778 Object.defineProperty(this, "btn", { 1779 enumerable: true, 1780 configurable: true, 1781 writable: true, 1782 value: void 0 1783 }); 1784 Object.defineProperty(this, "postWrapper", { 1785 enumerable: true, 1786 configurable: true, 1787 writable: true, 1788 value: void 0 1789 }); 1790 this.btn = $('#load-more-posts-btn'); 1791 this.postWrapper = $('#all-blog-posts'); 1792 this.events(); 1793 } 1794 events() { 1795 this.btn.on('click', this.requestMorePosts.bind(this)); 1796 } 1797 pushState(url) { 1798 history.replaceState({}, 'Title', url); 1799 } 1800 scrollIntoView($element) { 1801 if ($element && $element.length) { 1802 setTimeout(() => { 1803 $element[0].scrollIntoView({ 1804 behavior: 'smooth', 1805 block: 'center' 1806 }); 1807 }, 0); 1808 } 1809 } 1810 requestMorePosts(ev) { 1811 const self = this; 1812 ev.stopPropagation(); 1813 ev.preventDefault(); 1814 const btn = self.btn.parents('a'); 1815 $.ajax({ 1816 url: btn.attr('href'), 1817 contentType: 'text/html', 1818 beforeSend() { 1819 btn.css({ 1820 pointerEvents: 'none', 1821 opacity: '.5' 1822 }); 1823 self.btn.text('Loading...'); 1824 }, 1825 success(data) { 1826 const doc = $(data); 1827 const content = doc.find('#all-blog-posts'); 1828 const newBtn = doc.find('#load-more-posts-btn'); 1829 if (content.length) { 1830 self.pushState(btn.attr('href')); 1831 self.scrollIntoView(content.find('article').first()); 1832 self.postWrapper.append(content.children()); 1833 } 1834 if (newBtn.length) { 1835 const newLink = newBtn.parents('a').attr('href'); 1836 btn.attr('href', newLink); 1837 } else { 1838 btn.remove(); 1839 } 1840 }, 1841 complete() { 1842 btn.css({ 1843 pointerEvents: 'auto', 1844 opacity: '1' 1845 }); 1846 self.btn.text('Load More'); 1847 } 1848 }); 1849 } 1850} 1851 1852/***/ }), 1853
1854/***/ "./src/modules/pricing-comparison.ts": 1855/*!*******************************************!*\ 1856 !*** ./src/modules/pricing-comparison.ts ***! 1857 \*******************************************/ 1858/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1859 1860__webpack_require__.r(__webpack_exports__); 1861/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1862/* harmony export */ "default": () => (/* binding */ PricingComparison) 1863/* harmony export */ }); 1864/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ "./node_modules/gsap/index.js"); 1865/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/ScrollTrigger */ "./node_modules/gsap/ScrollTrigger.js"); 1866 1867 1868const $ = window.jQuery; 1869class PricingComparison { 1870 constructor() { 1871 Object.defineProperty(this, "primaryHeaderOffset", { 1872 enumerable: true, 1873 configurable: true, 1874 writable: true, 1875 value: 0 1876 }); 1877 Object.defineProperty(this, "scrollTrigger", { 1878 enumerable: true, 1879 configurable: true, 1880 writable: true, 1881 value: void 0 1882 }); 1883 const { 1884 $header, 1885 $body 1886 } = this.elements; 1887 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__.ScrollTrigger); 1888 if (!$header.length || !$body.length) { 1889 return; 1890 } 1891 this.headerStickyHandler(); 1892 this.events(); 1893 } 1894 get selectors() { 1895 return { 1896 header: '#pricing-comparison-sticky-header', 1897 body: '#pricing-comparison-table' 1898 }; 1899 } 1900 get elements() { 1901 return { 1902 $header: $(this.selectors.header), 1903 $body: $(this.selectors.body) 1904 }; 1905 } 1906 events() { 1907 const self = this; 1908 const elements = this.elements; 1909 this.scrollTrigger = gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__.ScrollTrigger.create({ 1910 trigger: elements.$body[0], 1911 start() { 1912 return `top ${self.primaryHeaderOffset}`; 1913 }, 1914 end() { 1915 return `bottom ${self.primaryHeaderOffset}`; 1916 }, 1917 onToggle() { 1918 self.headerStickyHandler(self.scrollTrigger.isActive); 1919 } 1920 }); 1921 } 1922 headerStickyHandler(isActive = false) { 1923 const { 1924 $header 1925 } = this.elements; 1926 $header.toggleClass('active', isActive); 1927 } 1928} 1929 1930/***/ }), 1931
1932/***/ "./src/modules/scroll-text.ts": 1933/*!************************************!*\ 1934 !*** ./src/modules/scroll-text.ts ***! 1935 \************************************/ 1936/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1937 1938__webpack_require__.r(__webpack_exports__); 1939/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1940/* harmony export */ "default": () => (/* binding */ ScrollText) 1941/* harmony export */ }); 1942/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ "./node_modules/gsap/index.js"); 1943/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/ScrollTrigger */ "./node_modules/gsap/ScrollTrigger.js"); 1944 1945 1946gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_1__.ScrollTrigger); 1947class ScrollText { 1948 constructor() { 1949 Object.defineProperty(this, "element", { 1950 enumerable: true, 1951 configurable: true, 1952 writable: true, 1953 value: void 0 1954 }); 1955 this.element = document.querySelector('.chatway-scroll-text'); 1956 if (this.element) { 1957 this.init(); 1958 } 1959 } 1960 init() { 1961 const self = this; 1962 gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(self.element, { 1963 scrollTrigger: { 1964 trigger: self.element, 1965 start: 'top 90%', 1966 end: 'top 45%', 1967 scrub: true // makes the animation smooth and tied to scroll 1968 }, 1969 onUpdate: function () { 1970 const progress = this.progress() * 100; 1971 const value = 100 - progress; 1972 self.element.style.setProperty('--progress', `${value}%`); 1973 } 1974 }); 1975 } 1976} 1977 1978/***/ }), 1979
1980/***/ "./src/modules/search.ts": 1981/*!*******************************!*\ 1982 !*** ./src/modules/search.ts ***! 1983 \*******************************/ 1984/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 1985 1986__webpack_require__.r(__webpack_exports__); 1987/* harmony export */ __webpack_require__.d(__webpack_exports__, { 1988/* harmony export */ "default": () => (/* binding */ Search) 1989/* harmony export */ }); 1990const $ = window.jQuery; 1991class Search { 1992 constructor() { 1993 Object.defineProperty(this, "$scope", { 1994 enumerable: true, 1995 configurable: true, 1996 writable: true, 1997 value: void 0 1998 }); 1999 Object.defineProperty(this, "$input", { 2000 enumerable: true, 2001 configurable: true, 2002 writable: true, 2003 value: void 0 2004 }); 2005 this.$scope = $('#chatway-search-form'); 2006 this.$input = this.$scope.find('input[type="search"]'); 2007 this.init(); 2008 this.events(); 2009 } 2010 events() { 2011 if (this.$input.length) { 2012 this.$input.on('chagne', this.init.bind(this)); 2013 } 2014 } 2015 init() { 2016 if (this.$input.length) { 2017 const val = this.$input.val() || ''; 2018 if (val.trim().length > 0) { 2019 this.$input.focus(); 2020 } 2021 } 2022 } 2023} 2024 2025/***/ }), 2026
2027/***/ "./src/modules/testimonial.ts": 2028/*!************************************!*\ 2029 !*** ./src/modules/testimonial.ts ***! 2030 \************************************/ 2031/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2032 2033__webpack_require__.r(__webpack_exports__); 2034/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2035/* harmony export */ "default": () => (/* binding */ Testimonial) 2036/* harmony export */ }); 2037/* harmony import */ var _base_Helper__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/base/Helper */ "./src/base/Helper.ts"); 2038const $ = window.jQuery; 2039 2040class Testimonial { 2041 constructor() { 2042 Object.defineProperty(this, "slickSettings", { 2043 enumerable: true, 2044 configurable: true, 2045 writable: true, 2046 value: { 2047 slidesToShow: 3, 2048 slidesToScroll: 1, 2049 centerPadding: '100px', 2050 arrows: false, 2051 autoplay: true, 2052 dots: true, 2053 autoplaySpeed: 3000, 2054 pauseOnFocus: false, 2055 responsive: [{ 2056 breakpoint: 2200, 2057 settings: { 2058 centerMode: true, 2059 centerPadding: '500px', 2060 slidesToShow: 1 2061 } 2062 }, { 2063 breakpoint: 1610, 2064 settings: { 2065 centerMode: true, 2066 centerPadding: '300px', 2067 slidesToShow: 1 2068 } 2069 }, { 2070 breakpoint: 1300, 2071 settings: { 2072 centerMode: true, 2073 centerPadding: '140px', 2074 slidesToShow: 1 2075 } 2076 }, { 2077 breakpoint: 1100, 2078 settings: { 2079 centerMode: true, 2080 centerPadding: '50px', 2081 slidesToShow: 1 2082 } 2083 }, { 2084 breakpoint: 768, 2085 settings: { 2086 centerMode: true, 2087 centerPadding: '0px', 2088 slidesToShow: 1 2089 } 2090 }] 2091 } 2092 }); 2093 this.init(); 2094 } 2095 init() { 2096 const { 2097 $testimonial 2098 } = this.elements; 2099 if (_base_Helper__WEBPACK_IMPORTED_MODULE_0__["default"].slickExists($testimonial)) { 2100 $testimonial.slick(this.slickSettings); 2101 } 2102 } 2103 get selectors() { 2104 return { 2105 scope: '#testimonial-container', 2106 testimonial: '.testimonial-slick' 2107 }; 2108 } 2109 get elements() { 2110 const { 2111 scope, 2112 testimonial 2113 } = this.selectors; 2114 return { 2115 $scope: $(scope), 2116 get $testimonial() { 2117 return this.$scope.find(testimonial); 2118 } 2119 }; 2120 } 2121} 2122 2123/***/ }), 2124
2125/***/ "./src/modules/tooltip.ts": 2126/*!********************************!*\ 2127 !*** ./src/modules/tooltip.ts ***! 2128 \********************************/ 2129/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2130 2131__webpack_require__.r(__webpack_exports__); 2132/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2133/* harmony export */ "default": () => (/* binding */ Tooltip) 2134/* harmony export */ }); 2135const $ = window.jQuery; 2136const screenWidth = window.innerWidth; 2137class Tooltip { 2138 constructor() { 2139 Object.defineProperty(this, "$tooltip", { 2140 enumerable: true, 2141 configurable: true, 2142 writable: true, 2143 value: void 0 2144 }); 2145 Object.defineProperty(this, "headerHeight", { 2146 enumerable: true, 2147 configurable: true, 2148 writable: true, 2149 value: void 0 2150 }); 2151 Object.defineProperty(this, "state", { 2152 enumerable: true, 2153 configurable: true, 2154 writable: true, 2155 value: new Map() 2156 }); 2157 Object.defineProperty(this, "classes", { 2158 enumerable: true, 2159 configurable: true, 2160 writable: true, 2161 value: { 2162 tooltipTop: 'tooltip-top', 2163 tooltipBottom: 'tooltip-bottom', 2164 imagePlaceholder: 'tooltip-loading-placeholder' 2165 } 2166 }); 2167 this.$tooltip = $('[data-tooltip-target]'); 2168 this.headerHeight = $('#chatway-theme-header').outerHeight(); 2169 this.events(); 2170 } 2171 resetTarget($el) { 2172 $el.removeClass(this.classes.tooltipTop); 2173 $el.removeClass(this.classes.tooltipBottom); 2174 $el.css({ 2175 left: '0px' 2176 }); 2177 } 2178 resetPointer($el) { 2179 $el.css({ 2180 left: '0px' 2181 }); 2182 } 2183 events() { 2184 const self = this; 2185 this.$tooltip.on('mouseover', function () { 2186 const $this = $(this); 2187 const id = $this.data('tooltip-target'); 2188 const $target = $(`[data-tooltip-id="${id}"]`); 2189 const $pointer = $target.find('.pointer'); 2190 self.resetTarget($target); 2191 self.resetPointer($pointer); 2192 const targetWidth = $target.outerWidth(); 2193 const pointerWidth = $pointer.outerWidth(); 2194 const currentWidth = $this.outerWidth(); 2195 // calculate tooltip spacing from the top 2196 const targetOffset = $target.offset(); 2197 const currentOffset = $this.offset(); 2198 const top = targetOffset.top - scrollY - self.headerHeight; 2199 //append vertical position class to the tooltip 2200 if (top < 4) { 2201 $target.addClass(self.classes.tooltipBottom); 2202 } else { 2203 $target.addClass(self.classes.tooltipTop); 2204 } 2205 let targetX = currentWidth / 2 - targetWidth / 2; 2206 let pointerX = targetWidth / 2 - pointerWidth / 2; 2207 const hasEnoughSpaceRight = screenWidth - (currentOffset.left + currentWidth / 2) > targetWidth / 2; 2208 const hasEnoughSpaceLeft = currentOffset.left + currentWidth / 2 > targetWidth / 2; 2209 if (!hasEnoughSpaceRight && hasEnoughSpaceLeft) { 2210 const remainingSpaceRight = screenWidth - (currentOffset.left + currentWidth / 2); 2211 targetX = remainingSpaceRight - targetWidth; 2212 pointerX = targetX * -1 + currentWidth / 2 - pointerWidth / 2; 2213 } 2214 if (!hasEnoughSpaceLeft && hasEnoughSpaceRight) { 2215 const remainingSpaceLeft = currentOffset.left; 2216 targetX = 5 - remainingSpaceLeft; 2217 pointerX = targetX * -1 + currentWidth / 2 - pointerWidth / 2; 2218 } 2219 $target.css({ 2220 left: targetX + 'px' 2221 }); 2222 $pointer.css({ 2223 left: pointerX + 'px' 2224 }); 2225 // loading tooltip image 2226 const $image = $target.find(`.${self.classes.imagePlaceholder}`); 2227 if ($image.length !== 0) { 2228 const src = $image.data('src'); 2229 self.renderImage(src, $image); 2230 } 2231 }); 2232 this.$tooltip.on('mouseout', function () { 2233 const $this = $(this); 2234 const id = $this.data('tooltip-target'); 2235 const $target = $(`[data-tooltip-id="${id}"]`); 2236 self.resetTarget($target); 2237 self.resetPointer($target); 2238 }); 2239 } 2240 renderImage(url, image) { 2241 // return if image is already loaded 2242 if (image.hasClass('loaded')) return; 2243 $.ajax({ 2244 url: url, 2245 type: 'GET', 2246 xhrFields: { 2247 responseType: 'arraybuffer' 2248 }, 2249 success: function (data) { 2250 const base64String = btoa(new Uint8Array(data).reduce((data, byte) => data + String.fromCharCode(byte), '')); 2251 image.attr('src', 'data:image/png;base64,' + base64String); 2252 image.addClass('loaded'); 2253 }, 2254 error: function (_xhr, _status, error) { 2255 console.error('Error loading image:', error); 2256 image.attr('src', url); 2257 } 2258 }); 2259 } 2260} 2261 2262/***/ }), 2263
vendor: 67,470 bytes, lines 2264-3857
2264/***/ "./node_modules/gsap/CSSPlugin.js": 2265/*!****************************************!*\ 2266 !*** ./node_modules/gsap/CSSPlugin.js ***! 2267 \****************************************/ 2268/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 2269 2270__webpack_require__.r(__webpack_exports__); 2271/* harmony export */ __webpack_require__.d(__webpack_exports__, { 2272/* harmony export */ CSSPlugin: () => (/* binding */ CSSPlugin), 2273/* harmony export */ _createElement: () => (/* binding */ _createElement), 2274/* harmony export */ _getBBox: () => (/* binding */ _getBBox), 2275/* harmony export */ checkPrefix: () => (/* binding */ _checkPropPrefix), 2276/* harmony export */ "default": () => (/* binding */ CSSPlugin) 2277/* harmony export */ }); 2278/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js"); 2279/*! 2280 * CSSPlugin 3.12.5 2281 * https://gsap.com 2282 * 2283 * Copyright 2008-2024, GreenSock. All rights reserved. 2284 * Subject to the terms at https://gsap.com/standard-license or for 2285 * Club GSAP members, the agreement issued with that membership. 2286 * @author: Jack Doyle, [email protected] 2287*/ 2288 2289/* eslint-disable */ 2290 2291 2292var _win, 2293 _doc, 2294 _docElement, 2295 _pluginInitted, 2296 _tempDiv, 2297 _tempDivStyler, 2298 _recentSetterPlugin, 2299 _reverting, 2300 _windowExists = function _windowExists() { 2301 return typeof window !== "undefined"; 2302}, 2303 _transformProps = {}, 2304 _RAD2DEG = 180 / Math.PI, 2305 _DEG2RAD = Math.PI / 180, 2306 _atan2 = Math.atan2, 2307 _bigNum = 1e8, 2308 _capsExp = /([A-Z])/g, 2309 _horizontalExp = /(left|right|width|margin|padding|x)/i, 2310 _complexExp = /[\s,\(]\S/, 2311 _propertyAliases = { 2312 autoAlpha: "opacity,visibility", 2313 scale: "scaleX,scaleY", 2314 alpha: "opacity" 2315}, 2316 _renderCSSProp = function _renderCSSProp(ratio, data) { 2317 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 2318}, 2319 _renderPropWithEnd = function _renderPropWithEnd(ratio, data) { 2320 return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data); 2321}, 2322 _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) { 2323 return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data); 2324}, 2325 //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) 2326_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) { 2327 var value = data.s + data.c * ratio; 2328 data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data); 2329}, 2330 _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) { 2331 return data.set(data.t, data.p, ratio ? data.e : data.b, data); 2332}, 2333 _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) { 2334 return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data); 2335}, 2336 _setterCSSStyle = function _setterCSSStyle(target, property, value) { 2337 return target.style[property] = value; 2338}, 2339 _setterCSSProp = function _setterCSSProp(target, property, value) { 2340 return target.style.setProperty(property, value); 2341}, 2342 _setterTransform = function _setterTransform(target, property, value) { 2343 return target._gsap[property] = value; 2344}, 2345 _setterScale = function _setterScale(target, property, value) { 2346 return target._gsap.scaleX = target._gsap.scaleY = value; 2347}, 2348 _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) { 2349 var cache = target._gsap; 2350 cache.scaleX = cache.scaleY = value; 2351 cache.renderTransform(ratio, cache); 2352}, 2353 _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) { 2354 var cache = target._gsap; 2355 cache[property] = value; 2356 cache.renderTransform(ratio, cache); 2357}, 2358 _transformProp = "transform", 2359 _transformOriginProp = _transformProp + "Origin", 2360 _saveStyle = function _saveStyle(property, isNotCSS) { 2361 var _this = this; 2362 2363 var target = this.target, 2364 style = target.style, 2365 cache = target._gsap; 2366 2367 if (property in _transformProps && style) { 2368 this.tfm = this.tfm || {}; 2369 2370 if (property !== "transform") { 2371 property = _propertyAliases[property] || property; 2372 ~property.indexOf(",") ? property.split(",").forEach(function (a) { 2373 return _this.tfm[a] = _get(target, a); 2374 }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property); // note: scale would map to "scaleX,scaleY", thus we loop and apply them both. 2375 2376 property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin); 2377 } else { 2378 return _propertyAliases.transform.split(",").forEach(function (p) { 2379 return _saveStyle.call(_this, p, isNotCSS); 2380 }); 2381 } 2382 2383 if (this.props.indexOf(_transformProp) >= 0) { 2384 return; 2385 } 2386 2387 if (cache.svg) { 2388 this.svgo = target.getAttribute("data-svg-origin"); 2389 this.props.push(_transformOriginProp, isNotCSS, ""); 2390 } 2391 2392 property = _transformProp; 2393 } 2394 2395 (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]); 2396}, 2397 _removeIndependentTransforms = function _removeIndependentTransforms(style) { 2398 if (style.translate) { 2399 style.removeProperty("translate"); 2400 style.removeProperty("scale"); 2401 style.removeProperty("rotate"); 2402 } 2403}, 2404 _revertStyle = function _revertStyle() { 2405 var props = this.props, 2406 target = this.target, 2407 style = target.style, 2408 cache = target._gsap, 2409 i, 2410 p; 2411 2412 for (i = 0; i < props.length; i += 3) { 2413 // stored like this: property, isNotCSS, value 2414 props[i + 1] ? target[props[i]] = props[i + 2] : props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === "--" ? props[i] : props[i].replace(_capsExp, "-$1").toLowerCase()); 2415 } 2416 2417 if (this.tfm) { 2418 for (p in this.tfm) { 2419 cache[p] = this.tfm[p]; 2420 } 2421 2422 if (cache.svg) { 2423 cache.renderTransform(); 2424 target.setAttribute("data-svg-origin", this.svgo || ""); 2425 } 2426 2427 i = _reverting(); 2428 2429 if ((!i || !i.isStart) && !style[_transformProp]) { 2430 _removeIndependentTransforms(style); 2431 2432 if (cache.zOrigin && style[_transformOriginProp]) { 2433 style[_transformOriginProp] += " " + cache.zOrigin + "px"; // since we're uncaching, we must put the zOrigin back into the transformOrigin so that we can pull it out accurately when we parse again. Otherwise, we'd lose the z portion of the origin since we extract it to protect from Safari bugs. 2434 2435 cache.zOrigin = 0; 2436 cache.renderTransform(); 2437 } 2438 2439 cache.uncache = 1; // if it's a startAt that's being reverted in the _initTween() of the core, we don't need to uncache transforms. This is purely a performance optimization. 2440 } 2441 } 2442}, 2443 _getStyleSaver = function _getStyleSaver(target, properties) { 2444 var saver = { 2445 target: target, 2446 props: [], 2447 revert: _revertStyle, 2448 save: _saveStyle 2449 }; 2450 target._gsap || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.getCache(target); // just make sure there's a _gsap cache defined because we read from it in _saveStyle() and it's more efficient to just check it here once. 2451 2452 properties && properties.split(",").forEach(function (p) { 2453 return saver.save(p); 2454 }); 2455 return saver; 2456}, 2457 _supports3D, 2458 _createElement = function _createElement(type, ns) { 2459 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. 2460 2461 return e && 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://gsap.com/forums/topic/20215-problem-using-tweenmax-in-standalone-self-containing-svg-file-err-cannot-set-property-csstext-of-undefined/). 2462}, 2463 _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) { 2464 var cs = getComputedStyle(target); 2465 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. 2466}, 2467 _prefixes = "O,Moz,ms,Ms,Webkit".split(","), 2468 _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) { 2469 var e = element || _tempDiv, 2470 s = e.style, 2471 i = 5; 2472 2473 if (property in s && !preferPrefix) { 2474 return property; 2475 } 2476 2477 property = property.charAt(0).toUpperCase() + property.substr(1); 2478 2479 while (i-- && !(_prefixes[i] + property in s)) {} 2480 2481 return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property; 2482}, 2483 _initCore = function _initCore() { 2484 if (_windowExists() && window.document) { 2485 _win = window; 2486 _doc = _win.document; 2487 _docElement = _doc.documentElement; 2488 _tempDiv = _createElement("div") || { 2489 style: {} 2490 }; 2491 _tempDivStyler = _createElement("div"); 2492 _transformProp = _checkPropPrefix(_transformProp); 2493 _transformOriginProp = _transformProp + "Origin"; 2494 _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. 2495 2496 _supports3D = !!_checkPropPrefix("perspective"); 2497 _reverting = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.reverting; 2498 _pluginInitted = 1; 2499 } 2500}, 2501 _getBBoxHack = function _getBBoxHack(swapIfPossible) { 2502 //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). 2503 var svg = _createElement("svg", this.ownerSVGElement && this.ownerSVGElement.getAttribute("xmlns") || "http://www.w3.org/2000/svg"), 2504 oldParent = this.parentNode, 2505 oldSibling = this.nextSibling, 2506 oldCSS = this.style.cssText, 2507 bbox; 2508 2509 _docElement.appendChild(svg); 2510 2511 svg.appendChild(this); 2512 this.style.display = "block"; 2513 2514 if (swapIfPossible) { 2515 try { 2516 bbox = this.getBBox(); 2517 this._gsapBBox = this.getBBox; //store the original 2518 2519 this.getBBox = _getBBoxHack; 2520 } catch (e) {} 2521 } else if (this._gsapBBox) { 2522 bbox = this._gsapBBox(); 2523 } 2524 2525 if (oldParent) { 2526 if (oldSibling) { 2527 oldParent.insertBefore(this, oldSibling); 2528 } else { 2529 oldParent.appendChild(this); 2530 } 2531 } 2532 2533 _docElement.removeChild(svg); 2534 2535 this.style.cssText = oldCSS; 2536 return bbox; 2537}, 2538 _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) { 2539 var i = attributesArray.length; 2540 2541 while (i--) { 2542 if (target.hasAttribute(attributesArray[i])) { 2543 return target.getAttribute(attributesArray[i]); 2544 } 2545 } 2546}, 2547 _getBBox = function _getBBox(target) { 2548 var bounds; 2549 2550 try { 2551 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 2552 } catch (error) { 2553 bounds = _getBBoxHack.call(target, true); 2554 } 2555 2556 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. 2557 2558 return bounds && !bounds.width && !bounds.x && !bounds.y ? { 2559 x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0, 2560 y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0, 2561 width: 0, 2562 height: 0 2563 } : bounds; 2564}, 2565 _isSVG = function _isSVG(e) { 2566 return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e)); 2567}, 2568 //reports if the element is an SVG on which getBBox() actually works 2569_removeProperty = function _removeProperty(target, property) { 2570 if (property) { 2571 var style = target.style, 2572 first2Chars; 2573 2574 if (property in _transformProps && property !== _transformOriginProp) { 2575 property = _transformProp; 2576 } 2577 2578 if (style.removeProperty) { 2579 first2Chars = property.substr(0, 2); 2580 2581 if (first2Chars === "ms" || property.substr(0, 6) === "webkit") { 2582 //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) 2583 property = "-" + property; 2584 } 2585 2586 style.removeProperty(first2Chars === "--" ? property : property.replace(_capsExp, "-$1").toLowerCase()); 2587 } else { 2588 //note: old versions of IE use "removeAttribute()" instead of "removeProperty()" 2589 style.removeAttribute(property); 2590 } 2591 } 2592}, 2593 _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) { 2594 var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue); 2595 plugin._pt = pt; 2596 pt.b = beginning; 2597 pt.e = end; 2598 2599 plugin._props.push(property); 2600 2601 return pt; 2602}, 2603 _nonConvertibleUnits = { 2604 deg: 1, 2605 rad: 1, 2606 turn: 1 2607}, 2608 _nonStandardLayouts = { 2609 grid: 1, 2610 flex: 1 2611}, 2612 //takes a single value like 20px and converts it to the unit specified, like "%", returning only the numeric amount. 2613_convertToUnit = function _convertToUnit(target, property, value, unit) { 2614 var curValue = parseFloat(value) || 0, 2615 curUnit = (value + "").trim().substr((curValue + "").length) || "px", 2616 // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim() 2617 style = _tempDiv.style, 2618 horizontal = _horizontalExp.test(property), 2619 isRootSVG = target.tagName.toLowerCase() === "svg", 2620 measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"), 2621 amount = 100, 2622 toPixels = unit === "px", 2623 toPercent = unit === "%", 2624 px, 2625 parent, 2626 cache, 2627 isSVG; 2628 2629 if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) { 2630 return curValue; 2631 } 2632 2633 curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px")); 2634 isSVG = target.getCTM && _isSVG(target); 2635 2636 if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) { 2637 px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty]; 2638 return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPercent ? curValue / px * amount : curValue / 100 * px); 2639 } 2640 2641 style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit); 2642 parent = ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode; 2643 2644 if (isSVG) { 2645 parent = (target.ownerSVGElement || {}).parentNode; 2646 } 2647 2648 if (!parent || parent === _doc || !parent.appendChild) { 2649 parent = _doc.body; 2650 } 2651 2652 cache = parent._gsap; 2653 2654 if (cache && toPercent && cache.width && horizontal && cache.time === _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time && !cache.uncache) { 2655 return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(curValue / cache.width * amount); 2656 } else { 2657 if (toPercent && (property === "height" || property === "width")) { 2658 // if we're dealing with width/height that's inside a container with padding and/or it's a flexbox/grid container, we must apply it to the target itself rather than the _tempDiv in order to ensure complete accuracy, factoring in the parent's padding. 2659 var v = target.style[property]; 2660 target.style[property] = amount + unit; 2661 px = target[measureProperty]; 2662 v ? target.style[property] = v : _removeProperty(target, property); 2663 } else { 2664 (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position")); 2665 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. 2666 2667 parent.appendChild(_tempDiv); 2668 px = _tempDiv[measureProperty]; 2669 parent.removeChild(_tempDiv); 2670 style.position = "absolute"; 2671 } 2672 2673 if (horizontal && toPercent) { 2674 cache = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(parent); 2675 cache.time = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time; 2676 cache.width = parent[measureProperty]; 2677 } 2678 } 2679 2680 return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0); 2681}, 2682 _get = function _get(target, property, unit, uncache) { 2683 var value; 2684 _pluginInitted || _initCore(); 2685 2686 if (property in _propertyAliases && property !== "transform") { 2687 property = _propertyAliases[property]; 2688 2689 if (~property.indexOf(",")) { 2690 property = property.split(",")[0]; 2691 } 2692 } 2693 2694 if (_transformProps[property] && property !== "transform") { 2695 value = _parseTransform(target, uncache); 2696 value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px"; 2697 } else { 2698 value = target.style[property]; 2699 2700 if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) { 2701 value = _specialProps[property] && _specialProps[property](target, property, unit) || _getComputedProperty(target, property) || (0,_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 2702 } 2703 } 2704 2705 return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value; 2706}, 2707 _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) { 2708 // 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. 2709 if (!start || start === "none") { 2710 // 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://gsap.com/forums/topic/18310-clippath-doesnt-work-on-ios/ 2711 var p = _checkPropPrefix(prop, target, 1), 2712 s = p && _getComputedProperty(target, p, 1); 2713 2714 if (s && s !== start) { 2715 prop = p; 2716 start = s; 2717 } else if (prop === "borderColor") { 2718 start = _getComputedProperty(target, "borderTopColor"); // Firefox bug: always reports "borderColor" as "", so we must fall back to borderTopColor. See https://gsap.com/forums/topic/24583-how-to-return-colors-that-i-had-after-reverse/ 2719 } 2720 } 2721 2722 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), 2723 index = 0, 2724 matchIndex = 0, 2725 a, 2726 result, 2727 startValues, 2728 startNum, 2729 color, 2730 startValue, 2731 endValue, 2732 endNum, 2733 chunk, 2734 endUnit, 2735 startUnit, 2736 endValues; 2737 pt.b = start; 2738 pt.e = end; 2739 start += ""; // ensure values are strings 2740 2741 end += ""; 2742 2743 if (end === "auto") { 2744 startValue = target.style[prop]; 2745 target.style[prop] = end; 2746 end = _getComputedProperty(target, prop) || end; 2747 startValue ? target.style[prop] = startValue : _removeProperty(target, prop); 2748 } 2749 2750 a = [start, end]; 2751 2752 (0,_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(). 2753 2754 2755 start = a[0]; 2756 end = a[1]; 2757 startValues = start.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || []; 2758 endValues = end.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || []; 2759 2760 if (endValues.length) { 2761 while (result = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.exec(end)) { 2762 endValue = result[0]; 2763 chunk = end.substring(index, result.index); 2764 2765 if (color) { 2766 color = (color + 1) % 5; 2767 } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") { 2768 color = 1; 2769 } 2770 2771 if (endValue !== (startValue = startValues[matchIndex++] || "")) { 2772 startNum = parseFloat(startValue) || 0; 2773 startUnit = startValue.substr((startNum + "").length); 2774 endValue.charAt(1) === "=" && (endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, endValue) + startUnit); 2775 endNum = parseFloat(endValue); 2776 endUnit = endValue.substr((endNum + "").length); 2777 index = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.lastIndex - endUnit.length; 2778 2779 if (!endUnit) { 2780 //if something like "perspective:300" is passed in and we must add a unit to the end 2781 endUnit = endUnit || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[prop] || startUnit; 2782 2783 if (index === end.length) { 2784 end += endUnit; 2785 pt.e += endUnit; 2786 } 2787 } 2788 2789 if (startUnit !== endUnit) { 2790 startNum = _convertToUnit(target, prop, startValue, endUnit) || 0; 2791 } // 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. 2792 2793 2794 pt._pt = { 2795 _next: pt._pt, 2796 p: chunk || matchIndex === 1 ? chunk : ",", 2797 //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. 2798 s: startNum, 2799 c: endNum - startNum, 2800 m: color && color < 4 || prop === "zIndex" ? Math.round : 0 2801 }; 2802 } 2803 } 2804 2805 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) 2806 } else { 2807 pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue; 2808 } 2809 2810 _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). 2811 2812 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. 2813 2814 return pt; 2815}, 2816 _keywordToPercent = { 2817 top: "0%", 2818 bottom: "100%", 2819 left: "0%", 2820 right: "100%", 2821 center: "50%" 2822}, 2823 _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) { 2824 var split = value.split(" "), 2825 x = split[0], 2826 y = split[1] || "50%"; 2827 2828 if (x === "top" || x === "bottom" || y === "left" || y === "right") { 2829 //the user provided them in the wrong order, so flip them 2830 value = x; 2831 x = y; 2832 y = value; 2833 } 2834 2835 split[0] = _keywordToPercent[x] || x; 2836 split[1] = _keywordToPercent[y] || y; 2837 return split.join(" "); 2838}, 2839 _renderClearProps = function _renderClearProps(ratio, data) { 2840 if (data.tween && data.tween._time === data.tween._dur) { 2841 var target = data.t, 2842 style = target.style, 2843 props = data.u, 2844 cache = target._gsap, 2845 prop, 2846 clearTransforms, 2847 i; 2848 2849 if (props === "all" || props === true) { 2850 style.cssText = ""; 2851 clearTransforms = 1; 2852 } else { 2853 props = props.split(","); 2854 i = props.length; 2855 2856 while (--i > -1) { 2857 prop = props[i]; 2858 2859 if (_transformProps[prop]) { 2860 clearTransforms = 1; 2861 prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp; 2862 } 2863 2864 _removeProperty(target, prop); 2865 } 2866 } 2867 2868 if (clearTransforms) { 2869 _removeProperty(target, _transformProp); 2870 2871 if (cache) { 2872 cache.svg && target.removeAttribute("transform"); 2873 2874 _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. 2875 2876 2877 cache.uncache = 1; 2878 2879 _removeIndependentTransforms(style); 2880 } 2881 } 2882 } 2883}, 2884 // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list. 2885_specialProps = { 2886 clearProps: function clearProps(plugin, target, property, endValue, tween) { 2887 if (tween.data !== "isFromStart") { 2888 var pt = plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 0, _renderClearProps); 2889 pt.u = endValue; 2890 pt.pr = -10; 2891 pt.tween = tween; 2892 2893 plugin._props.push(property); 2894 2895 return 1; 2896 } 2897 } 2898 /* className feature (about 0.4kb gzipped). 2899 , className(plugin, target, property, endValue, tween) { 2900 let _renderClassName = (ratio, data) => { 2901 data.css.render(ratio, data.css); 2902 if (!ratio || ratio === 1) { 2903 let inline = data.rmv, 2904 target = data.t, 2905 p; 2906 target.setAttribute("class", ratio ? data.e : data.b); 2907 for (p in inline) { 2908 _removeProperty(target, p); 2909 } 2910 } 2911 }, 2912 _getAllStyles = (target) => { 2913 let styles = {}, 2914 computed = getComputedStyle(target), 2915 p; 2916 for (p in computed) { 2917 if (isNaN(p) && p !== "cssText" && p !== "length") { 2918 styles[p] = computed[p]; 2919 } 2920 } 2921 _setDefaults(styles, _parseTransform(target, 1)); 2922 return styles; 2923 }, 2924 startClassList = target.getAttribute("class"), 2925 style = target.style, 2926 cssText = style.cssText, 2927 cache = target._gsap, 2928 classPT = cache.classPT, 2929 inlineToRemoveAtEnd = {}, 2930 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) : "")}, 2931 changingVars = {}, 2932 startVars = _getAllStyles(target), 2933 transformRelated = /(transform|perspective)/i, 2934 endVars, p; 2935 if (classPT) { 2936 classPT.r(1, classPT.d); 2937 _removeLinkedListItem(classPT.d.plugin, classPT, "_pt"); 2938 } 2939 target.setAttribute("class", data.e); 2940 endVars = _getAllStyles(target, true); 2941 target.setAttribute("class", startClassList); 2942 for (p in endVars) { 2943 if (endVars[p] !== startVars[p] && !transformRelated.test(p)) { 2944 changingVars[p] = endVars[p]; 2945 if (!style[p] && style[p] !== "0") { 2946 inlineToRemoveAtEnd[p] = 1; 2947 } 2948 } 2949 } 2950 cache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11); 2951 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://gsap.com/forums/topic/20368-possible-gsap-bug-switching-classnames-in-chrome/. 2952 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). 2953 } 2954 _parseTransform(target, true); //to clear the caching of transforms 2955 data.css = new gsap.plugins.css(); 2956 data.css.init(target, changingVars, tween); 2957 plugin._props.push(...data.css._props); 2958 return 1; 2959 } 2960 */ 2961 2962}, 2963 2964/* 2965 * -------------------------------------------------------------------------------------- 2966 * TRANSFORMS 2967 * -------------------------------------------------------------------------------------- 2968 */ 2969_identity2DMatrix = [1, 0, 0, 1, 0, 0], 2970 _rotationalProperties = {}, 2971 _isNullTransform = function _isNullTransform(value) { 2972 return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value; 2973}, 2974 _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) { 2975 var matrixString = _getComputedProperty(target, _transformProp); 2976 2977 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); 2978}, 2979 _getMatrix = function _getMatrix(target, force2D) { 2980 var cache = target._gsap || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(target), 2981 style = target.style, 2982 matrix = _getComputedTransformMatrixAsArray(target), 2983 parent, 2984 nextSibling, 2985 temp, 2986 addedToDOM; 2987 2988 if (cache.svg && target.getAttribute("transform")) { 2989 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. 2990 2991 matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f]; 2992 return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix; 2993 } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) { 2994 //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 2995 //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). 2996 temp = style.display; 2997 style.display = "block"; 2998 parent = target.parentNode; 2999 3000 if (!parent || !target.offsetParent) { 3001 // 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 3002 addedToDOM = 1; //flag 3003 3004 nextSibling = target.nextElementSibling; 3005 3006 _docElement.appendChild(target); //we must add it to the DOM in order to get values properly 3007 3008 } 3009 3010 matrix = _getComputedTransformMatrixAsArray(target); 3011 temp ? style.display = temp : _removeProperty(target, "display"); 3012 3013 if (addedToDOM) { 3014 nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target); 3015 } 3016 } 3017 3018 return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix; 3019}, 3020 _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) { 3021 var cache = target._gsap, 3022 matrix = matrixArray || _getMatrix(target, true), 3023 xOriginOld = cache.xOrigin || 0, 3024 yOriginOld = cache.yOrigin || 0, 3025 xOffsetOld = cache.xOffset || 0, 3026 yOffsetOld = cache.yOffset || 0, 3027 a = matrix[0], 3028 b = matrix[1], 3029 c = matrix[2], 3030 d = matrix[3], 3031 tx = matrix[4], 3032 ty = matrix[5], 3033 originSplit = origin.split(" "), 3034 xOrigin = parseFloat(originSplit[0]) || 0, 3035 yOrigin = parseFloat(originSplit[1]) || 0, 3036 bounds, 3037 determinant, 3038 x, 3039 y; 3040 3041 if (!originIsAbsolute) { 3042 bounds = _getBBox(target); 3043 xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * bounds.width : xOrigin); 3044 yOrigin = bounds.y + (~(originSplit[1] || originSplit[0]).indexOf("%") ? yOrigin / 100 * bounds.height : yOrigin); // if (!("xOrigin" in cache) && (xOrigin || yOrigin)) { // added in 3.12.3, reverted in 3.12.4; requires more exploration 3045 // xOrigin -= bounds.x; 3046 // yOrigin -= bounds.y; 3047 // } 3048 } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) { 3049 //if it's zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero. 3050 x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant; 3051 y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant; 3052 xOrigin = x; 3053 yOrigin = y; // theory: we only had to do this for smoothing and it assumes that the previous one was not originIsAbsolute. 3054 } 3055 3056 if (smooth || smooth !== false && cache.smooth) { 3057 tx = xOrigin - xOriginOld; 3058 ty = yOrigin - yOriginOld; 3059 cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx; 3060 cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty; 3061 } else { 3062 cache.xOffset = cache.yOffset = 0; 3063 } 3064 3065 cache.xOrigin = xOrigin; 3066 cache.yOrigin = yOrigin; 3067 cache.smooth = !!smooth; 3068 cache.origin = origin; 3069 cache.originIsAbsolute = !!originIsAbsolute; 3070 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). 3071 3072 if (pluginToAddPropTweensTo) { 3073 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin); 3074 3075 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin); 3076 3077 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset); 3078 3079 _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset); 3080 } 3081 3082 target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin); 3083}, 3084 _parseTransform = function _parseTransform(target, uncache) { 3085 var cache = target._gsap || new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.GSCache(target); 3086 3087 if ("x" in cache && !uncache && !cache.uncache) { 3088 return cache; 3089 } 3090 3091 var style = target.style, 3092 invertedScaleX = cache.scaleX < 0, 3093 px = "px", 3094 deg = "deg", 3095 cs = getComputedStyle(target), 3096 origin = _getComputedProperty(target, _transformOriginProp) || "0", 3097 x, 3098 y, 3099 z, 3100 scaleX, 3101 scaleY, 3102 rotation, 3103 rotationX, 3104 rotationY, 3105 skewX, 3106 skewY, 3107 perspective, 3108 xOrigin, 3109 yOrigin, 3110 matrix, 3111 angle, 3112 cos, 3113 sin, 3114 a, 3115 b, 3116 c, 3117 d, 3118 a12, 3119 a22, 3120 t1, 3121 t2, 3122 t3, 3123 a13, 3124 a23, 3125 a33, 3126 a42, 3127 a43, 3128 a32; 3129 x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0; 3130 scaleX = scaleY = 1; 3131 cache.svg = !!(target.getCTM && _isSVG(target)); 3132 3133 if (cs.translate) { 3134 // accommodate independent transforms by combining them into normal ones. 3135 if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") { 3136 style[_transformProp] = (cs.translate !== "none" ? "translate3d(" + (cs.translate + " 0 0").split(" ").slice(0, 3).join(", ") + ") " : "") + (cs.rotate !== "none" ? "rotate(" + cs.rotate + ") " : "") + (cs.scale !== "none" ? "scale(" + cs.scale.split(" ").join(",") + ") " : "") + (cs[_transformProp] !== "none" ? cs[_transformProp] : ""); 3137 } 3138 3139 style.scale = style.rotate = style.translate = "none"; 3140 } 3141 3142 matrix = _getMatrix(target, cache.svg); 3143 3144 if (cache.svg) { 3145 if (cache.uncache) { 3146 // if cache.uncache is true (and maybe if origin is 0,0), we need to set element.style.transformOrigin = (cache.xOrigin - bbox.x) + "px " + (cache.yOrigin - bbox.y) + "px". Previously we let the data-svg-origin stay instead, but when introducing revert(), it complicated things. 3147 t2 = target.getBBox(); 3148 origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px"; 3149 t1 = ""; 3150 } else { 3151 t1 = !uncache && target.getAttribute("data-svg-origin"); // Remember, to work around browser inconsistencies we always force SVG elements' transformOrigin to 0,0 and offset the translation accordingly. 3152 } 3153 3154 _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix); 3155 } 3156 3157 xOrigin = cache.xOrigin || 0; 3158 yOrigin = cache.yOrigin || 0; 3159 3160 if (matrix !== _identity2DMatrix) { 3161 a = matrix[0]; //a11 3162 3163 b = matrix[1]; //a21 3164 3165 c = matrix[2]; //a31 3166 3167 d = matrix[3]; //a41 3168 3169 x = a12 = matrix[4]; 3170 y = a22 = matrix[5]; //2D matrix 3171 3172 if (matrix.length === 6) { 3173 scaleX = Math.sqrt(a * a + b * b); 3174 scaleY = Math.sqrt(d * d + c * c); 3175 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). 3176 3177 skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0; 3178 skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD))); 3179 3180 if (cache.svg) { 3181 x -= xOrigin - (xOrigin * a + yOrigin * c); 3182 y -= yOrigin - (xOrigin * b + yOrigin * d); 3183 } //3D matrix 3184 3185 } else { 3186 a32 = matrix[6]; 3187 a42 = matrix[7]; 3188 a13 = matrix[8]; 3189 a23 = matrix[9]; 3190 a33 = matrix[10]; 3191 a43 = matrix[11]; 3192 x = matrix[12]; 3193 y = matrix[13]; 3194 z = matrix[14]; 3195 angle = _atan2(a32, a33); 3196 rotationX = angle * _RAD2DEG; //rotationX 3197 3198 if (angle) { 3199 cos = Math.cos(-angle); 3200 sin = Math.sin(-angle); 3201 t1 = a12 * cos + a13 * sin; 3202 t2 = a22 * cos + a23 * sin; 3203 t3 = a32 * cos + a33 * sin; 3204 a13 = a12 * -sin + a13 * cos; 3205 a23 = a22 * -sin + a23 * cos; 3206 a33 = a32 * -sin + a33 * cos; 3207 a43 = a42 * -sin + a43 * cos; 3208 a12 = t1; 3209 a22 = t2; 3210 a32 = t3; 3211 } //rotationY 3212 3213 3214 angle = _atan2(-c, a33); 3215 rotationY = angle * _RAD2DEG; 3216 3217 if (angle) { 3218 cos = Math.cos(-angle); 3219 sin = Math.sin(-angle); 3220 t1 = a * cos - a13 * sin; 3221 t2 = b * cos - a23 * sin; 3222 t3 = c * cos - a33 * sin; 3223 a43 = d * sin + a43 * cos; 3224 a = t1; 3225 b = t2; 3226 c = t3; 3227 } //rotationZ 3228 3229 3230 angle = _atan2(b, a); 3231 rotation = angle * _RAD2DEG; 3232 3233 if (angle) { 3234 cos = Math.cos(angle); 3235 sin = Math.sin(angle); 3236 t1 = a * cos + b * sin; 3237 t2 = a12 * cos + a22 * sin; 3238 b = b * cos - a * sin; 3239 a22 = a22 * cos - a12 * sin; 3240 a = t1; 3241 a12 = t2; 3242 } 3243 3244 if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) { 3245 //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. 3246 rotationX = rotation = 0; 3247 rotationY = 180 - rotationY; 3248 } 3249 3250 scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a * a + b * b + c * c)); 3251 scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a22 * a22 + a32 * a32)); 3252 angle = _atan2(a12, a22); 3253 skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0; 3254 perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0; 3255 } 3256 3257 if (cache.svg) { 3258 //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). 3259 t1 = target.getAttribute("transform"); 3260 cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp)); 3261 t1 && target.setAttribute("transform", t1); 3262 } 3263 } 3264 3265 if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) { 3266 if (invertedScaleX) { 3267 scaleX *= -1; 3268 skewX += rotation <= 0 ? 180 : -180; 3269 rotation += rotation <= 0 ? 180 : -180; 3270 } else { 3271 scaleY *= -1; 3272 skewX += skewX <= 0 ? 180 : -180; 3273 } 3274 } 3275 3276 uncache = uncache || cache.uncache; 3277 cache.x = x - ((cache.xPercent = x && (!uncache && cache.xPercent || (Math.round(target.offsetWidth / 2) === Math.round(-x) ? -50 : 0))) ? target.offsetWidth * cache.xPercent / 100 : 0) + px; 3278 cache.y = y - ((cache.yPercent = y && (!uncache && cache.yPercent || (Math.round(target.offsetHeight / 2) === Math.round(-y) ? -50 : 0))) ? target.offsetHeight * cache.yPercent / 100 : 0) + px; 3279 cache.z = z + px; 3280 cache.scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleX); 3281 cache.scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleY); 3282 cache.rotation = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotation) + deg; 3283 cache.rotationX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationX) + deg; 3284 cache.rotationY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationY) + deg; 3285 cache.skewX = skewX + deg; 3286 cache.skewY = skewY + deg; 3287 cache.transformPerspective = perspective + px; 3288 3289 if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || !uncache && cache.zOrigin || 0) { 3290 style[_transformOriginProp] = _firstTwoOnly(origin); 3291 } 3292 3293 cache.xOffset = cache.yOffset = 0; 3294 cache.force3D = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.force3D; 3295 cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms; 3296 cache.uncache = 0; 3297 return cache; 3298}, 3299 _firstTwoOnly = function _firstTwoOnly(value) { 3300 return (value = value.split(" "))[0] + " " + value[1]; 3301}, 3302 //for handling transformOrigin values, stripping out the 3rd dimension 3303_addPxTranslate = function _addPxTranslate(target, start, value) { 3304 var unit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(start); 3305 return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit; 3306}, 3307 _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) { 3308 cache.z = "0px"; 3309 cache.rotationY = cache.rotationX = "0deg"; 3310 cache.force3D = 0; 3311 3312 _renderCSSTransforms(ratio, cache); 3313}, 3314 _zeroDeg = "0deg", 3315 _zeroPx = "0px", 3316 _endParenthesis = ") ", 3317 _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) { 3318 var _ref = cache || this, 3319 xPercent = _ref.xPercent, 3320 yPercent = _ref.yPercent, 3321 x = _ref.x, 3322 y = _ref.y, 3323 z = _ref.z, 3324 rotation = _ref.rotation, 3325 rotationY = _ref.rotationY, 3326 rotationX = _ref.rotationX, 3327 skewX = _ref.skewX, 3328 skewY = _ref.skewY, 3329 scaleX = _ref.scaleX, 3330 scaleY = _ref.scaleY, 3331 transformPerspective = _ref.transformPerspective, 3332 force3D = _ref.force3D, 3333 target = _ref.target, 3334 zOrigin = _ref.zOrigin, 3335 transforms = "", 3336 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) 3337 3338 3339 if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) { 3340 var angle = parseFloat(rotationY) * _DEG2RAD, 3341 a13 = Math.sin(angle), 3342 a33 = Math.cos(angle), 3343 cos; 3344 3345 angle = parseFloat(rotationX) * _DEG2RAD; 3346 cos = Math.cos(angle); 3347 x = _addPxTranslate(target, x, a13 * cos * -zOrigin); 3348 y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin); 3349 z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin); 3350 } 3351 3352 if (transformPerspective !== _zeroPx) { 3353 transforms += "perspective(" + transformPerspective + _endParenthesis; 3354 } 3355 3356 if (xPercent || yPercent) { 3357 transforms += "translate(" + xPercent + "%, " + yPercent + "%) "; 3358 } 3359 3360 if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) { 3361 transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis; 3362 } 3363 3364 if (rotation !== _zeroDeg) { 3365 transforms += "rotate(" + rotation + _endParenthesis; 3366 } 3367 3368 if (rotationY !== _zeroDeg) { 3369 transforms += "rotateY(" + rotationY + _endParenthesis; 3370 } 3371 3372 if (rotationX !== _zeroDeg) { 3373 transforms += "rotateX(" + rotationX + _endParenthesis; 3374 } 3375 3376 if (skewX !== _zeroDeg || skewY !== _zeroDeg) { 3377 transforms += "skew(" + skewX + ", " + skewY + _endParenthesis; 3378 } 3379 3380 if (scaleX !== 1 || scaleY !== 1) { 3381 transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis; 3382 } 3383 3384 target.style[_transformProp] = transforms || "translate(0, 0)"; 3385}, 3386 _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) { 3387 var _ref2 = cache || this, 3388 xPercent = _ref2.xPercent, 3389 yPercent = _ref2.yPercent, 3390 x = _ref2.x, 3391 y = _ref2.y, 3392 rotation = _ref2.rotation, 3393 skewX = _ref2.skewX, 3394 skewY = _ref2.skewY, 3395 scaleX = _ref2.scaleX, 3396 scaleY = _ref2.scaleY, 3397 target = _ref2.target, 3398 xOrigin = _ref2.xOrigin, 3399 yOrigin = _ref2.yOrigin, 3400 xOffset = _ref2.xOffset, 3401 yOffset = _ref2.yOffset, 3402 forceCSS = _ref2.forceCSS, 3403 tx = parseFloat(x), 3404 ty = parseFloat(y), 3405 a11, 3406 a21, 3407 a12, 3408 a22, 3409 temp; 3410 3411 rotation = parseFloat(rotation); 3412 skewX = parseFloat(skewX); 3413 skewY = parseFloat(skewY); 3414 3415 if (skewY) { 3416 //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. 3417 skewY = parseFloat(skewY); 3418 skewX += skewY; 3419 rotation += skewY; 3420 } 3421 3422 if (rotation || skewX) { 3423 rotation *= _DEG2RAD; 3424 skewX *= _DEG2RAD; 3425 a11 = Math.cos(rotation) * scaleX; 3426 a21 = Math.sin(rotation) * scaleX; 3427 a12 = Math.sin(rotation - skewX) * -scaleY; 3428 a22 = Math.cos(rotation - skewX) * scaleY; 3429 3430 if (skewX) { 3431 skewY *= _DEG2RAD; 3432 temp = Math.tan(skewX - skewY); 3433 temp = Math.sqrt(1 + temp * temp); 3434 a12 *= temp; 3435 a22 *= temp; 3436 3437 if (skewY) { 3438 temp = Math.tan(skewY); 3439 temp = Math.sqrt(1 + temp * temp); 3440 a11 *= temp; 3441 a21 *= temp; 3442 } 3443 } 3444 3445 a11 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a11); 3446 a21 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a21); 3447 a12 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a12); 3448 a22 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a22); 3449 } else { 3450 a11 = scaleX; 3451 a22 = scaleY; 3452 a21 = a12 = 0; 3453 } 3454 3455 if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) { 3456 tx = _convertToUnit(target, "x", x, "px"); 3457 ty = _convertToUnit(target, "y", y, "px"); 3458 } 3459 3460 if (xOrigin || yOrigin || xOffset || yOffset) { 3461 tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset); 3462 ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset); 3463 } 3464 3465 if (xPercent || yPercent) { 3466 //The SVG spec doesn't support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it. 3467 temp = target.getBBox(); 3468 tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xPercent / 100 * temp.width); 3469 ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yPercent / 100 * temp.height); 3470 } 3471 3472 temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")"; 3473 target.setAttribute("transform", temp); 3474 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!) 3475}, 3476 _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) { 3477 var cap = 360, 3478 isString = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(endValue), 3479 endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1), 3480 change = endNum - startNum, 3481 finalValue = startNum + change + "deg", 3482 direction, 3483 pt; 3484 3485 if (isString) { 3486 direction = endValue.split("_")[1]; 3487 3488 if (direction === "short") { 3489 change %= cap; 3490 3491 if (change !== change % (cap / 2)) { 3492 change += change < 0 ? cap : -cap; 3493 } 3494 } 3495 3496 if (direction === "cw" && change < 0) { 3497 change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap; 3498 } else if (direction === "ccw" && change > 0) { 3499 change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap; 3500 } 3501 } 3502 3503 plugin._pt = pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd); 3504 pt.e = finalValue; 3505 pt.u = "deg"; 3506 3507 plugin._props.push(property); 3508 3509 return pt; 3510}, 3511 _assign = function _assign(target, source) { 3512 // Internet Explorer doesn't have Object.assign(), so we recreate it here. 3513 for (var p in source) { 3514 target[p] = source[p]; 3515 } 3516 3517 return target; 3518}, 3519 _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) { 3520 //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)" 3521 var startCache = _assign({}, target._gsap), 3522 exclude = "perspective,force3D,transformOrigin,svgOrigin", 3523 style = target.style, 3524 endCache, 3525 p, 3526 startValue, 3527 endValue, 3528 startNum, 3529 endNum, 3530 startUnit, 3531 endUnit; 3532 3533 if (startCache.svg) { 3534 startValue = target.getAttribute("transform"); 3535 target.setAttribute("transform", ""); 3536 style[_transformProp] = transforms; 3537 endCache = _parseTransform(target, 1); 3538 3539 _removeProperty(target, _transformProp); 3540 3541 target.setAttribute("transform", startValue); 3542 } else { 3543 startValue = getComputedStyle(target)[_transformProp]; 3544 style[_transformProp] = transforms; 3545 endCache = _parseTransform(target, 1); 3546 style[_transformProp] = startValue; 3547 } 3548 3549 for (p in _transformProps) { 3550 startValue = startCache[p]; 3551 endValue = endCache[p]; 3552 3553 if (startValue !== endValue && exclude.indexOf(p) < 0) { 3554 //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case. 3555 startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue); 3556 endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue); 3557 startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue); 3558 endNum = parseFloat(endValue); 3559 plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp); 3560 plugin._pt.u = endUnit || 0; 3561 3562 plugin._props.push(p); 3563 } 3564 } 3565 3566 _assign(endCache, startCache); 3567}; // 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. 3568 3569 3570(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)("padding,margin,Width,Radius", function (name, index) { 3571 var t = "Top", 3572 r = "Right", 3573 b = "Bottom", 3574 l = "Left", 3575 props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) { 3576 return index < 2 ? name + side : "border" + side + name; 3577 }); 3578 3579 _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) { 3580 var a, vars; 3581 3582 if (arguments.length < 4) { 3583 // getter, passed target, property, and unit (from _get()) 3584 a = props.map(function (prop) { 3585 return _get(plugin, prop, property); 3586 }); 3587 vars = a.join(" "); 3588 return vars.split(a[0]).length === 5 ? a[0] : vars; 3589 } 3590 3591 a = (endValue + "").split(" "); 3592 vars = {}; 3593 props.forEach(function (prop, i) { 3594 return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0]; 3595 }); 3596 plugin.init(target, vars, tween); 3597 }; 3598}); 3599 3600var CSSPlugin = { 3601 name: "css", 3602 register: _initCore, 3603 targetTest: function targetTest(target) { 3604 return target.style && target.nodeType; 3605 }, 3606 init: function init(target, vars, tween, index, targets) { 3607 var props = this._props, 3608 style = target.style, 3609 startAt = tween.vars.startAt, 3610 startValue, 3611 endValue, 3612 endNum, 3613 startNum, 3614 type, 3615 specialProp, 3616 p, 3617 startUnit, 3618 endUnit, 3619 relative, 3620 isTransformRelated, 3621 transformPropTween, 3622 cache, 3623 smooth, 3624 hasPriority, 3625 inlineProps; 3626 _pluginInitted || _initCore(); // we may call init() multiple times on the same plugin instance, like when adding special properties, so make sure we don't overwrite the revert data or inlineProps 3627 3628 this.styles = this.styles || _getStyleSaver(target); 3629 inlineProps = this.styles.props; 3630 this.tween = tween; 3631 3632 for (p in vars) { 3633 if (p === "autoRound") { 3634 continue; 3635 } 3636 3637 endValue = vars[p]; 3638 3639 if (_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._plugins[p] && (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._checkPlugin)(p, vars, tween, index, target, targets)) { 3640 // plugins 3641 continue; 3642 } 3643 3644 type = typeof endValue; 3645 specialProp = _specialProps[p]; 3646 3647 if (type === "function") { 3648 endValue = endValue.call(tween, index, target, targets); 3649 type = typeof endValue; 3650 } 3651 3652 if (type === "string" && ~endValue.indexOf("random(")) { 3653 endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(endValue); 3654 } 3655 3656 if (specialProp) { 3657 specialProp(this, target, p, endValue, tween) && (hasPriority = 1); 3658 } else if (p.substr(0, 2) === "--") { 3659 //CSS variable 3660 startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim(); 3661 endValue += ""; 3662 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.lastIndex = 0; 3663 3664 if (!_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.test(startValue)) { 3665 // colors don't have units 3666 startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue); 3667 endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue); 3668 } 3669 3670 endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit); 3671 this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p); 3672 props.push(p); 3673 inlineProps.push(p, 0, style[p]); 3674 } else if (type !== "undefined") { 3675 if (startAt && p in startAt) { 3676 // 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) 3677 startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p]; 3678 (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(startValue) && ~startValue.indexOf("random(") && (startValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(startValue)); 3679 (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue + "") || startValue === "auto" || (startValue += _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[p] || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(_get(target, p)) || ""); // for cases when someone passes in a unitless value like {x: 100}; if we try setting translate(100, 0px) it won't work. 3680 3681 (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); // can't work with relative values 3682 } else { 3683 startValue = _get(target, p); 3684 } 3685 3686 startNum = parseFloat(startValue); 3687 relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2); 3688 relative && (endValue = endValue.substr(2)); 3689 endNum = parseFloat(endValue); 3690 3691 if (p in _propertyAliases) { 3692 if (p === "autoAlpha") { 3693 //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened. 3694 if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) { 3695 //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience) 3696 startNum = 0; 3697 } 3698 3699 inlineProps.push("visibility", 0, style.visibility); 3700 3701 _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum); 3702 } 3703 3704 if (p !== "scale" && p !== "transform") { 3705 p = _propertyAliases[p]; 3706 ~p.indexOf(",") && (p = p.split(",")[0]); 3707 } 3708 } 3709 3710 isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED --- 3711 3712 if (isTransformRelated) { 3713 this.styles.save(p); 3714 3715 if (!transformPropTween) { 3716 cache = target._gsap; 3717 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. 3718 3719 smooth = vars.smoothOrigin !== false && cache.smooth; 3720 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) 3721 3722 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. 3723 } 3724 3725 if (p === "scale") { 3726 this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, cache, "scaleY", cache.scaleY, (relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(cache.scaleY, relative + endNum) : endNum) - cache.scaleY || 0, _renderCSSProp); 3727 this._pt.u = 0; 3728 props.push("scaleY", p); 3729 p += "X"; 3730 } else if (p === "transformOrigin") { 3731 inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]); 3732 endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages. 3733 3734 if (cache.svg) { 3735 _applySVGOrigin(target, endValue, 0, smooth, 0, this); 3736 } else { 3737 endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately! 3738 3739 endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit); 3740 3741 _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue)); 3742 } 3743 3744 continue; 3745 } else if (p === "svgOrigin") { 3746 _applySVGOrigin(target, endValue, 1, smooth, 0, this); 3747 3748 continue; 3749 } else if (p in _rotationalProperties) { 3750 _addRotationalPropTween(this, cache, p, startNum, relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, relative + endValue) : endValue); 3751 3752 continue; 3753 } else if (p === "smoothOrigin") { 3754 _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue); 3755 3756 continue; 3757 } else if (p === "force3D") { 3758 cache[p] = endValue; 3759 continue; 3760 } else if (p === "transform") { 3761 _addRawTransformPTs(this, endValue, target); 3762 3763 continue; 3764 } 3765 } else if (!(p in style)) { 3766 p = _checkPropPrefix(p) || p; 3767 } 3768 3769 if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) { 3770 startUnit = (startValue + "").substr((startNum + "").length); 3771 endNum || (endNum = 0); // protect against NaN 3772 3773 endUnit = (0,_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); 3774 startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit)); 3775 this._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(this._pt, isTransformRelated ? cache : style, p, startNum, (relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, relative + endNum) : endNum) - startNum, !isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp); 3776 this._pt.u = endUnit || 0; 3777 3778 if (startUnit !== endUnit && endUnit !== "%") { 3779 //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) 3780 this._pt.b = startValue; 3781 this._pt.r = _renderCSSPropWithBeginning; 3782 } 3783 } else if (!(p in style)) { 3784 if (p in target) { 3785 //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. 3786 this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets); 3787 } else if (p !== "parseTransform") { 3788 (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._missingPlugin)(p, endValue); 3789 3790 continue; 3791 } 3792 } else { 3793 _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue); 3794 } 3795 3796 isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : inlineProps.push(p, 1, startValue || target[p])); 3797 props.push(p); 3798 } 3799 } 3800 3801 hasPriority && (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._sortPropTweensByPriority)(this); 3802 }, 3803 render: function render(ratio, data) { 3804 if (data.tween._time || !_reverting()) { 3805 var pt = data._pt; 3806 3807 while (pt) { 3808 pt.r(ratio, pt.d); 3809 pt = pt._next; 3810 } 3811 } else { 3812 data.styles.revert(); 3813 } 3814 }, 3815 get: _get, 3816 aliases: _propertyAliases, 3817 getSetter: function getSetter(target, property, plugin) { 3818 //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. 3819 var p = _propertyAliases[property]; 3820 p && p.indexOf(",") < 0 && (property = p); 3821 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 && !(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isUndefined)(target.style[property]) ? _setterCSSStyle : ~property.indexOf("-") ? _setterCSSProp : (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getSetter)(target, property); 3822 }, 3823 core: { 3824 _removeProperty: _removeProperty, 3825 _getMatrix: _getMatrix 3826 } 3827}; 3828_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.checkPrefix = _checkPropPrefix; 3829_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.getStyleSaver = _getStyleSaver; 3830 3831(function (positionAndScale, rotation, others, aliases) { 3832 var all = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(positionAndScale + "," + rotation + "," + others, function (name) { 3833 _transformProps[name] = 1; 3834 }); 3835 3836 (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(rotation, function (name) { 3837 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = "deg"; 3838 _rotationalProperties[name] = 1; 3839 }); 3840 3841 _propertyAliases[all[13]] = positionAndScale + "," + rotation; 3842 3843 (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(aliases, function (name) { 3844 var split = name.split(":"); 3845 _propertyAliases[split[1]] = all[split[0]]; 3846 }); 3847})("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"); 3848 3849(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) { 3850 _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = "px"; 3851}); 3852 3853_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(CSSPlugin); 3854 3855 3856/***/ }), 3857
vendor: 26,448 bytes, lines 3858-4566
3858/***/ "./node_modules/gsap/Observer.js": 3859/*!***************************************!*\ 3860 !*** ./node_modules/gsap/Observer.js ***! 3861 \***************************************/ 3862/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 3863 3864__webpack_require__.r(__webpack_exports__); 3865/* harmony export */ __webpack_require__.d(__webpack_exports__, { 3866/* harmony export */ Observer: () => (/* binding */ Observer), 3867/* harmony export */ _getProxyProp: () => (/* binding */ _getProxyProp), 3868/* harmony export */ _getScrollFunc: () => (/* binding */ _getScrollFunc), 3869/* harmony export */ _getTarget: () => (/* binding */ _getTarget), 3870/* harmony export */ _getVelocityProp: () => (/* binding */ _getVelocityProp), 3871/* harmony export */ _horizontal: () => (/* binding */ _horizontal), 3872/* harmony export */ _isViewport: () => (/* binding */ _isViewport), 3873/* harmony export */ _proxies: () => (/* binding */ _proxies), 3874/* harmony export */ _scrollers: () => (/* binding */ _scrollers), 3875/* harmony export */ _vertical: () => (/* binding */ _vertical), 3876/* harmony export */ "default": () => (/* binding */ Observer) 3877/* harmony export */ }); 3878function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 3879 3880function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 3881 3882/*! 3883 * Observer 3.12.5 3884 * https://gsap.com 3885 * 3886 * @license Copyright 2008-2024, GreenSock. All rights reserved. 3887 * Subject to the terms at https://gsap.com/standard-license or for 3888 * Club GSAP members, the agreement issued with that membership. 3889 * @author: Jack Doyle, [email protected] 3890*/ 3891 3892/* eslint-disable */ 3893var gsap, 3894 _coreInitted, 3895 _clamp, 3896 _win, 3897 _doc, 3898 _docEl, 3899 _body, 3900 _isTouch, 3901 _pointerType, 3902 ScrollTrigger, 3903 _root, 3904 _normalizer, 3905 _eventTypes, 3906 _context, 3907 _getGSAP = function _getGSAP() { 3908 return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap; 3909}, 3910 _startup = 1, 3911 _observers = [], 3912 _scrollers = [], 3913 _proxies = [], 3914 _getTime = Date.now, 3915 _bridge = function _bridge(name, value) { 3916 return value; 3917}, 3918 _integrate = function _integrate() { 3919 var core = ScrollTrigger.core, 3920 data = core.bridge || {}, 3921 scrollers = core._scrollers, 3922 proxies = core._proxies; 3923 scrollers.push.apply(scrollers, _scrollers); 3924 proxies.push.apply(proxies, _proxies); 3925 _scrollers = scrollers; 3926 _proxies = proxies; 3927 3928 _bridge = function _bridge(name, value) { 3929 return data[name](value); 3930 }; 3931}, 3932 _getProxyProp = function _getProxyProp(element, property) { 3933 return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property]; 3934}, 3935 _isViewport = function _isViewport(el) { 3936 return !!~_root.indexOf(el); 3937}, 3938 _addListener = function _addListener(element, type, func, passive, capture) { 3939 return element.addEventListener(type, func, { 3940 passive: passive !== false, 3941 capture: !!capture 3942 }); 3943}, 3944 _removeListener = function _removeListener(element, type, func, capture) { 3945 return element.removeEventListener(type, func, !!capture); 3946}, 3947 _scrollLeft = "scrollLeft", 3948 _scrollTop = "scrollTop", 3949 _onScroll = function _onScroll() { 3950 return _normalizer && _normalizer.isPressed || _scrollers.cache++; 3951}, 3952 _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) { 3953 var cachingFunc = function cachingFunc(value) { 3954 // since reading the scrollTop/scrollLeft/pageOffsetY/pageOffsetX can trigger a layout, this function allows us to cache the value so it only gets read fresh after a "scroll" event fires (or while we're refreshing because that can lengthen the page and alter the scroll position). when "soft" is true, that means don't actually set the scroll, but cache the new value instead (useful in ScrollSmoother) 3955 if (value || value === 0) { 3956 _startup && (_win.history.scrollRestoration = "manual"); // otherwise the new position will get overwritten by the browser onload. 3957 3958 var isNormalizing = _normalizer && _normalizer.isPressed; 3959 value = cachingFunc.v = Math.round(value) || (_normalizer && _normalizer.iOS ? 1 : 0); //TODO: iOS Bug: if you allow it to go to 0, Safari can start to report super strange (wildly inaccurate) touch positions! 3960 3961 f(value); 3962 cachingFunc.cacheID = _scrollers.cache; 3963 isNormalizing && _bridge("ss", value); // set scroll (notify ScrollTrigger so it can dispatch a "scrollStart" event if necessary 3964 } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) { 3965 cachingFunc.cacheID = _scrollers.cache; 3966 cachingFunc.v = f(); 3967 } 3968 3969 return cachingFunc.v + cachingFunc.offset; 3970 }; 3971 3972 cachingFunc.offset = 0; 3973 return f && cachingFunc; 3974}, 3975 _horizontal = { 3976 s: _scrollLeft, 3977 p: "left", 3978 p2: "Left", 3979 os: "right", 3980 os2: "Right", 3981 d: "width", 3982 d2: "Width", 3983 a: "x", 3984 sc: _scrollCacheFunc(function (value) { 3985 return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0; 3986 }) 3987}, 3988 _vertical = { 3989 s: _scrollTop, 3990 p: "top", 3991 p2: "Top", 3992 os: "bottom", 3993 os2: "Bottom", 3994 d: "height", 3995 d2: "Height", 3996 a: "y", 3997 op: _horizontal, 3998 sc: _scrollCacheFunc(function (value) { 3999 return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0; 4000 }) 4001}, 4002 _getTarget = function _getTarget(t, self) { 4003 return (self && self._ctx && self._ctx.selector || gsap.utils.toArray)(t)[0] || (typeof t === "string" && gsap.config().nullTargetWarn !== false ? console.warn("Element not found:", t) : null); 4004}, 4005 _getScrollFunc = function _getScrollFunc(element, _ref) { 4006 var s = _ref.s, 4007 sc = _ref.sc; 4008 // we store the scroller functions in an alternating sequenced Array like [element, verticalScrollFunc, horizontalScrollFunc, ...] so that we can minimize memory, maximize performance, and we also record the last position as a ".rec" property in order to revert to that after refreshing to ensure things don't shift around. 4009 _isViewport(element) && (element = _doc.scrollingElement || _docEl); 4010 4011 var i = _scrollers.indexOf(element), 4012 offset = sc === _vertical.sc ? 1 : 2; 4013 4014 !~i && (i = _scrollers.push(element) - 1); 4015 _scrollers[i + offset] || _addListener(element, "scroll", _onScroll); // clear the cache when a scroll occurs 4016 4017 var prev = _scrollers[i + offset], 4018 func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) { 4019 return arguments.length ? element[s] = value : element[s]; 4020 }))); 4021 func.target = element; 4022 prev || (func.smooth = gsap.getProperty(element, "scrollBehavior") === "smooth"); // only set it the first time (don't reset every time a scrollFunc is requested because perhaps it happens during a refresh() when it's disabled in ScrollTrigger. 4023 4024 return func; 4025}, 4026 _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) { 4027 var v1 = value, 4028 v2 = value, 4029 t1 = _getTime(), 4030 t2 = t1, 4031 min = minTimeRefresh || 50, 4032 dropToZeroTime = Math.max(500, min * 3), 4033 update = function update(value, force) { 4034 var t = _getTime(); 4035 4036 if (force || t - t1 > min) { 4037 v2 = v1; 4038 v1 = value; 4039 t2 = t1; 4040 t1 = t; 4041 } else if (useDelta) { 4042 v1 += value; 4043 } else { 4044 // not totally necessary, but makes it a bit more accurate by adjusting the v1 value according to the new slope. This way we're not just ignoring the incoming data. Removing for now because it doesn't seem to make much practical difference and it's probably not worth the kb. 4045 v1 = v2 + (value - v2) / (t - t2) * (t1 - t2); 4046 } 4047 }, 4048 reset = function reset() { 4049 v2 = v1 = useDelta ? 0 : v1; 4050 t2 = t1 = 0; 4051 }, 4052 getVelocity = function getVelocity(latestValue) { 4053 var tOld = t2, 4054 vOld = v2, 4055 t = _getTime(); 4056 4057 (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue); 4058 return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000; 4059 }; 4060 4061 return { 4062 update: update, 4063 reset: reset, 4064 getVelocity: getVelocity 4065 }; 4066}, 4067 _getEvent = function _getEvent(e, preventDefault) { 4068 preventDefault && !e._gsapAllow && e.preventDefault(); 4069 return e.changedTouches ? e.changedTouches[0] : e; 4070}, 4071 _getAbsoluteMax = function _getAbsoluteMax(a) { 4072 var max = Math.max.apply(Math, a), 4073 min = Math.min.apply(Math, a); 4074 return Math.abs(max) >= Math.abs(min) ? max : min; 4075}, 4076 _setScrollTrigger = function _setScrollTrigger() { 4077 ScrollTrigger = gsap.core.globals().ScrollTrigger; 4078 ScrollTrigger && ScrollTrigger.core && _integrate(); 4079}, 4080 _initCore = function _initCore(core) { 4081 gsap = core || _getGSAP(); 4082 4083 if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) { 4084 _win = window; 4085 _doc = document; 4086 _docEl = _doc.documentElement; 4087 _body = _doc.body; 4088 _root = [_win, _doc, _docEl, _body]; 4089 _clamp = gsap.utils.clamp; 4090 4091 _context = gsap.core.context || function () {}; 4092 4093 _pointerType = "onpointerenter" in _body ? "pointer" : "mouse"; // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer. 4094 4095 _isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0; 4096 _eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(","); 4097 setTimeout(function () { 4098 return _startup = 0; 4099 }, 500); 4100 4101 _setScrollTrigger(); 4102 4103 _coreInitted = 1; 4104 } 4105 4106 return _coreInitted; 4107}; 4108 4109_horizontal.op = _vertical; 4110_scrollers.cache = 0; 4111var Observer = /*#__PURE__*/function () { 4112 function Observer(vars) { 4113 this.init(vars); 4114 } 4115 4116 var _proto = Observer.prototype; 4117 4118 _proto.init = function init(vars) { 4119 _coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)"); 4120 ScrollTrigger || _setScrollTrigger(); 4121 var tolerance = vars.tolerance, 4122 dragMinimum = vars.dragMinimum, 4123 type = vars.type, 4124 target = vars.target, 4125 lineHeight = vars.lineHeight, 4126 debounce = vars.debounce, 4127 preventDefault = vars.preventDefault, 4128 onStop = vars.onStop, 4129 onStopDelay = vars.onStopDelay, 4130 ignore = vars.ignore, 4131 wheelSpeed = vars.wheelSpeed, 4132 event = vars.event, 4133 onDragStart = vars.onDragStart, 4134 onDragEnd = vars.onDragEnd, 4135 onDrag = vars.onDrag, 4136 onPress = vars.onPress, 4137 onRelease = vars.onRelease, 4138 onRight = vars.onRight, 4139 onLeft = vars.onLeft, 4140 onUp = vars.onUp, 4141 onDown = vars.onDown, 4142 onChangeX = vars.onChangeX, 4143 onChangeY = vars.onChangeY, 4144 onChange = vars.onChange, 4145 onToggleX = vars.onToggleX, 4146 onToggleY = vars.onToggleY, 4147 onHover = vars.onHover, 4148 onHoverEnd = vars.onHoverEnd, 4149 onMove = vars.onMove, 4150 ignoreCheck = vars.ignoreCheck, 4151 isNormalizer = vars.isNormalizer, 4152 onGestureStart = vars.onGestureStart, 4153 onGestureEnd = vars.onGestureEnd, 4154 onWheel = vars.onWheel, 4155 onEnable = vars.onEnable, 4156 onDisable = vars.onDisable, 4157 onClick = vars.onClick, 4158 scrollSpeed = vars.scrollSpeed, 4159 capture = vars.capture, 4160 allowClicks = vars.allowClicks, 4161 lockAxis = vars.lockAxis, 4162 onLockAxis = vars.onLockAxis; 4163 this.target = target = _getTarget(target) || _docEl; 4164 this.vars = vars; 4165 ignore && (ignore = gsap.utils.toArray(ignore)); 4166 tolerance = tolerance || 1e-9; 4167 dragMinimum = dragMinimum || 0; 4168 wheelSpeed = wheelSpeed || 1; 4169 scrollSpeed = scrollSpeed || 1; 4170 type = type || "wheel,touch,pointer"; 4171 debounce = debounce !== false; 4172 lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22); // note: browser may report "normal", so default to 22. 4173 4174 var id, 4175 onStopDelayedCall, 4176 dragged, 4177 moved, 4178 wheeled, 4179 locked, 4180 axis, 4181 self = this, 4182 prevDeltaX = 0, 4183 prevDeltaY = 0, 4184 passive = vars.passive || !preventDefault, 4185 scrollFuncX = _getScrollFunc(target, _horizontal), 4186 scrollFuncY = _getScrollFunc(target, _vertical), 4187 scrollX = scrollFuncX(), 4188 scrollY = scrollFuncY(), 4189 limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown", 4190 // for devices that accommodate mouse events and touch events, we need to distinguish. 4191 isViewport = _isViewport(target), 4192 ownerDoc = target.ownerDocument || _doc, 4193 deltaX = [0, 0, 0], 4194 // wheel, scroll, pointer/touch 4195 deltaY = [0, 0, 0], 4196 onClickTime = 0, 4197 clickCapture = function clickCapture() { 4198 return onClickTime = _getTime(); 4199 }, 4200 _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) { 4201 return (self.event = e) && ignore && ~ignore.indexOf(e.target) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch); 4202 }, 4203 onStopFunc = function onStopFunc() { 4204 self._vx.reset(); 4205 4206 self._vy.reset(); 4207 4208 onStopDelayedCall.pause(); 4209 onStop && onStop(self); 4210 }, 4211 update = function update() { 4212 var dx = self.deltaX = _getAbsoluteMax(deltaX), 4213 dy = self.deltaY = _getAbsoluteMax(deltaY), 4214 changedX = Math.abs(dx) >= tolerance, 4215 changedY = Math.abs(dy) >= tolerance; 4216 4217 onChange && (changedX || changedY) && onChange(self, dx, dy, deltaX, deltaY); // in ScrollTrigger.normalizeScroll(), we need to know if it was touch/pointer so we need access to the deltaX/deltaY Arrays before we clear them out. 4218 4219 if (changedX) { 4220 onRight && self.deltaX > 0 && onRight(self); 4221 onLeft && self.deltaX < 0 && onLeft(self); 4222 onChangeX && onChangeX(self); 4223 onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self); 4224 prevDeltaX = self.deltaX; 4225 deltaX[0] = deltaX[1] = deltaX[2] = 0; 4226 } 4227 4228 if (changedY) { 4229 onDown && self.deltaY > 0 && onDown(self); 4230 onUp && self.deltaY < 0 && onUp(self); 4231 onChangeY && onChangeY(self); 4232 onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self); 4233 prevDeltaY = self.deltaY; 4234 deltaY[0] = deltaY[1] = deltaY[2] = 0; 4235 } 4236 4237 if (moved || dragged) { 4238 onMove && onMove(self); 4239 4240 if (dragged) { 4241 onDrag(self); 4242 dragged = false; 4243 } 4244 4245 moved = false; 4246 } 4247 4248 locked && !(locked = false) && onLockAxis && onLockAxis(self); 4249 4250 if (wheeled) { 4251 onWheel(self); 4252 wheeled = false; 4253 } 4254 4255 id = 0; 4256 }, 4257 onDelta = function onDelta(x, y, index) { 4258 deltaX[index] += x; 4259 deltaY[index] += y; 4260 4261 self._vx.update(x); 4262 4263 self._vy.update(y); 4264 4265 debounce ? id || (id = requestAnimationFrame(update)) : update(); 4266 }, 4267 onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) { 4268 if (lockAxis && !axis) { 4269 self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y"; 4270 locked = true; 4271 } 4272 4273 if (axis !== "y") { 4274 deltaX[2] += x; 4275 4276 self._vx.update(x, true); // update the velocity as frequently as possible instead of in the debounced function so that very quick touch-scrolls (flicks) feel natural. If it's the mouse/touch/pointer, force it so that we get snappy/accurate momentum scroll. 4277 4278 } 4279 4280 if (axis !== "x") { 4281 deltaY[2] += y; 4282 4283 self._vy.update(y, true); 4284 } 4285 4286 debounce ? id || (id = requestAnimationFrame(update)) : update(); 4287 }, 4288 _onDrag = function _onDrag(e) { 4289 if (_ignoreCheck(e, 1)) { 4290 return; 4291 } 4292 4293 e = _getEvent(e, preventDefault); 4294 var x = e.clientX, 4295 y = e.clientY, 4296 dx = x - self.x, 4297 dy = y - self.y, 4298 isDragging = self.isDragging; 4299 self.x = x; 4300 self.y = y; 4301 4302 if (isDragging || Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum) { 4303 onDrag && (dragged = true); 4304 isDragging || (self.isDragging = true); 4305 onTouchOrPointerDelta(dx, dy); 4306 isDragging || onDragStart && onDragStart(self); 4307 } 4308 }, 4309 _onPress = self.onPress = function (e) { 4310 if (_ignoreCheck(e, 1) || e && e.button) { 4311 return; 4312 } 4313 4314 self.axis = axis = null; 4315 onStopDelayedCall.pause(); 4316 self.isPressed = true; 4317 e = _getEvent(e); // note: may need to preventDefault(?) Won't side-scroll on iOS Safari if we do, though. 4318 4319 prevDeltaX = prevDeltaY = 0; 4320 self.startX = self.x = e.clientX; 4321 self.startY = self.y = e.clientY; 4322 4323 self._vx.reset(); // otherwise the t2 may be stale if the user touches and flicks super fast and releases in less than 2 requestAnimationFrame ticks, causing velocity to be 0. 4324 4325 4326 self._vy.reset(); 4327 4328 _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true); 4329 4330 self.deltaX = self.deltaY = 0; 4331 onPress && onPress(self); 4332 }, 4333 _onRelease = self.onRelease = function (e) { 4334 if (_ignoreCheck(e, 1)) { 4335 return; 4336 } 4337 4338 _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); 4339 4340 var isTrackingDrag = !isNaN(self.y - self.startY), 4341 wasDragging = self.isDragging, 4342 isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3), 4343 // some touch devices need some wiggle room in terms of sensing clicks - the finger may move a few pixels. 4344 eventData = _getEvent(e); 4345 4346 if (!isDragNotClick && isTrackingDrag) { 4347 self._vx.reset(); 4348 4349 self._vy.reset(); //if (preventDefault && allowClicks && self.isPressed) { // check isPressed because in a rare edge case, the inputObserver in ScrollTrigger may stopPropagation() on the press/drag, so the onRelease may get fired without the onPress/onDrag ever getting called, thus it could trigger a click to occur on a link after scroll-dragging it. 4350 4351 4352 if (preventDefault && allowClicks) { 4353 gsap.delayedCall(0.08, function () { 4354 // 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. 4355 if (_getTime() - onClickTime > 300 && !e.defaultPrevented) { 4356 if (e.target.click) { 4357 //some browsers (like mobile Safari) don't properly trigger the click event 4358 e.target.click(); 4359 } else if (ownerDoc.createEvent) { 4360 var syntheticEvent = ownerDoc.createEvent("MouseEvents"); 4361 syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null); 4362 e.target.dispatchEvent(syntheticEvent); 4363 } 4364 } 4365 }); 4366 } 4367 } 4368 4369 self.isDragging = self.isGesturing = self.isPressed = false; 4370 onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true); 4371 onDragEnd && wasDragging && onDragEnd(self); 4372 onRelease && onRelease(self, isDragNotClick); 4373 }, 4374 _onGestureStart = function _onGestureStart(e) { 4375 return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging); 4376 }, 4377 _onGestureEnd = function _onGestureEnd() { 4378 return (self.isGesturing = false) || onGestureEnd(self); 4379 }, 4380 onScroll = function onScroll(e) { 4381 if (_ignoreCheck(e)) { 4382 return; 4383 } 4384 4385 var x = scrollFuncX(), 4386 y = scrollFuncY(); 4387 onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1); 4388 scrollX = x; 4389 scrollY = y; 4390 onStop && onStopDelayedCall.restart(true); 4391 }, 4392 _onWheel = function _onWheel(e) { 4393 if (_ignoreCheck(e)) { 4394 return; 4395 } 4396 4397 e = _getEvent(e, preventDefault); 4398 onWheel && (wheeled = true); 4399 var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed; 4400 onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0); 4401 onStop && !isNormalizer && onStopDelayedCall.restart(true); 4402 }, 4403 _onMove = function _onMove(e) { 4404 if (_ignoreCheck(e)) { 4405 return; 4406 } 4407 4408 var x = e.clientX, 4409 y = e.clientY, 4410 dx = x - self.x, 4411 dy = y - self.y; 4412 self.x = x; 4413 self.y = y; 4414 moved = true; 4415 onStop && onStopDelayedCall.restart(true); 4416 (dx || dy) && onTouchOrPointerDelta(dx, dy); 4417 }, 4418 _onHover = function _onHover(e) { 4419 self.event = e; 4420 onHover(self); 4421 }, 4422 _onHoverEnd = function _onHoverEnd(e) { 4423 self.event = e; 4424 onHoverEnd(self); 4425 }, 4426 _onClick = function _onClick(e) { 4427 return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self); 4428 }; 4429 4430 onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause(); 4431 self.deltaX = self.deltaY = 0; 4432 self._vx = _getVelocityProp(0, 50, true); 4433 self._vy = _getVelocityProp(0, 50, true); 4434 self.scrollX = scrollFuncX; 4435 self.scrollY = scrollFuncY; 4436 self.isDragging = self.isGesturing = self.isPressed = false; 4437 4438 _context(this); 4439 4440 self.enable = function (e) { 4441 if (!self.isEnabled) { 4442 _addListener(isViewport ? ownerDoc : target, "scroll", _onScroll); 4443 4444 type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture); 4445 type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture); 4446 4447 if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) { 4448 _addListener(target, _eventTypes[0], _onPress, passive, capture); 4449 4450 _addListener(ownerDoc, _eventTypes[2], _onRelease); 4451 4452 _addListener(ownerDoc, _eventTypes[3], _onRelease); 4453 4454 allowClicks && _addListener(target, "click", clickCapture, true, true); 4455 onClick && _addListener(target, "click", _onClick); 4456 onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart); 4457 onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd); 4458 onHover && _addListener(target, _pointerType + "enter", _onHover); 4459 onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd); 4460 onMove && _addListener(target, _pointerType + "move", _onMove); 4461 } 4462 4463 self.isEnabled = true; 4464 e && e.type && _onPress(e); 4465 onEnable && onEnable(self); 4466 } 4467 4468 return self; 4469 }; 4470 4471 self.disable = function () { 4472 if (self.isEnabled) { 4473 // only remove the _onScroll listener if there aren't any others that rely on the functionality. 4474 _observers.filter(function (o) { 4475 return o !== self && _isViewport(o.target); 4476 }).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll); 4477 4478 if (self.isPressed) { 4479 self._vx.reset(); 4480 4481 self._vy.reset(); 4482 4483 _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true); 4484 } 4485 4486 _removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture); 4487 4488 _removeListener(target, "wheel", _onWheel, capture); 4489 4490 _removeListener(target, _eventTypes[0], _onPress, capture); 4491 4492 _removeListener(ownerDoc, _eventTypes[2], _onRelease); 4493 4494 _removeListener(ownerDoc, _eventTypes[3], _onRelease); 4495 4496 _removeListener(target, "click", clickCapture, true); 4497 4498 _removeListener(target, "click", _onClick); 4499 4500 _removeListener(ownerDoc, "gesturestart", _onGestureStart); 4501 4502 _removeListener(ownerDoc, "gestureend", _onGestureEnd); 4503 4504 _removeListener(target, _pointerType + "enter", _onHover); 4505 4506 _removeListener(target, _pointerType + "leave", _onHoverEnd); 4507 4508 _removeListener(target, _pointerType + "move", _onMove); 4509 4510 self.isEnabled = self.isPressed = self.isDragging = false; 4511 onDisable && onDisable(self); 4512 } 4513 }; 4514 4515 self.kill = self.revert = function () { 4516 self.disable(); 4517 4518 var i = _observers.indexOf(self); 4519 4520 i >= 0 && _observers.splice(i, 1); 4521 _normalizer === self && (_normalizer = 0); 4522 }; 4523 4524 _observers.push(self); 4525 4526 isNormalizer && _isViewport(target) && (_normalizer = self); 4527 self.enable(event); 4528 }; 4529 4530 _createClass(Observer, [{ 4531 key: "velocityX", 4532 get: function get() { 4533 return this._vx.getVelocity(); 4534 } 4535 }, { 4536 key: "velocityY", 4537 get: function get() { 4538 return this._vy.getVelocity(); 4539 } 4540 }]); 4541 4542 return Observer; 4543}(); 4544Observer.version = "3.12.5"; 4545 4546Observer.create = function (vars) { 4547 return new Observer(vars); 4548}; 4549 4550Observer.register = _initCore; 4551 4552Observer.getAll = function () { 4553 return _observers.slice(); 4554}; 4555 4556Observer.getById = function (id) { 4557 return _observers.filter(function (o) { 4558 return o.vars.id === id; 4559 })[0]; 4560}; 4561 4562_getGSAP() && gsap.registerPlugin(Observer); 4563 4564 4565/***/ }), 4566
vendor: 114,545 bytes, lines 4567-7239
4567/***/ "./node_modules/gsap/ScrollTrigger.js": 4568/*!********************************************!*\ 4569 !*** ./node_modules/gsap/ScrollTrigger.js ***! 4570 \********************************************/ 4571/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 4572 4573__webpack_require__.r(__webpack_exports__); 4574/* harmony export */ __webpack_require__.d(__webpack_exports__, { 4575/* harmony export */ ScrollTrigger: () => (/* binding */ ScrollTrigger), 4576/* harmony export */ "default": () => (/* binding */ ScrollTrigger) 4577/* harmony export */ }); 4578/* harmony import */ var _Observer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Observer.js */ "./node_modules/gsap/Observer.js"); 4579/*! 4580 * ScrollTrigger 3.12.5 4581 * https://gsap.com 4582 * 4583 * @license Copyright 2008-2024, GreenSock. All rights reserved. 4584 * Subject to the terms at https://gsap.com/standard-license or for 4585 * Club GSAP members, the agreement issued with that membership. 4586 * @author: Jack Doyle, [email protected] 4587*/ 4588 4589/* eslint-disable */ 4590 4591 4592var gsap, 4593 _coreInitted, 4594 _win, 4595 _doc, 4596 _docEl, 4597 _body, 4598 _root, 4599 _resizeDelay, 4600 _toArray, 4601 _clamp, 4602 _time2, 4603 _syncInterval, 4604 _refreshing, 4605 _pointerIsDown, 4606 _transformProp, 4607 _i, 4608 _prevWidth, 4609 _prevHeight, 4610 _autoRefresh, 4611 _sort, 4612 _suppressOverwrites, 4613 _ignoreResize, 4614 _normalizer, 4615 _ignoreMobileResize, 4616 _baseScreenHeight, 4617 _baseScreenWidth, 4618 _fixIOSBug, 4619 _context, 4620 _scrollRestoration, 4621 _div100vh, 4622 _100vh, 4623 _isReverted, 4624 _clampingMax, 4625 _limitCallbacks, 4626 // 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. 4627_startup = 1, 4628 _getTime = Date.now, 4629 _time1 = _getTime(), 4630 _lastScrollTime = 0, 4631 _enabled = 0, 4632 _parseClamp = function _parseClamp(value, type, self) { 4633 var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1); 4634 self["_" + type + "Clamp"] = clamp; 4635 return clamp ? value.substr(6, value.length - 7) : value; 4636}, 4637 _keepClamp = function _keepClamp(value, clamp) { 4638 return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value; 4639}, 4640 _rafBugFix = function _rafBugFix() { 4641 return _enabled && requestAnimationFrame(_rafBugFix); 4642}, 4643 // in some browsers (like Firefox), screen repaints weren't consistent unless we had SOMETHING queued up in requestAnimationFrame()! So this just creates a super simple loop to keep it alive and smooth out repaints. 4644_pointerDownHandler = function _pointerDownHandler() { 4645 return _pointerIsDown = 1; 4646}, 4647 _pointerUpHandler = function _pointerUpHandler() { 4648 return _pointerIsDown = 0; 4649}, 4650 _passThrough = function _passThrough(v) { 4651 return v; 4652}, 4653 _round = function _round(value) { 4654 return Math.round(value * 100000) / 100000 || 0; 4655}, 4656 _windowExists = function _windowExists() { 4657 return typeof window !== "undefined"; 4658}, 4659 _getGSAP = function _getGSAP() { 4660 return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap; 4661}, 4662 _isViewport = function _isViewport(e) { 4663 return !!~_root.indexOf(e); 4664}, 4665 _getViewportDimension = function _getViewportDimension(dimensionProperty) { 4666 return (dimensionProperty === "Height" ? _100vh : _win["inner" + dimensionProperty]) || _docEl["client" + dimensionProperty] || _body["client" + dimensionProperty]; 4667}, 4668 _getBoundsFunc = function _getBoundsFunc(element) { 4669 return (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(element, "getBoundingClientRect") || (_isViewport(element) ? function () { 4670 _winOffsets.width = _win.innerWidth; 4671 _winOffsets.height = _100vh; 4672 return _winOffsets; 4673 } : function () { 4674 return _getBounds(element); 4675 }); 4676}, 4677 _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) { 4678 var d = _ref.d, 4679 d2 = _ref.d2, 4680 a = _ref.a; 4681 return (a = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "getBoundingClientRect")) ? function () { 4682 return a()[d]; 4683 } : function () { 4684 return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0; 4685 }; 4686}, 4687 _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) { 4688 return !isViewport || ~_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.indexOf(element) ? _getBoundsFunc(element) : function () { 4689 return _winOffsets; 4690 }; 4691}, 4692 _maxScroll = function _maxScroll(element, _ref2) { 4693 var s = _ref2.s, 4694 d2 = _ref2.d2, 4695 d = _ref2.d, 4696 a = _ref2.a; 4697 return Math.max(0, (s = "scroll" + d2) && (a = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(element, s)) ? a() - _getBoundsFunc(element)()[d] : _isViewport(element) ? (_docEl[s] || _body[s]) - _getViewportDimension(d2) : element[s] - element["offset" + d2]); 4698}, 4699 _iterateAutoRefresh = function _iterateAutoRefresh(func, events) { 4700 for (var i = 0; i < _autoRefresh.length; i += 3) { 4701 (!events || ~events.indexOf(_autoRefresh[i + 1])) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]); 4702 } 4703}, 4704 _isString = function _isString(value) { 4705 return typeof value === "string"; 4706}, 4707 _isFunction = function _isFunction(value) { 4708 return typeof value === "function"; 4709}, 4710 _isNumber = function _isNumber(value) { 4711 return typeof value === "number"; 4712}, 4713 _isObject = function _isObject(value) { 4714 return typeof value === "object"; 4715}, 4716 _endAnimation = function _endAnimation(animation, reversed, pause) { 4717 return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause(); 4718}, 4719 _callback = function _callback(self, func) { 4720 if (self.enabled) { 4721 var result = self._ctx ? self._ctx.add(function () { 4722 return func(self); 4723 }) : func(self); 4724 result && result.totalTime && (self.callbackAnimation = result); 4725 } 4726}, 4727 _abs = Math.abs, 4728 _left = "left", 4729 _top = "top", 4730 _right = "right", 4731 _bottom = "bottom", 4732 _width = "width", 4733 _height = "height", 4734 _Right = "Right", 4735 _Left = "Left", 4736 _Top = "Top", 4737 _Bottom = "Bottom", 4738 _padding = "padding", 4739 _margin = "margin", 4740 _Width = "Width", 4741 _Height = "Height", 4742 _px = "px", 4743 _getComputedStyle = function _getComputedStyle(element) { 4744 return _win.getComputedStyle(element); 4745}, 4746 _makePositionable = function _makePositionable(element) { 4747 // if the element already has position: absolute or fixed, leave that, otherwise make it position: relative 4748 var position = _getComputedStyle(element).position; 4749 4750 element.style.position = position === "absolute" || position === "fixed" ? position : "relative"; 4751}, 4752 _setDefaults = function _setDefaults(obj, defaults) { 4753 for (var p in defaults) { 4754 p in obj || (obj[p] = defaults[p]); 4755 } 4756 4757 return obj; 4758}, 4759 _getBounds = function _getBounds(element, withoutTransforms) { 4760 var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, { 4761 x: 0, 4762 y: 0, 4763 xPercent: 0, 4764 yPercent: 0, 4765 rotation: 0, 4766 rotationX: 0, 4767 rotationY: 0, 4768 scale: 1, 4769 skewX: 0, 4770 skewY: 0 4771 }).progress(1), 4772 bounds = element.getBoundingClientRect(); 4773 tween && tween.progress(0).kill(); 4774 return bounds; 4775}, 4776 _getSize = function _getSize(element, _ref3) { 4777 var d2 = _ref3.d2; 4778 return element["offset" + d2] || element["client" + d2] || 0; 4779}, 4780 _getLabelRatioArray = function _getLabelRatioArray(timeline) { 4781 var a = [], 4782 labels = timeline.labels, 4783 duration = timeline.duration(), 4784 p; 4785 4786 for (p in labels) { 4787 a.push(labels[p] / duration); 4788 } 4789 4790 return a; 4791}, 4792 _getClosestLabel = function _getClosestLabel(animation) { 4793 return function (value) { 4794 return gsap.utils.snap(_getLabelRatioArray(animation), value); 4795 }; 4796}, 4797 _snapDirectional = function _snapDirectional(snapIncrementOrArray) { 4798 var snap = gsap.utils.snap(snapIncrementOrArray), 4799 a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) { 4800 return a - b; 4801 }); 4802 return a ? function (value, direction, threshold) { 4803 if (threshold === void 0) { 4804 threshold = 1e-3; 4805 } 4806 4807 var i; 4808 4809 if (!direction) { 4810 return snap(value); 4811 } 4812 4813 if (direction > 0) { 4814 value -= threshold; // to avoid rounding errors. If we're too strict, it might snap forward, then immediately again, and again. 4815 4816 for (i = 0; i < a.length; i++) { 4817 if (a[i] >= value) { 4818 return a[i]; 4819 } 4820 } 4821 4822 return a[i - 1]; 4823 } else { 4824 i = a.length; 4825 value += threshold; 4826 4827 while (i--) { 4828 if (a[i] <= value) { 4829 return a[i]; 4830 } 4831 } 4832 } 4833 4834 return a[0]; 4835 } : function (value, direction, threshold) { 4836 if (threshold === void 0) { 4837 threshold = 1e-3; 4838 } 4839 4840 var snapped = snap(value); 4841 return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray); 4842 }; 4843}, 4844 _getLabelAtDirection = function _getLabelAtDirection(timeline) { 4845 return function (value, st) { 4846 return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction); 4847 }; 4848}, 4849 _multiListener = function _multiListener(func, element, types, callback) { 4850 return types.split(",").forEach(function (type) { 4851 return func(element, type, callback); 4852 }); 4853}, 4854 _addListener = function _addListener(element, type, func, nonPassive, capture) { 4855 return element.addEventListener(type, func, { 4856 passive: !nonPassive, 4857 capture: !!capture 4858 }); 4859}, 4860 _removeListener = function _removeListener(element, type, func, capture) { 4861 return element.removeEventListener(type, func, !!capture); 4862}, 4863 _wheelListener = function _wheelListener(func, el, scrollFunc) { 4864 scrollFunc = scrollFunc && scrollFunc.wheelHandler; 4865 4866 if (scrollFunc) { 4867 func(el, "wheel", scrollFunc); 4868 func(el, "touchmove", scrollFunc); 4869 } 4870}, 4871 _markerDefaults = { 4872 startColor: "green", 4873 endColor: "red", 4874 indent: 0, 4875 fontSize: "16px", 4876 fontWeight: "normal" 4877}, 4878 _defaults = { 4879 toggleActions: "play", 4880 anticipatePin: 0 4881}, 4882 _keywords = { 4883 top: 0, 4884 left: 0, 4885 center: 0.5, 4886 bottom: 1, 4887 right: 1 4888}, 4889 _offsetToPx = function _offsetToPx(value, size) { 4890 if (_isString(value)) { 4891 var eqIndex = value.indexOf("="), 4892 relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0; 4893 4894 if (~eqIndex) { 4895 value.indexOf("%") > eqIndex && (relative *= size / 100); 4896 value = value.substr(0, eqIndex - 1); 4897 } 4898 4899 value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0); 4900 } 4901 4902 return value; 4903}, 4904 _createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) { 4905 var startColor = _ref4.startColor, 4906 endColor = _ref4.endColor, 4907 fontSize = _ref4.fontSize, 4908 indent = _ref4.indent, 4909 fontWeight = _ref4.fontWeight; 4910 4911 var e = _doc.createElement("div"), 4912 useFixedPosition = _isViewport(container) || (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(container, "pinType") === "fixed", 4913 isScroller = type.indexOf("scroller") !== -1, 4914 parent = useFixedPosition ? _body : container, 4915 isStart = type.indexOf("start") !== -1, 4916 color = isStart ? startColor : endColor, 4917 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;"; 4918 4919 css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;"); 4920 (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;"); 4921 matchWidthEl && (css += "box-sizing:border-box;text-align:left;width:" + matchWidthEl.offsetWidth + "px;"); 4922 e._isStart = isStart; 4923 e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : "")); 4924 e.style.cssText = css; 4925 e.innerText = name || name === 0 ? type + "-" + name : type; 4926 parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e); 4927 e._offset = e["offset" + direction.op.d2]; 4928 4929 _positionMarker(e, 0, direction, isStart); 4930 4931 return e; 4932}, 4933 _positionMarker = function _positionMarker(marker, start, direction, flipped) { 4934 var vars = { 4935 display: "block" 4936 }, 4937 side = direction[flipped ? "os2" : "p2"], 4938 oppositeSide = direction[flipped ? "p2" : "os2"]; 4939 marker._isFlipped = flipped; 4940 vars[direction.a + "Percent"] = flipped ? -100 : 0; 4941 vars[direction.a] = flipped ? "1px" : 0; 4942 vars["border" + side + _Width] = 1; 4943 vars["border" + oppositeSide + _Width] = 0; 4944 vars[direction.p] = start + "px"; 4945 gsap.set(marker, vars); 4946}, 4947 _triggers = [], 4948 _ids = {}, 4949 _rafID, 4950 _sync = function _sync() { 4951 return _getTime() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll))); 4952}, 4953 _onScroll = function _onScroll() { 4954 // previously, we tried to optimize performance by batching/deferring to the next requestAnimationFrame(), but discovered that Safari has a few bugs that make this unworkable (especially on iOS). See https://codepen.io/GreenSock/pen/16c435b12ef09c38125204818e7b45fc?editors=0010 and https://codepen.io/GreenSock/pen/JjOxYpQ/3dd65ccec5a60f1d862c355d84d14562?editors=0010 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503?editors=0010 4955 if (!_normalizer || !_normalizer.isPressed || _normalizer.startX > _body.clientWidth) { 4956 // if the user is dragging the scrollbar, allow it. 4957 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; 4958 4959 if (_normalizer) { 4960 _rafID || (_rafID = requestAnimationFrame(_updateAll)); 4961 } else { 4962 _updateAll(); // Safari in particular (on desktop) NEEDS the immediate update rather than waiting for a requestAnimationFrame() whereas iOS seems to benefit from waiting for the requestAnimationFrame() tick, at least when normalizing. See https://codepen.io/GreenSock/pen/qBYozqO?editors=0110 4963 4964 } 4965 4966 _lastScrollTime || _dispatch("scrollStart"); 4967 _lastScrollTime = _getTime(); 4968 } 4969}, 4970 _setBaseDimensions = function _setBaseDimensions() { 4971 _baseScreenWidth = _win.innerWidth; 4972 _baseScreenHeight = _win.innerHeight; 4973}, 4974 _onResize = function _onResize() { 4975 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; 4976 !_refreshing && !_ignoreResize && !_doc.fullscreenElement && !_doc.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== _win.innerWidth || Math.abs(_win.innerHeight - _baseScreenHeight) > _win.innerHeight * 0.25) && _resizeDelay.restart(true); 4977}, 4978 // ignore resizes triggered by refresh() 4979_listeners = {}, 4980 _emptyArray = [], 4981 _softRefresh = function _softRefresh() { 4982 return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true); 4983}, 4984 _dispatch = function _dispatch(type) { 4985 return _listeners[type] && _listeners[type].map(function (f) { 4986 return f(); 4987 }) || _emptyArray; 4988}, 4989 _savedStyles = [], 4990 // 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. 4991_revertRecorded = function _revertRecorded(media) { 4992 for (var i = 0; i < _savedStyles.length; i += 5) { 4993 if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) { 4994 _savedStyles[i].style.cssText = _savedStyles[i + 1]; 4995 _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || ""); 4996 _savedStyles[i + 3].uncache = 1; 4997 } 4998 } 4999}, 5000 _revertAll = function _revertAll(kill, media) { 5001 var trigger; 5002 5003 for (_i = 0; _i < _triggers.length; _i++) { 5004 trigger = _triggers[_i]; 5005 5006 if (trigger && (!media || trigger._ctx === media)) { 5007 if (kill) { 5008 trigger.kill(1); 5009 } else { 5010 trigger.revert(true, true); 5011 } 5012 } 5013 } 5014 5015 _isReverted = true; 5016 media && _revertRecorded(media); 5017 media || _dispatch("revert"); 5018}, 5019 _clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) { 5020 // zero-out all the recorded scroll positions. Don't use _triggers because if, for example, .matchMedia() is used to create some ScrollTriggers and then the user resizes and it removes ALL ScrollTriggers, and then go back to a size where there are ScrollTriggers, it would have kept the position(s) saved from the initial state. 5021 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; 5022 (force || !_refreshingAll) && _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) { 5023 return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0); 5024 }); 5025 _isString(scrollRestoration) && (_win.history.scrollRestoration = _scrollRestoration = scrollRestoration); 5026}, 5027 _refreshingAll, 5028 _refreshID = 0, 5029 _queueRefreshID, 5030 _queueRefreshAll = function _queueRefreshAll() { 5031 // we don't want to call _refreshAll() every time we create a new ScrollTrigger (for performance reasons) - it's better to batch them. Some frameworks dynamically load content and we can't rely on the window's "load" or "DOMContentLoaded" events to trigger it. 5032 if (_queueRefreshID !== _refreshID) { 5033 var id = _queueRefreshID = _refreshID; 5034 requestAnimationFrame(function () { 5035 return id === _refreshID && _refreshAll(true); 5036 }); 5037 } 5038}, 5039 _refresh100vh = function _refresh100vh() { 5040 _body.appendChild(_div100vh); 5041 5042 _100vh = !_normalizer && _div100vh.offsetHeight || _win.innerHeight; 5043 5044 _body.removeChild(_div100vh); 5045}, 5046 _hideAllMarkers = function _hideAllMarkers(hide) { 5047 return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) { 5048 return el.style.display = hide ? "none" : "block"; 5049 }); 5050}, 5051 _refreshAll = function _refreshAll(force, skipRevert) { 5052 if (_lastScrollTime && !force && !_isReverted) { 5053 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 5054 5055 return; 5056 } 5057 5058 _refresh100vh(); 5059 5060 _refreshingAll = ScrollTrigger.isRefreshing = true; 5061 5062 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) { 5063 return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj()); 5064 }); // force the clearing of the cache because some browsers take a little while to dispatch the "scroll" event and the user may have changed the scroll position and then called ScrollTrigger.refresh() right away 5065 5066 5067 var refreshInits = _dispatch("refreshInit"); 5068 5069 _sort && ScrollTrigger.sort(); 5070 skipRevert || _revertAll(); 5071 5072 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) { 5073 if (_isFunction(obj)) { 5074 obj.smooth && (obj.target.style.scrollBehavior = "auto"); // smooth scrolling interferes 5075 5076 obj(0); 5077 } 5078 }); 5079 5080 _triggers.slice(0).forEach(function (t) { 5081 return t.refresh(); 5082 }); // don't loop with _i because during a refresh() someone could call ScrollTrigger.update() which would iterate through _i resulting in a skip. 5083 5084 5085 _isReverted = false; 5086 5087 _triggers.forEach(function (t) { 5088 // nested pins (pinnedContainer) with pinSpacing may expand the container, so we must accommodate that here. 5089 if (t._subPinOffset && t.pin) { 5090 var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight", 5091 original = t.pin[prop]; 5092 t.revert(true, 1); 5093 t.adjustPinSpacing(t.pin[prop] - original); 5094 t.refresh(); 5095 } 5096 }); 5097 5098 _clampingMax = 1; // pinSpacing might be propping a page open, thus when we .setPositions() to clamp a ScrollTrigger's end we should leave the pinSpacing alone. That's what this flag is for. 5099 5100 _hideAllMarkers(true); 5101 5102 _triggers.forEach(function (t) { 5103 // the scroller's max scroll position may change after all the ScrollTriggers refreshed (like pinning could push it down), so we need to loop back and correct any with end: "max". Same for anything with a clamped end 5104 var max = _maxScroll(t.scroller, t._dir), 5105 endClamp = t.vars.end === "max" || t._endClamp && t.end > max, 5106 startClamp = t._startClamp && t.start >= max; 5107 5108 (endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true); 5109 }); 5110 5111 _hideAllMarkers(false); 5112 5113 _clampingMax = 0; 5114 refreshInits.forEach(function (result) { 5115 return result && result.render && result.render(-1); 5116 }); // 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. 5117 5118 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) { 5119 if (_isFunction(obj)) { 5120 obj.smooth && requestAnimationFrame(function () { 5121 return obj.target.style.scrollBehavior = "smooth"; 5122 }); 5123 obj.rec && obj(obj.rec); 5124 } 5125 }); 5126 5127 _clearScrollMemory(_scrollRestoration, 1); 5128 5129 _resizeDelay.pause(); 5130 5131 _refreshID++; 5132 _refreshingAll = 2; 5133 5134 _updateAll(2); 5135 5136 _triggers.forEach(function (t) { 5137 return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t); 5138 }); 5139 5140 _refreshingAll = ScrollTrigger.isRefreshing = false; 5141 5142 _dispatch("refresh"); 5143}, 5144 _lastScroll = 0, 5145 _direction = 1, 5146 _primary, 5147 _updateAll = function _updateAll(force) { 5148 if (force === 2 || !_refreshingAll && !_isReverted) { 5149 // _isReverted could be true if, for example, a matchMedia() is in the process of executing. We don't want to update during the time everything is reverted. 5150 ScrollTrigger.isUpdating = true; 5151 _primary && _primary.update(0); // ScrollSmoother uses refreshPriority -9999 to become the primary that gets updated before all others because it affects the scroll position. 5152 5153 var l = _triggers.length, 5154 time = _getTime(), 5155 recordVelocity = time - _time1 >= 50, 5156 scroll = l && _triggers[0].scroll(); 5157 5158 _direction = _lastScroll > scroll ? -1 : 1; 5159 _refreshingAll || (_lastScroll = scroll); 5160 5161 if (recordVelocity) { 5162 if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) { 5163 _lastScrollTime = 0; 5164 5165 _dispatch("scrollEnd"); 5166 } 5167 5168 _time2 = _time1; 5169 _time1 = time; 5170 } 5171 5172 if (_direction < 0) { 5173 _i = l; 5174 5175 while (_i-- > 0) { 5176 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 5177 } 5178 5179 _direction = 1; 5180 } else { 5181 for (_i = 0; _i < l; _i++) { 5182 _triggers[_i] && _triggers[_i].update(0, recordVelocity); 5183 } 5184 } 5185 5186 ScrollTrigger.isUpdating = false; 5187 } 5188 5189 _rafID = 0; 5190}, 5191 _propNamesToCopy = [_left, _top, _bottom, _right, _margin + _Bottom, _margin + _Right, _margin + _Top, _margin + _Left, "display", "flexShrink", "float", "zIndex", "gridColumnStart", "gridColumnEnd", "gridRowStart", "gridRowEnd", "gridArea", "justifySelf", "alignSelf", "placeSelf", "order"], 5192 _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]), 5193 _swapPinOut = function _swapPinOut(pin, spacer, state) { 5194 _setState(state); 5195 5196 var cache = pin._gsap; 5197 5198 if (cache.spacerIsNative) { 5199 _setState(cache.spacerState); 5200 } else if (pin._gsap.swappedIn) { 5201 var parent = spacer.parentNode; 5202 5203 if (parent) { 5204 parent.insertBefore(pin, spacer); 5205 parent.removeChild(spacer); 5206 } 5207 } 5208 5209 pin._gsap.swappedIn = false; 5210}, 5211 _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) { 5212 if (!pin._gsap.swappedIn) { 5213 var i = _propNamesToCopy.length, 5214 spacerStyle = spacer.style, 5215 pinStyle = pin.style, 5216 p; 5217 5218 while (i--) { 5219 p = _propNamesToCopy[i]; 5220 spacerStyle[p] = cs[p]; 5221 } 5222 5223 spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative"; 5224 cs.display === "inline" && (spacerStyle.display = "inline-block"); 5225 pinStyle[_bottom] = pinStyle[_right] = "auto"; 5226 spacerStyle.flexBasis = cs.flexBasis || "auto"; 5227 spacerStyle.overflow = "visible"; 5228 spacerStyle.boxSizing = "border-box"; 5229 spacerStyle[_width] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal) + _px; 5230 spacerStyle[_height] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical) + _px; 5231 spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0"; 5232 5233 _setState(spacerState); 5234 5235 pinStyle[_width] = pinStyle["max" + _Width] = cs[_width]; 5236 pinStyle[_height] = pinStyle["max" + _Height] = cs[_height]; 5237 pinStyle[_padding] = cs[_padding]; 5238 5239 if (pin.parentNode !== spacer) { 5240 pin.parentNode.insertBefore(spacer, pin); 5241 spacer.appendChild(pin); 5242 } 5243 5244 pin._gsap.swappedIn = true; 5245 } 5246}, 5247 _capsExp = /([A-Z])/g, 5248 _setState = function _setState(state) { 5249 if (state) { 5250 var style = state.t.style, 5251 l = state.length, 5252 i = 0, 5253 p, 5254 value; 5255 (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off 5256 5257 for (; i < l; i += 2) { 5258 value = state[i + 1]; 5259 p = state[i]; 5260 5261 if (value) { 5262 style[p] = value; 5263 } else if (style[p]) { 5264 style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase()); 5265 } 5266 } 5267 } 5268}, 5269 _getState = function _getState(element) { 5270 // 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. 5271 var l = _stateProps.length, 5272 style = element.style, 5273 state = [], 5274 i = 0; 5275 5276 for (; i < l; i++) { 5277 state.push(_stateProps[i], style[_stateProps[i]]); 5278 } 5279 5280 state.t = element; 5281 return state; 5282}, 5283 _copyState = function _copyState(state, override, omitOffsets) { 5284 var result = [], 5285 l = state.length, 5286 i = omitOffsets ? 8 : 0, 5287 // skip top, left, right, bottom if omitOffsets is true 5288 p; 5289 5290 for (; i < l; i += 2) { 5291 p = state[i]; 5292 result.push(p, p in override ? override[p] : state[i + 1]); 5293 } 5294 5295 result.t = state.t; 5296 return result; 5297}, 5298 _winOffsets = { 5299 left: 0, 5300 top: 0 5301}, 5302 // // potential future feature (?) Allow users to calculate where a trigger hits (scroll position) like getScrollPosition("#id", "top bottom") 5303// _getScrollPosition = (trigger, position, {scroller, containerAnimation, horizontal}) => { 5304// scroller = _getTarget(scroller || _win); 5305// let direction = horizontal ? _horizontal : _vertical, 5306// isViewport = _isViewport(scroller); 5307// _getSizeFunc(scroller, isViewport, direction); 5308// return _parsePosition(position, _getTarget(trigger), _getSizeFunc(scroller, isViewport, direction)(), direction, _getScrollFunc(scroller, direction)(), 0, 0, 0, _getOffsetsFunc(scroller, isViewport)(), isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 0, containerAnimation ? containerAnimation.duration() : _maxScroll(scroller), containerAnimation); 5309// }, 5310_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) { 5311 _isFunction(value) && (value = value(self)); 5312 5313 if (_isString(value) && value.substr(0, 3) === "max") { 5314 value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0); 5315 } 5316 5317 var time = containerAnimation ? containerAnimation.time() : 0, 5318 p1, 5319 p2, 5320 element; 5321 containerAnimation && containerAnimation.seek(0); 5322 isNaN(value) || (value = +value); // convert a string number like "45" to an actual number 5323 5324 if (!_isNumber(value)) { 5325 _isFunction(trigger) && (trigger = trigger(self)); 5326 var offsets = (value || "0").split(" "), 5327 bounds, 5328 localOffset, 5329 globalOffset, 5330 display; 5331 element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(trigger, self) || _body; 5332 bounds = _getBounds(element) || {}; 5333 5334 if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") { 5335 // if display is "none", it won't report getBoundingClientRect() properly 5336 display = element.style.display; 5337 element.style.display = "block"; 5338 bounds = _getBounds(element); 5339 display ? element.style.display = display : element.style.removeProperty("display"); 5340 } 5341 5342 localOffset = _offsetToPx(offsets[0], bounds[direction.d]); 5343 globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize); 5344 value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset; 5345 markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20); 5346 scrollerSize -= scrollerSize - globalOffset; // adjust for the marker 5347 } else { 5348 containerAnimation && (value = gsap.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMax, value)); 5349 markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true); 5350 } 5351 5352 if (clampZeroProp) { 5353 self[clampZeroProp] = value || -0.001; 5354 value < 0 && (value = 0); 5355 } 5356 5357 if (marker) { 5358 var position = value + scrollerSize, 5359 isStart = marker._isStart; 5360 p1 = "scroll" + direction.d2; 5361 5362 _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1); 5363 5364 if (useFixedPosition) { 5365 scrollerBounds = _getBounds(markerScroller); 5366 useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px); 5367 } 5368 } 5369 5370 if (containerAnimation && element) { 5371 p1 = _getBounds(element); 5372 containerAnimation.seek(scrollerMax); 5373 p2 = _getBounds(element); 5374 containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p]; 5375 value = value / containerAnimation._caScrollDist * scrollerMax; 5376 } 5377 5378 containerAnimation && containerAnimation.seek(time); 5379 return containerAnimation ? value : Math.round(value); 5380}, 5381 _prefixExp = /(webkit|moz|length|cssText|inset)/i, 5382 _reparent = function _reparent(element, parent, top, left) { 5383 if (element.parentNode !== parent) { 5384 var style = element.style, 5385 p, 5386 cs; 5387 5388 if (parent === _body) { 5389 element._stOrig = style.cssText; // record original inline styles so we can revert them later 5390 5391 cs = _getComputedStyle(element); 5392 5393 for (p in cs) { 5394 // must copy all relevant styles to ensure that nothing changes visually when we reparent to the <body>. Skip the vendor prefixed ones. 5395 if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") { 5396 style[p] = cs[p]; 5397 } 5398 } 5399 5400 style.top = top; 5401 style.left = left; 5402 } else { 5403 style.cssText = element._stOrig; 5404 } 5405 5406 gsap.core.getCache(element).uncache = 1; 5407 parent.appendChild(element); 5408 } 5409}, 5410 _interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) { 5411 var last1 = initialValue, 5412 last2 = last1; 5413 return function (value) { 5414 var current = Math.round(getValueFunc()); // round because in some [very uncommon] Windows environments, scroll can get reported with decimals even though it was set without. 5415 5416 if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) { 5417 // 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. 5418 value = current; 5419 onInterrupt && onInterrupt(); 5420 } 5421 5422 last2 = last1; 5423 last1 = value; 5424 return value; 5425 }; 5426}, 5427 _shiftMarker = function _shiftMarker(marker, direction, value) { 5428 var vars = {}; 5429 vars[direction.p] = "+=" + value; 5430 gsap.set(marker, vars); 5431}, 5432 // _mergeAnimations = animations => { 5433// let tl = gsap.timeline({smoothChildTiming: true}).startTime(Math.min(...animations.map(a => a.globalTime(0)))); 5434// animations.forEach(a => {let time = a.totalTime(); tl.add(a); a.totalTime(time); }); 5435// tl.smoothChildTiming = false; 5436// return tl; 5437// }, 5438// 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) 5439_getTweenCreator = function _getTweenCreator(scroller, direction) { 5440 var getScroll = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction), 5441 prop = "_scroll" + direction.p2, 5442 // 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. 5443 getTween = function getTween(scrollTo, vars, initialValue, change1, change2) { 5444 var tween = getTween.tween, 5445 onComplete = vars.onComplete, 5446 modifiers = {}; 5447 initialValue = initialValue || getScroll(); 5448 5449 var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () { 5450 tween.kill(); 5451 getTween.tween = 0; 5452 }); 5453 5454 change2 = change1 && change2 || 0; // if change1 is 0, we set that to the difference and ignore change2. Otherwise, there would be a compound effect. 5455 5456 change1 = change1 || scrollTo - initialValue; 5457 tween && tween.kill(); 5458 vars[prop] = scrollTo; 5459 vars.inherit = false; 5460 vars.modifiers = modifiers; 5461 5462 modifiers[prop] = function () { 5463 return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio); 5464 }; 5465 5466 vars.onUpdate = function () { 5467 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; 5468 getTween.tween && _updateAll(); // if it was interrupted/killed, like in a context.revert(), don't force an updateAll() 5469 }; 5470 5471 vars.onComplete = function () { 5472 getTween.tween = 0; 5473 onComplete && onComplete.call(tween); 5474 }; 5475 5476 tween = getTween.tween = gsap.to(scroller, vars); 5477 return tween; 5478 }; 5479 5480 scroller[prop] = getScroll; 5481 5482 getScroll.wheelHandler = function () { 5483 return getTween.tween && getTween.tween.kill() && (getTween.tween = 0); 5484 }; 5485 5486 _addListener(scroller, "wheel", getScroll.wheelHandler); // 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 wheel event. 5487 5488 5489 ScrollTrigger.isTouch && _addListener(scroller, "touchmove", getScroll.wheelHandler); 5490 return getTween; 5491}; 5492 5493var ScrollTrigger = /*#__PURE__*/function () { 5494 function ScrollTrigger(vars, animation) { 5495 _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)"); 5496 5497 _context(this); 5498 5499 this.init(vars, animation); 5500 } 5501 5502 var _proto = ScrollTrigger.prototype; 5503 5504 _proto.init = function init(vars, animation) { 5505 this.progress = this.start = 0; 5506 this.vars && this.kill(true, true); // in case it's being initted again 5507 5508 if (!_enabled) { 5509 this.update = this.refresh = this.kill = _passThrough; 5510 return; 5511 } 5512 5513 vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? { 5514 trigger: vars 5515 } : vars, _defaults); 5516 5517 var _vars = vars, 5518 onUpdate = _vars.onUpdate, 5519 toggleClass = _vars.toggleClass, 5520 id = _vars.id, 5521 onToggle = _vars.onToggle, 5522 onRefresh = _vars.onRefresh, 5523 scrub = _vars.scrub, 5524 trigger = _vars.trigger, 5525 pin = _vars.pin, 5526 pinSpacing = _vars.pinSpacing, 5527 invalidateOnRefresh = _vars.invalidateOnRefresh, 5528 anticipatePin = _vars.anticipatePin, 5529 onScrubComplete = _vars.onScrubComplete, 5530 onSnapComplete = _vars.onSnapComplete, 5531 once = _vars.once, 5532 snap = _vars.snap, 5533 pinReparent = _vars.pinReparent, 5534 pinSpacer = _vars.pinSpacer, 5535 containerAnimation = _vars.containerAnimation, 5536 fastScrollEnd = _vars.fastScrollEnd, 5537 preventOverlaps = _vars.preventOverlaps, 5538 direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical, 5539 isToggle = !scrub && scrub !== 0, 5540 scroller = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.scroller || _win), 5541 scrollerCache = gsap.core.getCache(scroller), 5542 isViewport = _isViewport(scroller), 5543 useFixedPosition = ("pinType" in vars ? vars.pinType : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "pinType") || isViewport && "fixed") === "fixed", 5544 callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack], 5545 toggleActions = isToggle && vars.toggleActions.split(" "), 5546 markers = "markers" in vars ? vars.markers : _defaults.markers, 5547 borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0, 5548 self = this, 5549 onRefreshInit = vars.onRefreshInit && function () { 5550 return vars.onRefreshInit(self); 5551 }, 5552 getScrollerSize = _getSizeFunc(scroller, isViewport, direction), 5553 getScrollerOffsets = _getOffsetsFunc(scroller, isViewport), 5554 lastSnap = 0, 5555 lastRefresh = 0, 5556 prevProgress = 0, 5557 scrollFunc = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction), 5558 tweenTo, 5559 pinCache, 5560 snapFunc, 5561 scroll1, 5562 scroll2, 5563 start, 5564 end, 5565 markerStart, 5566 markerEnd, 5567 markerStartTrigger, 5568 markerEndTrigger, 5569 markerVars, 5570 executingOnRefresh, 5571 change, 5572 pinOriginalState, 5573 pinActiveState, 5574 pinState, 5575 spacer, 5576 offset, 5577 pinGetter, 5578 pinSetter, 5579 pinStart, 5580 pinChange, 5581 spacingStart, 5582 spacerState, 5583 markerStartSetter, 5584 pinMoves, 5585 markerEndSetter, 5586 cs, 5587 snap1, 5588 snap2, 5589 scrubTween, 5590 scrubSmooth, 5591 snapDurClamp, 5592 snapDelayedCall, 5593 prevScroll, 5594 prevAnimProgress, 5595 caMarkerSetter, 5596 customRevertReturn; // for the sake of efficiency, _startClamp/_endClamp serve like a truthy value indicating that clamping was enabled on the start/end, and ALSO store the actual pre-clamped numeric value. We tap into that in ScrollSmoother for speed effects. So for example, if start="clamp(top bottom)" results in a start of -100 naturally, it would get clamped to 0 but -100 would be stored in _startClamp. 5597 5598 5599 self._startClamp = self._endClamp = false; 5600 self._dir = direction; 5601 anticipatePin *= 45; 5602 self.scroller = scroller; 5603 self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc; 5604 scroll1 = scrollFunc(); 5605 self.vars = vars; 5606 animation = animation || vars.animation; 5607 5608 if ("refreshPriority" in vars) { 5609 _sort = 1; 5610 vars.refreshPriority === -9999 && (_primary = self); // used by ScrollSmoother 5611 } 5612 5613 scrollerCache.tweenScroll = scrollerCache.tweenScroll || { 5614 top: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical), 5615 left: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal) 5616 }; 5617 self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p]; 5618 5619 self.scrubDuration = function (value) { 5620 scrubSmooth = _isNumber(value) && value; 5621 5622 if (!scrubSmooth) { 5623 scrubTween && scrubTween.progress(1).kill(); 5624 scrubTween = 0; 5625 } else { 5626 scrubTween ? scrubTween.duration(value) : scrubTween = gsap.to(animation, { 5627 ease: "expo", 5628 totalProgress: "+=0", 5629 inherit: false, 5630 duration: scrubSmooth, 5631 paused: true, 5632 onComplete: function onComplete() { 5633 return onScrubComplete && onScrubComplete(self); 5634 } 5635 }); 5636 } 5637 }; 5638 5639 if (animation) { 5640 animation.vars.lazy = false; 5641 animation._initted && !self.isReverted || animation.vars.immediateRender !== false && vars.immediateRender !== false && animation.duration() && animation.render(0, true, true); // special case: if this ScrollTrigger gets re-initted, a from() tween with a stagger could get initted initially and then reverted on the re-init which means it'll need to get rendered again here to properly display things. Otherwise, See https://gsap.com/forums/topic/36777-scrollsmoother-splittext-nextjs/ and https://codepen.io/GreenSock/pen/eYPyPpd?editors=0010 5642 5643 self.animation = animation.pause(); 5644 animation.scrollTrigger = self; 5645 self.scrubDuration(scrub); 5646 snap1 = 0; 5647 id || (id = animation.vars.id); 5648 } 5649 5650 if (snap) { 5651 // TODO: potential idea: use legitimate CSS scroll snapping by pushing invisible elements into the DOM that serve as snap positions, and toggle the document.scrollingElement.style.scrollSnapType onToggle. See https://codepen.io/GreenSock/pen/JjLrgWM for a quick proof of concept. 5652 if (!_isObject(snap) || snap.push) { 5653 snap = { 5654 snapTo: snap 5655 }; 5656 } 5657 5658 "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, { 5659 scrollBehavior: "auto" 5660 }); // smooth scrolling doesn't work with snap. 5661 5662 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (o) { 5663 return _isFunction(o) && o.target === (isViewport ? _doc.scrollingElement || _docEl : scroller) && (o.smooth = false); 5664 }); // note: set smooth to false on both the vertical and horizontal scroll getters/setters 5665 5666 5667 snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) { 5668 return _snapDirectional(snap.snapTo)(value, _getTime() - lastRefresh < 500 ? 0 : st.direction); 5669 } : gsap.utils.snap(snap.snapTo); 5670 snapDurClamp = snap.duration || { 5671 min: 0.1, 5672 max: 2 5673 }; 5674 snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp); 5675 snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () { 5676 var scroll = scrollFunc(), 5677 refreshedRecently = _getTime() - lastRefresh < 500, 5678 tween = tweenTo.tween; 5679 5680 if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) { 5681 var progress = (scroll - start) / change, 5682 totalProgress = animation && !isToggle ? animation.totalProgress() : progress, 5683 velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0, 5684 change1 = gsap.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185), 5685 naturalEnd = progress + (snap.inertia === false ? 0 : change1), 5686 endValue, 5687 endScroll, 5688 _snap = snap, 5689 onStart = _snap.onStart, 5690 _onInterrupt = _snap.onInterrupt, 5691 _onComplete = _snap.onComplete; 5692 endValue = snapFunc(naturalEnd, self); 5693 _isNumber(endValue) || (endValue = naturalEnd); // in case the function didn't return a number, fall back to using the naturalEnd 5694 5695 endScroll = Math.round(start + endValue * change); 5696 5697 if (scroll <= end && scroll >= start && endScroll !== scroll) { 5698 if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) { 5699 // there's an overlapping snap! So we must figure out which one is closer and let that tween live. 5700 return; 5701 } 5702 5703 if (snap.inertia === false) { 5704 change1 = endValue - progress; 5705 } 5706 5707 tweenTo(endScroll, { 5708 duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)), 5709 ease: snap.ease || "power3", 5710 data: _abs(endScroll - scroll), 5711 // record the distance so that if another snap tween occurs (conflict) we can prioritize the closest snap. 5712 onInterrupt: function onInterrupt() { 5713 return snapDelayedCall.restart(true) && _onInterrupt && _onInterrupt(self); 5714 }, 5715 onComplete: function onComplete() { 5716 self.update(); 5717 lastSnap = scrollFunc(); 5718 5719 if (animation) { 5720 // the resolution of the scrollbar is limited, so we should correct the scrubbed animation's playhead at the end to match EXACTLY where it was supposed to snap 5721 scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue); 5722 } 5723 5724 snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress; 5725 onSnapComplete && onSnapComplete(self); 5726 _onComplete && _onComplete(self); 5727 } 5728 }, scroll, change1 * change, endScroll - scroll - change1 * change); 5729 onStart && onStart(self, tweenTo.tween); 5730 } 5731 } else if (self.isActive && lastSnap !== scroll) { 5732 snapDelayedCall.restart(true); 5733 } 5734 }).pause(); 5735 } 5736 5737 id && (_ids[id] = self); 5738 trigger = self.trigger = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(trigger || pin !== true && pin); // if a trigger has some kind of scroll-related effect applied that could contaminate the "y" or "x" position (like a ScrollSmoother effect), we needed a way to temporarily revert it, so we use the stRevert property of the gsCache. It can return another function that we'll call at the end so it can return to its normal state. 5739 5740 customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert; 5741 customRevertReturn && (customRevertReturn = customRevertReturn(self)); 5742 pin = pin === true ? trigger : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pin); 5743 _isString(toggleClass) && (toggleClass = { 5744 targets: trigger, 5745 className: toggleClass 5746 }); 5747 5748 if (pin) { 5749 pinSpacing === false || pinSpacing === _margin || (pinSpacing = !pinSpacing && pin.parentNode && pin.parentNode.style && _getComputedStyle(pin.parentNode).display === "flex" ? false : _padding); // if the parent is display: flex, don't apply pinSpacing by default. We should check that pin.parentNode is an element (not shadow dom window) 5750 5751 self.pin = pin; 5752 pinCache = gsap.core.getCache(pin); 5753 5754 if (!pinCache.spacer) { 5755 // 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. 5756 if (pinSpacer) { 5757 pinSpacer = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pinSpacer); 5758 pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); // for React & Angular 5759 5760 pinCache.spacerIsNative = !!pinSpacer; 5761 pinSpacer && (pinCache.spacerState = _getState(pinSpacer)); 5762 } 5763 5764 pinCache.spacer = spacer = pinSpacer || _doc.createElement("div"); 5765 spacer.classList.add("pin-spacer"); 5766 id && spacer.classList.add("pin-spacer-" + id); 5767 pinCache.pinState = pinOriginalState = _getState(pin); 5768 } else { 5769 pinOriginalState = pinCache.pinState; 5770 } 5771 5772 vars.force3D !== false && gsap.set(pin, { 5773 force3D: true 5774 }); 5775 self.spacer = spacer = pinCache.spacer; 5776 cs = _getComputedStyle(pin); 5777 spacingStart = cs[pinSpacing + direction.os2]; 5778 pinGetter = gsap.getProperty(pin); 5779 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). 5780 5781 _swapPinIn(pin, spacer, cs); 5782 5783 pinState = _getState(pin); 5784 } 5785 5786 if (markers) { 5787 markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults; 5788 markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0); 5789 markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger); 5790 offset = markerStartTrigger["offset" + direction.op.d2]; 5791 5792 var content = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)((0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "content") || scroller); 5793 5794 markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation); 5795 markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation); 5796 containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px)); 5797 5798 if (!useFixedPosition && !(_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.length && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "fixedMarkers") === true)) { 5799 _makePositionable(isViewport ? _body : scroller); 5800 5801 gsap.set([markerStartTrigger, markerEndTrigger], { 5802 force3D: true 5803 }); 5804 markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px); 5805 markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px); 5806 } 5807 } 5808 5809 if (containerAnimation) { 5810 var oldOnUpdate = containerAnimation.vars.onUpdate, 5811 oldParams = containerAnimation.vars.onUpdateParams; 5812 containerAnimation.eventCallback("onUpdate", function () { 5813 self.update(0, 0, 1); 5814 oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []); 5815 }); 5816 } 5817 5818 self.previous = function () { 5819 return _triggers[_triggers.indexOf(self) - 1]; 5820 }; 5821 5822 self.next = function () { 5823 return _triggers[_triggers.indexOf(self) + 1]; 5824 }; 5825 5826 self.revert = function (revert, temp) { 5827 if (!temp) { 5828 return self.kill(true); 5829 } // for compatibility with gsap.context() and gsap.matchMedia() which call revert() 5830 5831 5832 var r = revert !== false || !self.enabled, 5833 prevRefreshing = _refreshing; 5834 5835 if (r !== self.isReverted) { 5836 if (r) { 5837 prevScroll = Math.max(scrollFunc(), 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. 5838 5839 prevProgress = self.progress; 5840 prevAnimProgress = animation && animation.progress(); 5841 } 5842 5843 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 5844 return m.style.display = r ? "none" : "block"; 5845 }); 5846 5847 if (r) { 5848 _refreshing = self; 5849 self.update(r); // make sure the pin is back in its original position so that all the measurements are correct. do this BEFORE swapping the pin out 5850 } 5851 5852 if (pin && (!pinReparent || !self.isActive)) { 5853 if (r) { 5854 _swapPinOut(pin, spacer, pinOriginalState); 5855 } else { 5856 _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState); 5857 } 5858 } 5859 5860 r || self.update(r); // when we're restoring, the update should run AFTER swapping the pin into its pin-spacer. 5861 5862 _refreshing = prevRefreshing; // restore. We set it to true during the update() so that things fire properly in there. 5863 5864 self.isReverted = r; 5865 } 5866 }; 5867 5868 self.refresh = function (soft, force, position, pinOffset) { 5869 // position is typically only defined if it's coming from setPositions() - it's a way to skip the normal parsing. pinOffset is also only from setPositions() and is mostly related to fancy stuff we need to do in ScrollSmoother with effects 5870 if ((_refreshing || !self.enabled) && !force) { 5871 return; 5872 } 5873 5874 if (pin && soft && _lastScrollTime) { 5875 _addListener(ScrollTrigger, "scrollEnd", _softRefresh); 5876 5877 return; 5878 } 5879 5880 !_refreshingAll && onRefreshInit && onRefreshInit(self); 5881 _refreshing = self; 5882 5883 if (tweenTo.tween && !position) { 5884 // we skip this if a position is passed in because typically that's from .setPositions() and it's best to allow in-progress snapping to continue. 5885 tweenTo.tween.kill(); 5886 tweenTo.tween = 0; 5887 } 5888 5889 scrubTween && scrubTween.pause(); 5890 invalidateOnRefresh && animation && animation.revert({ 5891 kill: false 5892 }).invalidate(); 5893 self.isReverted || self.revert(true, true); 5894 self._subPinOffset = false; // we'll set this to true in the sub-pins if we find any 5895 5896 var size = getScrollerSize(), 5897 scrollerBounds = getScrollerOffsets(), 5898 max = containerAnimation ? containerAnimation.duration() : _maxScroll(scroller, direction), 5899 isFirstRefresh = change <= 0.01, 5900 offset = 0, 5901 otherPinOffset = pinOffset || 0, 5902 parsedEnd = _isObject(position) ? position.end : vars.end, 5903 parsedEndTrigger = vars.endTrigger || trigger, 5904 parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"), 5905 pinnedContainer = self.pinnedContainer = vars.pinnedContainer && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.pinnedContainer, self), 5906 triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0, 5907 i = triggerIndex, 5908 cs, 5909 bounds, 5910 scroll, 5911 isVertical, 5912 override, 5913 curTrigger, 5914 curPin, 5915 oppositeScroll, 5916 initted, 5917 revertedPins, 5918 forcedOverflow, 5919 markerStartOffset, 5920 markerEndOffset; 5921 5922 if (markers && _isObject(position)) { 5923 // if we alter the start/end positions with .setPositions(), it generally feeds in absolute NUMBERS which don't convey information about where to line up the markers, so to keep it intuitive, we record how far the trigger positions shift after applying the new numbers and then offset by that much in the opposite direction. We do the same to the associated trigger markers too of course. 5924 markerStartOffset = gsap.getProperty(markerStartTrigger, direction.p); 5925 markerEndOffset = gsap.getProperty(markerEndTrigger, direction.p); 5926 } 5927 5928 while (i--) { 5929 // 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. 5930 curTrigger = _triggers[i]; 5931 curTrigger.end || curTrigger.refresh(0, 1) || (_refreshing = self); // if it's a timeline-based trigger that hasn't been fully initialized yet because it's waiting for 1 tick, just force the refresh() here, otherwise if it contains a pin that's supposed to affect other ScrollTriggers further down the page, they won't be adjusted properly. 5932 5933 curPin = curTrigger.pin; 5934 5935 if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) { 5936 revertedPins || (revertedPins = []); 5937 revertedPins.unshift(curTrigger); // we'll revert from first to last to make sure things reach their end state properly 5938 5939 curTrigger.revert(true, true); 5940 } 5941 5942 if (curTrigger !== _triggers[i]) { 5943 // in case it got removed. 5944 triggerIndex--; 5945 i--; 5946 } 5947 } 5948 5949 _isFunction(parsedStart) && (parsedStart = parsedStart(self)); 5950 parsedStart = _parseClamp(parsedStart, "start", self); 5951 start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0); 5952 _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self)); 5953 5954 if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) { 5955 if (~parsedEnd.indexOf(" ")) { 5956 parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd; 5957 } else { 5958 offset = _offsetToPx(parsedEnd.substr(2), size); 5959 parsedEnd = _isString(parsedStart) ? parsedStart : (containerAnimation ? gsap.utils.mapRange(0, containerAnimation.duration(), containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, start) : start) + offset; // _parsePosition won't factor in the offset if the start is a number, so do it here. 5960 5961 parsedEndTrigger = trigger; 5962 } 5963 } 5964 5965 parsedEnd = _parseClamp(parsedEnd, "end", self); 5966 end = Math.max(start, _parsePosition(parsedEnd || (parsedEndTrigger ? "100% 0" : max), parsedEndTrigger, size, direction, scrollFunc() + offset, markerEnd, markerEndTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._endClamp && "_endClamp")) || -0.001; 5967 offset = 0; 5968 i = triggerIndex; 5969 5970 while (i--) { 5971 curTrigger = _triggers[i]; 5972 curPin = curTrigger.pin; 5973 5974 if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) { 5975 cs = curTrigger.end - (self._startClamp ? Math.max(0, curTrigger.start) : curTrigger.start); 5976 5977 if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) { 5978 // numeric start values shouldn't be offset at all - treat them as absolute 5979 offset += cs * (1 - curTrigger.progress); 5980 } 5981 5982 curPin === pin && (otherPinOffset += cs); 5983 } 5984 } 5985 5986 start += offset; 5987 end += offset; 5988 self._startClamp && (self._startClamp += offset); 5989 5990 if (self._endClamp && !_refreshingAll) { 5991 self._endClamp = end || -0.001; 5992 end = Math.min(end, _maxScroll(scroller, direction)); 5993 } 5994 5995 change = end - start || (start -= 0.01) && 0.001; 5996 5997 if (isFirstRefresh) { 5998 // on the very first refresh(), the prevProgress couldn't have been accurate yet because the start/end were never calculated, so we set it here. Before 3.11.5, it could lead to an inaccurate scroll position restoration with snapping. 5999 prevProgress = gsap.utils.clamp(0, 1, gsap.utils.normalize(start, end, prevScroll)); 6000 } 6001 6002 self._pinPush = otherPinOffset; 6003 6004 if (markerStart && offset) { 6005 // offset the markers if necessary 6006 cs = {}; 6007 cs[direction.a] = "+=" + offset; 6008 pinnedContainer && (cs[direction.p] = "-=" + scrollFunc()); 6009 gsap.set([markerStart, markerEnd], cs); 6010 } 6011 6012 if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) { 6013 cs = _getComputedStyle(pin); 6014 isVertical = direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical; 6015 scroll = scrollFunc(); // recalculate because the triggers can affect the scroll 6016 6017 pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset; 6018 6019 if (!max && end > 1) { 6020 // 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://gsap.com/forums/topic/25182-scrolltrigger-width-of-page-increase-where-markers-are-set-to-false/ 6021 forcedOverflow = (isViewport ? _doc.scrollingElement || _docEl : scroller).style; 6022 forcedOverflow = { 6023 style: forcedOverflow, 6024 value: forcedOverflow["overflow" + direction.a.toUpperCase()] 6025 }; 6026 6027 if (isViewport && _getComputedStyle(_body)["overflow" + direction.a.toUpperCase()] !== "scroll") { 6028 // avoid an extra scrollbar if BOTH <html> and <body> have overflow set to "scroll" 6029 forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll"; 6030 } 6031 } 6032 6033 _swapPinIn(pin, spacer, cs); 6034 6035 pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms. 6036 6037 bounds = _getBounds(pin, true); 6038 oppositeScroll = useFixedPosition && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, isVertical ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical)(); 6039 6040 if (pinSpacing) { 6041 spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px]; 6042 spacerState.t = spacer; 6043 i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0; 6044 6045 if (i) { 6046 spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding). 6047 6048 spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px); 6049 } 6050 6051 _setState(spacerState); 6052 6053 if (pinnedContainer) { 6054 // in ScrollTrigger.refresh(), we need to re-evaluate the pinContainer's size because this pinSpacing may stretch it out, but we can't just add the exact distance because depending on layout, it may not push things down or it may only do so partially. 6055 _triggers.forEach(function (t) { 6056 if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) { 6057 t._subPinOffset = true; 6058 } 6059 }); 6060 } 6061 6062 useFixedPosition && scrollFunc(prevScroll); 6063 } else { 6064 i = _getSize(pin, direction); 6065 i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px); 6066 } 6067 6068 if (useFixedPosition) { 6069 override = { 6070 top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px, 6071 left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px, 6072 boxSizing: "border-box", 6073 position: "fixed" 6074 }; 6075 override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px; 6076 override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px; 6077 override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0"; 6078 override[_padding] = cs[_padding]; 6079 override[_padding + _Top] = cs[_padding + _Top]; 6080 override[_padding + _Right] = cs[_padding + _Right]; 6081 override[_padding + _Bottom] = cs[_padding + _Bottom]; 6082 override[_padding + _Left] = cs[_padding + _Left]; 6083 pinActiveState = _copyState(pinOriginalState, override, pinReparent); 6084 _refreshingAll && scrollFunc(0); 6085 } 6086 6087 if (animation) { 6088 // 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. 6089 initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock in starting values prematurely. 6090 6091 _suppressOverwrites(1); 6092 6093 animation.render(animation.duration(), true, true); 6094 pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset; 6095 pinMoves = Math.abs(change - pinChange) > 1; 6096 useFixedPosition && pinMoves && 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. 6097 6098 animation.render(0, true, true); 6099 initted || animation.invalidate(true); 6100 animation.parent || animation.totalTime(animation.totalTime()); // if, for example, a toggleAction called play() and then refresh() happens and when we render(1) above, it would cause the animation to complete and get removed from its parent, so this makes sure it gets put back in. 6101 6102 _suppressOverwrites(0); 6103 } else { 6104 pinChange = change; 6105 } 6106 6107 forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a)); 6108 } else if (trigger && scrollFunc() && !containerAnimation) { 6109 // 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() 6110 bounds = trigger.parentNode; 6111 6112 while (bounds && bounds !== _body) { 6113 if (bounds._pinOffset) { 6114 start -= bounds._pinOffset; 6115 end -= bounds._pinOffset; 6116 } 6117 6118 bounds = bounds.parentNode; 6119 } 6120 } 6121 6122 revertedPins && revertedPins.forEach(function (t) { 6123 return t.revert(false, true); 6124 }); 6125 self.start = start; 6126 self.end = end; 6127 scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc(); // reset velocity 6128 6129 if (!containerAnimation && !_refreshingAll) { 6130 scroll1 < prevScroll && scrollFunc(prevScroll); 6131 self.scroll.rec = 0; 6132 } 6133 6134 self.revert(false, true); 6135 lastRefresh = _getTime(); 6136 6137 if (snapDelayedCall) { 6138 lastSnap = -1; // just so snapping gets re-enabled, clear out any recorded last value 6139 // self.isActive && scrollFunc(start + change * prevProgress); // previously this line was here to ensure that when snapping kicks in, it's from the previous progress but in some cases that's not desirable, like an all-page ScrollTrigger when new content gets added to the page, that'd totally change the progress. 6140 6141 snapDelayedCall.restart(true); 6142 } 6143 6144 _refreshing = 0; 6145 animation && isToggle && (animation._initted || prevAnimProgress) && animation.progress() !== prevAnimProgress && animation.progress(prevAnimProgress || 0, 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(). 6146 6147 if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh) { 6148 // 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. 6149 animation && !isToggle && animation.totalProgress(containerAnimation && start < -0.001 && !prevProgress ? gsap.utils.normalize(start, end, 0) : prevProgress, true); // to avoid issues where animation callbacks like onStart aren't triggered. 6150 6151 self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress; 6152 } 6153 6154 pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange)); 6155 scrubTween && scrubTween.invalidate(); 6156 6157 if (!isNaN(markerStartOffset)) { 6158 // numbers were passed in for the position which are absolute, so instead of just putting the markers at the very bottom of the viewport, we figure out how far they shifted down (it's safe to assume they were originally positioned in closer relation to the trigger element with values like "top", "center", a percentage or whatever, so we offset that much in the opposite direction to basically revert them to the relative position thy were at previously. 6159 markerStartOffset -= gsap.getProperty(markerStartTrigger, direction.p); 6160 markerEndOffset -= gsap.getProperty(markerEndTrigger, direction.p); 6161 6162 _shiftMarker(markerStartTrigger, direction, markerStartOffset); 6163 6164 _shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0)); 6165 6166 _shiftMarker(markerEndTrigger, direction, markerEndOffset); 6167 6168 _shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0)); 6169 } 6170 6171 isFirstRefresh && !_refreshingAll && self.update(); // edge case - when you reload a page when it's already scrolled down, some browsers fire a "scroll" event before DOMContentLoaded, triggering an updateAll(). If we don't update the self.progress as part of refresh(), then when it happens next, it may record prevProgress as 0 when it really shouldn't, potentially causing a callback in an animation to fire again. 6172 6173 if (onRefresh && !_refreshingAll && !executingOnRefresh) { 6174 // when refreshing all, we do extra work to correct pinnedContainer sizes and ensure things don't exceed the maxScroll, so we should do all the refreshes at the end after all that work so that the start/end values are corrected. 6175 executingOnRefresh = true; 6176 onRefresh(self); 6177 executingOnRefresh = false; 6178 } 6179 }; 6180 6181 self.getVelocity = function () { 6182 return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0; 6183 }; 6184 6185 self.endAnimation = function () { 6186 _endAnimation(self.callbackAnimation); 6187 6188 if (animation) { 6189 scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1); 6190 } 6191 }; 6192 6193 self.labelToScroll = function (label) { 6194 return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0; 6195 }; 6196 6197 self.getTrailing = function (name) { 6198 var i = _triggers.indexOf(self), 6199 a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1); 6200 6201 return (_isString(name) ? a.filter(function (t) { 6202 return t.vars.preventOverlaps === name; 6203 }) : a).filter(function (t) { 6204 return self.direction > 0 ? t.end <= start : t.start >= end; 6205 }); 6206 }; 6207 6208 self.update = function (reset, recordVelocity, forceFake) { 6209 if (containerAnimation && !forceFake && !reset) { 6210 return; 6211 } 6212 6213 var scroll = _refreshingAll === true ? prevScroll : self.scroll(), 6214 p = reset ? 0 : (scroll - start) / change, 6215 clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0, 6216 prevProgress = self.progress, 6217 isActive, 6218 wasActive, 6219 toggleState, 6220 action, 6221 stateChanged, 6222 toggled, 6223 isAtMax, 6224 isTakingAction; 6225 6226 if (recordVelocity) { 6227 scroll2 = scroll1; 6228 scroll1 = containerAnimation ? scrollFunc() : scroll; 6229 6230 if (snap) { 6231 snap2 = snap1; 6232 snap1 = animation && !isToggle ? animation.totalProgress() : clipped; 6233 } 6234 } // 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). 6235 6236 6237 if (anticipatePin && pin && !_refreshing && !_startup && _lastScrollTime) { 6238 if (!clipped && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin) { 6239 clipped = 0.0001; 6240 } else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin) { 6241 clipped = 0.9999; 6242 } 6243 } 6244 6245 if (clipped !== prevProgress && self.enabled) { 6246 isActive = self.isActive = !!clipped && clipped < 1; 6247 wasActive = !!prevProgress && prevProgress < 1; 6248 toggled = isActive !== wasActive; 6249 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) 6250 6251 self.direction = clipped > prevProgress ? 1 : -1; 6252 self.progress = clipped; 6253 6254 if (stateChanged && !_refreshing) { 6255 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. 6256 6257 if (isToggle) { 6258 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) 6259 6260 isTakingAction = animation && (action === "complete" || action === "reset" || action in animation); 6261 } 6262 } 6263 6264 preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEach(function (t) { 6265 return t.endAnimation(); 6266 })); 6267 6268 if (!isToggle) { 6269 if (scrubTween && !_refreshing && !_startup) { 6270 scrubTween._dp._time - scrubTween._start !== scrubTween._time && scrubTween.render(scrubTween._dp._time - scrubTween._start); // if there's a scrub on both the container animation and this one (or a ScrollSmoother), the update order would cause this one not to have rendered yet, so it wouldn't make any progress before we .restart() it heading toward the new progress so it'd appear stuck thus we force a render here. 6271 6272 if (scrubTween.resetTo) { 6273 scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur); 6274 } else { 6275 // legacy support (courtesy), before 3.10.0 6276 scrubTween.vars.totalProgress = clipped; 6277 scrubTween.invalidate().restart(); 6278 } 6279 } else if (animation) { 6280 animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset))); 6281 } 6282 } 6283 6284 if (pin) { 6285 reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart); 6286 6287 if (!useFixedPosition) { 6288 pinSetter(_round(pinStart + pinChange * clipped)); 6289 } else if (stateChanged) { 6290 isAtMax = !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) 6291 6292 if (pinReparent) { 6293 if (!reset && (isActive || isAtMax)) { 6294 var bounds = _getBounds(pin, true), 6295 _offset = scroll - start; 6296 6297 _reparent(pin, _body, bounds.top + (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? _offset : 0) + _px, bounds.left + (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? 0 : _offset) + _px); 6298 } else { 6299 _reparent(pin, spacer); 6300 } 6301 } 6302 6303 _setState(isActive || isAtMax ? pinActiveState : pinState); 6304 6305 pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0)); 6306 } 6307 } 6308 6309 snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true); 6310 toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) { 6311 return el.classList[isActive || once ? "add" : "remove"](toggleClass.className); 6312 }); // classes could affect positioning, so do it even if reset or refreshing is true. 6313 6314 onUpdate && !isToggle && !reset && onUpdate(self); 6315 6316 if (stateChanged && !_refreshing) { 6317 if (isToggle) { 6318 if (isTakingAction) { 6319 if (action === "complete") { 6320 animation.pause().totalProgress(1); 6321 } else if (action === "reset") { 6322 animation.restart(true).pause(); 6323 } else if (action === "restart") { 6324 animation.restart(true); 6325 } else { 6326 animation[action](); 6327 } 6328 } 6329 6330 onUpdate && onUpdate(self); 6331 } 6332 6333 if (toggled || !_limitCallbacks) { 6334 // 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. 6335 onToggle && toggled && _callback(self, onToggle); 6336 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 6337 once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn't be called again if once is true. 6338 6339 if (!toggled) { 6340 // 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 6341 toggleState = clipped === 1 ? 1 : 3; 6342 callbacks[toggleState] && _callback(self, callbacks[toggleState]); 6343 } 6344 } 6345 6346 if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) { 6347 _endAnimation(self.callbackAnimation); 6348 6349 scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1); 6350 } 6351 } else if (isToggle && onUpdate && !_refreshing) { 6352 onUpdate(self); 6353 } 6354 } // update absolutely-positioned markers (only if the scroller isn't the viewport) 6355 6356 6357 if (markerEndSetter) { 6358 var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll; 6359 markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0)); 6360 markerEndSetter(n); 6361 } 6362 6363 caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0)); 6364 }; 6365 6366 self.enable = function (reset, refresh) { 6367 if (!self.enabled) { 6368 self.enabled = true; 6369 6370 _addListener(scroller, "resize", _onResize); 6371 6372 isViewport || _addListener(scroller, "scroll", _onScroll); 6373 onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit); 6374 6375 if (reset !== false) { 6376 self.progress = prevProgress = 0; 6377 scroll1 = scroll2 = lastSnap = scrollFunc(); 6378 } 6379 6380 refresh !== false && self.refresh(); 6381 } 6382 }; 6383 6384 self.getTween = function (snap) { 6385 return snap && tweenTo ? tweenTo.tween : scrubTween; 6386 }; 6387 6388 self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) { 6389 // doesn't persist after refresh()! Intended to be a way to override values that were set during refresh(), like you could set it in onRefresh() 6390 if (containerAnimation) { 6391 // convert ratios into scroll positions. Remember, start/end values on ScrollTriggers that have a containerAnimation refer to the time (in seconds), NOT scroll positions. 6392 var st = containerAnimation.scrollTrigger, 6393 duration = containerAnimation.duration(), 6394 _change = st.end - st.start; 6395 6396 newStart = st.start + _change * newStart / duration; 6397 newEnd = st.start + _change * newEnd / duration; 6398 } 6399 6400 self.refresh(false, false, { 6401 start: _keepClamp(newStart, keepClamp && !!self._startClamp), 6402 end: _keepClamp(newEnd, keepClamp && !!self._endClamp) 6403 }, pinOffset); 6404 self.update(); 6405 }; 6406 6407 self.adjustPinSpacing = function (amount) { 6408 if (spacerState && amount) { 6409 var i = spacerState.indexOf(direction.d) + 1; 6410 spacerState[i] = parseFloat(spacerState[i]) + amount + _px; 6411 spacerState[1] = parseFloat(spacerState[1]) + amount + _px; 6412 6413 _setState(spacerState); 6414 } 6415 }; 6416 6417 self.disable = function (reset, allowAnimation) { 6418 if (self.enabled) { 6419 reset !== false && self.revert(true, true); 6420 self.enabled = self.isActive = false; 6421 allowAnimation || scrubTween && scrubTween.pause(); 6422 prevScroll = 0; 6423 pinCache && (pinCache.uncache = 1); 6424 onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit); 6425 6426 if (snapDelayedCall) { 6427 snapDelayedCall.pause(); 6428 tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0); 6429 } 6430 6431 if (!isViewport) { 6432 var i = _triggers.length; 6433 6434 while (i--) { 6435 if (_triggers[i].scroller === scroller && _triggers[i] !== self) { 6436 return; //don't remove the listeners if there are still other triggers referencing it. 6437 } 6438 } 6439 6440 _removeListener(scroller, "resize", _onResize); 6441 6442 isViewport || _removeListener(scroller, "scroll", _onScroll); 6443 } 6444 } 6445 }; 6446 6447 self.kill = function (revert, allowAnimation) { 6448 self.disable(revert, allowAnimation); 6449 scrubTween && !allowAnimation && scrubTween.kill(); 6450 id && delete _ids[id]; 6451 6452 var i = _triggers.indexOf(self); 6453 6454 i >= 0 && _triggers.splice(i, 1); 6455 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... 6456 // if no other ScrollTrigger instances of the same scroller are found, wipe out any recorded scroll position. Otherwise, in a single page application, for example, it could maintain scroll position when it really shouldn't. 6457 6458 i = 0; 6459 6460 _triggers.forEach(function (t) { 6461 return t.scroller === self.scroller && (i = 1); 6462 }); 6463 6464 i || _refreshingAll || (self.scroll.rec = 0); 6465 6466 if (animation) { 6467 animation.scrollTrigger = null; 6468 revert && animation.revert({ 6469 kill: false 6470 }); 6471 allowAnimation || animation.kill(); 6472 } 6473 6474 markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) { 6475 return m.parentNode && m.parentNode.removeChild(m); 6476 }); 6477 _primary === self && (_primary = 0); 6478 6479 if (pin) { 6480 pinCache && (pinCache.uncache = 1); 6481 i = 0; 6482 6483 _triggers.forEach(function (t) { 6484 return t.pin === pin && i++; 6485 }); 6486 6487 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. 6488 } 6489 6490 vars.onKill && vars.onKill(self); 6491 }; 6492 6493 _triggers.push(self); 6494 6495 self.enable(false, false); 6496 customRevertReturn && customRevertReturn(self); 6497 6498 if (animation && animation.add && !change) { 6499 // 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. If "change" is defined, we know it must be re-enabling, thus we can refresh() right away. 6500 var updateFunc = self.update; // some browsers may fire a scroll event BEFORE a tick elapses and/or the DOMContentLoaded fires. So there's a chance update() will be called BEFORE a refresh() has happened on a Timeline-attached ScrollTrigger which means the start/end won't be calculated yet. We don't want to add conditional logic inside the update() method (like check to see if end is defined and if not, force a refresh()) because that's a function that gets hit a LOT (performance). So we swap out the real update() method for this one that'll re-attach it the first time it gets called and of course forces a refresh(). 6501 6502 self.update = function () { 6503 self.update = updateFunc; 6504 start || end || self.refresh(); 6505 }; 6506 6507 gsap.delayedCall(0.01, self.update); 6508 change = 0.01; 6509 start = end = 0; 6510 } else { 6511 self.refresh(); 6512 } 6513 6514 pin && _queueRefreshAll(); // pinning could affect the positions of other things, so make sure we queue a full refresh() 6515 }; 6516 6517 ScrollTrigger.register = function register(core) { 6518 if (!_coreInitted) { 6519 gsap = core || _getGSAP(); 6520 _windowExists() && window.document && ScrollTrigger.enable(); 6521 _coreInitted = _enabled; 6522 } 6523 6524 return _coreInitted; 6525 }; 6526 6527 ScrollTrigger.defaults = function defaults(config) { 6528 if (config) { 6529 for (var p in config) { 6530 _defaults[p] = config[p]; 6531 } 6532 } 6533 6534 return _defaults; 6535 }; 6536 6537 ScrollTrigger.disable = function disable(reset, kill) { 6538 _enabled = 0; 6539 6540 _triggers.forEach(function (trigger) { 6541 return trigger[kill ? "kill" : "disable"](reset); 6542 }); 6543 6544 _removeListener(_win, "wheel", _onScroll); 6545 6546 _removeListener(_doc, "scroll", _onScroll); 6547 6548 clearInterval(_syncInterval); 6549 6550 _removeListener(_doc, "touchcancel", _passThrough); 6551 6552 _removeListener(_body, "touchstart", _passThrough); 6553 6554 _multiListener(_removeListener, _doc, "pointerdown,touchstart,mousedown", _pointerDownHandler); 6555 6556 _multiListener(_removeListener, _doc, "pointerup,touchend,mouseup", _pointerUpHandler); 6557 6558 _resizeDelay.kill(); 6559 6560 _iterateAutoRefresh(_removeListener); 6561 6562 for (var i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) { 6563 _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]); 6564 6565 _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]); 6566 } 6567 }; 6568 6569 ScrollTrigger.enable = function enable() { 6570 _win = window; 6571 _doc = document; 6572 _docEl = _doc.documentElement; 6573 _body = _doc.body; 6574 6575 if (gsap) { 6576 _toArray = gsap.utils.toArray; 6577 _clamp = gsap.utils.clamp; 6578 _context = gsap.core.context || _passThrough; 6579 _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough; 6580 _scrollRestoration = _win.history.scrollRestoration || "auto"; 6581 _lastScroll = _win.pageYOffset; 6582 gsap.core.globals("ScrollTrigger", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don't have a "name" property. 6583 6584 if (_body) { 6585 _enabled = 1; 6586 _div100vh = document.createElement("div"); // to solve mobile browser address bar show/hide resizing, we shouldn't rely on window.innerHeight. Instead, use a <div> with its height set to 100vh and measure that since that's what the scrolling is based on anyway and it's not affected by address bar showing/hiding. 6587 6588 _div100vh.style.height = "100vh"; 6589 _div100vh.style.position = "absolute"; 6590 6591 _refresh100vh(); 6592 6593 _rafBugFix(); 6594 6595 _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.register(gsap); // isTouch is 0 if no touch, 1 if ONLY touch, and 2 if it can accommodate touch but also other types like mouse/pointer. 6596 6597 ScrollTrigger.isTouch = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch; 6598 _fixIOSBug = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch && /(iPad|iPhone|iPod|Mac)/g.test(navigator.userAgent); // since 2017, iOS has had a bug that causes event.clientX/Y to be inaccurate when a scroll occurs, thus we must alternate ignoring every other touchmove event to work around it. See https://bugs.webkit.org/show_bug.cgi?id=181954 and https://codepen.io/GreenSock/pen/ExbrPNa/087cef197dc35445a0951e8935c41503 6599 6600 _ignoreMobileResize = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch === 1; 6601 6602 _addListener(_win, "wheel", _onScroll); // mostly for 3rd party smooth scrolling libraries. 6603 6604 6605 _root = [_win, _doc, _docEl, _body]; 6606 6607 if (gsap.matchMedia) { 6608 ScrollTrigger.matchMedia = function (vars) { 6609 var mm = gsap.matchMedia(), 6610 p; 6611 6612 for (p in vars) { 6613 mm.add(p, vars[p]); 6614 } 6615 6616 return mm; 6617 }; 6618 6619 gsap.addEventListener("matchMediaInit", function () { 6620 return _revertAll(); 6621 }); 6622 gsap.addEventListener("matchMediaRevert", function () { 6623 return _revertRecorded(); 6624 }); 6625 gsap.addEventListener("matchMedia", function () { 6626 _refreshAll(0, 1); 6627 6628 _dispatch("matchMedia"); 6629 }); 6630 gsap.matchMedia("(orientation: portrait)", function () { 6631 // when orientation changes, we should take new base measurements for the ignoreMobileResize feature. 6632 _setBaseDimensions(); 6633 6634 return _setBaseDimensions; 6635 }); 6636 } else { 6637 console.warn("Requires GSAP 3.11.0 or later"); 6638 } 6639 6640 _setBaseDimensions(); 6641 6642 _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! 6643 6644 6645 var bodyStyle = _body.style, 6646 border = bodyStyle.borderTopStyle, 6647 AnimationProto = gsap.core.Animation.prototype, 6648 bounds, 6649 i; 6650 AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", { 6651 value: function value() { 6652 return this.time(-0.01, true); 6653 } 6654 }); // only for backwards compatibility (Animation.revert() was added after 3.10.4) 6655 6656 bodyStyle.borderTopStyle = "solid"; // 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. 6657 6658 bounds = _getBounds(_body); 6659 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical.m = Math.round(bounds.top + _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical.sc()) || 0; // accommodate the offset of the <body> caused by margins and/or padding 6660 6661 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.m = Math.round(bounds.left + _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.sc()) || 0; 6662 border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style"); // TODO: (?) maybe move to leveraging the velocity mechanism in Observer and skip intervals. 6663 6664 _syncInterval = setInterval(_sync, 250); 6665 gsap.delayedCall(0.5, function () { 6666 return _startup = 0; 6667 }); 6668 6669 _addListener(_doc, "touchcancel", _passThrough); // some older Android devices intermittently stop dispatching "touchmove" events if we don't listen for "touchcancel" on the document. 6670 6671 6672 _addListener(_body, "touchstart", _passThrough); //works around Safari bug: https://gsap.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/ 6673 6674 6675 _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", _pointerDownHandler); 6676 6677 _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", _pointerUpHandler); 6678 6679 _transformProp = gsap.utils.checkPrefix("transform"); 6680 6681 _stateProps.push(_transformProp); 6682 6683 _coreInitted = _getTime(); 6684 _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause(); 6685 _autoRefresh = [_doc, "visibilitychange", function () { 6686 var w = _win.innerWidth, 6687 h = _win.innerHeight; 6688 6689 if (_doc.hidden) { 6690 _prevWidth = w; 6691 _prevHeight = h; 6692 } else if (_prevWidth !== w || _prevHeight !== h) { 6693 _onResize(); 6694 } 6695 }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", _refreshAll, _win, "resize", _onResize]; 6696 6697 _iterateAutoRefresh(_addListener); 6698 6699 _triggers.forEach(function (trigger) { 6700 return trigger.enable(0, 1); 6701 }); 6702 6703 for (i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) { 6704 _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]); 6705 6706 _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]); 6707 } 6708 } 6709 } 6710 }; 6711 6712 ScrollTrigger.config = function config(vars) { 6713 "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks); 6714 var ms = vars.syncInterval; 6715 ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms); 6716 "ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize); 6717 6718 if ("autoRefreshEvents" in vars) { 6719 _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none"); 6720 _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1; 6721 } 6722 }; 6723 6724 ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) { 6725 var t = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(target), 6726 i = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.indexOf(t), 6727 isViewport = _isViewport(t); 6728 6729 if (~i) { 6730 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.splice(i, isViewport ? 6 : 2); 6731 } 6732 6733 if (vars) { 6734 isViewport ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.unshift(_win, vars, _body, vars, _docEl, vars) : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.unshift(t, vars); 6735 } 6736 }; 6737 6738 ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) { 6739 _triggers.forEach(function (t) { 6740 return t._ctx && t._ctx.query === query && t._ctx.kill(true, true); 6741 }); 6742 }; 6743 6744 ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) { 6745 var bounds = (_isString(element) ? (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element) : element).getBoundingClientRect(), 6746 offset = bounds[horizontal ? _width : _height] * ratio || 0; 6747 return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight; 6748 }; 6749 6750 ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) { 6751 _isString(element) && (element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element)); 6752 var bounds = element.getBoundingClientRect(), 6753 size = bounds[horizontal ? _width : _height], 6754 offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0; 6755 return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight; 6756 }; 6757 6758 ScrollTrigger.killAll = function killAll(allowListeners) { 6759 _triggers.slice(0).forEach(function (t) { 6760 return t.vars.id !== "ScrollSmoother" && t.kill(); 6761 }); 6762 6763 if (allowListeners !== true) { 6764 var listeners = _listeners.killAll || []; 6765 _listeners = {}; 6766 listeners.forEach(function (f) { 6767 return f(); 6768 }); 6769 } 6770 }; 6771 6772 return ScrollTrigger; 6773}(); 6774ScrollTrigger.version = "3.12.5"; 6775 6776ScrollTrigger.saveStyles = function (targets) { 6777 return targets ? _toArray(targets).forEach(function (target) { 6778 // saved styles are recorded in a consecutive alternating Array, like [element, cssText, transform attribute, cache, matchMedia, ...] 6779 if (target && target.style) { 6780 var i = _savedStyles.indexOf(target); 6781 6782 i >= 0 && _savedStyles.splice(i, 5); 6783 6784 _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _context()); 6785 } 6786 }) : _savedStyles; 6787}; 6788 6789ScrollTrigger.revert = function (soft, media) { 6790 return _revertAll(!soft, media); 6791}; 6792 6793ScrollTrigger.create = function (vars, animation) { 6794 return new ScrollTrigger(vars, animation); 6795}; 6796 6797ScrollTrigger.refresh = function (safe) { 6798 return safe ? _onResize() : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true); 6799}; 6800 6801ScrollTrigger.update = function (force) { 6802 return ++_Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache && _updateAll(force === true ? 2 : 0); 6803}; 6804 6805ScrollTrigger.clearScrollMemory = _clearScrollMemory; 6806 6807ScrollTrigger.maxScroll = function (element, horizontal) { 6808 return _maxScroll(element, horizontal ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical); 6809}; 6810 6811ScrollTrigger.getScrollFunc = function (element, horizontal) { 6812 return (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)((0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element), horizontal ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical); 6813}; 6814 6815ScrollTrigger.getById = function (id) { 6816 return _ids[id]; 6817}; 6818 6819ScrollTrigger.getAll = function () { 6820 return _triggers.filter(function (t) { 6821 return t.vars.id !== "ScrollSmoother"; 6822 }); 6823}; // it's common for people to ScrollTrigger.getAll(t => t.kill()) on page routes, for example, and we don't want it to ruin smooth scrolling by killing the main ScrollSmoother one. 6824 6825 6826ScrollTrigger.isScrolling = function () { 6827 return !!_lastScrollTime; 6828}; 6829 6830ScrollTrigger.snapDirectional = _snapDirectional; 6831 6832ScrollTrigger.addEventListener = function (type, callback) { 6833 var a = _listeners[type] || (_listeners[type] = []); 6834 ~a.indexOf(callback) || a.push(callback); 6835}; 6836 6837ScrollTrigger.removeEventListener = function (type, callback) { 6838 var a = _listeners[type], 6839 i = a && a.indexOf(callback); 6840 i >= 0 && a.splice(i, 1); 6841}; 6842 6843ScrollTrigger.batch = function (targets, vars) { 6844 var result = [], 6845 varsCopy = {}, 6846 interval = vars.interval || 0.016, 6847 batchMax = vars.batchMax || 1e9, 6848 proxyCallback = function proxyCallback(type, callback) { 6849 var elements = [], 6850 triggers = [], 6851 delay = gsap.delayedCall(interval, function () { 6852 callback(elements, triggers); 6853 elements = []; 6854 triggers = []; 6855 }).pause(); 6856 return function (self) { 6857 elements.length || delay.restart(true); 6858 elements.push(self.trigger); 6859 triggers.push(self); 6860 batchMax <= elements.length && delay.progress(1); 6861 }; 6862 }, 6863 p; 6864 6865 for (p in vars) { 6866 varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p]; 6867 } 6868 6869 if (_isFunction(batchMax)) { 6870 batchMax = batchMax(); 6871 6872 _addListener(ScrollTrigger, "refresh", function () { 6873 return batchMax = vars.batchMax(); 6874 }); 6875 } 6876 6877 _toArray(targets).forEach(function (target) { 6878 var config = {}; 6879 6880 for (p in varsCopy) { 6881 config[p] = varsCopy[p]; 6882 } 6883 6884 config.trigger = target; 6885 result.push(ScrollTrigger.create(config)); 6886 }); 6887 6888 return result; 6889}; // to reduce file size. clamps the scroll and also returns a duration multiplier so that if the scroll gets chopped shorter, the duration gets curtailed as well (otherwise if you're very close to the top of the page, for example, and swipe up really fast, it'll suddenly slow down and take a long time to reach the top). 6890 6891 6892var _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) { 6893 current > max ? scrollFunc(max) : current < 0 && scrollFunc(0); 6894 return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1; 6895}, 6896 _allowNativePanning = function _allowNativePanning(target, direction) { 6897 if (direction === true) { 6898 target.style.removeProperty("touch-action"); 6899 } else { 6900 target.style.touchAction = direction === true ? "auto" : direction ? "pan-" + direction + (_Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch ? " pinch-zoom" : "") : "none"; // note: Firefox doesn't support it pinch-zoom properly, at least in addition to a pan-x or pan-y. 6901 } 6902 6903 target === _docEl && _allowNativePanning(_body, direction); 6904}, 6905 _overflow = { 6906 auto: 1, 6907 scroll: 1 6908}, 6909 _nestedScroll = function _nestedScroll(_ref5) { 6910 var event = _ref5.event, 6911 target = _ref5.target, 6912 axis = _ref5.axis; 6913 6914 var node = (event.changedTouches ? event.changedTouches[0] : event).target, 6915 cache = node._gsap || gsap.core.getCache(node), 6916 time = _getTime(), 6917 cs; 6918 6919 if (!cache._isScrollT || time - cache._isScrollT > 2000) { 6920 // cache for 2 seconds to improve performance. 6921 while (node && node !== _body && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) { 6922 node = node.parentNode; 6923 } 6924 6925 cache._isScroll = node && node !== target && !_isViewport(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]); 6926 cache._isScrollT = time; 6927 } 6928 6929 if (cache._isScroll || axis === "x") { 6930 event.stopPropagation(); 6931 event._gsapAllow = true; 6932 } 6933}, 6934 // capture events on scrollable elements INSIDE the <body> and allow those by calling stopPropagation() when we find a scrollable ancestor 6935_inputObserver = function _inputObserver(target, type, inputs, nested) { 6936 return _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.create({ 6937 target: target, 6938 capture: true, 6939 debounce: false, 6940 lockAxis: true, 6941 type: type, 6942 onWheel: nested = nested && _nestedScroll, 6943 onPress: nested, 6944 onDrag: nested, 6945 onScroll: nested, 6946 onEnable: function onEnable() { 6947 return inputs && _addListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, false, true); 6948 }, 6949 onDisable: function onDisable() { 6950 return _removeListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, true); 6951 } 6952 }); 6953}, 6954 _inputExp = /(input|label|select|textarea)/i, 6955 _inputIsFocused, 6956 _captureInputs = function _captureInputs(e) { 6957 var isInput = _inputExp.test(e.target.tagName); 6958 6959 if (isInput || _inputIsFocused) { 6960 e._gsapAllow = true; 6961 _inputIsFocused = isInput; 6962 } 6963}, 6964 _getScrollNormalizer = function _getScrollNormalizer(vars) { 6965 _isObject(vars) || (vars = {}); 6966 vars.preventDefault = vars.isNormalizer = vars.allowClicks = true; 6967 vars.type || (vars.type = "wheel,touch"); 6968 vars.debounce = !!vars.debounce; 6969 vars.id = vars.id || "normalizer"; 6970 6971 var _vars2 = vars, 6972 normalizeScrollX = _vars2.normalizeScrollX, 6973 momentum = _vars2.momentum, 6974 allowNestedScroll = _vars2.allowNestedScroll, 6975 onRelease = _vars2.onRelease, 6976 self, 6977 maxY, 6978 target = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.target) || _docEl, 6979 smoother = gsap.core.globals().ScrollSmoother, 6980 smootherInstance = smoother && smoother.get(), 6981 content = _fixIOSBug && (vars.content && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()), 6982 scrollFuncY = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical), 6983 scrollFuncX = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal), 6984 scale = 1, 6985 initialScale = (_Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch && _win.visualViewport ? _win.visualViewport.scale * _win.visualViewport.width : _win.outerWidth) / _win.innerWidth, 6986 wheelRefresh = 0, 6987 resolveMomentumDuration = _isFunction(momentum) ? function () { 6988 return momentum(self); 6989 } : function () { 6990 return momentum || 2.8; 6991 }, 6992 lastRefreshID, 6993 skipTouchMove, 6994 inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll), 6995 resumeTouchMove = function resumeTouchMove() { 6996 return skipTouchMove = false; 6997 }, 6998 scrollClampX = _passThrough, 6999 scrollClampY = _passThrough, 7000 updateClamps = function updateClamps() { 7001 maxY = _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical); 7002 scrollClampY = _clamp(_fixIOSBug ? 1 : 0, maxY); 7003 normalizeScrollX && (scrollClampX = _clamp(0, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal))); 7004 lastRefreshID = _refreshID; 7005 }, 7006 removeContentOffset = function removeContentOffset() { 7007 content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px"; 7008 content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)"; 7009 scrollFuncY.offset = scrollFuncY.cacheID = 0; 7010 }, 7011 ignoreDrag = function ignoreDrag() { 7012 if (skipTouchMove) { 7013 requestAnimationFrame(resumeTouchMove); 7014 7015 var offset = _round(self.deltaY / 2), 7016 scroll = scrollClampY(scrollFuncY.v - offset); 7017 7018 if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) { 7019 scrollFuncY.offset = scroll - scrollFuncY.v; 7020 7021 var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset); 7022 7023 content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)"; 7024 content._gsap.y = y + "px"; 7025 scrollFuncY.cacheID = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache; 7026 7027 _updateAll(); 7028 } 7029 7030 return true; 7031 } 7032 7033 scrollFuncY.offset && removeContentOffset(); 7034 skipTouchMove = true; 7035 }, 7036 tween, 7037 startScrollX, 7038 startScrollY, 7039 onStopDelayedCall, 7040 onResize = function onResize() { 7041 // if the window resizes, like on an iPhone which Apple FORCES the address bar to show/hide even if we event.preventDefault(), it may be scrolling too far now that the address bar is showing, so we must dynamically adjust the momentum tween. 7042 updateClamps(); 7043 7044 if (tween.isActive() && tween.vars.scrollY > maxY) { 7045 scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY); 7046 } 7047 }; 7048 7049 content && gsap.set(content, { 7050 y: "+=0" 7051 }); // to ensure there's a cache (element._gsap) 7052 7053 vars.ignoreCheck = function (e) { 7054 return _fixIOSBug && e.type === "touchmove" && ignoreDrag(e) || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1; 7055 }; 7056 7057 vars.onPress = function () { 7058 skipTouchMove = false; 7059 var prevScale = scale; 7060 scale = _round((_win.visualViewport && _win.visualViewport.scale || 1) / initialScale); 7061 tween.pause(); 7062 prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x"); 7063 startScrollX = scrollFuncX(); 7064 startScrollY = scrollFuncY(); 7065 updateClamps(); 7066 lastRefreshID = _refreshID; 7067 }; 7068 7069 vars.onRelease = vars.onGestureStart = function (self, wasDragging) { 7070 scrollFuncY.offset && removeContentOffset(); 7071 7072 if (!wasDragging) { 7073 onStopDelayedCall.restart(true); 7074 } else { 7075 _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; // make sure we're pulling the non-cached value 7076 // alternate algorithm: durX = Math.min(6, Math.abs(self.velocityX / 800)), dur = Math.max(durX, Math.min(6, Math.abs(self.velocityY / 800))); dur = dur * (0.4 + (1 - _power4In(dur / 6)) * 0.6)) * (momentumSpeed || 1) 7077 7078 var dur = resolveMomentumDuration(), 7079 currentScroll, 7080 endScroll; 7081 7082 if (normalizeScrollX) { 7083 currentScroll = scrollFuncX(); 7084 endScroll = currentScroll + dur * 0.05 * -self.velocityX / 0.227; // the constant .227 is from power4(0.05). velocity is inverted because scrolling goes in the opposite direction. 7085 7086 dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal)); 7087 tween.vars.scrollX = scrollClampX(endScroll); 7088 } 7089 7090 currentScroll = scrollFuncY(); 7091 endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227; // the constant .227 is from power4(0.05) 7092 7093 dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical)); 7094 tween.vars.scrollY = scrollClampY(endScroll); 7095 tween.invalidate().duration(dur).play(0.01); 7096 7097 if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) { 7098 // iOS bug: it'll show the address bar but NOT fire the window "resize" event until the animation is done but we must protect against overshoot so we leverage an onUpdate to do so. 7099 gsap.to({}, { 7100 onUpdate: onResize, 7101 duration: dur 7102 }); 7103 } 7104 } 7105 7106 onRelease && onRelease(self); 7107 }; 7108 7109 vars.onWheel = function () { 7110 tween._ts && tween.pause(); 7111 7112 if (_getTime() - wheelRefresh > 1000) { 7113 // after 1 second, refresh the clamps otherwise that'll only happen when ScrollTrigger.refresh() is called or for touch-scrolling. 7114 lastRefreshID = 0; 7115 wheelRefresh = _getTime(); 7116 } 7117 }; 7118 7119 vars.onChange = function (self, dx, dy, xArray, yArray) { 7120 _refreshID !== lastRefreshID && updateClamps(); 7121 dx && normalizeScrollX && scrollFuncX(scrollClampX(xArray[2] === dx ? startScrollX + (self.startX - self.x) : scrollFuncX() + dx - xArray[1])); // for more precision, we track pointer/touch movement from the start, otherwise it'll drift. 7122 7123 if (dy) { 7124 scrollFuncY.offset && removeContentOffset(); 7125 var isTouch = yArray[2] === dy, 7126 y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1], 7127 yClamped = scrollClampY(y); 7128 isTouch && y !== yClamped && (startScrollY += yClamped - y); 7129 scrollFuncY(yClamped); 7130 } 7131 7132 (dy || dx) && _updateAll(); 7133 }; 7134 7135 vars.onEnable = function () { 7136 _allowNativePanning(target, normalizeScrollX ? false : "x"); 7137 7138 ScrollTrigger.addEventListener("refresh", onResize); 7139 7140 _addListener(_win, "resize", onResize); 7141 7142 if (scrollFuncY.smooth) { 7143 scrollFuncY.target.style.scrollBehavior = "auto"; 7144 scrollFuncY.smooth = scrollFuncX.smooth = false; 7145 } 7146 7147 inputObserver.enable(); 7148 }; 7149 7150 vars.onDisable = function () { 7151 _allowNativePanning(target, true); 7152 7153 _removeListener(_win, "resize", onResize); 7154 7155 ScrollTrigger.removeEventListener("refresh", onResize); 7156 inputObserver.kill(); 7157 }; 7158 7159 vars.lockAxis = vars.lockAxis !== false; 7160 self = new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars); 7161 self.iOS = _fixIOSBug; // used in the Observer getCachedScroll() function to work around an iOS bug that wreaks havoc with TouchEvent.clientY if we allow scroll to go all the way back to 0. 7162 7163 _fixIOSBug && !scrollFuncY() && scrollFuncY(1); // iOS bug causes event.clientY values to freak out (wildly inaccurate) if the scroll position is exactly 0. 7164 7165 _fixIOSBug && gsap.ticker.add(_passThrough); // prevent the ticker from sleeping 7166 7167 onStopDelayedCall = self._dc; 7168 tween = gsap.to(self, { 7169 ease: "power4", 7170 paused: true, 7171 inherit: false, 7172 scrollX: normalizeScrollX ? "+=0.1" : "+=0", 7173 scrollY: "+=0.1", 7174 modifiers: { 7175 scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () { 7176 return tween.pause(); 7177 }) 7178 }, 7179 onUpdate: _updateAll, 7180 onComplete: onStopDelayedCall.vars.onComplete 7181 }); // we need the modifier to sense if the scroll position is altered outside of the momentum tween (like with a scrollTo tween) so we can pause() it to prevent conflicts. 7182 7183 return self; 7184}; 7185 7186ScrollTrigger.sort = function (func) { 7187 return _triggers.sort(func || function (a, b) { 7188 return (a.vars.refreshPriority || 0) * -1e6 + a.start - (b.start + (b.vars.refreshPriority || 0) * -1e6); 7189 }); 7190}; 7191 7192ScrollTrigger.observe = function (vars) { 7193 return new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars); 7194}; 7195 7196ScrollTrigger.normalizeScroll = function (vars) { 7197 if (typeof vars === "undefined") { 7198 return _normalizer; 7199 } 7200 7201 if (vars === true && _normalizer) { 7202 return _normalizer.enable(); 7203 } 7204 7205 if (vars === false) { 7206 _normalizer && _normalizer.kill(); 7207 _normalizer = vars; 7208 return; 7209 } 7210 7211 var normalizer = vars instanceof _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer ? vars : _getScrollNormalizer(vars); 7212 _normalizer && _normalizer.target === normalizer.target && _normalizer.kill(); 7213 _isViewport(normalizer.target) && (_normalizer = normalizer); 7214 return normalizer; 7215}; 7216 7217ScrollTrigger.core = { 7218 // smaller file size way to leverage in ScrollSmoother and Observer 7219 _getVelocityProp: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._getVelocityProp, 7220 _inputObserver: _inputObserver, 7221 _scrollers: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers, 7222 _proxies: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies, 7223 bridge: { 7224 // when normalizeScroll sets the scroll position (ss = setScroll) 7225 ss: function ss() { 7226 _lastScrollTime || _dispatch("scrollStart"); 7227 _lastScrollTime = _getTime(); 7228 }, 7229 // a way to get the _refreshing value in Observer 7230 ref: function ref() { 7231 return _refreshing; 7232 } 7233 } 7234}; 7235_getGSAP() && gsap.registerPlugin(ScrollTrigger); 7236 7237 7238/***/ }), 7239
vendor: 174,689 bytes, lines 7240-11807
7240/***/ "./node_modules/gsap/gsap-core.js": 7241/*!****************************************!*\ 7242 !*** ./node_modules/gsap/gsap-core.js ***! 7243 \****************************************/ 7244/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 7245 7246__webpack_require__.r(__webpack_exports__); 7247/* harmony export */ __webpack_require__.d(__webpack_exports__, { 7248/* harmony export */ Animation: () => (/* binding */ Animation), 7249/* harmony export */ Back: () => (/* binding */ Back), 7250/* harmony export */ Bounce: () => (/* binding */ Bounce), 7251/* harmony export */ Circ: () => (/* binding */ Circ), 7252/* harmony export */ Cubic: () => (/* binding */ Cubic), 7253/* harmony export */ Elastic: () => (/* binding */ Elastic), 7254/* harmony export */ Expo: () => (/* binding */ Expo), 7255/* harmony export */ GSCache: () => (/* binding */ GSCache), 7256/* harmony export */ Linear: () => (/* binding */ Linear), 7257/* harmony export */ Power0: () => (/* binding */ Power0), 7258/* harmony export */ Power1: () => (/* binding */ Power1), 7259/* harmony export */ Power2: () => (/* binding */ Power2), 7260/* harmony export */ Power3: () => (/* binding */ Power3), 7261/* harmony export */ Power4: () => (/* binding */ Power4), 7262/* harmony export */ PropTween: () => (/* binding */ PropTween), 7263/* harmony export */ Quad: () => (/* binding */ Quad), 7264/* harmony export */ Quart: () => (/* binding */ Quart), 7265/* harmony export */ Quint: () => (/* binding */ Quint), 7266/* harmony export */ Sine: () => (/* binding */ Sine), 7267/* harmony export */ SteppedEase: () => (/* binding */ SteppedEase), 7268/* harmony export */ Strong: () => (/* binding */ Strong), 7269/* harmony export */ Timeline: () => (/* binding */ Timeline), 7270/* harmony export */ TimelineLite: () => (/* binding */ Timeline), 7271/* harmony export */ TimelineMax: () => (/* binding */ Timeline), 7272/* harmony export */ Tween: () => (/* binding */ Tween), 7273/* harmony export */ TweenLite: () => (/* binding */ Tween), 7274/* harmony export */ TweenMax: () => (/* binding */ Tween), 7275/* harmony export */ _checkPlugin: () => (/* binding */ _checkPlugin), 7276/* harmony export */ _colorExp: () => (/* binding */ _colorExp), 7277/* harmony export */ _colorStringFilter: () => (/* binding */ _colorStringFilter), 7278/* harmony export */ _config: () => (/* binding */ _config), 7279/* harmony export */ _forEachName: () => (/* binding */ _forEachName), 7280/* harmony export */ _getCache: () => (/* binding */ _getCache), 7281/* harmony export */ _getProperty: () => (/* binding */ _getProperty), 7282/* harmony export */ _getSetter: () => (/* binding */ _getSetter), 7283/* harmony export */ _isString: () => (/* binding */ _isString), 7284/* harmony export */ _isUndefined: () => (/* binding */ _isUndefined), 7285/* harmony export */ _missingPlugin: () => (/* binding */ _missingPlugin), 7286/* harmony export */ _numExp: () => (/* binding */ _numExp), 7287/* harmony export */ _numWithUnitExp: () => (/* binding */ _numWithUnitExp), 7288/* harmony export */ _parseRelative: () => (/* binding */ _parseRelative), 7289/* harmony export */ _plugins: () => (/* binding */ _plugins), 7290/* harmony export */ _relExp: () => (/* binding */ _relExp), 7291/* harmony export */ _removeLinkedListItem: () => (/* binding */ _removeLinkedListItem), 7292/* harmony export */ _renderComplexString: () => (/* binding */ _renderComplexString), 7293/* harmony export */ _replaceRandom: () => (/* binding */ _replaceRandom), 7294/* harmony export */ _round: () => (/* binding */ _round), 7295/* harmony export */ _roundModifier: () => (/* binding */ _roundModifier), 7296/* harmony export */ _setDefaults: () => (/* binding */ _setDefaults), 7297/* harmony export */ _sortPropTweensByPriority: () => (/* binding */ _sortPropTweensByPriority), 7298/* harmony export */ _ticker: () => (/* binding */ _ticker), 7299/* harmony export */ clamp: () => (/* binding */ clamp), 7300/* harmony export */ "default": () => (/* binding */ gsap), 7301/* harmony export */ distribute: () => (/* binding */ distribute), 7302/* harmony export */ getUnit: () => (/* binding */ getUnit), 7303/* harmony export */ gsap: () => (/* binding */ gsap), 7304/* harmony export */ interpolate: () => (/* binding */ interpolate), 7305/* harmony export */ mapRange: () => (/* binding */ mapRange), 7306/* harmony export */ normalize: () => (/* binding */ normalize), 7307/* harmony export */ pipe: () => (/* binding */ pipe), 7308/* harmony export */ random: () => (/* binding */ random), 7309/* harmony export */ selector: () => (/* binding */ selector), 7310/* harmony export */ shuffle: () => (/* binding */ shuffle), 7311/* harmony export */ snap: () => (/* binding */ snap), 7312/* harmony export */ splitColor: () => (/* binding */ splitColor), 7313/* harmony export */ toArray: () => (/* binding */ toArray), 7314/* harmony export */ unitize: () => (/* binding */ unitize), 7315/* harmony export */ wrap: () => (/* binding */ wrap), 7316/* harmony export */ wrapYoyo: () => (/* binding */ wrapYoyo) 7317/* harmony export */ }); 7318function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } 7319 7320function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; } 7321 7322/*! 7323 * GSAP 3.12.5 7324 * https://gsap.com 7325 * 7326 * @license Copyright 2008-2024, GreenSock. All rights reserved. 7327 * Subject to the terms at https://gsap.com/standard-license or for 7328 * Club GSAP members, the agreement issued with that membership. 7329 * @author: Jack Doyle, [email protected] 7330*/ 7331 7332/* eslint-disable */ 7333var _config = { 7334 autoSleep: 120, 7335 force3D: "auto", 7336 nullTargetWarn: 1, 7337 units: { 7338 lineHeight: "" 7339 } 7340}, 7341 _defaults = { 7342 duration: .5, 7343 overwrite: false, 7344 delay: 0 7345}, 7346 _suppressOverwrites, 7347 _reverting, 7348 _context, 7349 _bigNum = 1e8, 7350 _tinyNum = 1 / _bigNum, 7351 _2PI = Math.PI * 2, 7352 _HALF_PI = _2PI / 4, 7353 _gsID = 0, 7354 _sqrt = Math.sqrt, 7355 _cos = Math.cos, 7356 _sin = Math.sin, 7357 _isString = function _isString(value) { 7358 return typeof value === "string"; 7359}, 7360 _isFunction = function _isFunction(value) { 7361 return typeof value === "function"; 7362}, 7363 _isNumber = function _isNumber(value) { 7364 return typeof value === "number"; 7365}, 7366 _isUndefined = function _isUndefined(value) { 7367 return typeof value === "undefined"; 7368}, 7369 _isObject = function _isObject(value) { 7370 return typeof value === "object"; 7371}, 7372 _isNotFalse = function _isNotFalse(value) { 7373 return value !== false; 7374}, 7375 _windowExists = function _windowExists() { 7376 return typeof window !== "undefined"; 7377}, 7378 _isFuncOrString = function _isFuncOrString(value) { 7379 return _isFunction(value) || _isString(value); 7380}, 7381 _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {}, 7382 // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView(). 7383_isArray = Array.isArray, 7384 _strictNumExp = /(?:-?\.?\d|\.)+/gi, 7385 //only numbers (including negatives and decimals) but NOT relative values. 7386_numExp = /[-+=.]*\d+[.e\-+]*\d*[e\-+]*\d*/g, 7387 //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8. 7388_numWithUnitExp = /[-+=.]*\d+[.e-]*\d*[a-z%]*/g, 7389 _complexStringNumExp = /[-+=.]*\d+\.?\d*(?:e-|e\+)?\d*/gi, 7390 //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. 7391_relExp = /[+-]=-?[.\d]+/, 7392 _delimitedValueExp = /[^,'"\[\]\s]+/gi, 7393 // previously /[#\-+.]*\b[a-z\d\-=+%.]+/gi but didn't catch special characters. 7394_unitExp = /^[+\-=e\s\d]*\d+[.\d]*([a-z]*|%)\s*$/i, 7395 _globalTimeline, 7396 _win, 7397 _coreInitted, 7398 _doc, 7399 _globals = {}, 7400 _installScope = {}, 7401 _coreReady, 7402 _install = function _install(scope) { 7403 return (_installScope = _merge(scope, _globals)) && gsap; 7404}, 7405 _missingPlugin = function _missingPlugin(property, value) { 7406 return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()"); 7407}, 7408 _warn = function _warn(message, suppress) { 7409 return !suppress && console.warn(message); 7410}, 7411 _addGlobal = function _addGlobal(name, obj) { 7412 return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals; 7413}, 7414 _emptyFunc = function _emptyFunc() { 7415 return 0; 7416}, 7417 _startAtRevertConfig = { 7418 suppressEvents: true, 7419 isStart: true, 7420 kill: false 7421}, 7422 _revertConfigNoKill = { 7423 suppressEvents: true, 7424 kill: false 7425}, 7426 _revertConfig = { 7427 suppressEvents: true 7428}, 7429 _reservedProps = {}, 7430 _lazyTweens = [], 7431 _lazyLookup = {}, 7432 _lastRenderedFrame, 7433 _plugins = {}, 7434 _effects = {}, 7435 _nextGCFrame = 30, 7436 _harnessPlugins = [], 7437 _callbackNames = "", 7438 _harness = function _harness(targets) { 7439 var target = targets[0], 7440 harnessPlugin, 7441 i; 7442 _isObject(target) || _isFunction(target) || (targets = [targets]); 7443 7444 if (!(harnessPlugin = (target._gsap || {}).harness)) { 7445 // 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) 7446 i = _harnessPlugins.length; 7447 7448 while (i-- && !_harnessPlugins[i].targetTest(target)) {} 7449 7450 harnessPlugin = _harnessPlugins[i]; 7451 } 7452 7453 i = targets.length; 7454 7455 while (i--) { 7456 targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1); 7457 } 7458 7459 return targets; 7460}, 7461 _getCache = function _getCache(target) { 7462 return target._gsap || _harness(toArray(target))[0]._gsap; 7463}, 7464 _getProperty = function _getProperty(target, property, v) { 7465 return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v; 7466}, 7467 _forEachName = function _forEachName(names, func) { 7468 return (names = names.split(",")).forEach(func) || names; 7469}, 7470 //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). 7471_round = function _round(value) { 7472 return Math.round(value * 100000) / 100000 || 0; 7473}, 7474 _roundPrecise = function _roundPrecise(value) { 7475 return Math.round(value * 10000000) / 10000000 || 0; 7476}, 7477 // increased precision mostly for timing values. 7478_parseRelative = function _parseRelative(start, value) { 7479 var operator = value.charAt(0), 7480 end = parseFloat(value.substr(2)); 7481 start = parseFloat(start); 7482 return operator === "+" ? start + end : operator === "-" ? start - end : operator === "*" ? start * end : start / end; 7483}, 7484 _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) { 7485 //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. 7486 var l = toFind.length, 7487 i = 0; 7488 7489 for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {} 7490 7491 return i < l; 7492}, 7493 _lazyRender = function _lazyRender() { 7494 var l = _lazyTweens.length, 7495 a = _lazyTweens.slice(0), 7496 i, 7497 tween; 7498 7499 _lazyLookup = {}; 7500 _lazyTweens.length = 0; 7501 7502 for (i = 0; i < l; i++) { 7503 tween = a[i]; 7504 tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0); 7505 } 7506}, 7507 _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) { 7508 _lazyTweens.length && !_reverting && _lazyRender(); 7509 animation.render(time, suppressEvents, force || _reverting && time < 0 && (animation._initted || animation._startAt)); 7510 _lazyTweens.length && !_reverting && _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. 7511}, 7512 _numericIfPossible = function _numericIfPossible(value) { 7513 var n = parseFloat(value); 7514 return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value; 7515}, 7516 _passThrough = function _passThrough(p) { 7517 return p; 7518}, 7519 _setDefaults = function _setDefaults(obj, defaults) { 7520 for (var p in defaults) { 7521 p in obj || (obj[p] = defaults[p]); 7522 } 7523 7524 return obj; 7525}, 7526 _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) { 7527 return function (obj, defaults) { 7528 for (var p in defaults) { 7529 p in obj || p === "duration" && excludeDuration || p === "ease" || (obj[p] = defaults[p]); 7530 } 7531 }; 7532}, 7533 _merge = function _merge(base, toMerge) { 7534 for (var p in toMerge) { 7535 base[p] = toMerge[p]; 7536 } 7537 7538 return base; 7539}, 7540 _mergeDeep = function _mergeDeep(base, toMerge) { 7541 for (var p in toMerge) { 7542 p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]); 7543 } 7544 7545 return base; 7546}, 7547 _copyExcluding = function _copyExcluding(obj, excluding) { 7548 var copy = {}, 7549 p; 7550 7551 for (p in obj) { 7552 p in excluding || (copy[p] = obj[p]); 7553 } 7554 7555 return copy; 7556}, 7557 _inheritDefaults = function _inheritDefaults(vars) { 7558 var parent = vars.parent || _globalTimeline, 7559 func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults; 7560 7561 if (_isNotFalse(vars.inherit)) { 7562 while (parent) { 7563 func(vars, parent.vars.defaults); 7564 parent = parent.parent || parent._dp; 7565 } 7566 } 7567 7568 return vars; 7569}, 7570 _arraysMatch = function _arraysMatch(a1, a2) { 7571 var i = a1.length, 7572 match = i === a2.length; 7573 7574 while (match && i-- && a1[i] === a2[i]) {} 7575 7576 return i < 0; 7577}, 7578 _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) { 7579 if (firstProp === void 0) { 7580 firstProp = "_first"; 7581 } 7582 7583 if (lastProp === void 0) { 7584 lastProp = "_last"; 7585 } 7586 7587 var prev = parent[lastProp], 7588 t; 7589 7590 if (sortBy) { 7591 t = child[sortBy]; 7592 7593 while (prev && prev[sortBy] > t) { 7594 prev = prev._prev; 7595 } 7596 } 7597 7598 if (prev) { 7599 child._next = prev._next; 7600 prev._next = child; 7601 } else { 7602 child._next = parent[firstProp]; 7603 parent[firstProp] = child; 7604 } 7605 7606 if (child._next) { 7607 child._next._prev = child; 7608 } else { 7609 parent[lastProp] = child; 7610 } 7611 7612 child._prev = prev; 7613 child.parent = child._dp = parent; 7614 return child; 7615}, 7616 _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) { 7617 if (firstProp === void 0) { 7618 firstProp = "_first"; 7619 } 7620 7621 if (lastProp === void 0) { 7622 lastProp = "_last"; 7623 } 7624 7625 var prev = child._prev, 7626 next = child._next; 7627 7628 if (prev) { 7629 prev._next = next; 7630 } else if (parent[firstProp] === child) { 7631 parent[firstProp] = next; 7632 } 7633 7634 if (next) { 7635 next._prev = prev; 7636 } else if (parent[lastProp] === child) { 7637 parent[lastProp] = prev; 7638 } 7639 7640 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. 7641}, 7642 _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) { 7643 child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove && child.parent.remove(child); 7644 child._act = 0; 7645}, 7646 _uncache = function _uncache(animation, child) { 7647 if (animation && (!child || child._end > animation._dur || child._start < 0)) { 7648 // 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) 7649 var a = animation; 7650 7651 while (a) { 7652 a._dirty = 1; 7653 a = a.parent; 7654 } 7655 } 7656 7657 return animation; 7658}, 7659 _recacheAncestors = function _recacheAncestors(animation) { 7660 var parent = animation.parent; 7661 7662 while (parent && parent.parent) { 7663 //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. 7664 parent._dirty = 1; 7665 parent.totalDuration(); 7666 parent = parent.parent; 7667 } 7668 7669 return animation; 7670}, 7671 _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) { 7672 return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force)); 7673}, 7674 _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) { 7675 return !animation || animation._ts && _hasNoPausedAncestors(animation.parent); 7676}, 7677 _elapsedCycleDuration = function _elapsedCycleDuration(animation) { 7678 return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0; 7679}, 7680 // 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. 7681_animationCycle = function _animationCycle(tTime, cycleDuration) { 7682 var whole = Math.floor(tTime /= cycleDuration); 7683 return tTime && whole === tTime ? whole - 1 : whole; 7684}, 7685 _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) { 7686 return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur); 7687}, 7688 _setEnd = function _setEnd(animation) { 7689 return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0)); 7690}, 7691 _alignPlayhead = function _alignPlayhead(animation, totalTime) { 7692 // 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. 7693 var parent = animation._dp; 7694 7695 if (parent && parent.smoothChildTiming && animation._ts) { 7696 animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts)); 7697 7698 _setEnd(animation); 7699 7700 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. 7701 } 7702 7703 return animation; 7704}, 7705 7706/* 7707_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => { 7708 let cycleDuration = duration + repeatDelay, 7709 time = _round(clampedTotalTime % cycleDuration); 7710 if (time > duration) { 7711 time = duration; 7712 } 7713 return (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time; 7714}, 7715*/ 7716_postAddChecks = function _postAddChecks(timeline, child) { 7717 var t; 7718 7719 if (child._time || !child._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) { 7720 // in case, for example, the _start is moved on a tween that has already rendered, or if it's being inserted into a timeline BEFORE where the playhead is currently. 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. Special case: if it's a timeline (has .add() method) and no duration, we can skip rendering because the user may be populating it AFTER adding it to a parent timeline (unconventional, but possible, and we wouldn't want it to get removed if the parent's autoRemoveChildren is true). 7721 t = _parentToChildTotalTime(timeline.rawTime(), child); 7722 7723 if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) { 7724 child.render(t, true); 7725 } 7726 } //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. 7727 7728 7729 if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) { 7730 //in case any of the ancestors had completed but should now be enabled... 7731 if (timeline._dur < timeline.duration()) { 7732 t = timeline; 7733 7734 while (t._dp) { 7735 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. 7736 7737 t = t._dp; 7738 } 7739 } 7740 7741 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. 7742 } 7743}, 7744 _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) { 7745 child.parent && _removeFromParent(child); 7746 child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay); 7747 child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0)); 7748 7749 _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0); 7750 7751 _isFromOrFromStart(child) || (timeline._recent = child); 7752 skipChecks || _postAddChecks(timeline, child); 7753 timeline._ts < 0 && _alignPlayhead(timeline, timeline._tTime); // if the timeline is reversed and the new child makes it longer, we may need to adjust the parent's _start (push it back) 7754 7755 return timeline; 7756}, 7757 _scrollTrigger = function _scrollTrigger(animation, trigger) { 7758 return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation); 7759}, 7760 _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) { 7761 _initTween(tween, time, tTime); 7762 7763 if (!tween._initted) { 7764 return 1; 7765 } 7766 7767 if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) { 7768 _lazyTweens.push(tween); 7769 7770 tween._lazy = [tTime, suppressEvents]; 7771 return 1; 7772 } 7773}, 7774 _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) { 7775 var parent = _ref.parent; 7776 return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent)); 7777}, 7778 // check parent's _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn't force the ratio back to 0 7779_isFromOrFromStart = function _isFromOrFromStart(_ref2) { 7780 var data = _ref2.data; 7781 return data === "isFromStart" || data === "isStart"; 7782}, 7783 _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) { 7784 var prevRatio = tween.ratio, 7785 ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1, 7786 // if the tween or its parent is reversed and the totalTime is 0, we should go to a ratio of 0. Edge case: if a from() or fromTo() stagger tween is placed later in a timeline, the "startAt" zero-duration tween could initially render at a time when the parent timeline's playhead is technically BEFORE where this tween is, so make sure that any "from" and "fromTo" startAt tweens are rendered the first time at a ratio of 1. 7787 repeatDelay = tween._rDelay, 7788 tTime = 0, 7789 pt, 7790 iteration, 7791 prevIteration; 7792 7793 if (repeatDelay && tween._repeat) { 7794 // in case there's a zero-duration tween that has a repeat with a repeatDelay 7795 tTime = _clamp(0, tween._tDur, totalTime); 7796 iteration = _animationCycle(tTime, repeatDelay); 7797 tween._yoyo && iteration & 1 && (ratio = 1 - ratio); 7798 7799 if (iteration !== _animationCycle(tween._tTime, repeatDelay)) { 7800 // if iteration changed 7801 prevRatio = 1 - ratio; 7802 tween.vars.repeatRefresh && tween._initted && tween.invalidate(); 7803 } 7804 } 7805 7806 if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) { 7807 if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) { 7808 // 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. 7809 return; 7810 } 7811 7812 prevIteration = tween._zTime; 7813 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. 7814 7815 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. 7816 7817 tween.ratio = ratio; 7818 tween._from && (ratio = 1 - ratio); 7819 tween._time = 0; 7820 tween._tTime = tTime; 7821 pt = tween._pt; 7822 7823 while (pt) { 7824 pt.r(ratio, pt.d); 7825 pt = pt._next; 7826 } 7827 7828 totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true); 7829 tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate"); 7830 tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat"); 7831 7832 if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) { 7833 ratio && _removeFromParent(tween, 1); 7834 7835 if (!suppressEvents && !_reverting) { 7836 _callback(tween, ratio ? "onComplete" : "onReverseComplete", true); 7837 7838 tween._prom && tween._prom(); 7839 } 7840 } 7841 } else if (!tween._zTime) { 7842 tween._zTime = totalTime; 7843 } 7844}, 7845 _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) { 7846 var child; 7847 7848 if (time > prevTime) { 7849 child = animation._first; 7850 7851 while (child && child._start <= time) { 7852 if (child.data === "isPause" && child._start > prevTime) { 7853 return child; 7854 } 7855 7856 child = child._next; 7857 } 7858 } else { 7859 child = animation._last; 7860 7861 while (child && child._start >= time) { 7862 if (child.data === "isPause" && child._start < prevTime) { 7863 return child; 7864 } 7865 7866 child = child._prev; 7867 } 7868 } 7869}, 7870 _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) { 7871 var repeat = animation._repeat, 7872 dur = _roundPrecise(duration) || 0, 7873 totalProgress = animation._tTime / animation._tDur; 7874 totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur); 7875 animation._dur = dur; 7876 animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat); 7877 totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress); 7878 animation.parent && _setEnd(animation); 7879 skipUncache || _uncache(animation.parent, animation); 7880 return animation; 7881}, 7882 _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) { 7883 return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur); 7884}, 7885 _zeroPosition = { 7886 _start: 0, 7887 endTime: _emptyFunc, 7888 totalDuration: _emptyFunc 7889}, 7890 _parsePosition = function _parsePosition(animation, position, percentAnimation) { 7891 var labels = animation.labels, 7892 recent = animation._recent || _zeroPosition, 7893 clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur, 7894 //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. 7895 i, 7896 offset, 7897 isPercent; 7898 7899 if (_isString(position) && (isNaN(position) || position in labels)) { 7900 //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). 7901 offset = position.charAt(0); 7902 isPercent = position.substr(-1) === "%"; 7903 i = position.indexOf("="); 7904 7905 if (offset === "<" || offset === ">") { 7906 i >= 0 && (position = position.replace(/=/, "")); 7907 return (offset === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1); 7908 } 7909 7910 if (i < 0) { 7911 position in labels || (labels[position] = clippedDuration); 7912 return labels[position]; 7913 } 7914 7915 offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1)); 7916 7917 if (isPercent && percentAnimation) { 7918 offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration(); 7919 } 7920 7921 return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset; 7922 } 7923 7924 return position == null ? clippedDuration : +position; 7925}, 7926 _createTweenType = function _createTweenType(type, params, timeline) { 7927 var isLegacy = _isNumber(params[1]), 7928 varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1), 7929 vars = params[varsIndex], 7930 irVars, 7931 parent; 7932 7933 isLegacy && (vars.duration = params[1]); 7934 vars.parent = timeline; 7935 7936 if (type) { 7937 irVars = vars; 7938 parent = timeline; 7939 7940 while (parent && !("immediateRender" in irVars)) { 7941 // 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. 7942 irVars = parent.vars.defaults || {}; 7943 parent = _isNotFalse(parent.vars.inherit) && parent.parent; 7944 } 7945 7946 vars.immediateRender = _isNotFalse(irVars.immediateRender); 7947 type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // "from" vars 7948 } 7949 7950 return new Tween(params[0], vars, params[varsIndex + 1]); 7951}, 7952 _conditionalReturn = function _conditionalReturn(value, func) { 7953 return value || value === 0 ? func(value) : func; 7954}, 7955 _clamp = function _clamp(min, max, value) { 7956 return value < min ? min : value > max ? max : value; 7957}, 7958 getUnit = function getUnit(value, v) { 7959 return !_isString(value) || !(v = _unitExp.exec(value)) ? "" : v[1]; 7960}, 7961 // 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. 7962clamp = function clamp(min, max, value) { 7963 return _conditionalReturn(value, function (v) { 7964 return _clamp(min, max, v); 7965 }); 7966}, 7967 _slice = [].slice, 7968 _isArrayLike = function _isArrayLike(value, nonEmpty) { 7969 return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win; 7970}, 7971 _flatten = function _flatten(ar, leaveStrings, accumulator) { 7972 if (accumulator === void 0) { 7973 accumulator = []; 7974 } 7975 7976 return ar.forEach(function (value) { 7977 var _accumulator; 7978 7979 return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value); 7980 }) || accumulator; 7981}, 7982 //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. 7983toArray = function toArray(value, scope, leaveStrings) { 7984 return _context && !scope && _context.selector ? _context.selector(value) : _isString(value) && !leaveStrings && (_coreInitted || !_wake()) ? _slice.call((scope || _doc).querySelectorAll(value), 0) : _isArray(value) ? _flatten(value, leaveStrings) : _isArrayLike(value) ? _slice.call(value, 0) : value ? [value] : []; 7985}, 7986 selector = function selector(value) { 7987 value = toArray(value)[0] || _warn("Invalid scope") || {}; 7988 return function (v) { 7989 var el = value.current || value.nativeElement || value; 7990 return toArray(v, el.querySelectorAll ? el : el === value ? _warn("Invalid scope") || _doc.createElement("div") : value); 7991 }; 7992}, 7993 shuffle = function shuffle(a) { 7994 return a.sort(function () { 7995 return .5 - Math.random(); 7996 }); 7997}, 7998 // 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; 7999//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 8000distribute = function distribute(v) { 8001 if (_isFunction(v)) { 8002 return v; 8003 } 8004 8005 var vars = _isObject(v) ? v : { 8006 each: v 8007 }, 8008 //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. 8009 ease = _parseEase(vars.ease), 8010 from = vars.from || 0, 8011 base = parseFloat(vars.base) || 0, 8012 cache = {}, 8013 isDecimal = from > 0 && from < 1, 8014 ratios = isNaN(from) || isDecimal, 8015 axis = vars.axis, 8016 ratioX = from, 8017 ratioY = from; 8018 8019 if (_isString(from)) { 8020 ratioX = ratioY = { 8021 center: .5, 8022 edges: .5, 8023 end: 1 8024 }[from] || 0; 8025 } else if (!isDecimal && ratios) { 8026 ratioX = from[0]; 8027 ratioY = from[1]; 8028 } 8029 8030 return function (i, target, a) { 8031 var l = (a || vars).length, 8032 distances = cache[l], 8033 originX, 8034 originY, 8035 x, 8036 y, 8037 d, 8038 j, 8039 max, 8040 min, 8041 wrapAt; 8042 8043 if (!distances) { 8044 wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1]; 8045 8046 if (!wrapAt) { 8047 max = -_bigNum; 8048 8049 while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {} 8050 8051 wrapAt < l && wrapAt--; 8052 } 8053 8054 distances = cache[l] = []; 8055 originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt; 8056 originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0; 8057 max = 0; 8058 min = _bigNum; 8059 8060 for (j = 0; j < l; j++) { 8061 x = j % wrapAt - originX; 8062 y = originY - (j / wrapAt | 0); 8063 distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x); 8064 d > max && (max = d); 8065 d < min && (min = d); 8066 } 8067 8068 from === "random" && shuffle(distances); 8069 distances.max = max - min; 8070 distances.min = min; 8071 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); 8072 distances.b = l < 0 ? base - l : base; 8073 distances.u = getUnit(vars.amount || vars.each) || 0; //unit 8074 8075 ease = ease && l < 0 ? _invertEase(ease) : ease; 8076 } 8077 8078 l = (distances[i] - distances.min) / distances.max || 0; 8079 return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors 8080 }; 8081}, 8082 _roundModifier = function _roundModifier(v) { 8083 //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. 8084 var p = Math.pow(10, ((v + "").split(".")[1] || "").length); //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()) 8085 8086 return function (raw) { 8087 var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p); 8088 8089 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! 8090 }; 8091}, 8092 snap = function snap(snapTo, value) { 8093 var isArray = _isArray(snapTo), 8094 radius, 8095 is2D; 8096 8097 if (!isArray && _isObject(snapTo)) { 8098 radius = isArray = snapTo.radius || _bigNum; 8099 8100 if (snapTo.values) { 8101 snapTo = toArray(snapTo.values); 8102 8103 if (is2D = !_isNumber(snapTo[0])) { 8104 radius *= radius; //performance optimization so we don't have to Math.sqrt() in the loop. 8105 } 8106 } else { 8107 snapTo = _roundModifier(snapTo.increment); 8108 } 8109 } 8110 8111 return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) { 8112 is2D = snapTo(raw); 8113 return Math.abs(is2D - raw) <= radius ? is2D : raw; 8114 } : function (raw) { 8115 var x = parseFloat(is2D ? raw.x : raw), 8116 y = parseFloat(is2D ? raw.y : 0), 8117 min = _bigNum, 8118 closest = 0, 8119 i = snapTo.length, 8120 dx, 8121 dy; 8122 8123 while (i--) { 8124 if (is2D) { 8125 dx = snapTo[i].x - x; 8126 dy = snapTo[i].y - y; 8127 dx = dx * dx + dy * dy; 8128 } else { 8129 dx = Math.abs(snapTo[i] - x); 8130 } 8131 8132 if (dx < min) { 8133 min = dx; 8134 closest = i; 8135 } 8136 } 8137 8138 closest = !radius || min <= radius ? snapTo[closest] : raw; 8139 return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw); 8140 }); 8141}, 8142 random = function random(min, max, roundingIncrement, returnFunction) { 8143 return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () { 8144 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; 8145 }); 8146}, 8147 pipe = function pipe() { 8148 for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) { 8149 functions[_key] = arguments[_key]; 8150 } 8151 8152 return function (value) { 8153 return functions.reduce(function (v, f) { 8154 return f(v); 8155 }, value); 8156 }; 8157}, 8158 unitize = function unitize(func, unit) { 8159 return function (value) { 8160 return func(parseFloat(value)) + (unit || getUnit(value)); 8161 }; 8162}, 8163 normalize = function normalize(min, max, value) { 8164 return mapRange(min, max, 0, 1, value); 8165}, 8166 _wrapArray = function _wrapArray(a, wrapper, value) { 8167 return _conditionalReturn(value, function (index) { 8168 return a[~~wrapper(index)]; 8169 }); 8170}, 8171 wrap = function wrap(min, max, value) { 8172 // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug causes problems (unrelated to GSAP). 8173 var range = max - min; 8174 return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) { 8175 return (range + (value - min) % range) % range + min; 8176 }); 8177}, 8178 wrapYoyo = function wrapYoyo(min, max, value) { 8179 var range = max - min, 8180 total = range * 2; 8181 return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) { 8182 value = (total + (value - min) % total) % total || 0; 8183 return min + (value > range ? total - value : value); 8184 }); 8185}, 8186 _replaceRandom = function _replaceRandom(value) { 8187 //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]) 8188 var prev = 0, 8189 s = "", 8190 i, 8191 nums, 8192 end, 8193 isArray; 8194 8195 while (~(i = value.indexOf("random(", prev))) { 8196 end = value.indexOf(")", i); 8197 isArray = value.charAt(i + 7) === "["; 8198 nums = value.substr(i + 7, end - i - 7).match(isArray ? _delimitedValueExp : _strictNumExp); 8199 s += value.substr(prev, i - prev) + random(isArray ? nums : +nums[0], isArray ? 0 : +nums[1], +nums[2] || 1e-5); 8200 prev = end + 1; 8201 } 8202 8203 return s + value.substr(prev, value.length - prev); 8204}, 8205 mapRange = function mapRange(inMin, inMax, outMin, outMax, value) { 8206 var inRange = inMax - inMin, 8207 outRange = outMax - outMin; 8208 return _conditionalReturn(value, function (value) { 8209 return outMin + ((value - inMin) / inRange * outRange || 0); 8210 }); 8211}, 8212 interpolate = function interpolate(start, end, progress, mutate) { 8213 var func = isNaN(start + end) ? 0 : function (p) { 8214 return (1 - p) * start + p * end; 8215 }; 8216 8217 if (!func) { 8218 var isString = _isString(start), 8219 master = {}, 8220 p, 8221 i, 8222 interpolators, 8223 l, 8224 il; 8225 8226 progress === true && (mutate = 1) && (progress = null); 8227 8228 if (isString) { 8229 start = { 8230 p: start 8231 }; 8232 end = { 8233 p: end 8234 }; 8235 } else if (_isArray(start) && !_isArray(end)) { 8236 interpolators = []; 8237 l = start.length; 8238 il = l - 2; 8239 8240 for (i = 1; i < l; i++) { 8241 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. 8242 } 8243 8244 l--; 8245 8246 func = function func(p) { 8247 p *= l; 8248 var i = Math.min(il, ~~p); 8249 return interpolators[i](p - i); 8250 }; 8251 8252 progress = end; 8253 } else if (!mutate) { 8254 start = _merge(_isArray(start) ? [] : {}, start); 8255 } 8256 8257 if (!interpolators) { 8258 for (p in end) { 8259 _addPropTween.call(master, start, p, "get", end[p]); 8260 } 8261 8262 func = function func(p) { 8263 return _renderPropTweens(p, master) || (isString ? start.p : start); 8264 }; 8265 } 8266 } 8267 8268 return _conditionalReturn(progress, func); 8269}, 8270 _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) { 8271 //used for nextLabel() and previousLabel() 8272 var labels = timeline.labels, 8273 min = _bigNum, 8274 p, 8275 distance, 8276 label; 8277 8278 for (p in labels) { 8279 distance = labels[p] - fromTime; 8280 8281 if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) { 8282 label = p; 8283 min = distance; 8284 } 8285 } 8286 8287 return label; 8288}, 8289 _callback = function _callback(animation, type, executeLazyFirst) { 8290 var v = animation.vars, 8291 callback = v[type], 8292 prevContext = _context, 8293 context = animation._ctx, 8294 params, 8295 scope, 8296 result; 8297 8298 if (!callback) { 8299 return; 8300 } 8301 8302 params = v[type + "Params"]; 8303 scope = v.callbackScope || animation; 8304 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. 8305 8306 context && (_context = context); 8307 result = params ? callback.apply(scope, params) : callback.call(scope); 8308 _context = prevContext; 8309 return result; 8310}, 8311 _interrupt = function _interrupt(animation) { 8312 _removeFromParent(animation); 8313 8314 animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting); 8315 animation.progress() < 1 && _callback(animation, "onInterrupt"); 8316 return animation; 8317}, 8318 _quickTween, 8319 _registerPluginQueue = [], 8320 _createPlugin = function _createPlugin(config) { 8321 if (!config) return; 8322 config = !config.name && config["default"] || config; // UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}. 8323 8324 if (_windowExists() || config.headless) { 8325 // edge case: some build tools may pass in a null/undefined value 8326 var name = config.name, 8327 isFunc = _isFunction(config), 8328 Plugin = name && !isFunc && config.init ? function () { 8329 this._props = []; 8330 } : config, 8331 //in case someone passes in an object that's not a plugin, like CustomEase 8332 instanceDefaults = { 8333 init: _emptyFunc, 8334 render: _renderPropTweens, 8335 add: _addPropTween, 8336 kill: _killPropTweensOf, 8337 modifier: _addPluginModifier, 8338 rawVars: 0 8339 }, 8340 statics = { 8341 targetTest: 0, 8342 get: 0, 8343 getSetter: _getSetter, 8344 aliases: {}, 8345 register: 0 8346 }; 8347 8348 _wake(); 8349 8350 if (config !== Plugin) { 8351 if (_plugins[name]) { 8352 return; 8353 } 8354 8355 _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods 8356 8357 8358 _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods 8359 8360 8361 _plugins[Plugin.prop = name] = Plugin; 8362 8363 if (config.targetTest) { 8364 _harnessPlugins.push(Plugin); 8365 8366 _reservedProps[name] = 1; 8367 } 8368 8369 name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; //for the global name. "motionPath" should become MotionPathPlugin 8370 } 8371 8372 _addGlobal(name, Plugin); 8373 8374 config.register && config.register(gsap, Plugin, PropTween); 8375 } else { 8376 _registerPluginQueue.push(config); 8377 } 8378}, 8379 8380/* 8381 * -------------------------------------------------------------------------------------- 8382 * COLORS 8383 * -------------------------------------------------------------------------------------- 8384 */ 8385_255 = 255, 8386 _colorLookup = { 8387 aqua: [0, _255, _255], 8388 lime: [0, _255, 0], 8389 silver: [192, 192, 192], 8390 black: [0, 0, 0], 8391 maroon: [128, 0, 0], 8392 teal: [0, 128, 128], 8393 blue: [0, 0, _255], 8394 navy: [0, 0, 128], 8395 white: [_255, _255, _255], 8396 olive: [128, 128, 0], 8397 yellow: [_255, _255, 0], 8398 orange: [_255, 165, 0], 8399 gray: [128, 128, 128], 8400 purple: [128, 0, 128], 8401 green: [0, 128, 0], 8402 red: [_255, 0, 0], 8403 pink: [_255, 192, 203], 8404 cyan: [0, _255, _255], 8405 transparent: [_255, _255, _255, 0] 8406}, 8407 // possible future idea to replace the hard-coded color name values - put this in the ticker.wake() where we set the _doc: 8408// let ctx = _doc.createElement("canvas").getContext("2d"); 8409// _forEachName("aqua,lime,silver,black,maroon,teal,blue,navy,white,olive,yellow,orange,gray,purple,green,red,pink,cyan", color => {ctx.fillStyle = color; _colorLookup[color] = splitColor(ctx.fillStyle)}); 8410_hue = function _hue(h, m1, m2) { 8411 h += h < 0 ? 1 : h > 1 ? -1 : 0; 8412 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; 8413}, 8414 splitColor = function splitColor(v, toHSL, forceAlpha) { 8415 var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0, 8416 r, 8417 g, 8418 b, 8419 h, 8420 s, 8421 l, 8422 max, 8423 min, 8424 d, 8425 wasHSL; 8426 8427 if (!a) { 8428 if (v.substr(-1) === ",") { 8429 //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. 8430 v = v.substr(0, v.length - 1); 8431 } 8432 8433 if (_colorLookup[v]) { 8434 a = _colorLookup[v]; 8435 } else if (v.charAt(0) === "#") { 8436 if (v.length < 6) { 8437 //for shorthand like #9F0 or #9F0F (could have alpha) 8438 r = v.charAt(1); 8439 g = v.charAt(2); 8440 b = v.charAt(3); 8441 v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : ""); 8442 } 8443 8444 if (v.length === 9) { 8445 // hex with alpha, like #fd5e53ff 8446 a = parseInt(v.substr(1, 6), 16); 8447 return [a >> 16, a >> 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255]; 8448 } 8449 8450 v = parseInt(v.substr(1), 16); 8451 a = [v >> 16, v >> 8 & _255, v & _255]; 8452 } else if (v.substr(0, 3) === "hsl") { 8453 a = wasHSL = v.match(_strictNumExp); 8454 8455 if (!toHSL) { 8456 h = +a[0] % 360 / 360; 8457 s = +a[1] / 100; 8458 l = +a[2] / 100; 8459 g = l <= .5 ? l * (s + 1) : l + s - l * s; 8460 r = l * 2 - g; 8461 a.length > 3 && (a[3] *= 1); //cast as number 8462 8463 a[0] = _hue(h + 1 / 3, r, g); 8464 a[1] = _hue(h, r, g); 8465 a[2] = _hue(h - 1 / 3, r, g); 8466 } else if (~v.indexOf("=")) { 8467 //if relative values are found, just return the raw strings with the relative prefixes in place. 8468 a = v.match(_numExp); 8469 forceAlpha && a.length < 4 && (a[3] = 1); 8470 return a; 8471 } 8472 } else { 8473 a = v.match(_strictNumExp) || _colorLookup.transparent; 8474 } 8475 8476 a = a.map(Number); 8477 } 8478 8479 if (toHSL && !wasHSL) { 8480 r = a[0] / _255; 8481 g = a[1] / _255; 8482 b = a[2] / _255; 8483 max = Math.max(r, g, b); 8484 min = Math.min(r, g, b); 8485 l = (max + min) / 2; 8486 8487 if (max === min) { 8488 h = s = 0; 8489 } else { 8490 d = max - min; 8491 s = l > 0.5 ? d / (2 - max - min) : d / (max + min); 8492 h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4; 8493 h *= 60; 8494 } 8495 8496 a[0] = ~~(h + .5); 8497 a[1] = ~~(s * 100 + .5); 8498 a[2] = ~~(l * 100 + .5); 8499 } 8500 8501 forceAlpha && a.length < 4 && (a[3] = 1); 8502 return a; 8503}, 8504 _colorOrderData = function _colorOrderData(v) { 8505 // 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() 8506 var values = [], 8507 c = [], 8508 i = -1; 8509 v.split(_colorExp).forEach(function (v) { 8510 var a = v.match(_numWithUnitExp) || []; 8511 values.push.apply(values, a); 8512 c.push(i += a.length + 1); 8513 }); 8514 values.c = c; 8515 return values; 8516}, 8517 _formatColors = function _formatColors(s, toHSL, orderMatchData) { 8518 var result = "", 8519 colors = (s + result).match(_colorExp), 8520 type = toHSL ? "hsla(" : "rgba(", 8521 i = 0, 8522 c, 8523 shell, 8524 d, 8525 l; 8526 8527 if (!colors) { 8528 return s; 8529 } 8530 8531 colors = colors.map(function (color) { 8532 return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")"; 8533 }); 8534 8535 if (orderMatchData) { 8536 d = _colorOrderData(s); 8537 c = orderMatchData.c; 8538 8539 if (c.join(result) !== d.c.join(result)) { 8540 shell = s.replace(_colorExp, "1").split(_numWithUnitExp); 8541 l = shell.length - 1; 8542 8543 for (; i < l; i++) { 8544 result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift()); 8545 } 8546 } 8547 } 8548 8549 if (!shell) { 8550 shell = s.split(_colorExp); 8551 l = shell.length - 1; 8552 8553 for (; i < l; i++) { 8554 result += shell[i] + colors[i]; 8555 } 8556 } 8557 8558 return result + shell[l]; 8559}, 8560 _colorExp = function () { 8561 var s = "(?:\\b(?:(?:rgb|rgba|hsl|hsla)\\(.+?\\))|\\B#(?:[0-9a-f]{3,4}){1,2}\\b", 8562 //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., 8563 p; 8564 8565 for (p in _colorLookup) { 8566 s += "|" + p + "\\b"; 8567 } 8568 8569 return new RegExp(s + ")", "gi"); 8570}(), 8571 _hslExp = /hsl[a]?\(/, 8572 _colorStringFilter = function _colorStringFilter(a) { 8573 var combined = a.join(" "), 8574 toHSL; 8575 _colorExp.lastIndex = 0; 8576 8577 if (_colorExp.test(combined)) { 8578 toHSL = _hslExp.test(combined); 8579 a[1] = _formatColors(a[1], toHSL); 8580 a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value. 8581 8582 return true; 8583 } 8584}, 8585 8586/* 8587 * -------------------------------------------------------------------------------------- 8588 * TICKER 8589 * -------------------------------------------------------------------------------------- 8590 */ 8591_tickerActive, 8592 _ticker = function () { 8593 var _getTime = Date.now, 8594 _lagThreshold = 500, 8595 _adjustedLag = 33, 8596 _startTime = _getTime(), 8597 _lastUpdate = _startTime, 8598 _gap = 1000 / 240, 8599 _nextTime = _gap, 8600 _listeners = [], 8601 _id, 8602 _req, 8603 _raf, 8604 _self, 8605 _delta, 8606 _i, 8607 _tick = function _tick(v) { 8608 var elapsed = _getTime() - _lastUpdate, 8609 manual = v === true, 8610 overlap, 8611 dispatch, 8612 time, 8613 frame; 8614 8615 (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag); 8616 _lastUpdate += elapsed; 8617 time = _lastUpdate - _startTime; 8618 overlap = time - _nextTime; 8619 8620 if (overlap > 0 || manual) { 8621 frame = ++_self.frame; 8622 _delta = time - _self.time * 1000; 8623 _self.time = time = time / 1000; 8624 _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap); 8625 dispatch = 1; 8626 } 8627 8628 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. 8629 8630 if (dispatch) { 8631 for (_i = 0; _i < _listeners.length; _i++) { 8632 // 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. 8633 _listeners[_i](time, _delta, frame, v); 8634 } 8635 } 8636 }; 8637 8638 _self = { 8639 time: 0, 8640 frame: 0, 8641 tick: function tick() { 8642 _tick(true); 8643 }, 8644 deltaRatio: function deltaRatio(fps) { 8645 return _delta / (1000 / (fps || 60)); 8646 }, 8647 wake: function wake() { 8648 if (_coreReady) { 8649 if (!_coreInitted && _windowExists()) { 8650 _win = _coreInitted = window; 8651 _doc = _win.document || {}; 8652 _globals.gsap = gsap; 8653 (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version); 8654 8655 _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {}); 8656 8657 _registerPluginQueue.forEach(_createPlugin); 8658 } 8659 8660 _raf = typeof requestAnimationFrame !== "undefined" && requestAnimationFrame; 8661 _id && _self.sleep(); 8662 8663 _req = _raf || function (f) { 8664 return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0); 8665 }; 8666 8667 _tickerActive = 1; 8668 8669 _tick(2); 8670 } 8671 }, 8672 sleep: function sleep() { 8673 (_raf ? cancelAnimationFrame : clearTimeout)(_id); 8674 _tickerActive = 0; 8675 _req = _emptyFunc; 8676 }, 8677 lagSmoothing: function lagSmoothing(threshold, adjustedLag) { 8678 _lagThreshold = threshold || Infinity; // zero should be interpreted as basically unlimited 8679 8680 _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold); 8681 }, 8682 fps: function fps(_fps) { 8683 _gap = 1000 / (_fps || 240); 8684 _nextTime = _self.time * 1000 + _gap; 8685 }, 8686 add: function add(callback, once, prioritize) { 8687 var func = once ? function (t, d, f, v) { 8688 callback(t, d, f, v); 8689 8690 _self.remove(func); 8691 } : callback; 8692 8693 _self.remove(callback); 8694 8695 _listeners[prioritize ? "unshift" : "push"](func); 8696 8697 _wake(); 8698 8699 return func; 8700 }, 8701 remove: function remove(callback, i) { 8702 ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--; 8703 }, 8704 _listeners: _listeners 8705 }; 8706 return _self; 8707}(), 8708 _wake = function _wake() { 8709 return !_tickerActive && _ticker.wake(); 8710}, 8711 //also ensures the core classes are initialized. 8712 8713/* 8714* ------------------------------------------------- 8715* EASING 8716* ------------------------------------------------- 8717*/ 8718_easeMap = {}, 8719 _customEaseExp = /^[\d.\-M][\d.\-,\s]/, 8720 _quotesExp = /["']/g, 8721 _parseObjectInString = function _parseObjectInString(value) { 8722 //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. 8723 var obj = {}, 8724 split = value.substr(1, value.length - 3).split(":"), 8725 key = split[0], 8726 i = 1, 8727 l = split.length, 8728 index, 8729 val, 8730 parsedVal; 8731 8732 for (; i < l; i++) { 8733 val = split[i]; 8734 index = i !== l - 1 ? val.lastIndexOf(",") : val.length; 8735 parsedVal = val.substr(0, index); 8736 obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal; 8737 key = val.substr(index + 1).trim(); 8738 } 8739 8740 return obj; 8741}, 8742 _valueInParentheses = function _valueInParentheses(value) { 8743 var open = value.indexOf("(") + 1, 8744 close = value.indexOf(")"), 8745 nested = value.indexOf("(", open); 8746 return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close); 8747}, 8748 _configEaseFromString = function _configEaseFromString(name) { 8749 //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). 8750 var split = (name + "").split("("), 8751 ease = _easeMap[split[0]]; 8752 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; 8753}, 8754 _invertEase = function _invertEase(ease) { 8755 return function (p) { 8756 return 1 - ease(1 - p); 8757 }; 8758}, 8759 // allow yoyoEase to be set in children and have those affected when the parent/ancestor timeline yoyos. 8760_propagateYoyoEase = function _propagateYoyoEase(timeline, isYoyo) { 8761 var child = timeline._first, 8762 ease; 8763 8764 while (child) { 8765 if (child instanceof Timeline) { 8766 _propagateYoyoEase(child, isYoyo); 8767 } else if (child.vars.yoyoEase && (!child._yoyo || !child._repeat) && child._yoyo !== isYoyo) { 8768 if (child.timeline) { 8769 _propagateYoyoEase(child.timeline, isYoyo); 8770 } else { 8771 ease = child._ease; 8772 child._ease = child._yEase; 8773 child._yEase = ease; 8774 child._yoyo = isYoyo; 8775 } 8776 } 8777 8778 child = child._next; 8779 } 8780}, 8781 _parseEase = function _parseEase(ease, defaultEase) { 8782 return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase; 8783}, 8784 _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) { 8785 if (easeOut === void 0) { 8786 easeOut = function easeOut(p) { 8787 return 1 - easeIn(1 - p); 8788 }; 8789 } 8790 8791 if (easeInOut === void 0) { 8792 easeInOut = function easeInOut(p) { 8793 return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2; 8794 }; 8795 } 8796 8797 var ease = { 8798 easeIn: easeIn, 8799 easeOut: easeOut, 8800 easeInOut: easeInOut 8801 }, 8802 lowercaseName; 8803 8804 _forEachName(names, function (name) { 8805 _easeMap[name] = _globals[name] = ease; 8806 _easeMap[lowercaseName = name.toLowerCase()] = easeOut; 8807 8808 for (var p in ease) { 8809 _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p]; 8810 } 8811 }); 8812 8813 return ease; 8814}, 8815 _easeInOutFromOut = function _easeInOutFromOut(easeOut) { 8816 return function (p) { 8817 return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2; 8818 }; 8819}, 8820 _configElastic = function _configElastic(type, amplitude, period) { 8821 var p1 = amplitude >= 1 ? amplitude : 1, 8822 //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. 8823 p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1), 8824 p3 = p2 / _2PI * (Math.asin(1 / p1) || 0), 8825 easeOut = function easeOut(p) { 8826 return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1; 8827 }, 8828 ease = type === "out" ? easeOut : type === "in" ? function (p) { 8829 return 1 - easeOut(1 - p); 8830 } : _easeInOutFromOut(easeOut); 8831 8832 p2 = _2PI / p2; //precalculate to optimize 8833 8834 ease.config = function (amplitude, period) { 8835 return _configElastic(type, amplitude, period); 8836 }; 8837 8838 return ease; 8839}, 8840 _configBack = function _configBack(type, overshoot) { 8841 if (overshoot === void 0) { 8842 overshoot = 1.70158; 8843 } 8844 8845 var easeOut = function easeOut(p) { 8846 return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0; 8847 }, 8848 ease = type === "out" ? easeOut : type === "in" ? function (p) { 8849 return 1 - easeOut(1 - p); 8850 } : _easeInOutFromOut(easeOut); 8851 8852 ease.config = function (overshoot) { 8853 return _configBack(type, overshoot); 8854 }; 8855 8856 return ease; 8857}; // 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. 8858// _weightedEase = ratio => { 8859// let y = 0.5 + ratio / 2; 8860// return p => (2 * (1 - p) * p * y + p * p); 8861// }, 8862// 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. 8863// _weightedEaseStrong = ratio => { 8864// ratio = .5 + ratio / 2; 8865// let o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio), 8866// b = ratio - o, 8867// c = ratio + o; 8868// return p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p; 8869// }; 8870 8871 8872_forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) { 8873 var power = i < 5 ? i + 1 : i; 8874 8875 _insertEase(name + ",Power" + (power - 1), i ? function (p) { 8876 return Math.pow(p, power); 8877 } : function (p) { 8878 return p; 8879 }, function (p) { 8880 return 1 - Math.pow(1 - p, power); 8881 }, function (p) { 8882 return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2; 8883 }); 8884}); 8885 8886_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn; 8887 8888_insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic()); 8889 8890(function (n, c) { 8891 var n1 = 1 / c, 8892 n2 = 2 * n1, 8893 n3 = 2.5 * n1, 8894 easeOut = function easeOut(p) { 8895 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; 8896 }; 8897 8898 _insertEase("Bounce", function (p) { 8899 return 1 - easeOut(1 - p); 8900 }, easeOut); 8901})(7.5625, 2.75); 8902 8903_insertEase("Expo", function (p) { 8904 return p ? Math.pow(2, 10 * (p - 1)) : 0; 8905}); 8906 8907_insertEase("Circ", function (p) { 8908 return -(_sqrt(1 - p * p) - 1); 8909}); 8910 8911_insertEase("Sine", function (p) { 8912 return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1; 8913}); 8914 8915_insertEase("Back", _configBack("in"), _configBack("out"), _configBack()); 8916 8917_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = { 8918 config: function config(steps, immediateStart) { 8919 if (steps === void 0) { 8920 steps = 1; 8921 } 8922 8923 var p1 = 1 / steps, 8924 p2 = steps + (immediateStart ? 0 : 1), 8925 p3 = immediateStart ? 1 : 0, 8926 max = 1 - _tinyNum; 8927 return function (p) { 8928 return ((p2 * _clamp(0, max, p) | 0) + p3) * p1; 8929 }; 8930 } 8931}; 8932_defaults.ease = _easeMap["quad.out"]; 8933 8934_forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) { 8935 return _callbackNames += name + "," + name + "Params,"; 8936}); 8937/* 8938 * -------------------------------------------------------------------------------------- 8939 * CACHE 8940 * -------------------------------------------------------------------------------------- 8941 */ 8942 8943 8944var GSCache = function GSCache(target, harness) { 8945 this.id = _gsID++; 8946 target._gsap = this; 8947 this.target = target; 8948 this.harness = harness; 8949 this.get = harness ? harness.get : _getProperty; 8950 this.set = harness ? harness.getSetter : _getSetter; 8951}; 8952/* 8953 * -------------------------------------------------------------------------------------- 8954 * ANIMATION 8955 * -------------------------------------------------------------------------------------- 8956 */ 8957 8958var Animation = /*#__PURE__*/function () { 8959 function Animation(vars) { 8960 this.vars = vars; 8961 this._delay = +vars.delay || 0; 8962 8963 if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) { 8964 // 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. 8965 this._rDelay = vars.repeatDelay || 0; 8966 this._yoyo = !!vars.yoyo || !!vars.yoyoEase; 8967 } 8968 8969 this._ts = 1; 8970 8971 _setDuration(this, +vars.duration, 1, 1); 8972 8973 this.data = vars.data; 8974 8975 if (_context) { 8976 this._ctx = _context; 8977 8978 _context.data.push(this); 8979 } 8980 8981 _tickerActive || _ticker.wake(); 8982 } 8983 8984 var _proto = Animation.prototype; 8985 8986 _proto.delay = function delay(value) { 8987 if (value || value === 0) { 8988 this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay); 8989 this._delay = value; 8990 return this; 8991 } 8992 8993 return this._delay; 8994 }; 8995 8996 _proto.duration = function duration(value) { 8997 return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur; 8998 }; 8999 9000 _proto.totalDuration = function totalDuration(value) { 9001 if (!arguments.length) { 9002 return this._tDur; 9003 } 9004 9005 this._dirty = 0; 9006 return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1)); 9007 }; 9008 9009 _proto.totalTime = function totalTime(_totalTime, suppressEvents) { 9010 _wake(); 9011 9012 if (!arguments.length) { 9013 return this._tTime; 9014 } 9015 9016 var parent = this._dp; 9017 9018 if (parent && parent.smoothChildTiming && this._ts) { 9019 _alignPlayhead(this, _totalTime); 9020 9021 !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. 9022 //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. 9023 9024 while (parent && parent.parent) { 9025 if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) { 9026 parent.totalTime(parent._tTime, true); 9027 } 9028 9029 parent = parent.parent; 9030 } 9031 9032 if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) { 9033 //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. 9034 _addToTimeline(this._dp, this, this._start - this._delay); 9035 } 9036 } 9037 9038 if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !_totalTime && !this._initted && (this.add || this._ptLookup)) { 9039 // 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) 9040 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 9041 //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it's worth the performance hit) 9042 // this._lock = 1; 9043 9044 _lazySafeRender(this, _totalTime, suppressEvents); // this._lock = 0; 9045 //} 9046 9047 } 9048 9049 return this; 9050 }; 9051 9052 _proto.time = function time(value, suppressEvents) { 9053 return arguments.length ? this.totalTime(Math.min(this.totalDuration(), value + _elapsedCycleDuration(this)) % (this._dur + this._rDelay) || (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! 9054 }; 9055 9056 _proto.totalProgress = function totalProgress(value, suppressEvents) { 9057 return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() > 0 ? 1 : 0; 9058 }; 9059 9060 _proto.progress = function progress(value, suppressEvents) { 9061 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.rawTime() > 0 ? 1 : 0; 9062 }; 9063 9064 _proto.iteration = function iteration(value, suppressEvents) { 9065 var cycleDuration = this.duration() + this._rDelay; 9066 9067 return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1; 9068 } // potential future addition: 9069 // isPlayingBackwards() { 9070 // let animation = this, 9071 // orientation = 1; // 1 = forward, -1 = backward 9072 // while (animation) { 9073 // orientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1; 9074 // animation = animation.parent; 9075 // } 9076 // return orientation < 0; 9077 // } 9078 ; 9079 9080 _proto.timeScale = function timeScale(value, suppressEvents) { 9081 if (!arguments.length) { 9082 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. 9083 } 9084 9085 if (this._rts === value) { 9086 return this; 9087 } 9088 9089 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. 9090 // future addition? Up side: fast and minimal file size. Down side: only works on this animation; if a timeline is reversed, for example, its childrens' onReverse wouldn't get called. 9091 //(+value < 0 && this._rts >= 0) && _callback(this, "onReverse", true); 9092 // 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. 9093 9094 this._rts = +value || 0; 9095 this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused. 9096 9097 this.totalTime(_clamp(-Math.abs(this._delay), this._tDur, tTime), suppressEvents !== false); 9098 9099 _setEnd(this); // if parent.smoothChildTiming was false, the end time didn't get updated in the _alignPlayhead() method, so do it here. 9100 9101 9102 return _recacheAncestors(this); 9103 }; 9104 9105 _proto.paused = function paused(value) { 9106 if (!arguments.length) { 9107 return this._ps; 9108 } 9109 9110 if (this._ps !== value) { 9111 this._ps = value; 9112 9113 if (value) { 9114 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. 9115 9116 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) 9117 } else { 9118 _wake(); 9119 9120 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. 9121 9122 this.totalTime(this.parent && !this.parent.smoothChildTiming ? this.rawTime() : this._tTime || this._pTime, this.progress() === 1 && Math.abs(this._zTime) !== _tinyNum && (this._tTime -= _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. 9123 } 9124 } 9125 9126 return this; 9127 }; 9128 9129 _proto.startTime = function startTime(value) { 9130 if (arguments.length) { 9131 this._start = value; 9132 var parent = this.parent || this._dp; 9133 parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, value - this._delay); 9134 return this; 9135 } 9136 9137 return this._start; 9138 }; 9139 9140 _proto.endTime = function endTime(includeRepeats) { 9141 return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1); 9142 }; 9143 9144 _proto.rawTime = function rawTime(wrapRepeats) { 9145 var parent = this.parent || this._dp; // _dp = detached parent 9146 9147 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); 9148 }; 9149 9150 _proto.revert = function revert(config) { 9151 if (config === void 0) { 9152 config = _revertConfig; 9153 } 9154 9155 var prevIsReverting = _reverting; 9156 _reverting = config; 9157 9158 if (this._initted || this._startAt) { 9159 this.timeline && this.timeline.revert(config); 9160 this.totalTime(-0.01, config.suppressEvents); 9161 } 9162 9163 this.data !== "nested" && config.kill !== false && this.kill(); 9164 _reverting = prevIsReverting; 9165 return this; 9166 }; 9167 9168 _proto.globalTime = function globalTime(rawTime) { 9169 var animation = this, 9170 time = arguments.length ? rawTime : animation.rawTime(); 9171 9172 while (animation) { 9173 time = animation._start + time / (Math.abs(animation._ts) || 1); 9174 animation = animation._dp; 9175 } 9176 9177 return !this.parent && this._sat ? this._sat.globalTime(rawTime) : time; // the _startAt tweens for .fromTo() and .from() that have immediateRender should always be FIRST in the timeline (important for context.revert()). "_sat" stands for _startAtTween, referring to the parent tween that created the _startAt. We must discern if that tween had immediateRender so that we can know whether or not to prioritize it in revert(). 9178 }; 9179 9180 _proto.repeat = function repeat(value) { 9181 if (arguments.length) { 9182 this._repeat = value === Infinity ? -2 : value; 9183 return _onUpdateTotalDuration(this); 9184 } 9185 9186 return this._repeat === -2 ? Infinity : this._repeat; 9187 }; 9188 9189 _proto.repeatDelay = function repeatDelay(value) { 9190 if (arguments.length) { 9191 var time = this._time; 9192 this._rDelay = value; 9193 9194 _onUpdateTotalDuration(this); 9195 9196 return time ? this.time(time) : this; 9197 } 9198 9199 return this._rDelay; 9200 }; 9201 9202 _proto.yoyo = function yoyo(value) { 9203 if (arguments.length) { 9204 this._yoyo = value; 9205 return this; 9206 } 9207 9208 return this._yoyo; 9209 }; 9210 9211 _proto.seek = function seek(position, suppressEvents) { 9212 return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents)); 9213 }; 9214 9215 _proto.restart = function restart(includeDelay, suppressEvents) { 9216 return this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents)); 9217 }; 9218 9219 _proto.play = function play(from, suppressEvents) { 9220 from != null && this.seek(from, suppressEvents); 9221 return this.reversed(false).paused(false); 9222 }; 9223 9224 _proto.reverse = function reverse(from, suppressEvents) { 9225 from != null && this.seek(from || this.totalDuration(), suppressEvents); 9226 return this.reversed(true).paused(false); 9227 }; 9228 9229 _proto.pause = function pause(atTime, suppressEvents) { 9230 atTime != null && this.seek(atTime, suppressEvents); 9231 return this.paused(true); 9232 }; 9233 9234 _proto.resume = function resume() { 9235 return this.paused(false); 9236 }; 9237 9238 _proto.reversed = function reversed(value) { 9239 if (arguments.length) { 9240 !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum. 9241 9242 return this; 9243 } 9244 9245 return this._rts < 0; 9246 }; 9247 9248 _proto.invalidate = function invalidate() { 9249 this._initted = this._act = 0; 9250 this._zTime = -_tinyNum; 9251 return this; 9252 }; 9253 9254 _proto.isActive = function isActive() { 9255 var parent = this.parent || this._dp, 9256 start = this._start, 9257 rawTime; 9258 return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum); 9259 }; 9260 9261 _proto.eventCallback = function eventCallback(type, callback, params) { 9262 var vars = this.vars; 9263 9264 if (arguments.length > 1) { 9265 if (!callback) { 9266 delete vars[type]; 9267 } else { 9268 vars[type] = callback; 9269 params && (vars[type + "Params"] = params); 9270 type === "onUpdate" && (this._onUpdate = callback); 9271 } 9272 9273 return this; 9274 } 9275 9276 return vars[type]; 9277 }; 9278 9279 _proto.then = function then(onFulfilled) { 9280 var self = this; 9281 return new Promise(function (resolve) { 9282 var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough, 9283 _resolve = function _resolve() { 9284 var _then = self.then; 9285 self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322) 9286 9287 _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then); 9288 resolve(f); 9289 self.then = _then; 9290 }; 9291 9292 if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) { 9293 _resolve(); 9294 } else { 9295 self._prom = _resolve; 9296 } 9297 }); 9298 }; 9299 9300 _proto.kill = function kill() { 9301 _interrupt(this); 9302 }; 9303 9304 return Animation; 9305}(); 9306 9307_setDefaults(Animation.prototype, { 9308 _time: 0, 9309 _start: 0, 9310 _end: 0, 9311 _tTime: 0, 9312 _tDur: 0, 9313 _dirty: 0, 9314 _repeat: 0, 9315 _yoyo: false, 9316 parent: null, 9317 _initted: false, 9318 _rDelay: 0, 9319 _ts: 1, 9320 _dp: 0, 9321 ratio: 0, 9322 _zTime: -_tinyNum, 9323 _prom: 0, 9324 _ps: false, 9325 _rts: 1 9326}); 9327/* 9328 * ------------------------------------------------- 9329 * TIMELINE 9330 * ------------------------------------------------- 9331 */ 9332 9333 9334var Timeline = /*#__PURE__*/function (_Animation) { 9335 _inheritsLoose(Timeline, _Animation); 9336 9337 function Timeline(vars, position) { 9338 var _this; 9339 9340 if (vars === void 0) { 9341 vars = {}; 9342 } 9343 9344 _this = _Animation.call(this, vars) || this; 9345 _this.labels = {}; 9346 _this.smoothChildTiming = !!vars.smoothChildTiming; 9347 _this.autoRemoveChildren = !!vars.autoRemoveChildren; 9348 _this._sort = _isNotFalse(vars.sortChildren); 9349 _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position); 9350 vars.reversed && _this.reverse(); 9351 vars.paused && _this.paused(true); 9352 vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger); 9353 return _this; 9354 } 9355 9356 var _proto2 = Timeline.prototype; 9357 9358 _proto2.to = function to(targets, vars, position) { 9359 _createTweenType(0, arguments, this); 9360 9361 return this; 9362 }; 9363 9364 _proto2.from = function from(targets, vars, position) { 9365 _createTweenType(1, arguments, this); 9366 9367 return this; 9368 }; 9369 9370 _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) { 9371 _createTweenType(2, arguments, this); 9372 9373 return this; 9374 }; 9375 9376 _proto2.set = function set(targets, vars, position) { 9377 vars.duration = 0; 9378 vars.parent = this; 9379 _inheritDefaults(vars).repeatDelay || (vars.repeat = 0); 9380 vars.immediateRender = !!vars.immediateRender; 9381 new Tween(targets, vars, _parsePosition(this, position), 1); 9382 return this; 9383 }; 9384 9385 _proto2.call = function call(callback, params, position) { 9386 return _addToTimeline(this, Tween.delayedCall(0, callback, params), position); 9387 } //ONLY for backward compatibility! Maybe delete? 9388 ; 9389 9390 _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 9391 vars.duration = duration; 9392 vars.stagger = vars.stagger || stagger; 9393 vars.onComplete = onCompleteAll; 9394 vars.onCompleteParams = onCompleteAllParams; 9395 vars.parent = this; 9396 new Tween(targets, vars, _parsePosition(this, position)); 9397 return this; 9398 }; 9399 9400 _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) { 9401 vars.runBackwards = 1; 9402 _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender); 9403 return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams); 9404 }; 9405 9406 _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) { 9407 toVars.startAt = fromVars; 9408 _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender); 9409 return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams); 9410 }; 9411 9412 _proto2.render = function render(totalTime, suppressEvents, force) { 9413 var prevTime = this._time, 9414 tDur = this._dirty ? this.totalDuration() : this._tDur, 9415 dur = this._dur, 9416 tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime), 9417 // if a paused timeline is resumed (or its _start is updated for another reason...which rounds it), that could result in the playhead shifting a **tiny** amount and a zero-duration child at that spot may get rendered at a different ratio, like its totalTime in render() may be 1e-17 instead of 0, for example. 9418 crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur), 9419 time, 9420 child, 9421 next, 9422 iteration, 9423 cycleDuration, 9424 prevPaused, 9425 pauseTween, 9426 timeScale, 9427 prevStart, 9428 prevIteration, 9429 yoyo, 9430 isYoyo; 9431 this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur); 9432 9433 if (tTime !== this._tTime || force || crossingStart) { 9434 if (prevTime !== this._time && dur) { 9435 //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). 9436 tTime += this._time - prevTime; 9437 totalTime += this._time - prevTime; 9438 } 9439 9440 time = tTime; 9441 prevStart = this._start; 9442 timeScale = this._ts; 9443 prevPaused = !timeScale; 9444 9445 if (crossingStart) { 9446 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. 9447 9448 (totalTime || !suppressEvents) && (this._zTime = totalTime); 9449 } 9450 9451 if (this._repeat) { 9452 //adjust the time for repeats and yoyos 9453 yoyo = this._yoyo; 9454 cycleDuration = dur + this._rDelay; 9455 9456 if (this._repeat < -1 && totalTime < 0) { 9457 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 9458 } 9459 9460 time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 9461 9462 if (tTime === tDur) { 9463 // 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) 9464 iteration = this._repeat; 9465 time = dur; 9466 } else { 9467 iteration = ~~(tTime / cycleDuration); 9468 9469 if (iteration && iteration === tTime / cycleDuration) { 9470 time = dur; 9471 iteration--; 9472 } 9473 9474 time > dur && (time = dur); 9475 } 9476 9477 prevIteration = _animationCycle(this._tTime, cycleDuration); 9478 !prevTime && this._tTime && prevIteration !== iteration && this._tTime - prevIteration * cycleDuration - this._dur <= 0 && (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://gsap.com/forums/topic/23823-closing-nav-animation-not-working-on-ie-and-iphone-6-maybe-other-older-browser/?tab=comments#comment-113005 also, this._tTime - prevIteration * cycleDuration - this._dur <= 0 just checks to make sure it wasn't previously in the "repeatDelay" portion 9479 9480 if (yoyo && iteration & 1) { 9481 time = dur - time; 9482 isYoyo = 1; 9483 } 9484 /* 9485 make sure children at the end/beginning of the timeline are rendered properly. If, for example, 9486 a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which 9487 would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there 9488 could be a callback or a short tween that's at 2.95 or 3 seconds in which wouldn't render. So 9489 we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must 9490 ensure that zero-duration tweens at the very beginning or end of the Timeline work. 9491 */ 9492 9493 9494 if (iteration !== prevIteration && !this._lock) { 9495 var rewinding = yoyo && prevIteration & 1, 9496 doesWrap = rewinding === (yoyo && iteration & 1); 9497 iteration < prevIteration && (rewinding = !rewinding); 9498 prevTime = rewinding ? 0 : tTime % dur ? dur : tTime; // if the playhead is landing exactly at the end of an iteration, use that totalTime rather than only the duration, otherwise it'll skip the 2nd render since it's effectively at the same time. 9499 9500 this._lock = 1; 9501 this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0; 9502 this._tTime = tTime; // if a user gets the iteration() inside the onRepeat, for example, it should be accurate. 9503 9504 !suppressEvents && this.parent && _callback(this, "onRepeat"); 9505 this.vars.repeatRefresh && !isYoyo && (this.invalidate()._lock = 1); 9506 9507 if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) { 9508 // if prevTime is 0 and we render at the very end, _time will be the end, thus won't match. So in this edge case, prevTime won't match _time but that's okay. If it gets killed in the onRepeat, eject as well. 9509 return this; 9510 } 9511 9512 dur = this._dur; // in case the duration changed in the onRepeat 9513 9514 tDur = this._tDur; 9515 9516 if (doesWrap) { 9517 this._lock = 2; 9518 prevTime = rewinding ? dur : -0.0001; 9519 this.render(prevTime, true); 9520 this.vars.repeatRefresh && !isYoyo && this.invalidate(); 9521 } 9522 9523 this._lock = 0; 9524 9525 if (!this._ts && !prevPaused) { 9526 return this; 9527 } //in order for yoyoEase to work properly when there's a stagger, we must swap out the ease in each sub-tween. 9528 9529 9530 _propagateYoyoEase(this, isYoyo); 9531 } 9532 } 9533 9534 if (this._hasPause && !this._forcing && this._lock < 2) { 9535 pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time)); 9536 9537 if (pauseTween) { 9538 tTime -= time - (time = pauseTween._start); 9539 } 9540 } 9541 9542 this._tTime = tTime; 9543 this._time = time; 9544 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. 9545 9546 if (!this._initted) { 9547 this._onUpdate = this.vars.onUpdate; 9548 this._initted = 1; 9549 this._zTime = totalTime; 9550 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}). 9551 } 9552 9553 if (!prevTime && time && !suppressEvents && !iteration) { 9554 _callback(this, "onStart"); 9555 9556 if (this._tTime !== tTime) { 9557 // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart. 9558 return this; 9559 } 9560 } 9561 9562 if (time >= prevTime && totalTime >= 0) { 9563 child = this._first; 9564 9565 while (child) { 9566 next = child._next; 9567 9568 if ((child._act || time >= child._start) && child._ts && pauseTween !== child) { 9569 if (child.parent !== this) { 9570 // 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. 9571 return this.render(totalTime, suppressEvents, force); 9572 } 9573 9574 child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force); 9575 9576 if (time !== this._time || !this._ts && !prevPaused) { 9577 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 9578 pauseTween = 0; 9579 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) 9580 9581 break; 9582 } 9583 } 9584 9585 child = next; 9586 } 9587 } else { 9588 child = this._last; 9589 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. 9590 9591 while (child) { 9592 next = child._prev; 9593 9594 if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) { 9595 if (child.parent !== this) { 9596 // 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. 9597 return this.render(totalTime, suppressEvents, force); 9598 } 9599 9600 child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && (child._initted || child._startAt)); // if reverting, we should always force renders of initted tweens (but remember that .fromTo() or .from() may have a _startAt but not _initted yet). If, for example, a .fromTo() tween with a stagger (which creates an internal timeline) gets reverted BEFORE some of its child tweens render for the first time, it may not properly trigger them to revert. 9601 9602 if (time !== this._time || !this._ts && !prevPaused) { 9603 //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete 9604 pauseTween = 0; 9605 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) 9606 9607 break; 9608 } 9609 } 9610 9611 child = next; 9612 } 9613 } 9614 9615 if (pauseTween && !suppressEvents) { 9616 this.pause(); 9617 pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1; 9618 9619 if (this._ts) { 9620 //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). 9621 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. 9622 9623 _setEnd(this); 9624 9625 return this.render(totalTime, suppressEvents, force); 9626 } 9627 } 9628 9629 this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true); 9630 if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) { 9631 // remember, a child's callback may alter this timeline's playhead or timeScale which is why we need to add some of these checks. 9632 (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. 9633 9634 if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) { 9635 _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true); 9636 9637 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 9638 } 9639 } 9640 } 9641 9642 return this; 9643 }; 9644 9645 _proto2.add = function add(child, position) { 9646 var _this2 = this; 9647 9648 _isNumber(position) || (position = _parsePosition(this, position, child)); 9649 9650 if (!(child instanceof Animation)) { 9651 if (_isArray(child)) { 9652 child.forEach(function (obj) { 9653 return _this2.add(obj, position); 9654 }); 9655 return this; 9656 } 9657 9658 if (_isString(child)) { 9659 return this.addLabel(child, position); 9660 } 9661 9662 if (_isFunction(child)) { 9663 child = Tween.delayedCall(0, child); 9664 } else { 9665 return this; 9666 } 9667 } 9668 9669 return this !== child ? _addToTimeline(this, child, position) : this; //don't allow a timeline to be added to itself as a child! 9670 }; 9671 9672 _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) { 9673 if (nested === void 0) { 9674 nested = true; 9675 } 9676 9677 if (tweens === void 0) { 9678 tweens = true; 9679 } 9680 9681 if (timelines === void 0) { 9682 timelines = true; 9683 } 9684 9685 if (ignoreBeforeTime === void 0) { 9686 ignoreBeforeTime = -_bigNum; 9687 } 9688 9689 var a = [], 9690 child = this._first; 9691 9692 while (child) { 9693 if (child._start >= ignoreBeforeTime) { 9694 if (child instanceof Tween) { 9695 tweens && a.push(child); 9696 } else { 9697 timelines && a.push(child); 9698 nested && a.push.apply(a, child.getChildren(true, tweens, timelines)); 9699 } 9700 } 9701 9702 child = child._next; 9703 } 9704 9705 return a; 9706 }; 9707 9708 _proto2.getById = function getById(id) { 9709 var animations = this.getChildren(1, 1, 1), 9710 i = animations.length; 9711 9712 while (i--) { 9713 if (animations[i].vars.id === id) { 9714 return animations[i]; 9715 } 9716 } 9717 }; 9718 9719 _proto2.remove = function remove(child) { 9720 if (_isString(child)) { 9721 return this.removeLabel(child); 9722 } 9723 9724 if (_isFunction(child)) { 9725 return this.killTweensOf(child); 9726 } 9727 9728 _removeLinkedListItem(this, child); 9729 9730 if (child === this._recent) { 9731 this._recent = this._last; 9732 } 9733 9734 return _uncache(this); 9735 }; 9736 9737 _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) { 9738 if (!arguments.length) { 9739 return this._tTime; 9740 } 9741 9742 this._forcing = 1; 9743 9744 if (!this._dp && this._ts) { 9745 //special case for the global timeline (or any other that has no parent or detached parent). 9746 this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts)); 9747 } 9748 9749 _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents); 9750 9751 this._forcing = 0; 9752 return this; 9753 }; 9754 9755 _proto2.addLabel = function addLabel(label, position) { 9756 this.labels[label] = _parsePosition(this, position); 9757 return this; 9758 }; 9759 9760 _proto2.removeLabel = function removeLabel(label) { 9761 delete this.labels[label]; 9762 return this; 9763 }; 9764 9765 _proto2.addPause = function addPause(position, callback, params) { 9766 var t = Tween.delayedCall(0, callback || _emptyFunc, params); 9767 t.data = "isPause"; 9768 this._hasPause = 1; 9769 return _addToTimeline(this, t, _parsePosition(this, position)); 9770 }; 9771 9772 _proto2.removePause = function removePause(position) { 9773 var child = this._first; 9774 position = _parsePosition(this, position); 9775 9776 while (child) { 9777 if (child._start === position && child.data === "isPause") { 9778 _removeFromParent(child); 9779 } 9780 9781 child = child._next; 9782 } 9783 }; 9784 9785 _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) { 9786 var tweens = this.getTweensOf(targets, onlyActive), 9787 i = tweens.length; 9788 9789 while (i--) { 9790 _overwritingTween !== tweens[i] && tweens[i].kill(targets, props); 9791 } 9792 9793 return this; 9794 }; 9795 9796 _proto2.getTweensOf = function getTweensOf(targets, onlyActive) { 9797 var a = [], 9798 parsedTargets = toArray(targets), 9799 child = this._first, 9800 isGlobalTime = _isNumber(onlyActive), 9801 // a number is interpreted as a global time. If the animation spans 9802 children; 9803 9804 while (child) { 9805 if (child instanceof Tween) { 9806 if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) { 9807 // note: if this is for overwriting, it should only be for tweens that aren't paused and are initted. 9808 a.push(child); 9809 } 9810 } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) { 9811 a.push.apply(a, children); 9812 } 9813 9814 child = child._next; 9815 } 9816 9817 return a; 9818 } // potential future feature - targets() on timelines 9819 // targets() { 9820 // let result = []; 9821 // this.getChildren(true, true, false).forEach(t => result.push(...t.targets())); 9822 // return result.filter((v, i) => result.indexOf(v) === i); 9823 // } 9824 ; 9825 9826 _proto2.tweenTo = function tweenTo(position, vars) { 9827 vars = vars || {}; 9828 9829 var tl = this, 9830 endTime = _parsePosition(tl, position), 9831 _vars = vars, 9832 startAt = _vars.startAt, 9833 _onStart = _vars.onStart, 9834 onStartParams = _vars.onStartParams, 9835 immediateRender = _vars.immediateRender, 9836 initted, 9837 tween = Tween.to(tl, _setDefaults({ 9838 ease: vars.ease || "none", 9839 lazy: false, 9840 immediateRender: false, 9841 time: endTime, 9842 overwrite: "auto", 9843 duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum, 9844 onStart: function onStart() { 9845 tl.pause(); 9846 9847 if (!initted) { 9848 var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()); 9849 tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true); 9850 initted = 1; 9851 } 9852 9853 _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don't want to overwrite it. 9854 } 9855 }, vars)); 9856 9857 return immediateRender ? tween.render(0) : tween; 9858 }; 9859 9860 _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) { 9861 return this.tweenTo(toPosition, _setDefaults({ 9862 startAt: { 9863 time: _parsePosition(this, fromPosition) 9864 } 9865 }, vars)); 9866 }; 9867 9868 _proto2.recent = function recent() { 9869 return this._recent; 9870 }; 9871 9872 _proto2.nextLabel = function nextLabel(afterTime) { 9873 if (afterTime === void 0) { 9874 afterTime = this._time; 9875 } 9876 9877 return _getLabelInDirection(this, _parsePosition(this, afterTime)); 9878 }; 9879 9880 _proto2.previousLabel = function previousLabel(beforeTime) { 9881 if (beforeTime === void 0) { 9882 beforeTime = this._time; 9883 } 9884 9885 return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1); 9886 }; 9887 9888 _proto2.currentLabel = function currentLabel(value) { 9889 return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum); 9890 }; 9891 9892 _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) { 9893 if (ignoreBeforeTime === void 0) { 9894 ignoreBeforeTime = 0; 9895 } 9896 9897 var child = this._first, 9898 labels = this.labels, 9899 p; 9900 9901 while (child) { 9902 if (child._start >= ignoreBeforeTime) { 9903 child._start += amount; 9904 child._end += amount; 9905 } 9906 9907 child = child._next; 9908 } 9909 9910 if (adjustLabels) { 9911 for (p in labels) { 9912 if (labels[p] >= ignoreBeforeTime) { 9913 labels[p] += amount; 9914 } 9915 } 9916 } 9917 9918 return _uncache(this); 9919 }; 9920 9921 _proto2.invalidate = function invalidate(soft) { 9922 var child = this._first; 9923 this._lock = 0; 9924 9925 while (child) { 9926 child.invalidate(soft); 9927 child = child._next; 9928 } 9929 9930 return _Animation.prototype.invalidate.call(this, soft); 9931 }; 9932 9933 _proto2.clear = function clear(includeLabels) { 9934 if (includeLabels === void 0) { 9935 includeLabels = true; 9936 } 9937 9938 var child = this._first, 9939 next; 9940 9941 while (child) { 9942 next = child._next; 9943 this.remove(child); 9944 child = next; 9945 } 9946 9947 this._dp && (this._time = this._tTime = this._pTime = 0); 9948 includeLabels && (this.labels = {}); 9949 return _uncache(this); 9950 }; 9951 9952 _proto2.totalDuration = function totalDuration(value) { 9953 var max = 0, 9954 self = this, 9955 child = self._last, 9956 prevStart = _bigNum, 9957 prev, 9958 start, 9959 parent; 9960 9961 if (arguments.length) { 9962 return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value)); 9963 } 9964 9965 if (self._dirty) { 9966 parent = self.parent; 9967 9968 while (child) { 9969 prev = child._prev; //record it here in case the tween changes position in the sequence... 9970 9971 child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation's cache is clean before analyzing it. 9972 9973 start = child._start; 9974 9975 if (start > prevStart && self._sort && child._ts && !self._lock) { 9976 //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence 9977 self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add(). 9978 9979 _addToTimeline(self, child, start - child._delay, 1)._lock = 0; 9980 } else { 9981 prevStart = start; 9982 } 9983 9984 if (start < 0 && child._ts) { 9985 //children aren't allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found. 9986 max -= start; 9987 9988 if (!parent && !self._dp || parent && parent.smoothChildTiming) { 9989 self._start += start / self._ts; 9990 self._time -= start; 9991 self._tTime -= start; 9992 } 9993 9994 self.shiftChildren(-start, false, -1e999); 9995 prevStart = 0; 9996 } 9997 9998 child._end > max && child._ts && (max = child._end); 9999 child = prev; 10000 } 10001 10002 _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1); 10003 10004 self._dirty = 0; 10005 } 10006 10007 return self._tDur; 10008 }; 10009 10010 Timeline.updateRoot = function updateRoot(time) { 10011 if (_globalTimeline._ts) { 10012 _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline)); 10013 10014 _lastRenderedFrame = _ticker.frame; 10015 } 10016 10017 if (_ticker.frame >= _nextGCFrame) { 10018 _nextGCFrame += _config.autoSleep || 120; 10019 var child = _globalTimeline._first; 10020 if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) { 10021 while (child && !child._ts) { 10022 child = child._next; 10023 } 10024 10025 child || _ticker.sleep(); 10026 } 10027 } 10028 }; 10029 10030 return Timeline; 10031}(Animation); 10032 10033_setDefaults(Timeline.prototype, { 10034 _lock: 0, 10035 _hasPause: 0, 10036 _forcing: 0 10037}); 10038 10039var _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) { 10040 //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. 10041 var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter), 10042 index = 0, 10043 matchIndex = 0, 10044 result, 10045 startNums, 10046 color, 10047 endNum, 10048 chunk, 10049 startNum, 10050 hasRandom, 10051 a; 10052 pt.b = start; 10053 pt.e = end; 10054 start += ""; //ensure values are strings 10055 10056 end += ""; 10057 10058 if (hasRandom = ~end.indexOf("random(")) { 10059 end = _replaceRandom(end); 10060 } 10061 10062 if (stringFilter) { 10063 a = [start, end]; 10064 stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values. 10065 10066 start = a[0]; 10067 end = a[1]; 10068 } 10069 10070 startNums = start.match(_complexStringNumExp) || []; 10071 10072 while (result = _complexStringNumExp.exec(end)) { 10073 endNum = result[0]; 10074 chunk = end.substring(index, result.index); 10075 10076 if (color) { 10077 color = (color + 1) % 5; 10078 } else if (chunk.substr(-5) === "rgba(") { 10079 color = 1; 10080 } 10081 10082 if (endNum !== startNums[matchIndex++]) { 10083 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. 10084 10085 pt._pt = { 10086 _next: pt._pt, 10087 p: chunk || matchIndex === 1 ? chunk : ",", 10088 //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. 10089 s: startNum, 10090 c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum, 10091 m: color && color < 4 ? Math.round : 0 10092 }; 10093 index = _complexStringNumExp.lastIndex; 10094 } 10095 } 10096 10097 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) 10098 10099 pt.fp = funcParam; 10100 10101 if (_relExp.test(end) || hasRandom) { 10102 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). 10103 } 10104 10105 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. 10106 10107 return pt; 10108}, 10109 _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) { 10110 _isFunction(end) && (end = end(index || 0, target, targets)); 10111 var currentValue = target[prop], 10112 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](), 10113 setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc, 10114 pt; 10115 10116 if (_isString(end)) { 10117 if (~end.indexOf("random(")) { 10118 end = _replaceRandom(end); 10119 } 10120 10121 if (end.charAt(1) === "=") { 10122 pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0); 10123 10124 if (pt || pt === 0) { 10125 // to avoid isNaN, like if someone passes in a value like "!= whatever" 10126 end = pt; 10127 } 10128 } 10129 } 10130 10131 if (!optional || parsedStart !== end || _forceAllPropTweens) { 10132 if (!isNaN(parsedStart * end) && end !== "") { 10133 // fun fact: any number multiplied by "" is evaluated as the number 0! 10134 pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter); 10135 funcParam && (pt.fp = funcParam); 10136 modifier && pt.modifier(modifier, this, target); 10137 return this._pt = pt; 10138 } 10139 10140 !currentValue && !(prop in target) && _missingPlugin(prop, end); 10141 return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam); 10142 } 10143}, 10144 //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. 10145_processVars = function _processVars(vars, index, target, targets, tween) { 10146 _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets)); 10147 10148 if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) { 10149 return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars; 10150 } 10151 10152 var copy = {}, 10153 p; 10154 10155 for (p in vars) { 10156 copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets); 10157 } 10158 10159 return copy; 10160}, 10161 _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) { 10162 var plugin, pt, ptLookup, i; 10163 10164 if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) { 10165 tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority); 10166 10167 if (tween !== _quickTween) { 10168 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. 10169 10170 i = plugin._props.length; 10171 10172 while (i--) { 10173 ptLookup[plugin._props[i]] = pt; 10174 } 10175 } 10176 } 10177 10178 return plugin; 10179}, 10180 _overwritingTween, 10181 //store a reference temporarily so we can avoid overwriting itself. 10182_forceAllPropTweens, 10183 _initTween = function _initTween(tween, time, tTime) { 10184 var vars = tween.vars, 10185 ease = vars.ease, 10186 startAt = vars.startAt, 10187 immediateRender = vars.immediateRender, 10188 lazy = vars.lazy, 10189 onUpdate = vars.onUpdate, 10190 runBackwards = vars.runBackwards, 10191 yoyoEase = vars.yoyoEase, 10192 keyframes = vars.keyframes, 10193 autoRevert = vars.autoRevert, 10194 dur = tween._dur, 10195 prevStartAt = tween._startAt, 10196 targets = tween._targets, 10197 parent = tween.parent, 10198 fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets, 10199 autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites, 10200 tl = tween.timeline, 10201 cleanVars, 10202 i, 10203 p, 10204 pt, 10205 target, 10206 hasPriority, 10207 gsData, 10208 harness, 10209 plugin, 10210 ptLookup, 10211 index, 10212 harnessVars, 10213 overwritten; 10214 tl && (!keyframes || !ease) && (ease = "none"); 10215 tween._ease = _parseEase(ease, _defaults.ease); 10216 tween._yEase = yoyoEase ? _invertEase(_parseEase(yoyoEase === true ? ease : yoyoEase, _defaults.ease)) : 0; 10217 10218 if (yoyoEase && tween._yoyo && !tween._repeat) { 10219 //there must have been a parent timeline with yoyo:true that is currently in its yoyo phase, so flip the eases. 10220 yoyoEase = tween._yEase; 10221 tween._yEase = tween._ease; 10222 tween._ease = yoyoEase; 10223 } 10224 10225 tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens. 10226 10227 if (!tl || keyframes && !vars.stagger) { 10228 //if there's an internal timeline, skip all the parsing because we passed that task down the chain. 10229 harness = targets[0] ? _getCache(targets[0]).harness : 0; 10230 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. 10231 10232 cleanVars = _copyExcluding(vars, _reservedProps); 10233 10234 if (prevStartAt) { 10235 prevStartAt._zTime < 0 && prevStartAt.progress(1); // in case it's a lazy startAt that hasn't rendered yet. 10236 10237 time < 0 && runBackwards && immediateRender && !autoRevert ? prevStartAt.render(-1, true) : prevStartAt.revert(runBackwards && dur ? _revertConfigNoKill : _startAtRevertConfig); // if it's a "startAt" (not "from()" or runBackwards: true), we only need to do a shallow revert (keep transforms cached in CSSPlugin) 10238 // don't just _removeFromParent(prevStartAt.render(-1, true)) because that'll leave inline styles. We're creating a new _startAt for "startAt" tweens that re-capture things to ensure that if the pre-tween values changed since the tween was created, they're recorded. 10239 10240 prevStartAt._lazy = 0; 10241 } 10242 10243 if (startAt) { 10244 _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({ 10245 data: "isStart", 10246 overwrite: false, 10247 parent: parent, 10248 immediateRender: true, 10249 lazy: !prevStartAt && _isNotFalse(lazy), 10250 startAt: null, 10251 delay: 0, 10252 onUpdate: onUpdate && function () { 10253 return _callback(tween, "onUpdate"); 10254 }, 10255 stagger: 0 10256 }, 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); 10257 10258 10259 tween._startAt._dp = 0; // don't allow it to get put back into root timeline! Like when revert() is called and totalTime() gets set. 10260 10261 tween._startAt._sat = tween; // used in globalTime(). _sat stands for _startAtTween 10262 10263 time < 0 && (_reverting || !immediateRender && !autoRevert) && tween._startAt.revert(_revertConfigNoKill); // rare edge case, like if a render is forced in the negative direction of a non-initted tween. 10264 10265 if (immediateRender) { 10266 if (dur && time <= 0 && tTime <= 0) { 10267 // check tTime here because in the case of a yoyo tween whose playhead gets pushed to the end like tween.progress(1), we should allow it through so that the onComplete gets fired properly. 10268 time && (tween._zTime = time); 10269 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. 10270 } 10271 } 10272 } else if (runBackwards && dur) { 10273 //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) 10274 if (!prevStartAt) { 10275 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 10276 10277 p = _setDefaults({ 10278 overwrite: false, 10279 data: "isFromStart", 10280 //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. 10281 lazy: immediateRender && !prevStartAt && _isNotFalse(lazy), 10282 immediateRender: immediateRender, 10283 //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) 10284 stagger: 0, 10285 parent: parent //ensures that nested tweens that had a stagger are handled properly, like gsap.from(".class", {y: gsap.utils.wrap([-100,100]), stagger: 0.5}) 10286 10287 }, cleanVars); 10288 harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}}) 10289 10290 _removeFromParent(tween._startAt = Tween.set(targets, p)); 10291 10292 tween._startAt._dp = 0; // don't allow it to get put back into root timeline! 10293 10294 tween._startAt._sat = tween; // used in globalTime() 10295 10296 time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true)); 10297 tween._zTime = time; 10298 10299 if (!immediateRender) { 10300 _initTween(tween._startAt, _tinyNum, _tinyNum); //ensures that the initial values are recorded 10301 10302 } else if (!time) { 10303 return; 10304 } 10305 } 10306 } 10307 10308 tween._pt = tween._ptCache = 0; 10309 lazy = dur && _isNotFalse(lazy) || lazy && !dur; 10310 10311 for (i = 0; i < targets.length; i++) { 10312 target = targets[i]; 10313 gsData = target._gsap || _harness(targets)[i]._gsap; 10314 tween._ptLookup[i] = ptLookup = {}; 10315 _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) 10316 10317 index = fullTargets === targets ? i : fullTargets.indexOf(target); 10318 10319 if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) { 10320 tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority); 10321 10322 plugin._props.forEach(function (name) { 10323 ptLookup[name] = pt; 10324 }); 10325 10326 plugin.priority && (hasPriority = 1); 10327 } 10328 10329 if (!harness || harnessVars) { 10330 for (p in cleanVars) { 10331 if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) { 10332 plugin.priority && (hasPriority = 1); 10333 } else { 10334 ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter); 10335 } 10336 } 10337 } 10338 10339 tween._op && tween._op[i] && tween.kill(target, tween._op[i]); 10340 10341 if (autoOverwrite && tween._pt) { 10342 _overwritingTween = tween; 10343 10344 _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); // make sure the overwriting doesn't overwrite THIS tween!!! 10345 10346 10347 overwritten = !tween.parent; 10348 _overwritingTween = 0; 10349 } 10350 10351 tween._pt && lazy && (_lazyLookup[gsData.id] = 1); 10352 } 10353 10354 hasPriority && _sortPropTweensByPriority(tween); 10355 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. 10356 } 10357 10358 tween._onUpdate = onUpdate; 10359 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. 10360 10361 keyframes && time <= 0 && tl.render(_bigNum, true, true); // if there's a 0% keyframe, it'll render in the "before" state for any staggered/delayed animations thus when the following tween initializes, it'll use the "before" state instead of the "after" state as the initial values. 10362}, 10363 _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) { 10364 var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property], 10365 pt, 10366 rootPT, 10367 lookup, 10368 i; 10369 10370 if (!ptCache) { 10371 ptCache = tween._ptCache[property] = []; 10372 lookup = tween._ptLookup; 10373 i = tween._targets.length; 10374 10375 while (i--) { 10376 pt = lookup[i][property]; 10377 10378 if (pt && pt.d && pt.d._pt) { 10379 // it's a plugin, so find the nested PropTween 10380 pt = pt.d._pt; 10381 10382 while (pt && pt.p !== property && pt.fp !== property) { 10383 // "fp" is functionParam for things like setting CSS variables which require .setProperty("--var-name", value) 10384 pt = pt._next; 10385 } 10386 } 10387 10388 if (!pt) { 10389 // there is no PropTween associated with that property, so we must FORCE one to be created and ditch out of this 10390 // if the tween has other properties that already rendered at new positions, we'd normally have to rewind to put them back like tween.render(0, true) before forcing an _initTween(), but that can create another edge case like tweening a timeline's progress would trigger onUpdates to fire which could move other things around. It's better to just inform users that .resetTo() should ONLY be used for tweens that already have that property. For example, you can't gsap.to(...{ y: 0 }) and then tween.restTo("x", 200) for example. 10391 _forceAllPropTweens = 1; // otherwise, when we _addPropTween() and it finds no change between the start and end values, it skips creating a PropTween (for efficiency...why tween when there's no difference?) but in this case we NEED that PropTween created so we can edit it. 10392 10393 tween.vars[property] = "+=0"; 10394 10395 _initTween(tween, time); 10396 10397 _forceAllPropTweens = 0; 10398 return skipRecursion ? _warn(property + " not eligible for reset") : 1; // if someone tries to do a quickTo() on a special property like borderRadius which must get split into 4 different properties, that's not eligible for .resetTo(). 10399 } 10400 10401 ptCache.push(pt); 10402 } 10403 } 10404 10405 i = ptCache.length; 10406 10407 while (i--) { 10408 rootPT = ptCache[i]; 10409 pt = rootPT._pt || rootPT; // complex values may have nested PropTweens. We only accommodate the FIRST value. 10410 10411 pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c; 10412 pt.c = value - pt.s; 10413 rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); // mainly for CSSPlugin (end value) 10414 10415 rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); // (beginning value) 10416 } 10417}, 10418 _addAliasesToVars = function _addAliasesToVars(targets, vars) { 10419 var harness = targets[0] ? _getCache(targets[0]).harness : 0, 10420 propertyAliases = harness && harness.aliases, 10421 copy, 10422 p, 10423 i, 10424 aliases; 10425 10426 if (!propertyAliases) { 10427 return vars; 10428 } 10429 10430 copy = _merge({}, vars); 10431 10432 for (p in propertyAliases) { 10433 if (p in copy) { 10434 aliases = propertyAliases[p].split(","); 10435 i = aliases.length; 10436 10437 while (i--) { 10438 copy[aliases[i]] = copy[p]; 10439 } 10440 } 10441 } 10442 10443 return copy; 10444}, 10445 // parses multiple formats, like {"0%": {x: 100}, {"50%": {x: -20}} and { x: {"0%": 100, "50%": -20} }, and an "ease" can be set on any object. We populate an "allProps" object with an Array for each property, like {x: [{}, {}], y:[{}, {}]} with data for each property tween. The objects have a "t" (time), "v", (value), and "e" (ease) property. This allows us to piece together a timeline later. 10446_parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) { 10447 var ease = obj.ease || easeEach || "power1.inOut", 10448 p, 10449 a; 10450 10451 if (_isArray(obj)) { 10452 a = allProps[prop] || (allProps[prop] = []); // t = time (out of 100), v = value, e = ease 10453 10454 obj.forEach(function (value, i) { 10455 return a.push({ 10456 t: i / (obj.length - 1) * 100, 10457 v: value, 10458 e: ease 10459 }); 10460 }); 10461 } else { 10462 for (p in obj) { 10463 a = allProps[p] || (allProps[p] = []); 10464 p === "ease" || a.push({ 10465 t: parseFloat(prop), 10466 v: obj[p], 10467 e: ease 10468 }); 10469 } 10470 } 10471}, 10472 _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) { 10473 return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value; 10474}, 10475 _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,autoRevert", 10476 _staggerPropsToSkip = {}; 10477 10478_forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) { 10479 return _staggerPropsToSkip[name] = 1; 10480}); 10481/* 10482 * -------------------------------------------------------------------------------------- 10483 * TWEEN 10484 * -------------------------------------------------------------------------------------- 10485 */ 10486 10487 10488var Tween = /*#__PURE__*/function (_Animation2) { 10489 _inheritsLoose(Tween, _Animation2); 10490 10491 function Tween(targets, vars, position, skipInherit) { 10492 var _this3; 10493 10494 if (typeof vars === "number") { 10495 position.duration = vars; 10496 vars = position; 10497 position = null; 10498 } 10499 10500 _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this; 10501 var _this3$vars = _this3.vars, 10502 duration = _this3$vars.duration, 10503 delay = _this3$vars.delay, 10504 immediateRender = _this3$vars.immediateRender, 10505 stagger = _this3$vars.stagger, 10506 overwrite = _this3$vars.overwrite, 10507 keyframes = _this3$vars.keyframes, 10508 defaults = _this3$vars.defaults, 10509 scrollTrigger = _this3$vars.scrollTrigger, 10510 yoyoEase = _this3$vars.yoyoEase, 10511 parent = vars.parent || _globalTimeline, 10512 parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets), 10513 tl, 10514 i, 10515 copy, 10516 l, 10517 p, 10518 curTarget, 10519 staggerFunc, 10520 staggerVarsToMerge; 10521 _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://gsap.com", !_config.nullTargetWarn) || []; 10522 _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property 10523 10524 _this3._overwrite = overwrite; 10525 10526 if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 10527 vars = _this3.vars; 10528 tl = _this3.timeline = new Timeline({ 10529 data: "nested", 10530 defaults: defaults || {}, 10531 targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets 10532 }); // we need to store the targets because for staggers and keyframes, we end up creating an individual tween for each but function-based values need to know the index and the whole Array of targets. 10533 10534 tl.kill(); 10535 tl.parent = tl._dp = _assertThisInitialized(_this3); 10536 tl._start = 0; 10537 10538 if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) { 10539 l = parsedTargets.length; 10540 staggerFunc = stagger && distribute(stagger); 10541 10542 if (_isObject(stagger)) { 10543 //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween. 10544 for (p in stagger) { 10545 if (~_staggerTweenProps.indexOf(p)) { 10546 staggerVarsToMerge || (staggerVarsToMerge = {}); 10547 staggerVarsToMerge[p] = stagger[p]; 10548 } 10549 } 10550 } 10551 10552 for (i = 0; i < l; i++) { 10553 copy = _copyExcluding(vars, _staggerPropsToSkip); 10554 copy.stagger = 0; 10555 yoyoEase && (copy.yoyoEase = yoyoEase); 10556 staggerVarsToMerge && _merge(copy, staggerVarsToMerge); 10557 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. 10558 10559 copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets); 10560 copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay; 10561 10562 if (!stagger && l === 1 && copy.delay) { 10563 // if someone does delay:"random(1, 5)", repeat:-1, for example, the delay shouldn't be inside the repeat. 10564 _this3._delay = delay = copy.delay; 10565 _this3._start += delay; 10566 copy.delay = 0; 10567 } 10568 10569 tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0); 10570 tl._ease = _easeMap.none; 10571 } 10572 10573 tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline's duration is 0, we don't need a timeline internally! 10574 } else if (keyframes) { 10575 _inheritDefaults(_setDefaults(tl.vars.defaults, { 10576 ease: "none" 10577 })); 10578 10579 tl._ease = _parseEase(keyframes.ease || vars.ease || "none"); 10580 var time = 0, 10581 a, 10582 kf, 10583 v; 10584 10585 if (_isArray(keyframes)) { 10586 keyframes.forEach(function (frame) { 10587 return tl.to(parsedTargets, frame, ">"); 10588 }); 10589 tl.duration(); // to ensure tl._dur is cached because we tap into it for performance purposes in the render() method. 10590 } else { 10591 copy = {}; 10592 10593 for (p in keyframes) { 10594 p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach); 10595 } 10596 10597 for (p in copy) { 10598 a = copy[p].sort(function (a, b) { 10599 return a.t - b.t; 10600 }); 10601 time = 0; 10602 10603 for (i = 0; i < a.length; i++) { 10604 kf = a[i]; 10605 v = { 10606 ease: kf.e, 10607 duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration 10608 }; 10609 v[p] = kf.v; 10610 tl.to(parsedTargets, v, time); 10611 time += v.duration; 10612 } 10613 } 10614 10615 tl.duration() < duration && tl.to({}, { 10616 duration: duration - tl.duration() 10617 }); // in case keyframes didn't go to 100% 10618 } 10619 } 10620 10621 duration || _this3.duration(duration = tl.duration()); 10622 } else { 10623 _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain) 10624 } 10625 10626 if (overwrite === true && !_suppressOverwrites) { 10627 _overwritingTween = _assertThisInitialized(_this3); 10628 10629 _globalTimeline.killTweensOf(parsedTargets); 10630 10631 _overwritingTween = 0; 10632 } 10633 10634 _addToTimeline(parent, _assertThisInitialized(_this3), position); 10635 10636 vars.reversed && _this3.reverse(); 10637 vars.paused && _this3.paused(true); 10638 10639 if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") { 10640 _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) 10641 10642 _this3.render(Math.max(0, -delay) || 0); //in case delay is negative 10643 10644 } 10645 10646 scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger); 10647 return _this3; 10648 } 10649 10650 var _proto3 = Tween.prototype; 10651 10652 _proto3.render = function render(totalTime, suppressEvents, force) { 10653 var prevTime = this._time, 10654 tDur = this._tDur, 10655 dur = this._dur, 10656 isNegative = totalTime < 0, 10657 tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime, 10658 time, 10659 pt, 10660 iteration, 10661 cycleDuration, 10662 prevIteration, 10663 isYoyo, 10664 ratio, 10665 timeline, 10666 yoyoEase; 10667 10668 if (!dur) { 10669 _renderZeroDurationTween(this, totalTime, suppressEvents, force); 10670 } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative) { 10671 //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) 10672 time = tTime; 10673 timeline = this.timeline; 10674 10675 if (this._repeat) { 10676 //adjust the time for repeats and yoyos 10677 cycleDuration = dur + this._rDelay; 10678 10679 if (this._repeat < -1 && isNegative) { 10680 return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force); 10681 } 10682 10683 time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!) 10684 10685 if (tTime === tDur) { 10686 // 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) 10687 iteration = this._repeat; 10688 time = dur; 10689 } else { 10690 iteration = ~~(tTime / cycleDuration); 10691 10692 if (iteration && iteration === _roundPrecise(tTime / cycleDuration)) { 10693 time = dur; 10694 iteration--; 10695 } 10696 10697 time > dur && (time = dur); 10698 } 10699 10700 isYoyo = this._yoyo && iteration & 1; 10701 10702 if (isYoyo) { 10703 yoyoEase = this._yEase; 10704 time = dur - time; 10705 } 10706 10707 prevIteration = _animationCycle(this._tTime, cycleDuration); 10708 10709 if (time === prevTime && !force && this._initted && iteration === prevIteration) { 10710 //could be during the repeatDelay part. No need to render and fire callbacks. 10711 this._tTime = tTime; 10712 return this; 10713 } 10714 10715 if (iteration !== prevIteration) { 10716 timeline && this._yEase && _propagateYoyoEase(timeline, isYoyo); //repeatRefresh functionality 10717 10718 if (this.vars.repeatRefresh && !isYoyo && !this._lock && this._time !== cycleDuration && this._initted) { 10719 // this._time will === cycleDuration when we render at EXACTLY the end of an iteration. Without this condition, it'd often do the repeatRefresh render TWICE (again on the very next tick). 10720 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. 10721 10722 this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0; 10723 } 10724 } 10725 } 10726 10727 if (!this._initted) { 10728 if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) { 10729 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. 10730 10731 return this; 10732 } 10733 10734 if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) { 10735 // rare edge case - during initialization, an onUpdate in the _startAt (.fromTo()) might force this tween to render at a different spot in which case we should ditch this render() call so that it doesn't revert the values. But we also don't want to dump if we're doing a repeatRefresh render! 10736 return this; 10737 } 10738 10739 if (dur !== this._dur) { 10740 // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should. 10741 return this.render(totalTime, suppressEvents, force); 10742 } 10743 } 10744 10745 this._tTime = tTime; 10746 this._time = time; 10747 10748 if (!this._act && this._ts) { 10749 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. 10750 10751 this._lazy = 0; 10752 } 10753 10754 this.ratio = ratio = (yoyoEase || this._ease)(time / dur); 10755 10756 if (this._from) { 10757 this.ratio = ratio = 1 - ratio; 10758 } 10759 10760 if (time && !prevTime && !suppressEvents && !iteration) { 10761 _callback(this, "onStart"); 10762 10763 if (this._tTime !== tTime) { 10764 // in case the onStart triggered a render at a different spot, eject. Like if someone did animation.pause(0.5) or something inside the onStart. 10765 return this; 10766 } 10767 } 10768 10769 pt = this._pt; 10770 10771 while (pt) { 10772 pt.r(ratio, pt.d); 10773 pt = pt._next; 10774 } 10775 10776 timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime); 10777 10778 if (this._onUpdate && !suppressEvents) { 10779 isNegative && _rewindStartAt(this, totalTime, suppressEvents, 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. 10780 10781 _callback(this, "onUpdate"); 10782 } 10783 10784 this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat"); 10785 10786 if ((tTime === this._tDur || !tTime) && this._tTime === tTime) { 10787 isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true); 10788 (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. 10789 10790 if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) { 10791 // if prevTime and tTime are zero, we shouldn't fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play(); 10792 _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true); 10793 10794 this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom(); 10795 } 10796 } 10797 } 10798 10799 return this; 10800 }; 10801 10802 _proto3.targets = function targets() { 10803 return this._targets; 10804 }; 10805 10806 _proto3.invalidate = function invalidate(soft) { 10807 // "soft" gives us a way to clear out everything EXCEPT the recorded pre-"from" portion of from() tweens. Otherwise, for example, if you tween.progress(1).render(0, true true).invalidate(), the "from" values would persist and then on the next render, the from() tweens would initialize and the current value would match the "from" values, thus animate from the same value to the same value (no animation). We tap into this in ScrollTrigger's refresh() where we must push a tween to completion and then back again but honor its init state in case the tween is dependent on another tween further up on the page. 10808 (!soft || !this.vars.runBackwards) && (this._startAt = 0); 10809 this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0; 10810 this._ptLookup = []; 10811 this.timeline && this.timeline.invalidate(soft); 10812 return _Animation2.prototype.invalidate.call(this, soft); 10813 }; 10814 10815 _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) { 10816 _tickerActive || _ticker.wake(); 10817 this._ts || this.play(); 10818 var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts), 10819 ratio; 10820 this._initted || _initTween(this, time); 10821 ratio = this._ease(time / this._dur); // don't just get tween.ratio because it may not have rendered yet. 10822 // possible future addition to allow an object with multiple values to update, like tween.resetTo({x: 100, y: 200}); At this point, it doesn't seem worth the added kb given the fact that most users will likely opt for the convenient gsap.quickTo() way of interacting with this method. 10823 // if (_isObject(property)) { // performance optimization 10824 // for (p in property) { 10825 // if (_updatePropTweens(this, p, property[p], value ? value[p] : null, start, ratio, time)) { 10826 // return this.resetTo(property, value, start, startIsRelative); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again. 10827 // } 10828 // } 10829 // } else { 10830 10831 if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) { 10832 return this.resetTo(property, value, start, startIsRelative, 1); // if a PropTween wasn't found for the property, it'll get forced with a re-initialization so we need to jump out and start over again. 10833 } //} 10834 10835 10836 _alignPlayhead(this, 0); 10837 10838 this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0); 10839 return this.render(0); 10840 }; 10841 10842 _proto3.kill = function kill(targets, vars) { 10843 if (vars === void 0) { 10844 vars = "all"; 10845 } 10846 10847 if (!targets && (!vars || vars === "all")) { 10848 this._lazy = this._pt = 0; 10849 return this.parent ? _interrupt(this) : this; 10850 } 10851 10852 if (this.timeline) { 10853 var tDur = this.timeline.totalDuration(); 10854 this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt. 10855 10856 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. 10857 10858 return this; 10859 } 10860 10861 var parsedTargets = this._targets, 10862 killingTargets = targets ? toArray(targets) : parsedTargets, 10863 propTweenLookup = this._ptLookup, 10864 firstPT = this._pt, 10865 overwrittenProps, 10866 curLookup, 10867 curOverwriteProps, 10868 props, 10869 p, 10870 pt, 10871 i; 10872 10873 if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) { 10874 vars === "all" && (this._pt = 0); 10875 return _interrupt(this); 10876 } 10877 10878 overwrittenProps = this._op = this._op || []; 10879 10880 if (vars !== "all") { 10881 //so people can pass in a comma-delimited list of property names 10882 if (_isString(vars)) { 10883 p = {}; 10884 10885 _forEachName(vars, function (name) { 10886 return p[name] = 1; 10887 }); 10888 10889 vars = p; 10890 } 10891 10892 vars = _addAliasesToVars(parsedTargets, vars); 10893 } 10894 10895 i = parsedTargets.length; 10896 10897 while (i--) { 10898 if (~killingTargets.indexOf(parsedTargets[i])) { 10899 curLookup = propTweenLookup[i]; 10900 10901 if (vars === "all") { 10902 overwrittenProps[i] = vars; 10903 props = curLookup; 10904 curOverwriteProps = {}; 10905 } else { 10906 curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {}; 10907 props = vars; 10908 } 10909 10910 for (p in props) { 10911 pt = curLookup && curLookup[p]; 10912 10913 if (pt) { 10914 if (!("kill" in pt.d) || pt.d.kill(p) === true) { 10915 _removeLinkedListItem(this, pt, "_pt"); 10916 } 10917 10918 delete curLookup[p]; 10919 } 10920 10921 if (curOverwriteProps !== "all") { 10922 curOverwriteProps[p] = 1; 10923 } 10924 } 10925 } 10926 } 10927 10928 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. 10929 10930 return this; 10931 }; 10932 10933 Tween.to = function to(targets, vars) { 10934 return new Tween(targets, vars, arguments[2]); 10935 }; 10936 10937 Tween.from = function from(targets, vars) { 10938 return _createTweenType(1, arguments); 10939 }; 10940 10941 Tween.delayedCall = function delayedCall(delay, callback, params, scope) { 10942 return new Tween(callback, 0, { 10943 immediateRender: false, 10944 lazy: false, 10945 overwrite: false, 10946 delay: delay, 10947 onComplete: callback, 10948 onReverseComplete: callback, 10949 onCompleteParams: params, 10950 onReverseCompleteParams: params, 10951 callbackScope: scope 10952 }); // we must use onReverseComplete too for things like timeline.add(() => {...}) which should be triggered in BOTH directions (forward and reverse) 10953 }; 10954 10955 Tween.fromTo = function fromTo(targets, fromVars, toVars) { 10956 return _createTweenType(2, arguments); 10957 }; 10958 10959 Tween.set = function set(targets, vars) { 10960 vars.duration = 0; 10961 vars.repeatDelay || (vars.repeat = 0); 10962 return new Tween(targets, vars); 10963 }; 10964 10965 Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) { 10966 return _globalTimeline.killTweensOf(targets, props, onlyActive); 10967 }; 10968 10969 return Tween; 10970}(Animation); 10971 10972_setDefaults(Tween.prototype, { 10973 _targets: [], 10974 _lazy: 0, 10975 _startAt: 0, 10976 _op: 0, 10977 _onInit: 0 10978}); //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) 10979// _forEachName("to,from,fromTo,set,call,add,addLabel,addPause", name => { 10980// Tween.prototype[name] = function() { 10981// let tl = new Timeline(); 10982// return _addToTimeline(tl, this)[name].apply(tl, toArray(arguments)); 10983// } 10984// }); 10985//for backward compatibility. Leverage the timeline calls. 10986 10987 10988_forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) { 10989 Tween[name] = function () { 10990 var tl = new Timeline(), 10991 params = _slice.call(arguments, 0); 10992 10993 params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0); 10994 return tl[name].apply(tl, params); 10995 }; 10996}); 10997/* 10998 * -------------------------------------------------------------------------------------- 10999 * PROPTWEEN 11000 * -------------------------------------------------------------------------------------- 11001 */ 11002 11003 11004var _setterPlain = function _setterPlain(target, property, value) { 11005 return target[property] = value; 11006}, 11007 _setterFunc = function _setterFunc(target, property, value) { 11008 return target[property](value); 11009}, 11010 _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) { 11011 return target[property](data.fp, value); 11012}, 11013 _setterAttribute = function _setterAttribute(target, property, value) { 11014 return target.setAttribute(property, value); 11015}, 11016 _getSetter = function _getSetter(target, property) { 11017 return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain; 11018}, 11019 _renderPlain = function _renderPlain(ratio, data) { 11020 return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data); 11021}, 11022 _renderBoolean = function _renderBoolean(ratio, data) { 11023 return data.set(data.t, data.p, !!(data.s + data.c * ratio), data); 11024}, 11025 _renderComplexString = function _renderComplexString(ratio, data) { 11026 var pt = data._pt, 11027 s = ""; 11028 11029 if (!ratio && data.b) { 11030 //b = beginning string 11031 s = data.b; 11032 } else if (ratio === 1 && data.e) { 11033 //e = ending string 11034 s = data.e; 11035 } else { 11036 while (pt) { 11037 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. 11038 11039 pt = pt._next; 11040 } 11041 11042 s += data.c; //we use the "c" of the PropTween to store the final chunk of non-numeric text. 11043 } 11044 11045 data.set(data.t, data.p, s, data); 11046}, 11047 _renderPropTweens = function _renderPropTweens(ratio, data) { 11048 var pt = data._pt; 11049 11050 while (pt) { 11051 pt.r(ratio, pt.d); 11052 pt = pt._next; 11053 } 11054}, 11055 _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) { 11056 var pt = this._pt, 11057 next; 11058 11059 while (pt) { 11060 next = pt._next; 11061 pt.p === property && pt.modifier(modifier, tween, target); 11062 pt = next; 11063 } 11064}, 11065 _killPropTweensOf = function _killPropTweensOf(property) { 11066 var pt = this._pt, 11067 hasNonDependentRemaining, 11068 next; 11069 11070 while (pt) { 11071 next = pt._next; 11072 11073 if (pt.p === property && !pt.op || pt.op === property) { 11074 _removeLinkedListItem(this, pt, "_pt"); 11075 } else if (!pt.dep) { 11076 hasNonDependentRemaining = 1; 11077 } 11078 11079 pt = next; 11080 } 11081 11082 return !hasNonDependentRemaining; 11083}, 11084 _setterWithModifier = function _setterWithModifier(target, property, value, data) { 11085 data.mSet(target, property, data.m.call(data.tween, value, data.mt), data); 11086}, 11087 _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) { 11088 var pt = parent._pt, 11089 next, 11090 pt2, 11091 first, 11092 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) 11093 11094 while (pt) { 11095 next = pt._next; 11096 pt2 = first; 11097 11098 while (pt2 && pt2.pr > pt.pr) { 11099 pt2 = pt2._next; 11100 } 11101 11102 if (pt._prev = pt2 ? pt2._prev : last) { 11103 pt._prev._next = pt; 11104 } else { 11105 first = pt; 11106 } 11107 11108 if (pt._next = pt2) { 11109 pt2._prev = pt; 11110 } else { 11111 last = pt; 11112 } 11113 11114 pt = next; 11115 } 11116 11117 parent._pt = first; 11118}; //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) 11119 11120 11121var PropTween = /*#__PURE__*/function () { 11122 function PropTween(next, target, prop, start, change, renderer, data, setter, priority) { 11123 this.t = target; 11124 this.s = start; 11125 this.c = change; 11126 this.p = prop; 11127 this.r = renderer || _renderPlain; 11128 this.d = data || this; 11129 this.set = setter || _setterPlain; 11130 this.pr = priority || 0; 11131 this._next = next; 11132 11133 if (next) { 11134 next._prev = this; 11135 } 11136 } 11137 11138 var _proto4 = PropTween.prototype; 11139 11140 _proto4.modifier = function modifier(func, tween, target) { 11141 this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier) 11142 11143 this.set = _setterWithModifier; 11144 this.m = func; 11145 this.mt = target; //modifier target 11146 11147 this.tween = tween; 11148 }; 11149 11150 return PropTween; 11151}(); //Initialization tasks 11152 11153_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) { 11154 return _reservedProps[name] = 1; 11155}); 11156 11157_globals.TweenMax = _globals.TweenLite = Tween; 11158_globals.TimelineLite = _globals.TimelineMax = Timeline; 11159_globalTimeline = new Timeline({ 11160 sortChildren: false, 11161 defaults: _defaults, 11162 autoRemoveChildren: true, 11163 id: "root", 11164 smoothChildTiming: true 11165}); 11166_config.stringFilter = _colorStringFilter; 11167 11168var _media = [], 11169 _listeners = {}, 11170 _emptyArray = [], 11171 _lastMediaTime = 0, 11172 _contextID = 0, 11173 _dispatch = function _dispatch(type) { 11174 return (_listeners[type] || _emptyArray).map(function (f) { 11175 return f(); 11176 }); 11177}, 11178 _onMediaChange = function _onMediaChange() { 11179 var time = Date.now(), 11180 matches = []; 11181 11182 if (time - _lastMediaTime > 2) { 11183 _dispatch("matchMediaInit"); 11184 11185 _media.forEach(function (c) { 11186 var queries = c.queries, 11187 conditions = c.conditions, 11188 match, 11189 p, 11190 anyMatch, 11191 toggled; 11192 11193 for (p in queries) { 11194 match = _win.matchMedia(queries[p]).matches; // 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. 11195 11196 match && (anyMatch = 1); 11197 11198 if (match !== conditions[p]) { 11199 conditions[p] = match; 11200 toggled = 1; 11201 } 11202 } 11203 11204 if (toggled) { 11205 c.revert(); 11206 anyMatch && matches.push(c); 11207 } 11208 }); 11209 11210 _dispatch("matchMediaRevert"); 11211 11212 matches.forEach(function (c) { 11213 return c.onMatch(c, function (func) { 11214 return c.add(null, func); 11215 }); 11216 }); 11217 _lastMediaTime = time; 11218 11219 _dispatch("matchMedia"); 11220 } 11221}; 11222 11223var Context = /*#__PURE__*/function () { 11224 function Context(func, scope) { 11225 this.selector = scope && selector(scope); 11226 this.data = []; 11227 this._r = []; // returned/cleanup functions 11228 11229 this.isReverted = false; 11230 this.id = _contextID++; // to work around issues that frameworks like Vue cause by making things into Proxies which make it impossible to do something like _media.indexOf(this) because "this" would no longer refer to the Context instance itself - it'd refer to a Proxy! We needed a way to identify the context uniquely 11231 11232 func && this.add(func); 11233 } 11234 11235 var _proto5 = Context.prototype; 11236 11237 _proto5.add = function add(name, func, scope) { 11238 // possible future addition if we need the ability to add() an animation to a context and for whatever reason cannot create that animation inside of a context.add(() => {...}) function. 11239 // if (name && _isFunction(name.revert)) { 11240 // this.data.push(name); 11241 // return (name._ctx = this); 11242 // } 11243 if (_isFunction(name)) { 11244 scope = func; 11245 func = name; 11246 name = _isFunction; 11247 } 11248 11249 var self = this, 11250 f = function f() { 11251 var prev = _context, 11252 prevSelector = self.selector, 11253 result; 11254 prev && prev !== self && prev.data.push(self); 11255 scope && (self.selector = selector(scope)); 11256 _context = self; 11257 result = func.apply(self, arguments); 11258 _isFunction(result) && self._r.push(result); 11259 _context = prev; 11260 self.selector = prevSelector; 11261 self.isReverted = false; 11262 return result; 11263 }; 11264 11265 self.last = f; 11266 return name === _isFunction ? f(self, function (func) { 11267 return self.add(null, func); 11268 }) : name ? self[name] = f : f; 11269 }; 11270 11271 _proto5.ignore = function ignore(func) { 11272 var prev = _context; 11273 _context = null; 11274 func(this); 11275 _context = prev; 11276 }; 11277 11278 _proto5.getTweens = function getTweens() { 11279 var a = []; 11280 this.data.forEach(function (e) { 11281 return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e); 11282 }); 11283 return a; 11284 }; 11285 11286 _proto5.clear = function clear() { 11287 this._r.length = this.data.length = 0; 11288 }; 11289 11290 _proto5.kill = function kill(revert, matchMedia) { 11291 var _this4 = this; 11292 11293 if (revert) { 11294 (function () { 11295 var tweens = _this4.getTweens(), 11296 i = _this4.data.length, 11297 t; 11298 11299 while (i--) { 11300 // Flip plugin tweens are very different in that they should actually be pushed to their end. The plugin replaces the timeline's .revert() method to do exactly that. But we also need to remove any of those nested tweens inside the flip timeline so that they don't get individually reverted. 11301 t = _this4.data[i]; 11302 11303 if (t.data === "isFlip") { 11304 t.revert(); 11305 t.getChildren(true, true, false).forEach(function (tween) { 11306 return tweens.splice(tweens.indexOf(tween), 1); 11307 }); 11308 } 11309 } // save as an object so that we can cache the globalTime for each tween to optimize performance during the sort 11310 11311 11312 tweens.map(function (t) { 11313 return { 11314 g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity, 11315 t: t 11316 }; 11317 }).sort(function (a, b) { 11318 return b.g - a.g || -Infinity; 11319 }).forEach(function (o) { 11320 return o.t.revert(revert); 11321 }); // note: all of the _startAt tweens should be reverted in reverse order that they were created, and they'll all have the same globalTime (-1) so the " || -1" in the sort keeps the order properly. 11322 11323 i = _this4.data.length; 11324 11325 while (i--) { 11326 // make sure we loop backwards so that, for example, SplitTexts that were created later on the same element get reverted first 11327 t = _this4.data[i]; 11328 11329 if (t instanceof Timeline) { 11330 if (t.data !== "nested") { 11331 t.scrollTrigger && t.scrollTrigger.revert(); 11332 t.kill(); // don't revert() the timeline because that's duplicating efforts since we already reverted all the tweens 11333 } 11334 } else { 11335 !(t instanceof Tween) && t.revert && t.revert(revert); 11336 } 11337 } 11338 11339 _this4._r.forEach(function (f) { 11340 return f(revert, _this4); 11341 }); 11342 11343 _this4.isReverted = true; 11344 })(); 11345 } else { 11346 this.data.forEach(function (e) { 11347 return e.kill && e.kill(); 11348 }); 11349 } 11350 11351 this.clear(); 11352 11353 if (matchMedia) { 11354 var i = _media.length; 11355 11356 while (i--) { 11357 // previously, we checked _media.indexOf(this), but some frameworks like Vue enforce Proxy objects that make it impossible to get the proper result that way, so we must use a unique ID number instead. 11358 _media[i].id === this.id && _media.splice(i, 1); 11359 } 11360 } 11361 }; 11362 11363 _proto5.revert = function revert(config) { 11364 this.kill(config || {}); 11365 }; 11366 11367 return Context; 11368}(); 11369 11370var MatchMedia = /*#__PURE__*/function () { 11371 function MatchMedia(scope) { 11372 this.contexts = []; 11373 this.scope = scope; 11374 _context && _context.data.push(this); 11375 } 11376 11377 var _proto6 = MatchMedia.prototype; 11378 11379 _proto6.add = function add(conditions, func, scope) { 11380 _isObject(conditions) || (conditions = { 11381 matches: conditions 11382 }); 11383 var context = new Context(0, scope || this.scope), 11384 cond = context.conditions = {}, 11385 mq, 11386 p, 11387 active; 11388 _context && !context.selector && (context.selector = _context.selector); // in case a context is created inside a context. Like a gsap.matchMedia() that's inside a scoped gsap.context() 11389 11390 this.contexts.push(context); 11391 func = context.add("onMatch", func); 11392 context.queries = conditions; 11393 11394 for (p in conditions) { 11395 if (p === "all") { 11396 active = 1; 11397 } else { 11398 mq = _win.matchMedia(conditions[p]); 11399 11400 if (mq) { 11401 _media.indexOf(context) < 0 && _media.push(context); 11402 (cond[p] = mq.matches) && (active = 1); 11403 mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange); 11404 } 11405 } 11406 } 11407 11408 active && func(context, function (f) { 11409 return context.add(null, f); 11410 }); 11411 return this; 11412 } // refresh() { 11413 // let time = _lastMediaTime, 11414 // media = _media; 11415 // _lastMediaTime = -1; 11416 // _media = this.contexts; 11417 // _onMediaChange(); 11418 // _lastMediaTime = time; 11419 // _media = media; 11420 // } 11421 ; 11422 11423 _proto6.revert = function revert(config) { 11424 this.kill(config || {}); 11425 }; 11426 11427 _proto6.kill = function kill(revert) { 11428 this.contexts.forEach(function (c) { 11429 return c.kill(revert, true); 11430 }); 11431 }; 11432 11433 return MatchMedia; 11434}(); 11435/* 11436 * -------------------------------------------------------------------------------------- 11437 * GSAP 11438 * -------------------------------------------------------------------------------------- 11439 */ 11440 11441 11442var _gsap = { 11443 registerPlugin: function registerPlugin() { 11444 for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { 11445 args[_key2] = arguments[_key2]; 11446 } 11447 11448 args.forEach(function (config) { 11449 return _createPlugin(config); 11450 }); 11451 }, 11452 timeline: function timeline(vars) { 11453 return new Timeline(vars); 11454 }, 11455 getTweensOf: function getTweensOf(targets, onlyActive) { 11456 return _globalTimeline.getTweensOf(targets, onlyActive); 11457 }, 11458 getProperty: function getProperty(target, property, unit, uncache) { 11459 _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in 11460 11461 var getter = _getCache(target || {}).get, 11462 format = unit ? _passThrough : _numericIfPossible; 11463 11464 unit === "native" && (unit = ""); 11465 return !target ? target : !property ? function (property, unit, uncache) { 11466 return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 11467 } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache)); 11468 }, 11469 quickSetter: function quickSetter(target, property, unit) { 11470 target = toArray(target); 11471 11472 if (target.length > 1) { 11473 var setters = target.map(function (t) { 11474 return gsap.quickSetter(t, property, unit); 11475 }), 11476 l = setters.length; 11477 return function (value) { 11478 var i = l; 11479 11480 while (i--) { 11481 setters[i](value); 11482 } 11483 }; 11484 } 11485 11486 target = target[0] || {}; 11487 11488 var Plugin = _plugins[property], 11489 cache = _getCache(target), 11490 p = cache.harness && (cache.harness.aliases || {})[property] || property, 11491 // in case it's an alias, like "rotate" for "rotation". 11492 setter = Plugin ? function (value) { 11493 var p = new Plugin(); 11494 _quickTween._pt = 0; 11495 p.init(target, unit ? value + unit : value, _quickTween, 0, [target]); 11496 p.render(1, p); 11497 _quickTween._pt && _renderPropTweens(1, _quickTween); 11498 } : cache.set(target, p); 11499 11500 return Plugin ? setter : function (value) { 11501 return setter(target, p, unit ? value + unit : value, cache, 1); 11502 }; 11503 }, 11504 quickTo: function quickTo(target, property, vars) { 11505 var _merge2; 11506 11507 var tween = gsap.to(target, _merge((_merge2 = {}, _merge2[property] = "+=0.1", _merge2.paused = true, _merge2), vars || {})), 11508 func = function func(value, start, startIsRelative) { 11509 return tween.resetTo(property, value, start, startIsRelative); 11510 }; 11511 11512 func.tween = tween; 11513 return func; 11514 }, 11515 isTweening: function isTweening(targets) { 11516 return _globalTimeline.getTweensOf(targets, true).length > 0; 11517 }, 11518 defaults: function defaults(value) { 11519 value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease)); 11520 return _mergeDeep(_defaults, value || {}); 11521 }, 11522 config: function config(value) { 11523 return _mergeDeep(_config, value || {}); 11524 }, 11525 registerEffect: function registerEffect(_ref3) { 11526 var name = _ref3.name, 11527 effect = _ref3.effect, 11528 plugins = _ref3.plugins, 11529 defaults = _ref3.defaults, 11530 extendTimeline = _ref3.extendTimeline; 11531 (plugins || "").split(",").forEach(function (pluginName) { 11532 return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin."); 11533 }); 11534 11535 _effects[name] = function (targets, vars, tl) { 11536 return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl); 11537 }; 11538 11539 if (extendTimeline) { 11540 Timeline.prototype[name] = function (targets, vars, position) { 11541 return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position); 11542 }; 11543 } 11544 }, 11545 registerEase: function registerEase(name, ease) { 11546 _easeMap[name] = _parseEase(ease); 11547 }, 11548 parseEase: function parseEase(ease, defaultEase) { 11549 return arguments.length ? _parseEase(ease, defaultEase) : _easeMap; 11550 }, 11551 getById: function getById(id) { 11552 return _globalTimeline.getById(id); 11553 }, 11554 exportRoot: function exportRoot(vars, includeDelayedCalls) { 11555 if (vars === void 0) { 11556 vars = {}; 11557 } 11558 11559 var tl = new Timeline(vars), 11560 child, 11561 next; 11562 tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming); 11563 11564 _globalTimeline.remove(tl); 11565 11566 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). 11567 11568 tl._time = tl._tTime = _globalTimeline._time; 11569 child = _globalTimeline._first; 11570 11571 while (child) { 11572 next = child._next; 11573 11574 if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) { 11575 _addToTimeline(tl, child, child._start - child._delay); 11576 } 11577 11578 child = next; 11579 } 11580 11581 _addToTimeline(_globalTimeline, tl, 0); 11582 11583 return tl; 11584 }, 11585 context: function context(func, scope) { 11586 return func ? new Context(func, scope) : _context; 11587 }, 11588 matchMedia: function matchMedia(scope) { 11589 return new MatchMedia(scope); 11590 }, 11591 matchMediaRefresh: function matchMediaRefresh() { 11592 return _media.forEach(function (c) { 11593 var cond = c.conditions, 11594 found, 11595 p; 11596 11597 for (p in cond) { 11598 if (cond[p]) { 11599 cond[p] = false; 11600 found = 1; 11601 } 11602 } 11603 11604 found && c.revert(); 11605 }) || _onMediaChange(); 11606 }, 11607 addEventListener: function addEventListener(type, callback) { 11608 var a = _listeners[type] || (_listeners[type] = []); 11609 ~a.indexOf(callback) || a.push(callback); 11610 }, 11611 removeEventListener: function removeEventListener(type, callback) { 11612 var a = _listeners[type], 11613 i = a && a.indexOf(callback); 11614 i >= 0 && a.splice(i, 1); 11615 }, 11616 utils: { 11617 wrap: wrap, 11618 wrapYoyo: wrapYoyo, 11619 distribute: distribute, 11620 random: random, 11621 snap: snap, 11622 normalize: normalize, 11623 getUnit: getUnit, 11624 clamp: clamp, 11625 splitColor: splitColor, 11626 toArray: toArray, 11627 selector: selector, 11628 mapRange: mapRange, 11629 pipe: pipe, 11630 unitize: unitize, 11631 interpolate: interpolate, 11632 shuffle: shuffle 11633 }, 11634 install: _install, 11635 effects: _effects, 11636 ticker: _ticker, 11637 updateRoot: Timeline.updateRoot, 11638 plugins: _plugins, 11639 globalTimeline: _globalTimeline, 11640 core: { 11641 PropTween: PropTween, 11642 globals: _addGlobal, 11643 Tween: Tween, 11644 Timeline: Timeline, 11645 Animation: Animation, 11646 getCache: _getCache, 11647 _removeLinkedListItem: _removeLinkedListItem, 11648 reverting: function reverting() { 11649 return _reverting; 11650 }, 11651 context: function context(toAdd) { 11652 if (toAdd && _context) { 11653 _context.data.push(toAdd); 11654 11655 toAdd._ctx = _context; 11656 } 11657 11658 return _context; 11659 }, 11660 suppressOverwrites: function suppressOverwrites(value) { 11661 return _suppressOverwrites = value; 11662 } 11663 } 11664}; 11665 11666_forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) { 11667 return _gsap[name] = Tween[name]; 11668}); 11669 11670_ticker.add(Timeline.updateRoot); 11671 11672_quickTween = _gsap.to({}, { 11673 duration: 0 11674}); // ---- EXTRA PLUGINS -------------------------------------------------------- 11675 11676var _getPluginPropTween = function _getPluginPropTween(plugin, prop) { 11677 var pt = plugin._pt; 11678 11679 while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) { 11680 pt = pt._next; 11681 } 11682 11683 return pt; 11684}, 11685 _addModifiers = function _addModifiers(tween, modifiers) { 11686 var targets = tween._targets, 11687 p, 11688 i, 11689 pt; 11690 11691 for (p in modifiers) { 11692 i = targets.length; 11693 11694 while (i--) { 11695 pt = tween._ptLookup[i][p]; 11696 11697 if (pt && (pt = pt.d)) { 11698 if (pt._pt) { 11699 // is a plugin 11700 pt = _getPluginPropTween(pt, p); 11701 } 11702 11703 pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p); 11704 } 11705 } 11706 } 11707}, 11708 _buildModifierPlugin = function _buildModifierPlugin(name, modifier) { 11709 return { 11710 name: name, 11711 rawVars: 1, 11712 //don't pre-process function-based values or "random()" strings. 11713 init: function init(target, vars, tween) { 11714 tween._onInit = function (tween) { 11715 var temp, p; 11716 11717 if (_isString(vars)) { 11718 temp = {}; 11719 11720 _forEachName(vars, function (name) { 11721 return temp[name] = 1; 11722 }); //if the user passes in a comma-delimited list of property names to roundProps, like "x,y", we round to whole numbers. 11723 11724 11725 vars = temp; 11726 } 11727 11728 if (modifier) { 11729 temp = {}; 11730 11731 for (p in vars) { 11732 temp[p] = modifier(vars[p]); 11733 } 11734 11735 vars = temp; 11736 } 11737 11738 _addModifiers(tween, vars); 11739 }; 11740 } 11741 }; 11742}; //register core plugins 11743 11744 11745var gsap = _gsap.registerPlugin({ 11746 name: "attr", 11747 init: function init(target, vars, tween, index, targets) { 11748 var p, pt, v; 11749 this.tween = tween; 11750 11751 for (p in vars) { 11752 v = target.getAttribute(p) || ""; 11753 pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p); 11754 pt.op = p; 11755 pt.b = v; // record the beginning value so we can revert() 11756 11757 this._props.push(p); 11758 } 11759 }, 11760 render: function render(ratio, data) { 11761 var pt = data._pt; 11762 11763 while (pt) { 11764 _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); // if reverting, go back to the original (pt.b) 11765 11766 pt = pt._next; 11767 } 11768 } 11769}, { 11770 name: "endArray", 11771 init: function init(target, value) { 11772 var i = value.length; 11773 11774 while (i--) { 11775 this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1); 11776 } 11777 } 11778}, _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. 11779 11780Tween.version = Timeline.version = gsap.version = "3.12.5"; 11781_coreReady = 1; 11782_windowExists() && _wake(); 11783var Power0 = _easeMap.Power0, 11784 Power1 = _easeMap.Power1, 11785 Power2 = _easeMap.Power2, 11786 Power3 = _easeMap.Power3, 11787 Power4 = _easeMap.Power4, 11788 Linear = _easeMap.Linear, 11789 Quad = _easeMap.Quad, 11790 Cubic = _easeMap.Cubic, 11791 Quart = _easeMap.Quart, 11792 Quint = _easeMap.Quint, 11793 Strong = _easeMap.Strong, 11794 Elastic = _easeMap.Elastic, 11795 Back = _easeMap.Back, 11796 SteppedEase = _easeMap.SteppedEase, 11797 Bounce = _easeMap.Bounce, 11798 Sine = _easeMap.Sine, 11799 Expo = _easeMap.Expo, 11800 Circ = _easeMap.Circ; 11801 11802 //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it. 11803 11804 11805 11806/***/ }), 11807
vendor: 3,598 bytes, lines 11808-11851
11808/***/ "./node_modules/gsap/index.js": 11809/*!************************************!*\ 11810 !*** ./node_modules/gsap/index.js ***! 11811 \************************************/ 11812/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => { 11813 11814__webpack_require__.r(__webpack_exports__); 11815/* harmony export */ __webpack_require__.d(__webpack_exports__, { 11816/* harmony export */ Back: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Back), 11817/* harmony export */ Bounce: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Bounce), 11818/* harmony export */ CSSPlugin: () => (/* reexport safe */ _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__.CSSPlugin), 11819/* harmony export */ Circ: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Circ), 11820/* harmony export */ Cubic: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Cubic), 11821/* harmony export */ Elastic: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Elastic), 11822/* harmony export */ Expo: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Expo), 11823/* harmony export */ Linear: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Linear), 11824/* harmony export */ Power0: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power0), 11825/* harmony export */ Power1: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power1), 11826/* harmony export */ Power2: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power2), 11827/* harmony export */ Power3: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power3), 11828/* harmony export */ Power4: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power4), 11829/* harmony export */ Quad: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quad), 11830/* harmony export */ Quart: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quart), 11831/* harmony export */ Quint: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quint), 11832/* harmony export */ Sine: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Sine), 11833/* harmony export */ SteppedEase: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.SteppedEase), 11834/* harmony export */ Strong: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Strong), 11835/* harmony export */ TimelineLite: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineLite), 11836/* harmony export */ TimelineMax: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineMax), 11837/* harmony export */ TweenLite: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TweenLite), 11838/* harmony export */ TweenMax: () => (/* binding */ TweenMaxWithCSS), 11839/* harmony export */ "default": () => (/* binding */ gsapWithCSS), 11840/* harmony export */ gsap: () => (/* binding */ gsapWithCSS) 11841/* harmony export */ }); 11842/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js"); 11843/* harmony import */ var _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CSSPlugin.js */ "./node_modules/gsap/CSSPlugin.js"); 11844 11845 11846var gsapWithCSS = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(_CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__.CSSPlugin) || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap, 11847 // to protect from tree shaking 11848TweenMaxWithCSS = gsapWithCSS.core.Tween; 11849 11850 11851/***/ })
vendor: 6,603 bytes, lines 11851-11951
11851 11852 11853/******/ }); 11854/************************************************************************/ 11855/******/ // The module cache 11856/******/ var __webpack_module_cache__ = {}; 11857/******/ 11858/******/ // The require function 11859/******/ function __webpack_require__(moduleId) { 11860/******/ // Check if module is in cache 11861/******/ var cachedModule = __webpack_module_cache__[moduleId]; 11862/******/ if (cachedModule !== undefined) { 11863/******/ return cachedModule.exports; 11864/******/ } 11865/******/ // Create a new module (and put it into the cache) 11866/******/ var module = __webpack_module_cache__[moduleId] = { 11867/******/ // no module.id needed 11868/******/ // no module.loaded needed 11869/******/ exports: {} 11870/******/ }; 11871/******/ 11872/******/ // Execute the module function 11873/******/ __webpack_modules__[moduleId](module, module.exports, __webpack_require__); 11874/******/ 11875/******/ // Return the exports of the module 11876/******/ return module.exports; 11877/******/ } 11878/******/ 11879/************************************************************************/ 11880/******/ /* webpack/runtime/compat get default export */ 11881/******/ (() => { 11882/******/ // getDefaultExport function for compatibility with non-harmony modules 11883/******/ __webpack_require__.n = (module) => { 11884/******/ var getter = module && module.__esModule ? 11885/******/ () => (module['default']) : 11886/******/ () => (module); 11887/******/ __webpack_require__.d(getter, { a: getter }); 11888/******/ return getter; 11889/******/ }; 11890/******/ })(); 11891/******/ 11892/******/ /* webpack/runtime/define property getters */ 11893/******/ (() => { 11894/******/ // define getter functions for harmony exports 11895/******/ __webpack_require__.d = (exports, definition) => { 11896/******/ for(var key in definition) { 11897/******/ if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) { 11898/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); 11899/******/ } 11900/******/ } 11901/******/ }; 11902/******/ })(); 11903/******/ 11904/******/ /* webpack/runtime/hasOwnProperty shorthand */ 11905/******/ (() => { 11906/******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) 11907/******/ })(); 11908/******/ 11909/******/ /* webpack/runtime/make namespace object */ 11910/******/ (() => { 11911/******/ // define __esModule on exports 11912/******/ __webpack_require__.r = (exports) => { 11913/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { 11914/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); 11915/******/ } 11916/******/ Object.defineProperty(exports, '__esModule', { value: true }); 11917/******/ }; 11918/******/ })(); 11919/******/ 11920/************************************************************************/ 11921var __webpack_exports__ = {}; 11922// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. 11923(() => { 11924/*!********************!*\ 11925 !*** ./src/app.ts ***! 11926 \********************/ 11927__webpack_require__.r(__webpack_exports__); 11928/* harmony import */ var _base_AppBase__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @/base/AppBase */ "./src/base/AppBase.ts"); 11929/* harmony import */ var _modules_header__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @/modules/header */ "./src/modules/header/index.ts"); 11930/* harmony import */ var _modules_search__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! @/modules/search */ "./src/modules/search.ts"); 11931/* harmony import */ var _modules_loadMorePosts__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! @/modules/loadMorePosts */ "./src/modules/loadMorePosts.ts"); 11932/* harmony import */ var _base_Helper__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! @/base/Helper */ "./src/base/Helper.ts"); 11933/* harmony import */ var _modules_header_megamenu__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! @/modules/header/megamenu */ "./src/modules/header/megamenu.ts"); 11934/* harmony import */ var _modules_header_product_megamenu__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! @/modules/header/product-megamenu */ "./src/modules/header/product-megamenu.ts"); 11935/* harmony import */ var _modules_testimonial__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! @/modules/testimonial */ "./src/modules/testimonial.ts"); 11936/* harmony import */ var _decorators_lib_exists__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! @/decorators/lib-exists */ "./src/decorators/lib-exists.ts"); 11937/* harmony import */ var _modules_headway__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! @/modules/headway */ "./src/modules/headway.ts"); 11938/* harmony import */ var _modules_tooltip__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(/*! ./modules/tooltip */ "./src/modules/tooltip.ts"); 11939/* harmony import */ var _modules_comparison_table__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(/*! ./modules/comparison-table */ "./src/modules/comparison-table.ts"); 11940/* harmony import */ var _modules_feature_slide__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(/*! ./modules/feature-slide */ "./src/modules/feature-slide.ts"); 11941/* harmony import */ var _modules_scroll_text__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(/*! ./modules/scroll-text */ "./src/modules/scroll-text.ts"); 11942/* harmony import */ var _modules_pricing_comparison__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(/*! ./modules/pricing-comparison */ "./src/modules/pricing-comparison.ts"); 11943/* harmony import */ var _modules_glossary_search__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(/*! @/modules/glossary-search */ "./src/modules/glossary-search.ts"); 11944/* harmony import */ var _modules_glossary_scroll_pagination__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(/*! @/modules/glossary-scroll-pagination */ "./src/modules/glossary-scroll-pagination.ts"); 11945/* harmony import */ var _inc_chatway_widget_support__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(/*! ./inc/chatway-widget-support */ "./src/inc/chatway-widget-support.ts"); 11946/* harmony import */ var _inc_chatway_widget_support__WEBPACK_IMPORTED_MODULE_17___default = /*#__PURE__*/__webpack_require__.n(_inc_chatway_widget_support__WEBPACK_IMPORTED_MODULE_17__); 11947var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { 11948 var c = arguments.length, 11949 r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, 11950 d; 11951 if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c >
11951 3 ? d(target, key, r) : d(target, key)) || r; 11952 return c > 3 && r && Object.defineProperty(target, key, r), r; 11953}; 11954/** 11955 * Internal dependencies 11956 */ 11957 11958 11959 11960 11961 11962 11963 11964 11965 11966 11967 11968 11969 11970 11971 11972 11973 11974 11975const $ = window.jQuery; 11976class App extends _base_AppBase__WEBPACK_IMPORTED_MODULE_0__["default"] { 11977 init() { 11978 new _modules_comparison_table__WEBPACK_IMPORTED_MODULE_11__["default"](); 11979 new _modules_header__WEBPACK_IMPORTED_MODULE_1__["default"](); 11980 new _modules_header_megamenu__WEBPACK_IMPORTED_MODULE_5__["default"](); 11981 new _modules_header_product_megamenu__WEBPACK_IMPORTED_MODULE_6__["default"](); 11982 new _modules_search__WEBPACK_IMPORTED_MODULE_2__["default"](); 11983 new _modules_loadMorePosts__WEBPACK_IMPORTED_MODULE_3__["default"](); 11984 new _modules_testimonial__WEBPACK_IMPORTED_MODULE_7__["default"](); 11985 new _modules_headway__WEBPACK_IMPORTED_MODULE_9__["default"](); 11986 new _modules_tooltip__WEBPACK_IMPORTED_MODULE_10__["default"](); 11987 new _modules_feature_slide__WEBPACK_IMPORTED_MODULE_12__["default"](); 11988 new _modules_scroll_text__WEBPACK_IMPORTED_MODULE_13__["default"](); 11989 new _modules_pricing_comparison__WEBPACK_IMPORTED_MODULE_14__["default"](); 11990 new _modules_glossary_search__WEBPACK_IMPORTED_MODULE_15__["default"](); 11991 new _modules_glossary_scroll_pagination__WEBPACK_IMPORTED_MODULE_16__["default"](); 11992 this.events(); 11993 this.aos(); 11994 this.accordion(); 11995 } 11996 events() { 11997 $('.scroll-to-cta-footer').on('click', ev => { 11998 ev.preventDefault(); 11999 _base_Helper__WEBPACK_IMPORTED_MODULE_4__["default"].scrollIntoView('#footer-cta'); 12000 }); 12001 if (window.location.href.includes('utm_source=mobile_app_support')) { 12002 //@ts-ignore 12003 window.$chatwayOnLoad = function () { 12004 setTimeout(() => { 12005 //@ts-ignore 12006 window.$chatway.openChatwayWidget(); 12007 }, 1000); 12008 }; 12009 } 12010 } 12011 aos() { 12012 window.AOS.init({ 12013 once: true 12014 // disable: true, 12015 }); 12016 } 12017 accordion() { 12018 const element = document.querySelector('.accordion-container'); 12019 if (!element) { 12020 return; 12021 } 12022 new window.Accordion('.accordion-container'); 12023 } 12024} 12025__decorate([(0,_decorators_lib_exists__WEBPACK_IMPORTED_MODULE_8__["default"])('AOS')], App.prototype, "aos", null); 12026__decorate([(0,_decorators_lib_exists__WEBPACK_IMPORTED_MODULE_8__["default"])('Accordion')], App.prototype, "accordion", null); 12027new App(); 12028})(); 12029 12030/******/ })() 12031; 12032//# sourceMappingURL=app.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.