PageSourceSearch

https://www.realinsight.com/wp-content/themes/real-insight/dist/js/main.bundle.js?ver=1788466303

js realinsight.com collected 2026-10-04 13:28:08 UTC 992,096 bytes, 1 lines download raw bytes

1(()=>{var __webpack_modules__={"./node_modules/ev-emitter/ev-emitter.js"(module){eval("{/**\n * EvEmitter v2.1.1\n * Lil' event emitter\n * MIT License\n */\n\n( function( global, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS - Browserify, Webpack\n    module.exports = factory();\n  } else {\n    // Browser globals\n    global.EvEmitter = factory();\n  }\n\n}( typeof window != 'undefined' ? window : this, function() {\n\nfunction EvEmitter() {}\n\nlet proto = EvEmitter.prototype;\n\nproto.on = function( eventName, listener ) {\n  if ( !eventName || !listener ) return this;\n\n  // set events hash\n  let events = this._events = this._events || {};\n  // set listeners array\n  let listeners = events[ eventName ] = events[ eventName ] || [];\n  // only add once\n  if ( !listeners.includes( listener ) ) {\n    listeners.push( listener );\n  }\n\n  return this;\n};\n\nproto.once = function( eventName, listener ) {\n  if ( !eventName || !listener ) return this;\n\n  // add event\n  this.on( eventName, listener );\n  // set once flag\n  // set onceEvents hash\n  let onceEvents = this._onceEvents = this._onceEvents || {};\n  // set onceListeners object\n  let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};\n  // set flag\n  onceListeners[ listener ] = true;\n\n  return this;\n};\n\nproto.off = function( eventName, listener ) {\n  let listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) return this;\n\n  let index = listeners.indexOf( listener );\n  if ( index != -1 ) {\n    listeners.splice( index, 1 );\n  }\n\n  return this;\n};\n\nproto.emitEvent = function( eventName, args ) {\n  let listeners = this._events && this._events[ eventName ];\n  if ( !listeners || !listeners.length ) return this;\n\n  // copy over to avoid interference if .off() in listener\n  listeners = listeners.slice( 0 );\n  args = args || [];\n  // once stuff\n  let onceListeners = this._onceEvents && this._onceEvents[ eventName ];\n\n  for ( let listener of listeners ) {\n    let isOnce = onceListeners && onceListeners[ listener ];\n    if ( isOnce ) {\n      // remove listener\n      // remove before trigger to prevent recursion\n      this.off( eventName, listener );\n      // unset once flag\n      delete onceListeners[ listener ];\n    }\n    // trigger listener\n    listener.apply( this, args );\n  }\n\n  return this;\n};\n\nproto.allOff = function() {\n  delete this._events;\n  delete this._onceEvents;\n  return this;\n};\n\nreturn EvEmitter;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/ev-emitter/ev-emitter.js?\n}")},"./node_modules/fizzy-ui-utils/utils.js"(module){eval("{/**\n * Fizzy UI utils v3.0.0\n * MIT license\n */\n\n( function( global, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( global );\n  } else {\n    // browser global\n    global.fizzyUIUtils = factory( global );\n  }\n\n}( this, function factory( global ) {\n\nlet utils = {};\n\n// ----- extend ----- //\n\n// extends objects\nutils.extend = function( a, b ) {\n  return Object.assign( a, b );\n};\n\n// ----- modulo ----- //\n\nutils.modulo = function( num, div ) {\n  return ( ( num % div ) + div ) % div;\n};\n\n// ----- makeArray ----- //\n\n// turn element or nodeList into an array\nutils.makeArray = function( obj ) {\n  // use object if already an array\n  if ( Array.isArray( obj ) ) return obj;\n\n  // return empty array if undefined or null. #6\n  if ( obj === null || obj === undefined ) return [];\n\n  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';\n  // convert nodeList to array\n  if ( isArrayLike ) return [ ...obj ];\n\n  // array of single index\n  return [ obj ];\n};\n\n// ----- removeFrom ----- //\n\nutils.removeFrom = function( ary, obj ) {\n  let index = ary.indexOf( obj );\n  if ( index != -1 ) {\n    ary.splice( index, 1 );\n  }\n};\n\n// ----- getParent ----- //\n\nutils.getParent = function( elem, selector ) {\n  while ( elem.parentNode && elem != document.body ) {\n    elem = elem.parentNode;\n    if ( elem.matches( selector ) ) return elem;\n  }\n};\n\n// ----- getQueryElement ----- //\n\n// use element as selector string\nutils.getQueryElement = function( elem ) {\n  if ( typeof elem == 'string' ) {\n    return document.querySelector( elem );\n  }\n  return elem;\n};\n\n// ----- handleEvent ----- //\n\n// enable .ontype to trigger from .addEventListener( elem, 'type' )\nutils.handleEvent = function( event ) {\n  let method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\n// ----- filterFindElements ----- //\n\nutils.filterFindElements = function( elems, selector ) {\n  // make array of elems\n  elems = utils.makeArray( elems );\n\n  return elems\n    // check that elem is an actual element\n    .filter( ( elem ) => elem instanceof HTMLElement )\n    .reduce( ( ffElems, elem ) => {\n      // add elem if no selector\n      if ( !selector ) {\n        ffElems.push( elem );\n        return ffElems;\n      }\n      // filter & find items if we have a selector\n      // filter\n      if ( elem.matches( selector ) ) {\n        ffElems.push( elem );\n      }\n      // find children\n      let childElems = elem.querySelectorAll( selector );\n      // concat childElems to filterFound array\n      ffElems = ffElems.concat( ...childElems );\n      return ffElems;\n    }, [] );\n};\n\n// ----- debounceMethod ----- //\n\nutils.debounceMethod = function( _class, methodName, threshold ) {\n  threshold = threshold || 100;\n  // original method\n  let method = _class.prototype[ methodName ];\n  let timeoutName = methodName + 'Timeout';
1\n\n  _class.prototype[ methodName ] = function() {\n    clearTimeout( this[ timeoutName ] );\n\n    let args = arguments;\n    this[ timeoutName ] = setTimeout( () => {\n      method.apply( this, args );\n      delete this[ timeoutName ];\n    }, threshold );\n  };\n};\n\n// ----- docReady ----- //\n\nutils.docReady = function( onDocReady ) {\n  let readyState = document.readyState;\n  if ( readyState == 'complete' || readyState == 'interactive' ) {\n    // do async to allow for other scripts to run. metafizzy/flickity#441\n    setTimeout( onDocReady );\n  } else {\n    document.addEventListener( 'DOMContentLoaded', onDocReady );\n  }\n};\n\n// ----- htmlInit ----- //\n\n// http://bit.ly/3oYLusc\nutils.toDashed = function( str ) {\n  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {\n    return $1 + '-' + $2;\n  } ).toLowerCase();\n};\n\nlet console = global.console;\n\n// allow user to initialize classes via [data-namespace] or .js-namespace class\n// htmlInit( Widget, 'widgetName' )\n// options are parsed from data-namespace-options\nutils.htmlInit = function( WidgetClass, namespace ) {\n  utils.docReady( function() {\n    let dashedNamespace = utils.toDashed( namespace );\n    let dataAttr = 'data-' + dashedNamespace;\n    let dataAttrElems = document.querySelectorAll( `[${dataAttr}]` );\n    let jQuery = global.jQuery;\n\n    [ ...dataAttrElems ].forEach( ( elem ) => {\n      let attr = elem.getAttribute( dataAttr );\n      let options;\n      try {\n        options = attr && JSON.parse( attr );\n      } catch ( error ) {\n        // log error, do not initialize\n        if ( console ) {\n          console.error( `Error parsing ${dataAttr} on ${elem.className}: ${error}` );\n        }\n        return;\n      }\n      // initialize\n      let instance = new WidgetClass( elem, options );\n      // make available via $().data('namespace')\n      if ( jQuery ) {\n        jQuery.data( elem, namespace, instance );\n      }\n    } );\n\n  } );\n};\n\n// -----  ----- //\n\nreturn utils;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/fizzy-ui-utils/utils.js?\n}")},"./node_modules/flickity/js/add-remove-cell.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// add, remove cell\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\"),\n        __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\"),\n    );\n  } else {\n    // browser global\n    factory(\n        window.Flickity,\n        window.fizzyUIUtils,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( Flickity, utils ) {\n\n// append cells to a document fragment\nfunction getCellsFragment( cells ) {\n  let fragment = document.createDocumentFragment();\n  cells.forEach( ( cell ) => fragment.appendChild( cell.element ) );\n  return fragment;\n}\n\n// -------------------------- add/remove cell prototype -------------------------- //\n\nlet proto = Flickity.prototype;\n\n/**\n * Insert, prepend, or append cells\n * @param {[Element, Array, NodeList]} elems - Elements to insert\n * @param {Integer} index - Zero-based number to insert\n */\nproto.insert = function( elems, index ) {\n  let cells = this._makeCells( elems );\n  if ( !cells || !cells.length ) return;\n\n  let len = this.cells.length;\n  // default to append\n  index = index === undefined ? len : index;\n  // add cells with document fragment\n  let fragment = getCellsFragment( cells );\n  // append to slider\n  let isAppend = index === len;\n  if ( isAppend ) {\n    this.slider.appendChild( fragment );\n  } else {\n    let insertCellElement = this.cells[ index ].element;\n    this.slider.insertBefore( fragment, insertCellElement );\n  }\n  // add to this.cells\n  if ( index === 0 ) {\n    // prepend, add to start\n    this.cells = cells.concat( this.cells );\n  } else if ( isAppend ) {\n    // append, add to end\n    this.cells = this.cells.concat( cells );\n  } else {\n    // insert in this.cells\n    let endCells = this.cells.splice( index, len - index );\n    this.cells = this.cells.concat( cells ).concat( endCells );\n  }\n\n  this._sizeCells( cells );\n  this.cellChange( index );\n  this.positionSliderAtSelected();\n};\n\nproto.append = function( elems ) {\n  this.insert( elems, this.cells.length );\n};\n\nproto.prepend = function( elems ) {\n  this.insert( elems, 0 );\n};\n\n/**\n * Remove cells\n * @param {[Element, Array, NodeList]} elems - ELements to remove\n */\nproto.remove = function( elems ) {\n  let cells = this.getCells( elems );\n  if ( !cells || !cells.length ) return;\n\n  let minCellIndex = this.cells.length - 1;
1\n  // remove cells from collection & DOM\n  cells.forEach( ( cell ) => {\n    cell.remove();\n    let index = this.cells.indexOf( cell );\n    minCellIndex = Math.min( index, minCellIndex );\n    utils.removeFrom( this.cells, cell );\n  } );\n\n  this.cellChange( minCellIndex );\n  this.positionSliderAtSelected();\n};\n\n/**\n * logic to be run after a cell's size changes\n * @param {Element} elem - cell's element\n */\nproto.cellSizeChange = function( elem ) {\n  let cell = this.getCell( elem );\n  if ( !cell ) return;\n\n  cell.getSize();\n\n  let index = this.cells.indexOf( cell );\n  this.cellChange( index );\n  // do not position slider after lazy load\n};\n\n/**\n * logic any time a cell is changed: added, removed, or size changed\n * @param {Integer} changedCellIndex - index of the changed cell, optional\n */\nproto.cellChange = function( changedCellIndex ) {\n  let prevSelectedElem = this.selectedElement;\n  this._positionCells( changedCellIndex );\n  this._updateWrapShiftCells();\n  this.setGallerySize();\n  // update selectedIndex, try to maintain position & select previous selected element\n  let cell = this.getCell( prevSelectedElem );\n  if ( cell ) this.selectedIndex = this.getCellSlideIndex( cell );\n  this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );\n\n  this.emitEvent( 'cellChange', [ changedCellIndex ] );\n  // position slider\n  this.select( this.selectedIndex );\n};\n\n// -----  ----- //\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/add-remove-cell.js?\n}")},"./node_modules/flickity/js/animate.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// animate\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\") );\n  } else {\n    // browser global\n    window.Flickity = window.Flickity || {};\n    window.Flickity.animatePrototype = factory( window.fizzyUIUtils );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( utils ) {\n\n// -------------------------- animate -------------------------- //\n\nlet proto = {};\n\nproto.startAnimation = function() {\n  if ( this.isAnimating ) return;\n\n  this.isAnimating = true;\n  this.restingFrames = 0;\n  this.animate();\n};\n\nproto.animate = function() {\n  this.applyDragForce();\n  this.applySelectedAttraction();\n\n  let previousX = this.x;\n\n  this.integratePhysics();\n  this.positionSlider();\n  this.settle( previousX );\n  // animate next frame\n  if ( this.isAnimating ) requestAnimationFrame( () => this.animate() );\n};\n\nproto.positionSlider = function() {\n  let x = this.x;\n  // wrap position around\n  if ( this.isWrapping ) {\n    x = utils.modulo( x, this.slideableWidth ) - this.slideableWidth;\n    this.shiftWrapCells( x );\n  }\n\n  this.setTranslateX( x, this.isAnimating );\n  this.dispatchScrollEvent();\n};\n\nproto.setTranslateX = function( x, is3d ) {\n  x += this.cursorPosition;\n  // reverse if right-to-left and using transform\n  if ( this.options.rightToLeft ) x = -x;\n  let translateX = this.getPositionValue( x );\n  // use 3D transforms for hardware acceleration on iOS\n  // but use 2D when settled, for better font-rendering\n  this.slider.style.transform = is3d ?\n    `translate3d(${translateX},0,0)` : `translateX(${translateX})`;\n};\n\nproto.dispatchScrollEvent = function() {\n  let firstSlide = this.slides[0];\n  if ( !firstSlide ) return;\n\n  let positionX = -this.x - firstSlide.target;\n  let progress = positionX / this.slidesWidth;\n  this.dispatchEvent( 'scroll', null, [ progress, positionX ] );\n};\n\nproto.positionSliderAtSelected = function() {\n  if ( !this.cells.length ) return;\n\n  this.x = -this.selectedSlide.target;\n  this.velocity = 0; // stop wobble\n  this.positionSlider();\n};\n\nproto.getPositionValue = function( position ) {\n  if ( this.options.percentPosition ) {\n    // percent position, round to 2 digits, like 12.34%\n    return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 ) + '%';\n  } else {\n    // pixel positioning\n    return Math.round( position ) + 'px';\n  }\n};\n\nproto.settle = function( previousX ) {\n  // keep track of frames where x hasn't moved\n  let isResting = !this.isPointerDown &&\n      Math.round( this.x * 100 ) === Math.round( previousX * 100 );\n  if ( isResting ) this.restingFrames++;\n  // stop animating if resting for 3 or more frames\n  if ( this.restingFrames > 2 ) {\n    this.isAnimating = false;\n    delete this.isFreeScrolling;\n    // render position with translateX when settled\n    this.positionSlider();\n    this.dispatchEvent( 'settle', null, [ this.selectedIndex ] );\n  }\n};\n\nproto.shiftWrapCells = function( x ) {\n  // shift before cells\n  let beforeGap = this.cursorPosition + x;\n  this._shiftCells( this.beforeShiftCells, beforeGap, -1 );\n  // shift after cells\n  let afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition );\n  this._shiftCells( this.afterShiftCells, afterGap, 1 );\n};\n\nproto._shiftCells = function( cells, gap, shift ) {\n  cells.forEac
1h( ( cell ) => {\n    let cellShift = gap > 0 ? shift : 0;\n    this._wrapShiftCell( cell, cellShift );\n    gap -= cell.size.outerWidth;\n  } );\n};\n\nproto._unshiftCells = function( cells ) {\n  if ( !cells || !cells.length ) return;\n\n  cells.forEach( ( cell ) => this._wrapShiftCell( cell, 0 ) );\n};\n\n// @param {Integer} shift - 0, 1, or -1\nproto._wrapShiftCell = function( cell, shift ) {\n  this._renderCellPosition( cell, cell.x + this.slideableWidth * shift );\n};\n\n// -------------------------- physics -------------------------- //\n\nproto.integratePhysics = function() {\n  this.x += this.velocity;\n  this.velocity *= this.getFrictionFactor();\n};\n\nproto.applyForce = function( force ) {\n  this.velocity += force;\n};\n\nproto.getFrictionFactor = function() {\n  return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ];\n};\n\nproto.getRestingPosition = function() {\n  // my thanks to Steven Wittens, who simplified this math greatly\n  return this.x + this.velocity / ( 1 - this.getFrictionFactor() );\n};\n\nproto.applyDragForce = function() {\n  if ( !this.isDraggable || !this.isPointerDown ) return;\n\n  // change the position to drag position by applying force\n  let dragVelocity = this.dragX - this.x;\n  let dragForce = dragVelocity - this.velocity;\n  this.applyForce( dragForce );\n};\n\nproto.applySelectedAttraction = function() {\n  // do not attract if pointer down or no slides\n  let dragDown = this.isDraggable && this.isPointerDown;\n  if ( dragDown || this.isFreeScrolling || !this.slides.length ) return;\n\n  let distance = this.selectedSlide.target * -1 - this.x;\n  let force = distance * this.options.selectedAttraction;\n  this.applyForce( force );\n};\n\nreturn proto;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/animate.js?\n}")},"./node_modules/flickity/js/cell.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// Flickity.Cell\
1n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( __webpack_require__(/*! get-size */ \"./node_modules/get-size/get-size.js\") );\n  } else {\n    // browser global\n    window.Flickity = window.Flickity || {};\n    window.Flickity.Cell = factory( window.getSize );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( getSize ) {\n\nconst cellClassName = 'flickity-cell';\n\nfunction Cell( elem ) {\n  this.element = elem;\n  this.element.classList.add( cellClassName );\n\n  this.x = 0;\n  this.unselect();\n}\n\nlet proto = Cell.prototype;\n\nproto.destroy = function() {\n  // reset style\n  this.unselect();\n  this.element.classList.remove( cellClassName );\n  this.element.style.transform = '';\n  this.element.removeAttribute('aria-hidden');\n};\n\nproto.getSize = function() {\n  this.size = getSize( this.element );\n};\n\nproto.select = function() {\n  this.element.classList.add('is-selected');\n  this.element.removeAttribute('aria-hidden');\n};\n\nproto.unselect = function() {\n  this.element.classList.remove('is-selected');\n  this.element.setAttribute( 'aria-hidden', 'true' );\n};\n\nproto.remove = function() {\n  this.element.remove();\n};\n\nreturn Cell;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/cell.js?\n}")},"./node_modules/flickity/js/core.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// Flickity main\n/* eslint-disable max-params */\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        window,\n        __webpack_require__(/*! ev-emitter */ \"./node_modules/ev-emitter/ev-emitter.js\"),\n        __webpack_require__(/*! get-size */ \"./node_modules/get-size/get-size.js\"),\n        __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\"),\n        __webpack_require__(/*! ./cell */ \"./node_modules/flickity/js/cell.js\"),\n        __webpack_require__(/*! ./slide */ \"./node_modules/flickity/js/slide.js\"),\n        __webpack_require__(/*! ./animate */ \"./node_modules/flickity/js/animate.js\"),\n    );\n  } else {\n    // browser global\n    let _Flickity = window.Flickity;\n\n    window.Flickity = factory(\n        window,\n        window.EvEmitter,\n        window.getSize,\n        window.fizzyUIUtils,\n        _Flickity.Cell,\n        _Flickity.Slide,\n        _Flickity.animatePrototype,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this,\n    function factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {\n/* eslint-enable max-params */\n\n// vars\nconst { getComputedStyle, console } = window;\nlet { jQuery } = window;\n\n// -------------------------- Flickity -------------------------- //\n\n// globally unique identifiers\nlet GUID = 0;\n// internal store of all Flickity intances\nlet instances = {};\n\nfunction Flickity( element, options ) {\n  let queryElement = utils.getQueryElement( element );\n  if ( !queryElement ) {\n    if ( console ) console.error(`Bad element for Flickity: ${queryElement || element}`);\n    return;\n  }\n  this.element = queryElement;\n  // do not initialize twice on same element\n  if ( this.element.flickityGUID ) {\n    let instance = instances[ this.element.flickityGUID ];\n    if ( instance ) instance.option( options );\n    return instance;\n  }\n\n  // add jQuery\n  if ( jQuery ) {\n    this.$element = jQuery( this.element );\n  }\n  // options\n  this.options = { ...this.constructor.defaults };\n  this.option( options );\n\n  // kick things off\n  this._create();\n}\n\nFlickity.defaults = {\n  accessibility: true,\n  // adaptiveHeight: false,\n  cellAlign: 'center',\n  // cellSelector: undefined,\n  // contain: false,\n  freeScrollFriction: 0.075, // friction when free-scrolling\n  friction: 0.28, // friction when selecting\n  namespaceJQueryEvents: true,\n  // initialIndex: 0,\n  percentPosition: true,\n  resize: true,\n  selectedAttraction: 0.025,\n  setGallerySize: true,\n  // watchCSS: false,\n  // wrapAround: false\n};\n\n// hash of methods triggered on _create()\nFlickity.create = {};\n\nlet proto = Flickity.prototype;\n// inherit EventEmitter\nObject.assign( proto, EvEmitter.prototype );
1\n\nproto._create = function() {\n  let { resize, watchCSS, rightToLeft } = this.options;\n  // add id for Flickity.data\n  let id = this.guid = ++GUID;\n  this.element.flickityGUID = id; // expando\n  instances[ id ] = this; // associate via id\n  // initial properties\n  this.selectedIndex = 0;\n  // how many frames slider has been in same position\n  this.restingFrames = 0;\n  // initial physics properties\n  this.x = 0;\n  this.velocity = 0;\n  this.beginMargin = rightToLeft ? 'marginRight' : 'marginLeft';\n  this.endMargin = rightToLeft ? 'marginLeft' : 'marginRight';\n  // create viewport & slider\n  this.viewport = document.createElement('div');\n  this.viewport.className = 'flickity-viewport';\n  this._createSlider();\n  // used for keyboard navigation\n  this.focusableElems = [ this.element ];\n\n  if ( resize || watchCSS ) {\n    window.addEventListener( 'resize', this );\n  }\n\n  // add listeners from on option\n  for ( let eventName in this.options.on ) {\n    let listener = this.options.on[ eventName ];\n    this.on( eventName, listener );\n  }\n\n  for ( let method in Flickity.create ) {\n    Flickity.create[ method ].call( this );\n  }\n\n  if ( watchCSS ) {\n    this.watchCSS();\n  } else {\n    this.activate();\n  }\n};\n\n/**\n * set options\n * @param {Object} opts - options to extend\n */\nproto.option = function( opts ) {\n  Object.assign( this.options, opts );\n};\n\nproto.activate = function() {\n  if ( this.isActive ) return;\n\n  this.isActive = true;\n  this.element.classList.add('flickity-enabled');\n  if ( this.options.rightToLeft ) {\n    this.element.classList.add('flickity-rtl');\n  }\n\n  this.getSize();\n  // move initial cell elements so they can be loaded as cells\n  let cellElems = this._filterFindCellElements( this.element.children );\n  this.slider.append( ...cellElems );\n  this.viewport.append( this.slider );\n  this.element.append( this.viewport );\n  // get cells from children\n  this.reloadCells();\n\n  if ( this.options.accessibility ) {\n    // allow element to focusable\n    this.element.tabIndex = 0;\n    // listen for key presses\n    this.element.addEventListener( 'keydown', this );\n  }\n\n  this.emitEvent('activate');\n  this.selectInitialIndex();\n  // flag for initial activation, for using initialIndex\n  this.isInitActivated = true;\n  // ready event. #493\n  this.dispatchEvent('ready');\n};\n\n// slider positions the cells\nproto._createSlider = function() {\n  // slider element does all the positioning\n  let slider = document.createElement('div');\n  slider.className = 'flickity-slider';\n  this.slider = slider;\n};\n\nproto._filterFindCellElements = function( elems ) {\n  return utils.filterFindElements( elems, this.options.cellSelector );\n};\n\n// goes through all children\nproto.reloadCells = function() {\n  // collection of item elements\n  this.cells = this._makeCells( this.slider.children );\n  this.positionCells();\n  this._updateWrapShiftCells();\n  this.setGallerySize();\n};\n\n/**\n * turn elements into Flickity.Cells\n * @param {[Array, NodeList, HTMLElement]} elems - elements to make into cells\n * @returns {Array} items - collection of new Flickity Cells\n */\nproto._makeCells = function( elems ) {\n  let cellElems = this._filterFindCellElements( elems );\n\n  // create new Cells for collection\n  return cellElems.map( ( cellElem ) => new Cell( cellElem ) );\n};\n\nproto.getLastCell = function() {\n  return this.cells[ this.cells.length - 1 ];\n};\n\nproto.getLastSlide = function() {\n  return this.slides[ this.slides.length - 1 ];\n};\n\n// positions all cells\nproto.positionCells = function() {\n  // size all cells\n  this._sizeCells( this.cells );\n  // position all cells\n  this._positionCells( 0 );\n};\n\n/**\n * position certain cells\n * @param {Integer} index - which cell to start with\n */\nproto._positionCells = function( index ) {\n  index = index || 0;\n  // also measure maxCellHeight\n  // start 0 if positioning all cells\n  this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;\n  let cellX = 0;\n  // get cellX\n  if ( index > 0 ) {\n    let startCell = this.cells[ index - 1 ];\n    cellX = startCell.x + startCell.size.outerWidth;\n  }\n\n  this.cells.slice( index ).forEach( ( cell ) => {\n    cell.x = cellX;\n    this._renderCellPosition( cell, cellX );\n    cellX += cell.size.outerWidth;\n    this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );\n  } );\n  // keep track of cellX for wrap-around\n  this.slideableWidth = cellX;\n  // slides\n  this.updateSlides();\n  // contain slides target\n  this._containSlides();\n  // update slidesWidth\n  this.slidesWidth = this.cells.length ?\n    this.getLastSlide().target - this.slides[0].target : 0;\n};\n\nproto._renderCellPosition = function( cell, x ) {\n  // render position of cell with in slider\n  let sideOffset = this.options.rightToLeft ? -1 : 1;\n  let renderX = x * sideOffset;\n  if ( this.options.percentPosition ) renderX *= this.size.innerWidth / cell.size.width;\n  let positionValue = this.getPositionValue( renderX );\n  cell.element.style.transform = `translateX( ${positionValue} )`;\n};\n\n/**\n * cell.getSize() on multiple cells\n * @param {Array} cells - cells to size\n */\nproto._sizeCells = function( cells ) {\n  cells.forEac
1h( ( cell ) => cell.getSize() );\n};\n\n// --------------------------  -------------------------- //\n\nproto.updateSlides = function() {\n  this.slides = [];\n  if ( !this.cells.length ) return;\n\n  let { beginMargin, endMargin } = this;\n  let slide = new Slide( beginMargin, endMargin, this.cellAlign );\n  this.slides.push( slide );\n\n  let canCellFit = this._getCanCellFit();\n\n  this.cells.forEach( ( cell, i ) => {\n    // just add cell if first cell in slide\n    if ( !slide.cells.length ) {\n      slide.addCell( cell );\n      return;\n    }\n\n    let slideWidth = ( slide.outerWidth - slide.firstMargin ) +\n      ( cell.size.outerWidth - cell.size[ endMargin ] );\n\n    if ( canCellFit( i, slideWidth ) ) {\n      slide.addCell( cell );\n    } else {\n      // doesn't fit, new slide\n      slide.updateTarget();\n\n      slide = new Slide( beginMargin, endMargin, this.cellAlign );\n      this.slides.push( slide );\n      slide.addCell( cell );\n    }\n  } );\n  // last slide\n  slide.updateTarget();\n  // update .selectedSlide\n  this.updateSelectedSlide();\n};\n\nproto._getCanCellFit = function() {\n  let { groupCells } = this.options;\n  if ( !groupCells ) return () => false;\n\n  if ( typeof groupCells == 'number' ) {\n    // group by number. 3 -> [0,1,2], [3,4,5], ...\n    let number = parseInt( groupCells, 10 );\n    return ( i ) => ( i % number ) !== 0;\n  }\n  // default, group by width of slide\n  let percent = 1;\n  // parse '75%\n  let percentMatch = typeof groupCells == 'string' && groupCells.match( /^(\\d+)%$/ );\n  if ( percentMatch ) percent = parseInt( percentMatch[1], 10 ) / 100;\n  let groupWidth = ( this.size.innerWidth + 1 ) * percent;\n  return ( i, slideWidth ) => slideWidth <= groupWidth;\n};\n\n// alias _init for jQuery plugin .flickity()\nproto._init =\nproto.reposition = function() {\n  this.positionCells();\n  this.positionSliderAtSelected();\n};\n\nproto.getSize = function() {\n  this.size = getSize( this.element );\n  this.setCellAlign();\n  this.cursorPosition = this.size.innerWidth * this.cellAlign;\n};\n\nlet cellAlignShorthands = {\n  left: 0,\n  center: 0.5,\n  right: 1,\n};\n\nproto.setCellAlign = function() {\n  let { cellAlign, rightToLeft } = this.options;\n  let shorthand = cellAlignShorthands[ cellAlign ];\n  this.cellAlign = shorthand !== undefined ? shorthand : cellAlign;\n  if ( rightToLeft ) this.cellAlign = 1 - this.cellAlign;\n};\n\nproto.setGallerySize = function() {\n  if ( !this.options.setGallerySize ) return;\n\n  let height = this.options.adaptiveHeight && this.selectedSlide ?\n    this.selectedSlide.height : this.maxCellHeight;\n  this.viewport.style.height = `${height}px`;\n};\n\nproto._updateWrapShiftCells = function() {\n  // update isWrapping\n  this.isWrapping = this.getIsWrapping();\n  // only for wrap-around\n  if ( !this.isWrapping ) return;\n\n  // unshift previous cells\n  this._unshiftCells( this.beforeShiftCells );\n  this._unshiftCells( this.afterShiftCells );\n  // get before cells\n  // initial gap\n  let beforeGapX = this.cursorPosition;\n  let lastIndex = this.cells.length - 1;\n  this.beforeShiftCells = this._getGapCells( beforeGapX, lastIndex, -1 );\n  // get after cells\n  // ending gap between last cell and end of gallery viewport\n  let afterGapX = this.size.innerWidth - this.cursorPosition;\n  // start cloning at first cell, working forwards\n  this.afterShiftCells = this._getGapCells( afterGapX, 0, 1 );\n};\n\nproto.getIsWrapping = function() {\n  let { wrapAround } = this.options;\n  if ( !wrapAround || this.slides.length < 2 ) return false;\n\n  if ( wrapAround !== 'fill' ) return true;\n  // check that slides can fit\n\n  let gapWidth = this.slideableWidth - this.size.innerWidth;\n  if ( gapWidth > this.size.innerWidth ) return true; // gap * 2x big, all good\n  // check that content width - shifting cell is bigger than viewport width\n  for ( let cell of this.cells ) {\n    if ( cell.size.outerWidth > gapWidth ) return false;\n  }\n  return true;\n};\n\nproto._getGapCells = function( gapX, cellIndex, increment ) {\n  // keep adding cells until the cover the initial gap\n  let cells = [];\n  while ( gapX >
1 0 ) {\n    let cell = this.cells[ cellIndex ];\n    if ( !cell ) break;\n\n    cells.push( cell );\n    cellIndex += increment;\n    gapX -= cell.size.outerWidth;\n  }\n  return cells;\n};\n\n// ----- contain & wrap ----- //\n\n// contain cell targets so no excess sliding\nproto._containSlides = function() {\n  let isContaining = this.options.contain && !this.isWrapping &&\n      this.cells.length;\n  if ( !isContaining ) return;\n\n  let contentWidth = this.slideableWidth - this.getLastCell().size[ this.endMargin ];\n  // content is less than gallery size\n  let isContentSmaller = contentWidth < this.size.innerWidth;\n  if ( isContentSmaller ) {\n    // all cells fit inside gallery\n    this.slides.forEach( ( slide ) => {\n      slide.target = contentWidth * this.cellAlign;\n    } );\n  } else {\n    // contain to bounds\n    let beginBound = this.cursorPosition + this.cells[0].size[ this.beginMargin ];\n    let endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );\n    this.slides.forEach( ( slide ) => {\n      slide.target = Math.max( slide.target, beginBound );\n      slide.target = Math.min( slide.target, endBound );\n    } );\n  }\n};\n\n// ----- events ----- //\n\n/**\n * emits events via eventEmitter and jQuery events\n * @param {String} type - name of event\n * @param {Event} event - original event\n * @param {Array} args - extra arguments\n */\nproto.dispatchEvent = function( type, event, args ) {\n  let emitArgs = event ? [ event ].concat( args ) : args;\n  this.emitEvent( type, emitArgs );\n\n  if ( jQuery && this.$element ) {\n    // default trigger with type if no event\n    type += this.options.namespaceJQueryEvents ? '.flickity' : '';\n    let $event = type;\n    if ( event ) {\n      // create jQuery event\n      let jQEvent = new jQuery.Event( event );\n      jQEvent.type = type;\n      $event = jQEvent;\n    }\n    this.$element.trigger( $event, args );\n  }\n};\n\nconst unidraggerEvents = [\n  'dragStart',\n  'dragMove',\n  'dragEnd',\n  'pointerDown',\n  'pointerMove',\n  'pointerEnd',\n  'staticClick',\n];\n\nlet _emitEvent = proto.emitEvent;\nproto.emitEvent = function( eventName, args ) {\n  if ( eventName === 'staticClick' ) {\n    // add cellElem and cellIndex args to staticClick\n    let clickedCell = this.getParentCell( args[0].target );\n    let cellElem = clickedCell && clickedCell.element;\n    let cellIndex = clickedCell && this.cells.indexOf( clickedCell );\n    args = args.concat( cellElem, cellIndex );\n  }\n  // do regular thing\n  _emitEvent.call( this, eventName, args );\n  // duck-punch in jQuery events for Unidragger events\n  let isUnidraggerEvent = unidraggerEvents.includes( eventName );\n  if ( !isUnidraggerEvent || !jQuery || !this.$element ) return;\n\n  eventName += this.options.namespaceJQueryEvents ? '.flickity' : '';\n  let event = args.shift( 0 );\n  let jQEvent = new jQuery.Event( event );\n  jQEvent.type = eventName;\n  this.$element.trigger( jQEvent, args );\n};\n\n// -------------------------- select -------------------------- //\n\n/**\n * @param {Integer} index - index of the slide\n * @param {Boolean} isWrap - will wrap-around to last/first if at the end\n * @param {Boolean} isInstant - will immediately set position at selected cell\n */\nproto.select = function( index, isWrap, isInstant ) {\n  if ( !this.isActive ) return;\n\n  index = parseInt( index, 10 );\n  this._wrapSelect( index );\n\n  if ( this.isWrapping || isWrap ) {\n    index = utils.modulo( index, this.slides.length );\n  }\n  // bail if invalid index\n  if ( !this.slides[ index ] ) return;\n\n  let prevIndex = this.selectedIndex;\n  this.selectedIndex = index;\n  this.updateSelectedSlide();\n  if ( isInstant ) {\n    this.positionSliderAtSelected();\n  } else {\n    this.startAnimation();\n  }\n  if ( this.options.adaptiveHeight ) {\n    this.setGallerySize();\n  }\n  // events\n  this.dispatchEvent( 'select', null, [ index ] );\n  // change event if new index\n  if ( index !== prevIndex ) {\n    this.dispatchEvent( 'change', null, [ index ] );\n  }\n};\n\n// wraps position for wrapAround, to move to closest slide. #113\nproto._wrapSelect = function( index ) {\n  if ( !this.isWrapping ) return;\n\n  const { selectedIndex, slideableWidth, slides: { length } } = this;\n  // shift index for wrap, do not wrap dragSelect\n  if ( !this.isDragSelect ) {\n    let wrapIndex = utils.modulo( index, length );\n    // go to shortest\n    let delta = Math.abs( wrapIndex - selectedIndex );\n    let backWrapDelta = Math.abs( ( wrapIndex + length ) - selectedIndex );\n    let forewardWrapDelta = Math.abs( ( wrapIndex - length ) - selectedIndex );\n    if ( backWrapDelta < delta ) {\n      index += length;\n    } else if ( forewardWrapDelta < delta ) {\n      index -= length;\n    }\n  }\n\n  // wrap position so slider is within normal area\n  if ( index < 0 ) {\n    this.x -= slideableWidth;\n  } else if ( index >= length ) {\n    this.x += slideableWidth;\n  }\n};\n\nproto.previous = function( isWrap, isInstant ) {\n  this.select( this.selectedIndex - 1, isWrap, isInstant );\n};\n\nproto.next = function( isWrap, isInstant ) {\n  this.select( this.selectedIndex + 1, isWrap, isInstant );\n};
1\n\nproto.updateSelectedSlide = function() {\n  let slide = this.slides[ this.selectedIndex ];\n  // selectedIndex could be outside of slides, if triggered before resize()\n  if ( !slide ) return;\n\n  // unselect previous selected slide\n  this.unselectSelectedSlide();\n  // update new selected slide\n  this.selectedSlide = slide;\n  slide.select();\n  this.selectedCells = slide.cells;\n  this.selectedElements = slide.getCellElements();\n  // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility\n  this.selectedCell = slide.cells[0];\n  this.selectedElement = this.selectedElements[0];\n};\n\nproto.unselectSelectedSlide = function() {\n  if ( this.selectedSlide ) this.selectedSlide.unselect();\n};\n\nproto.selectInitialIndex = function() {\n  let initialIndex = this.options.initialIndex;\n  // already activated, select previous selectedIndex\n  if ( this.isInitActivated ) {\n    this.select( this.selectedIndex, false, true );\n    return;\n  }\n  // select with selector string\n  if ( initialIndex && typeof initialIndex == 'string' ) {\n    let cell = this.queryCell( initialIndex );\n    if ( cell ) {\n      this.selectCell( initialIndex, false, true );\n      return;\n    }\n  }\n\n  let index = 0;\n  // select with number\n  if ( initialIndex && this.slides[ initialIndex ] ) {\n    index = initialIndex;\n  }\n  // select instantly\n  this.select( index, false, true );\n};\n\n/**\n * select slide from number or cell element\n * @param {[Element, Number]} value - zero-based index or element to select\n * @param {Boolean} isWrap - enables wrapping around for extra index\n * @param {Boolean} isInstant - disables slide animation\n */\nproto.selectCell = function( value, isWrap, isInstant ) {\n  // get cell\n  let cell = this.queryCell( value );\n  if ( !cell ) return;\n\n  let index = this.getCellSlideIndex( cell );\n  this.select( index, isWrap, isInstant );\n};\n\nproto.getCellSlideIndex = function( cell ) {\n  // get index of slide that has cell\n  let cellSlide = this.slides.find( ( slide ) => slide.cells.includes( cell ) );\n  return this.slides.indexOf( cellSlide );\n};\n\n// -------------------------- get cells -------------------------- //\n\n/**\n * get Flickity.Cell, given an Element\n * @param {Element} elem - matching cell element\n * @returns {Flickity.Cell} cell - matching cell\n */\nproto.getCell = function( elem ) {\n  // loop through cells to get the one that matches\n  for ( let cell of this.cells ) {\n    if ( cell.element === elem ) return cell;\n  }\n};\n\n/**\n * get collection of Flickity.Cells, given Elements\n * @param {[Element, Array, NodeList]} elems - multiple elements\n * @returns {Array} cells - Flickity.Cells\n */\nproto.getCells = function( elems ) {\n  elems = utils.makeArray( elems );\n  return elems.map( ( elem ) => this.getCell( elem ) ).filter( Boolean );\n};\n\n/**\n * get cell elements\n * @returns {Array} cellElems\n */\nproto.getCellElements = function() {\n  return this.cells.map( ( cell ) => cell.element );\n};\n\n/**\n * get parent cell from an element\n * @param {Element} elem - child element\n * @returns {Flickit.Cell} cell - parent cell\n */\nproto.getParentCell = function( elem ) {\n  // first check if elem is cell\n  let cell = this.getCell( elem );\n  if ( cell ) return cell;\n\n  // try to get parent cell elem\n  let closest = elem.closest('.flickity-slider > *');\n  return this.getCell( closest );\n};\n\n/**\n * get cells adjacent to a slide\n * @param {Integer} adjCount - number of adjacent slides\n * @param {Integer} index - index of slide to start\n * @returns {Array} cells - array of Flickity.Cells\n */\nproto.getAdjacentCellElements = function( adjCount, index ) {\n  if ( !adjCount ) return this.selectedSlide.getCellElements();\n\n  index = index === undefined ? this.selectedIndex : index;\n\n  let len = this.slides.length;\n  if ( 1 + ( adjCount * 2 ) >= len ) {\n    return this.getCellElements(); // get all\n  }\n\n  let cellElems = [];\n  for ( let i = index - adjCount; i <= index + adjCount; i++ ) {\n    let slideIndex = this.isWrapping ? utils.modulo( i, len ) : i;\n    let slide = this.slides[ slideIndex ];\n    if ( slide ) {\n      cellElems = cellElems.concat( slide.getCellElements() );\n    }\n  }\n  return cellElems;\n};\n\n/**\n * select slide from number or cell element\n * @param {[Element, String, Number]} selector - element, selector string, or index\n * @returns {Flickity.Cell} - matching cell\n */\nproto.queryCell = function( selector ) {\n  if ( typeof selector == 'number' ) {\n    // use number as index\n    return this.cells[ selector ];\n  }\n  // do not select invalid selectors from hash: #123, #/. #791\n  let isSelectorStr
1ing = typeof selector == 'string' && !selector.match( /^[#.]?[\\d/]/ );\n  if ( isSelectorString ) {\n    // use string as selector, get element\n    selector = this.element.querySelector( selector );\n  }\n  // get cell from element\n  return this.getCell( selector );\n};\n\n// -------------------------- events -------------------------- //\n\nproto.uiChange = function() {\n  this.emitEvent('uiChange');\n};\n\n// ----- resize ----- //\n\nproto.onresize = function() {\n  this.watchCSS();\n  this.resize();\n};\n\nutils.debounceMethod( Flickity, 'onresize', 150 );\n\nproto.resize = function() {\n  // #1177 disable resize behavior when animating or dragging for iOS 15\n  if ( !this.isActive || this.isAnimating || this.isDragging ) return;\n  this.getSize();\n  // wrap values\n  if ( this.isWrapping ) {\n    this.x = utils.modulo( this.x, this.slideableWidth );\n  }\n  this.positionCells();\n  this._updateWrapShiftCells();\n  this.setGallerySize();\n  this.emitEvent('resize');\n  // update selected index for group slides, instant\n  // TODO: position can be lost between groups of various numbers\n  let selectedElement = this.selectedElements && this.selectedElements[0];\n  this.selectCell( selectedElement, false, true );\n};\n\n// watches the :after property, activates/deactivates\nproto.watchCSS = function() {\n  if ( !this.options.watchCSS ) return;\n\n  let afterContent = getComputedStyle( this.element, ':after' ).content;\n  // activate if :after { content: 'flickity' }\n  if ( afterContent.includes('flickity') ) {\n    this.activate();\n  } else {\n    this.deactivate();\n  }\n};\n\n// ----- keydown ----- //\n\n// go previous/next if left/right keys pressed\nproto.onkeydown = function( event ) {\n  let { activeElement } = document;\n  let handler = Flickity.keyboardHandlers[ event.key ];\n  // only work if element is in focus\n  if ( !this.options.accessibility || !activeElement || !handler ) return;\n\n  let isFocused = this.focusableElems.some( ( elem ) => activeElement === elem );\n  if ( isFocused ) handler.call( this );\n};\n\nFlickity.keyboardHandlers = {\n  ArrowLeft: function() {\n    this.uiChange();\n    let leftMethod = this.options.rightToLeft ? 'next' : 'previous';\n    this[ leftMethod ]();\n  },\n  ArrowRight: function() {\n    this.uiChange();\n    let rightMethod = this.options.rightToLeft ? 'previous' : 'next';\n    this[ rightMethod ]();\n  },\n};\n\n// ----- focus ----- //\n\nproto.focus = function() {\n  this.element.focus({ preventScroll: true });\n};\n\n// -------------------------- destroy -------------------------- //\n\n// deactivate all Flickity functionality, but keep stuff available\nproto.deactivate = function() {\n  if ( !this.isActive ) return;\n\n  this.element.classList.remove('flickity-enabled');\n  this.element.classList.remove('flickity-rtl');\n  this.unselectSelectedSlide();\n  // destroy cells\n  this.cells.forEach( ( cell ) => cell.destroy() );\n  this.viewport.remove();\n  // move child elements back into element\n  this.element.append( ...this.slider.children );\n  if ( this.options.accessibility ) {\n    this.element.removeAttribute('tabIndex');\n    this.element.removeEventListener( 'keydown', this );\n  }\n  // set flags\n  this.isActive = false;\n  this.emitEvent('deactivate');\n};\n\nproto.destroy = function() {\n  this.deactivate();\n  window.removeEventListener( 'resize', this );\n  this.allOff();\n  this.emitEvent('destroy');\n  if ( jQuery && this.$element ) {\n    jQuery.removeData( this.element, 'flickity' );\n  }\n  delete this.element.flickityGUID;\n  delete instances[ this.guid ];\n};\n\n// -------------------------- prototype -------------------------- //\n\nObject.assign( proto, animatePrototype );\n\n// -------------------------- extras -------------------------- //\n\n/**\n * get Flickity instance from element\n * @param {[Element, String]} elem - element or selector string\n * @returns {Flickity} - Flickity instance\n */\nFlickity.data = function( elem ) {\n  elem = utils.getQueryElement( elem );\n  if ( elem ) return instances[ elem.flickityGUID ];\n};\n\nutils.htmlInit( Flickity, 'flickity' );\n\nlet { jQueryBridget } = window;\nif ( jQuery && jQueryBridget ) {\n  jQueryBridget( 'flickity', Flickity, jQuery );\n}\n\n// set internal jQuery, for Webpack + jQuery v3, #478\nFlickity.setJQuery = function( jq ) {\n  jQuery = jq;\n};\n\nFlickity.Cell = Cell;\nFlickity.Slide = Slide;\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/core.js?\n}")},"./node_modules/flickity/js/drag.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// drag\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        window,\n        __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\"),\n        __webpack_require__(/*! unidragger */ \"./node_modules/unidragger/unidragger.js\"),\n        __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\"),\n    );\n  } else {\n    // browser global\n    window.Flickity = factory(\n        window,\n        window.Flickity,\n        window.Unidragger,\n        window.fizzyUIUtils,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this,\n    function factory( window, Flickity, Unidragger, utils ) {\n\n// ----- defaults ----- //\n\nObject.assign( Flickity.defaults, {\n  draggable: '>1',\n  dragThreshold: 3,\n} );\n\n// -------------------------- drag prototype -------------------------- //\n\nlet proto = Flickity.prototype;\nObject.assign( proto, Unidragger.prototype ); // inherit Unidragger\nproto.touchActionValue = '';\n\n// --------------------------  -------------------------- //\n\nFlickity.create.drag = function() {\
1n  this.on( 'activate', this.onActivateDrag );\n  this.on( 'uiChange', this._uiChangeDrag );\n  this.on( 'deactivate', this.onDeactivateDrag );\n  this.on( 'cellChange', this.updateDraggable );\n  this.on( 'pointerDown', this.handlePointerDown );\n  this.on( 'pointerUp', this.handlePointerUp );\n  this.on( 'pointerDown', this.handlePointerDone );\n  this.on( 'dragStart', this.handleDragStart );\n  this.on( 'dragMove', this.handleDragMove );\n  this.on( 'dragEnd', this.handleDragEnd );\n  this.on( 'staticClick', this.handleStaticClick );\n  // TODO updateDraggable on resize? if groupCells & slides change\n};\n\nproto.onActivateDrag = function() {\n  this.handles = [ this.viewport ];\n  this.bindHandles();\n  this.updateDraggable();\n};\n\nproto.onDeactivateDrag = function() {\n  this.unbindHandles();\n  this.element.classList.remove('is-draggable');\n};\n\nproto.updateDraggable = function() {\n  // disable dragging if less than 2 slides. #278\n  if ( this.options.draggable === '>1' ) {\n    this.isDraggable = this.slides.length > 1;\n  } else {\n    this.isDraggable = this.options.draggable;\n  }\n  this.element.classList.toggle( 'is-draggable', this.isDraggable );\n};\n\nproto._uiChangeDrag = function() {\n  delete this.isFreeScrolling;\n};\n\n// -------------------------- pointer events -------------------------- //\n\nproto.handlePointerDown = function( event ) {\n  if ( !this.isDraggable ) {\n    // proceed for staticClick\n    this.bindActivePointerEvents( event );\n    return;\n  }\n\n  let isTouchStart = event.type === 'touchstart';\n  let isTouchPointer = event.pointerType === 'touch';\n  let isFocusNode = event.target.matches('input, textarea, select');\n  if ( !isTouchStart && !isTouchPointer && !isFocusNode ) event.preventDefault();\n  if ( !isFocusNode ) this.focus();\n  // blur\n  if ( document.activeElement !== this.element ) document.activeElement.blur();\n  // stop if it was moving\n  this.dragX = this.x;\n  this.viewport.classList.add('is-pointer-down');\n  // track scrolling\n  this.pointerDownScroll = getScrollPosition();\n  window.addEventListener( 'scroll', this );\n  this.bindActivePointerEvents( event );\n};\n\n// ----- move ----- //\n\nproto.hasDragStarted = function( moveVector ) {\n  return Math.abs( moveVector.x ) > this.options.dragThreshold;\n};\n\n// ----- up ----- //\n\nproto.handlePointerUp = function() {\n  delete this.isTouchScrolling;\n  this.viewport.classList.remove('is-pointer-down');\n};\n\nproto.handlePointerDone = function() {\n  window.removeEventListener( 'scroll', this );\n  delete this.pointerDownScroll;\n};\n\n// -------------------------- dragging -------------------------- //\n\nproto.handleDragStart = function() {\n  if ( !this.isDraggable ) return;\n\n  this.dragStartPosition = this.x;\n  this.startAnimation();\n  window.removeEventListener( 'scroll', this );\n};\n\nproto.handleDragMove = function( event, pointer, moveVector ) {\n  if ( !this.isDraggable ) return;\n\n  event.preventDefault();\n\n  this.previousDragX = this.dragX;\n  // reverse if right-to-left\n  let direction = this.options.rightToLeft ? -1 : 1;\n  // wrap around move. #589\n  if ( this.isWrapping ) moveVector.x %= this.slideableWidth;\n  let dragX = this.dragStartPosition + moveVector.x * direction;\n\n  if ( !this.isWrapping ) {\n    // slow drag\n    let originBound = Math.max( -this.slides[0].target, this.dragStartPosition );\n    dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX;\n    let endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition );\n    dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX;\n  }\n\n  this.dragX = dragX;\n  this.dragMoveTime = new Date();\n};\n\nproto.handleDragEnd = function() {\n  if ( !this.isDraggable ) return;\n\n  let { freeScroll } = this.options;\n  if ( freeScroll ) this.isFreeScrolling = true;\n  // set selectedIndex based on where flick will end up\n  let index = this.dragEndRestingSelect();\n\n  if ( freeScroll && !this.isWrapping ) {\n    // if free-scroll & not wrap around\n    // do not free-scroll if going outside of bounding slides\n    // so bounding slides can attract slider, and keep it in bounds\n    let restingX = this.getRestingPosition();\n    this.isFreeScrolling = -restingX > this.slides[0].target &&\n      -restingX < this.getLastSlide().target;\n  } else if ( !freeScroll && index === this.selectedIndex ) {\n    // boost selection if selected index has not changed\n    index += this.dragEndBoostSelect();\n  }\n  delete this.previousDragX;\n  // apply selection\n  // HACK, set flag so dragging stays in correct direction\n  this.isDragSelect = this.isWrapping;\n  this.select( index );\n  delete this.isDragSelect;\n};
1\n\nproto.dragEndRestingSelect = function() {\n  let restingX = this.getRestingPosition();\n  // how far away from selected slide\n  let distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) );\n  // get closet resting going up and going down\n  let positiveResting = this._getClosestResting( restingX, distance, 1 );\n  let negativeResting = this._getClosestResting( restingX, distance, -1 );\n  // use closer resting for wrap-around\n  return positiveResting.distance < negativeResting.distance ?\n    positiveResting.index : negativeResting.index;\n};\n\n/**\n * given resting X and distance to selected cell\n * get the distance and index of the closest cell\n * @param {Number} restingX - estimated post-flick resting position\n * @param {Number} distance - distance to selected cell\n * @param {Integer} increment - +1 or -1, going up or down\n * @returns {Object} - { distance: {Number}, index: {Integer} }\n */\nproto._getClosestResting = function( restingX, distance, increment ) {\n  let index = this.selectedIndex;\n  let minDistance = Infinity;\n  let condition = this.options.contain && !this.isWrapping ?\n    // if containing, keep going if distance is equal to minDistance\n    ( dist, minDist ) => dist <= minDist :\n    ( dist, minDist ) => dist < minDist;\n\n  while ( condition( distance, minDistance ) ) {\n    // measure distance to next cell\n    index += increment;\n    minDistance = distance;\n    distance = this.getSlideDistance( -restingX, index );\n    if ( distance === null ) break;\n\n    distance = Math.abs( distance );\n  }\n  return {\n    distance: minDistance,\n    // selected was previous index\n    index: index - increment,\n  };\n};\n\n/**\n * measure distance between x and a slide target\n * @param {Number} x - horizontal position\n * @param {Integer} index - slide index\n * @returns {Number} - slide distance\n */\nproto.getSlideDistance = function( x, index ) {\n  let len = this.slides.length;\n  // wrap around if at least 2 slides\n  let isWrapAround = this.options.wrapAround && len > 1;\n  let slideIndex = isWrapAround ? utils.modulo( index, len ) : index;\n  let slide = this.slides[ slideIndex ];\n  if ( !slide ) return null;\n\n  // add distance for wrap-around slides\n  let wrap = isWrapAround ? this.slideableWidth * Math.floor( index/len ) : 0;\n  return x - ( slide.target + wrap );\n};\n\nproto.dragEndBoostSelect = function() {\n  // do not boost if no previousDragX or dragMoveTime\n  if ( this.previousDragX === undefined || !this.dragMoveTime ||\n    // or if drag was held for 100 ms\n    new Date() - this.dragMoveTime > 100 ) {\n    return 0;\n  }\n\n  let distance = this.getSlideDistance( -this.dragX, this.selectedIndex );\n  let delta = this.previousDragX - this.dragX;\n  if ( distance > 0 && delta > 0 ) {\n    // boost to next if moving towards the right, and positive velocity\n    return 1;\n  } else if ( distance < 0 && delta < 0 ) {\n    // boost to previous if moving towards the left, and negative velocity\n    return -1;\n  }\n  return 0;\n};\n\n// ----- scroll ----- //\n\nproto.onscroll = function() {\n  let scroll = getScrollPosition();\n  let scrollMoveX = this.pointerDownScroll.x - scroll.x;\n  let scrollMoveY = this.pointerDownScroll.y - scroll.y;\n  // cancel click/tap if scroll is too much\n  if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) {\n    this.pointerDone();\n  }\n};\n\n// ----- utils ----- //\n\nfunction getScrollPosition() {\n  return {\n    x: window.pageXOffset,\n    y: window.pageYOffset,\n  };\n}\n\n// -----  ----- //\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/drag.js?\n}")},"./node_modules/flickity/js/imagesloaded.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// imagesloaded\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\"),\n        __webpack_require__(/*! imagesloaded */ \"./node_modules/imagesloaded/imagesloaded.js\"),\n    );\n  } else {\n    // browser global\n    factory(\n        window.Flickity,\n        window.imagesLoaded,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this,\n    function factory( Flickity, imagesLoaded ) {\n\nFlickity.create.imagesLoaded = function() {\
1n  this.on( 'activate', this.imagesLoaded );\n};\n\nFlickity.prototype.imagesLoaded = function() {\n  if ( !this.options.imagesLoaded ) return;\n\n  let onImagesLoadedProgress = ( instance, image ) => {\n    let cell = this.getParentCell( image.img );\n    this.cellSizeChange( cell && cell.element );\n    if ( !this.options.freeScroll ) this.positionSliderAtSelected();\n  };\n  imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress );\n};\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/imagesloaded.js?\n}")},"./node_modules/flickity/js/index.js"(module,__unused_webpack_exports,__webpack_require__){eval('{/*!\n * Flickity v3.0.0\n * Touch, responsive, flickable carousels\n *\n * Licensed GPLv3 for open source use\n * or Flickity Commercial License for commercial use\n *\n * https://flickity.metafizzy.co\n * Copyright 2015-2022 Metafizzy\n */\n\nif (  true && module.exports ) {\n  const Flickity = __webpack_require__(/*! ./core */ "./node_modules/flickity/js/core.js");\n  __webpack_require__(/*! ./drag */ "./node_modules/flickity/js/drag.js");\n  __webpack_require__(/*! ./prev-next-button */ "./node_modules/flickity/js/prev-next-button.js");\n  __webpack_require__(/*! ./page-dots */ "./node_modules/flickity/js/page-dots.js");\n  __webpack_require__(/*! ./player */ "./node_modules/flickity/js/player.js");\n  __webpack_require__(/*! ./add-remove-cell */ "./node_modules/flickity/js/add-remove-cell.js");\n  __webpack_require__(/*! ./lazyload */ "./node_modules/flickity/js/lazyload.js");\n  __webpack_require__(/*! ./imagesloaded */ "./node_modules/flickity/js/imagesloaded.js");\n\n  module.exports = Flickity;\n}\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/index.js?\n}')},"./node_modules/flickity/js/lazyload.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// lazyload\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\"),\n        __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\"),\n    );\n  } else {\n    // browser global\n    factory(\n        window.Flickity,\n        window.fizzyUIUtils,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( Flickity, utils ) {\n\nconst lazyAttr = 'data-flickity-lazyload';\nconst lazySrcAttr = `${lazyAttr}-src`;\nconst lazySrcsetAttr = `${lazyAttr}-srcset`;\nconst imgSelector = `img[${lazyAttr}], img[${lazySrcAttr}], ` +\n  `img[${lazySrcsetAttr}], source[${lazySrcsetAttr}]`;\n\nFlickity.create.lazyLoad = function() {\n  this.on( 'select', this.lazyLoad );\n\n  this.handleLazyLoadComplete = this.onLazyLoadComplete.bind( this );\n};\n\nlet proto = Flickity.prototype;\n\nproto.lazyLoad = function() {\n  let { lazyLoad } = this.options;\n  if ( !lazyLoad ) return;\n\n  // get adjacent cells, use lazyLoad option for adjacent count\n  let adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0;\n  // lazy load images\n  this.getAdjacentCellElements( adjCount )\n    .map( getCellLazyImages )\n    .flat()\n    .forEach( ( img ) => new LazyLoader( img, this.handleLazyLoadComplete ) );\n};\n\nfunction getCellLazyImages( cellElem ) {\n  // check if cell element is lazy image\n  if ( cellElem.matches('img') ) {\n    let cellAttr = cellElem.getAttribute( lazyAttr );\n    let cellSrcAttr = cellElem.getAttribute( lazySrcAttr );\n    let cellSrcsetAttr = cellElem.getAttribute( lazySrcsetAttr );\n    if ( cellAttr || cellSrcAttr || cellSrcsetAttr ) {\n      return cellElem;\n    }\n  }\n  // select lazy images in cell\n  return [ ...cellElem.querySelectorAll( imgSelector ) ];\n}\n\nproto.onLazyLoadComplete = function( img, event ) {\n  let cell = this.getParentCell( img );\n  let cellElem = cell && cell.element;\n  this.cellSizeChange( cellElem );\n\n  this.dispatchEvent( 'lazyLoad', event, cellElem );\n};\n\n// -------------------------- LazyLoader -------------------------- //\n\n/**\n * class to handle loading images\n * @param {Image} img - Image element\n * @param {Function} onComplete - callback function\n */\nfunction LazyLoader( img, onComplete ) {\n  this.img = img;\n  this.onComplete = onComplete;\n  this.load();\n}\n\nLazyLoader.prototype.handleEvent = utils.handleEvent;
1\n\nLazyLoader.prototype.load = function() {\n  this.img.addEventListener( 'load', this );\n  this.img.addEventListener( 'error', this );\n  // get src & srcset\n  let src = this.img.getAttribute( lazyAttr ) ||\n    this.img.getAttribute( lazySrcAttr );\n  let srcset = this.img.getAttribute( lazySrcsetAttr );\n  // set src & serset\n  this.img.src = src;\n  if ( srcset ) this.img.setAttribute( 'srcset', srcset );\n  // remove attr\n  this.img.removeAttribute( lazyAttr );\n  this.img.removeAttribute( lazySrcAttr );\n  this.img.removeAttribute( lazySrcsetAttr );\n};\n\nLazyLoader.prototype.onload = function( event ) {\n  this.complete( event, 'flickity-lazyloaded' );\n};\n\nLazyLoader.prototype.onerror = function( event ) {\n  this.complete( event, 'flickity-lazyerror' );\n};\n\nLazyLoader.prototype.complete = function( event, className ) {\n  // unbind events\n  this.img.removeEventListener( 'load', this );\n  this.img.removeEventListener( 'error', this );\n  let mediaElem = this.img.parentNode.matches('picture') ? this.img.parentNode : this.img;\n  mediaElem.classList.add( className );\n\n  this.onComplete( this.img, event );\n};\n\n// -----  ----- //\n\nFlickity.LazyLoader = LazyLoader;\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/lazyload.js?\n}")},"./node_modules/flickity/js/page-dots.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// page dots\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\"),\n        __webpack_require__(/*! fizzy-ui-utils */ \"./node_modules/fizzy-ui-utils/utils.js\"),\n    );\n  } else {\n    // browser global\n    factory(\n        window.Flickity,\n        window.fizzyUIUtils,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( Flickity, utils ) {\n\n// -------------------------- PageDots -------------------------- //\n\nfunction PageDots() {\n  // create holder element\n  this.holder = document.createElement('div');\n  this.holder.className = 'flickity-page-dots';\n  // create dots, array of elements\n  this.dots = [];\n}\n\nPageDots.prototype.setDots = function( slidesLength ) {\n  // get difference between number of slides and number of dots\n  let delta = slidesLength - this.dots.length;\n  if ( delta > 0 ) {\n    this.addDots( delta );\n  } else if ( delta < 0 ) {\n    this.removeDots( -delta );\n  }\n};\n\nPageDots.prototype.addDots = function( count ) {\n  let newDots = new Array( count ).fill()\n    .map( ( item, i ) => {\n      let dot = document.createElement('button');\n      dot.setAttribute( 'type', 'button' );\n      let num = i + 1 + this.dots.length;\n      dot.className = 'flickity-page-dot';\n      dot.textContent = `View slide ${num}`;\n      return dot;\n    } );\n\n  this.holder.append( ...newDots );\n  this.dots = this.dots.concat( newDots );\n};\n\nPageDots.prototype.removeDots = function( count ) {\n  // remove from this.dots collection\n  let removeDots = this.dots.splice( this.dots.length - count, count );\n  // remove from DOM\n  removeDots.forEach( ( dot ) => dot.remove() );\n};\n\nPageDots.prototype.updateSelected = function( index ) {\n  // remove selected class on previous\n  if ( this.selectedDot ) {\n    this.selectedDot.classList.remove('is-selected');\n    this.selectedDot.removeAttribute('aria-current');\n  }\n  // don't proceed if no dots\n  if ( !this.dots.length ) return;\n\n  this.selectedDot = this.dots[ index ];\n  this.selectedDot.classList.add('is-selected');\n  this.selectedDot.setAttribute( 'aria-current', 'step' );\n};\n\nFlickity.PageDots = PageDots;\n\n// -------------------------- Flickity -------------------------- //\n\nObject.assign( Flickity.defaults, {\n  pageDots: true,\n} );\n\nFlickity.create.pageDots = function() {\n  if ( !this.options.pageDots ) return;\n\n  this.pageDots = new PageDots();\n  this.handlePageDotsClick = this.onPageDotsClick.bind( this );\n  // events\n  this.on( 'activate', this.activatePageDots );\n  this.on( 'select', this.updateSelectedPageDots );\n  this.on( 'cellChange', this.updatePageDots );\n  this.on( 'resize', this.updatePageDots );\n  this.on( 'deactivate', this.deactivatePageDots );\n};\n\nlet proto = Flickity.prototype;
1\n\nproto.activatePageDots = function() {\n  this.pageDots.setDots( this.slides.length );\n  this.focusableElems.push( ...this.pageDots.dots );\n  this.pageDots.holder.addEventListener( 'click', this.handlePageDotsClick );\n  this.element.append( this.pageDots.holder );\n};\n\nproto.onPageDotsClick = function( event ) {\n  let index = this.pageDots.dots.indexOf( event.target );\n  if ( index === -1 ) return; // only dot clicks\n\n  this.uiChange();\n  this.select( index );\n};\n\nproto.updateSelectedPageDots = function() {\n  this.pageDots.updateSelected( this.selectedIndex );\n};\n\nproto.updatePageDots = function() {\n  this.pageDots.dots.forEach( ( dot ) => {\n    utils.removeFrom( this.focusableElems, dot );\n  } );\n  this.pageDots.setDots( this.slides.length );\n  this.focusableElems.push( ...this.pageDots.dots );\n};\n\nproto.deactivatePageDots = function() {\n  this.pageDots.holder.remove();\n  this.pageDots.holder.removeEventListener( 'click', this.handlePageDotsClick );\n};\n\n// -----  ----- //\n\nFlickity.PageDots = PageDots;\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/page-dots.js?\n}")},"./node_modules/flickity/js/player.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// player & autoPlay\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\") );\n  } else {\n    // browser global\n    factory( window.Flickity );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( Flickity ) {\n\n// -------------------------- Player -------------------------- //\n\nfunction Player( autoPlay, onTick ) {\n  this.autoPlay = autoPlay;\n  this.onTick = onTick;\n  this.state = 'stopped';\n  // visibility change event handler\n  this.onVisibilityChange = this.visibilityChange.bind( this );\n  this.onVisibilityPlay = this.visibilityPlay.bind( this );\n}\n\n// start play\nPlayer.prototype.play = function() {\n  if ( this.state === 'playing' ) return;\n\n  // do not play if page is hidden, start playing when page is visible\n  let isPageHidden = document.hidden;\n  if ( isPageHidden ) {\n    document.addEventListener( 'visibilitychange', this.onVisibilityPlay );\n    return;\n  }\n\n  this.state = 'playing';\n  // listen to visibility change\n  document.addEventListener( 'visibilitychange', this.onVisibilityChange );\n  // start ticking\n  this.tick();\n};\n\nPlayer.prototype.tick = function() {\n  // do not tick if not playing\n  if ( this.state !== 'playing' ) return;\n\n  // default to 3 seconds\n  let time = typeof this.autoPlay == 'number' ? this.autoPlay : 3000;\n  // HACK: reset ticks if stopped and started within interval\n  this.clear();\n  this.timeout = setTimeout( () => {\n    this.onTick();\n    this.tick();\n  }, time );\n};\n\nPlayer.prototype.stop = function() {\n  this.state = 'stopped';\n  this.clear();\n  // remove visibility change event\n  document.removeEventListener( 'visibilitychange', this.onVisibilityChange );\n};\n\nPlayer.prototype.clear = function() {\n  clearTimeout( this.timeout );\n};\n\nPlayer.prototype.pause = function() {\n  if ( this.state === 'playing' ) {\n    this.state = 'paused';\n    this.clear();\n  }\n};\n\nPlayer.prototype.unpause = function() {\n  // re-start play if paused\n  if ( this.state === 'paused' ) this.play();\n};\n\n// pause if page visibility is hidden, unpause if visible\nPlayer.prototype.visibilityChange = function() {\n  let isPageHidden = document.hidden;\n  this[ isPageHidden ? 'pause' : 'unpause' ]();\n};\n\nPlayer.prototype.visibilityPlay = function() {\n  this.play();\n  document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );\n};\n\n// -------------------------- Flickity -------------------------- //\n\nObject.assign( Flickity.defaults, {\n  pauseAutoPlayOnHover: true,\n} );\n\nFlickity.create.player = function() {\n  this.player = new Player( this.options.autoPlay, () => {\n    this.next( true );\n  } );\n\n  this.on( 'activate', this.activatePlayer );\n  this.on( 'uiChange', this.stopPlayer );\n  this.on( 'pointerDown', this.stopPlayer );\n  this.on( 'deactivate', this.deactivatePlayer );\n};\n\nlet proto = Flickity.prototype;
1\n\nproto.activatePlayer = function() {\n  if ( !this.options.autoPlay ) return;\n\n  this.player.play();\n  this.element.addEventListener( 'mouseenter', this );\n};\n\n// Player API, don't hate the ... thanks I know where the door is\n\nproto.playPlayer = function() {\n  this.player.play();\n};\n\nproto.stopPlayer = function() {\n  this.player.stop();\n};\n\nproto.pausePlayer = function() {\n  this.player.pause();\n};\n\nproto.unpausePlayer = function() {\n  this.player.unpause();\n};\n\nproto.deactivatePlayer = function() {\n  this.player.stop();\n  this.element.removeEventListener( 'mouseenter', this );\n};\n\n// ----- mouseenter/leave ----- //\n\n// pause auto-play on hover\nproto.onmouseenter = function() {\n  if ( !this.options.pauseAutoPlayOnHover ) return;\n\n  this.player.pause();\n  this.element.addEventListener( 'mouseleave', this );\n};\n\n// resume auto-play on hover off\nproto.onmouseleave = function() {\n  this.player.unpause();\n  this.element.removeEventListener( 'mouseleave', this );\n};\n\n// -----  ----- //\n\nFlickity.Player = Player;\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/player.js?\n}")},"./node_modules/flickity/js/prev-next-button.js"(module,__unused_webpack_exports,__webpack_require__){eval("{// prev/next buttons\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( __webpack_require__(/*! ./core */ \"./node_modules/flickity/js/core.js\") );\n  } else {\n    // browser global\n    factory( window.Flickity );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( Flickity ) {\n\nconst svgURI = 'http://www.w3.org/2000/svg';\n\n// -------------------------- PrevNextButton -------------------------- //\n\nfunction PrevNextButton( increment, direction, arrowShape ) {\n  this.increment = increment;\n  this.direction = direction;\n  this.isPrevious = increment === 'previous';\n  this.isLeft = direction === 'left';\n  this._create( arrowShape );\n}\n\nPrevNextButton.prototype._create = function( arrowShape ) {\n  // properties\n  let element = this.element = document.createElement('button');\n  element.className = `flickity-button flickity-prev-next-button ${this.increment}`;\n  let label = this.isPrevious ? 'Previous' : 'Next';\n  // prevent button from submitting form https://stackoverflow.com/a/10836076/182183\n  element.setAttribute( 'type', 'button' );\n  element.setAttribute( 'aria-label', label );\n  // init as disabled\n  this.disable();\n  // create arrow\n  let svg = this.createSVG( label, arrowShape );\n  element.append( svg );\n};\n\nPrevNextButton.prototype.createSVG = function( label, arrowShape ) {\n  let svg = document.createElementNS( svgURI, 'svg' );\n  svg.setAttribute( 'class', 'flickity-button-icon' );\n  svg.setAttribute( 'viewBox', '0 0 100 100' );\n  // add title #1189\n  let title = document.createElementNS( svgURI, 'title' );\n  title.append( label );\n  // add path\n  let path = document.createElementNS( svgURI, 'path' );\n  let pathMovements = getArrowMovements( arrowShape );\n  path.setAttribute( 'd', pathMovements );\n  path.setAttribute( 'class', 'arrow' );\n  // rotate arrow\n  if ( !this.isLeft ) {\n    path.setAttribute( 'transform', 'translate(100, 100) rotate(180)' );\n  }\n  svg.append( title, path );\n  return svg;\n};\n\n// get SVG path movmement\nfunction getArrowMovements( shape ) {\n  // use shape as movement if string\n  if ( typeof shape == 'string' ) return shape;\n\n  let { x0, x1, x2, x3, y1, y2 } = shape;\n\n  // create movement string\n  return `M ${x0}, 50\n    L ${x1}, ${y1 + 50}\n    L ${x2}, ${y2 + 50}\n    L ${x3}, 50\n    L ${x2}, ${50 - y2}\n    L ${x1}, ${50 - y1}\n    Z`;\n}\n\n// -----  ----- //\n\nPrevNextButton.prototype.enable = function() {\n  this.element.removeAttribute('disabled');\n};\n\nPrevNextButton.prototype.disable = function() {\n  this.element.setAttribute( 'disabled', true );\n};\n\n// -------------------------- Flickity prototype -------------------------- //\n\nObject.assign( Flickity.defaults, {\n  prevNextButtons: true,\n  arrowShape: {\n    x0: 10,\n    x1: 60, y1: 50,\n    x2: 70, y2: 40,\n    x3: 30,\n  },\n} );
1\n\nFlickity.create.prevNextButtons = function() {\n  if ( !this.options.prevNextButtons ) return;\n\n  let { rightToLeft, arrowShape } = this.options;\n  let prevDirection = rightToLeft ? 'right' : 'left';\n  let nextDirection = rightToLeft ? 'left' : 'right';\n  this.prevButton = new PrevNextButton( 'previous', prevDirection, arrowShape );\n  this.nextButton = new PrevNextButton( 'next', nextDirection, arrowShape );\n  this.focusableElems.push( this.prevButton.element );\n  this.focusableElems.push( this.nextButton.element );\n\n  this.handlePrevButtonClick = () => {\n    this.uiChange();\n    this.previous();\n  };\n\n  this.handleNextButtonClick = () => {\n    this.uiChange();\n    this.next();\n  };\n\n  this.on( 'activate', this.activatePrevNextButtons );\n  this.on( 'select', this.updatePrevNextButtons );\n};\n\nlet proto = Flickity.prototype;\n\nproto.updatePrevNextButtons = function() {\n  let lastIndex = this.slides.length ? this.slides.length - 1 : 0;\n  this.updatePrevNextButton( this.prevButton, 0 );\n  this.updatePrevNextButton( this.nextButton, lastIndex );\n};\n\nproto.updatePrevNextButton = function( button, disabledIndex ) {\n  // enable is wrapAround and at least 2 slides\n  if ( this.isWrapping && this.slides.length > 1 ) {\n    button.enable();\n    return;\n  }\n\n  let isEnabled = this.selectedIndex !== disabledIndex;\n  button[ isEnabled ? 'enable' : 'disable' ]();\n  // if disabling button that is focused,\n  // shift focus to element to maintain keyboard accessibility\n  let isDisabledFocused = !isEnabled && document.activeElement === button.element;\n  if ( isDisabledFocused ) this.focus();\n};\n\nproto.activatePrevNextButtons = function() {\n  this.prevButton.element.addEventListener( 'click', this.handlePrevButtonClick );\n  this.nextButton.element.addEventListener( 'click', this.handleNextButtonClick );\n  this.element.append( this.prevButton.element, this.nextButton.element );\n  this.on( 'deactivate', this.deactivatePrevNextButtons );\n};\n\nproto.deactivatePrevNextButtons = function() {\n  this.prevButton.element.remove();\n  this.nextButton.element.remove();\n  this.prevButton.element.removeEventListener( 'click', this.handlePrevButtonClick );\n  this.nextButton.element.removeEventListener( 'click', this.handleNextButtonClick );\n  this.off( 'deactivate', this.deactivatePrevNextButtons );\n};\n\n// --------------------------  -------------------------- //\n\nFlickity.PrevNextButton = PrevNextButton;\n\nreturn Flickity;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/prev-next-button.js?\n}")},"./node_modules/flickity/js/slide.js"(module){eval("{// slide\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory();\n  } else {\n    // browser global\n    window.Flickity = window.Flickity || {};\n    window.Flickity.Slide = factory();\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory() {\n\nfunction Slide( beginMargin, endMargin, cellAlign ) {\n  this.beginMargin = beginMargin;\n  this.endMargin = endMargin;\n  this.cellAlign = cellAlign;\n  this.cells = [];\n  this.outerWidth = 0;\n  this.height = 0;\n}\n\nlet proto = Slide.prototype;\n\nproto.addCell = function( cell ) {\n  this.cells.push( cell );\n  this.outerWidth += cell.size.outerWidth;\n  this.height = Math.max( cell.size.outerHeight, this.height );\n  // first cell stuff\n  if ( this.cells.length === 1 ) {\n    this.x = cell.x; // x comes from first cell\n    this.firstMargin = cell.size[ this.beginMargin ];\n  }\n};\n\nproto.updateTarget = function() {\n  let lastCell = this.getLastCell();\n  let lastMargin = lastCell ? lastCell.size[ this.endMargin ] : 0;\n  let slideWidth = this.outerWidth - ( this.firstMargin + lastMargin );\n  this.target = this.x + this.firstMargin + slideWidth * this.cellAlign;\n};\n\nproto.getLastCell = function() {\n  return this.cells[ this.cells.length - 1 ];\n};\n\nproto.select = function() {\n  this.cells.forEach( ( cell ) => cell.select() );\n};
1\n\nproto.unselect = function() {\n  this.cells.forEach( ( cell ) => cell.unselect() );\n};\n\nproto.getCellElements = function() {\n  return this.cells.map( ( cell ) => cell.element );\n};\n\nreturn Slide;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/flickity/js/slide.js?\n}")},"./node_modules/get-size/get-size.js"(module){eval("{/*!\n * Infinite Scroll v2.0.4\n * measure size of elements\n * MIT license\n */\n\n( function( window, factory ) {\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory();\n  } else {\n    // browser global\n    window.getSize = factory();\n  }\n\n} )( window, function factory() {\n\n// -------------------------- helpers -------------------------- //\n\n// get a number from a string, not a percentage\nfunction getStyleSize( value ) {\n  let num = parseFloat( value );\n  // not a percent like '100%', and a number\n  let isValid = value.indexOf('%') == -1 && !isNaN( num );\n  return isValid && num;\n}\n\n// -------------------------- measurements -------------------------- //\n\nlet measurements = [\n  'paddingLeft',\n  'paddingRight',\n  'paddingTop',\n  'paddingBottom',\n  'marginLeft',\n  'marginRight',\n  'marginTop',\n  'marginBottom',\n  'borderLeftWidth',\n  'borderRightWidth',\n  'borderTopWidth',\n  'borderBottomWidth',\n];\n\nlet measurementsLength = measurements.length;\n\nfunction getZeroSize() {\n  let size = {\n    width: 0,\n    height: 0,\n    innerWidth: 0,\n    innerHeight: 0,\n    outerWidth: 0,\n    outerHeight: 0,\n  };\n  measurements.forEach( ( measurement ) => {\n    size[ measurement ] = 0;\n  } );\n  return size;\n}\n\n// -------------------------- getSize -------------------------- //\n\nfunction getSize( elem ) {\n  // use querySeletor if elem is string\n  if ( typeof elem == 'string' ) elem = document.querySelector( elem );\n\n  // do not proceed on non-objects\n  let isElement = elem && typeof elem == 'object' && elem.nodeType;\n  if ( !isElement ) return;\n\n  let style = getComputedStyle( elem );\n\n  // if hidden, everything is 0\n  if ( style.display == 'none' ) return getZeroSize();\n\n  let size = {};\n  size.width = elem.offsetWidth;\n  size.height = elem.offsetHeight;\n\n  let isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';\n\n  // get all measurements\n  measurements.forEach( ( measurement ) => {\n    let value = style[ measurement ];\n    let num = parseFloat( value );\n    // any 'auto', 'medium' value will be 0\n    size[ measurement ] = !isNaN( num ) ? num : 0;\n  } );\n\n  let paddingWidth = size.paddingLeft + size.paddingRight;\n  let paddingHeight = size.paddingTop + size.paddingBottom;\n  let marginWidth = size.marginLeft + size.marginRight;\n  let marginHeight = size.marginTop + size.marginBottom;\n  let borderWidth = size.borderLeftWidth + size.borderRightWidth;\n  let borderHeight = size.borderTopWidth + size.borderBottomWidth;\n\n  // overwrite width and height if we can get it from style\n  let styleWidth = getStyleSize( style.width );\n  if ( styleWidth !== false ) {\n    size.width = styleWidth +\n      // add padding and border unless it's already including it\n      ( isBorderBox ? 0 : paddingWidth + borderWidth );\n  }\n\n  let styleHeight = getStyleSize( style.height );\n  if ( styleHeight !== false ) {\n    size.height = styleHeight +\n      // add padding and border unless it's already including it\n      ( isBorderBox ? 0 : paddingHeight + borderHeight );\n  }\n\n  size.innerWidth = size.width - ( paddingWidth + borderWidth );\n  size.innerHeight = size.height - ( paddingHeight + borderHeight );\n\n  size.outerWidth = size.width + marginWidth;\n  size.outerHeight = size.height + marginHeight;\n\n  return size;\n}\n\nreturn getSize;\n\n} );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/get-size/get-size.js?\n}")},"./node_modules/gsap/CSSPlugin.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   CSSPlugin: () => (/* binding */ CSSPlugin),\n/* harmony export */   _createElement: () => (/* binding */ _createElement),\n/* harmony export */   _getBBox: () => (/* binding */ _getBBox),\n/* harmony export */   checkPrefix: () => (/* binding */ _checkPropPrefix),\n/* harmony export */   "default": () => (/* binding */ CSSPlugin)\n/* harmony export */ });\n/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js");\n/*!\n * CSSPlugin 3.15.0\n * https://gsap.com\n *\n * Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\nvar _win,\n    _doc,\n    _docElement,\n    _pluginInitted,\n    _tempDiv,\n    _tempDivStyler,\n    _recentSetterPlugin,\n    _reverting,\n    _windowExists = function _windowExists() {\n  return typeof window !== "undefined";\n},\n    _transformProps = {},\n    _RAD2DEG = 180 / Math.PI,\n    _DEG2RAD = Math.PI / 180,\n    _atan2 = Math.atan2,\n    _bigNum = 1e8,\n    _capsExp = /([A-Z])/g,\n    _horizontalExp = /(left|right|width|margin|padding|x)/i,\n    _complexExp = /[\\s,\\(]\\S/,\n    _propertyAliases = {\n  autoAlpha: "opacity,visibility",\n  scale: "scaleX,scaleY",\n  alpha: "opacity"\n},\n    _renderCSSProp = function _renderCSSProp(ratio, data) {\n  return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n    _renderPropWithEnd = function _renderPropWithEnd(ratio, data) {\n  return data.set(data.t, data.p, ratio === 1 ? data.e : Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u, data);\n},\n    _renderCSSPropWithBeginning = function _renderCSSPropWithBeginning(ratio, data) {\n  return data.set(data.t, data.p, ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);\n},\n    //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)\n_renderCSSPropWithBeginningAndEnd = function _renderCSSPropWithBeginningAndEnd(ratio, data) {\n  return data.set(data.t, data.p, ratio === 1 ? data.e : ratio ? Math.round((data.s + data.c * ratio) * 10000) / 10000 + data.u : data.b, data);\n},\n    //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)\n_renderRoundedCSSProp = function _renderRoundedCSSProp(ratio, data) {\n  var value = data.s + data.c * ratio;\n  data.set(data.t, data.p, ~~(value + (value < 0 ? -.5 : .5)) + data.u, data);\n},\n    _renderNonTweeningValue = function _renderNonTweeningValue(ratio, data) {\n  return data.set(data.t, data.p, ratio ? data.e : data.b, data);\n},\n    _renderNonTweeningValueOnlyAtEnd = function _renderNonTweeningValueOnlyAtEnd(ratio, data) {\n  return data.set(data.t, data.p, ratio !== 1 ? data.b : data.e, data);\n},\n    _setterCSSStyle = function _setterCSSStyle(target, property, value) {\n  return target.style[property] = value;\n},\n    _setterCSSProp = function _setterCSSProp(target, property, value) {\n  return target.style.setProperty(property, value);\n},\n    _setterTransform = function _setterTransform(target, property, value) {\n  return target._gsap[property] = value;\n},\n    _setterScale = function _setterScale(target, property, value) {\n  return target._gsap.scaleX = target._gsap.scaleY = value;\n},\n    _setterScaleWithRender = function _setterScaleWithRender(target, property, value, data, ratio) {\n  var cache = target._gsap;\n  cache.scaleX = cache.scaleY = value;\n  cache.renderTransform(ratio, cache);\n},\n    _setterTransformWithRender = function _setterTransformWithRender(target, property, value, data, ratio) {\n  var cache = target._gsap;\n  cache[property] = value;\n  cache.renderTransform(ratio, cache);\n},\n    _transformProp = "transform",\n    _transformOriginProp = _transformProp + "Origin",\n    _saveStyle = function _saveStyle(property, isNotCSS) {\n  var _this = this;\n\n  var target = this.target,\n      style = target.style,\n      cache = target._gsap;\n\n  if (property in _transformProps && style) {\n    this.tfm = this.tfm || {};\n\n    if (property !== "transform") {\n      property = _propertyAliases[property] || property;\n      ~property.indexOf(",") ? property.split(",").forEach(function (a) {\n        return _this.tfm[a] = _get(target, a);\n      }) : this.tfm[property] = cache.x ? cache[property] : _get(target, property); // note: scale would map to "scaleX,scaleY", thus we loop and apply them both.\n\n      property === _transformOriginProp && (this.tfm.zOrigin = cache.zOrigin);\n    } else {\n      return _propertyAliases.transform.split(",").forEach(function (p) {\n        return _saveStyle.call(_this, p, isNotCSS);\n      });\n    }\n\n    if (this.props.indexOf(_transformProp) >= 0) {\n      return;\n    }\n\n    if (cache.svg) {\n      this.svgo = target.getAttribute("data-svg-origin");\n      this.props.push(_transformOriginProp, isNotCSS, "");\n    }\n\n    property = _transformProp;\n  }\n\n  (style || isNotCSS) && this.props.push(property, isNotCSS, style[property]);\n},\n    _removeIndependentTransforms = function _removeIndependentTransforms(style) {\n  if (style.translate) {\n    style.removeProperty("translate");\n    style.removeProperty("scale");\n    style.removeProperty("rotate");\n  }\n},\n    _revertStyle = function _revertStyle() {\n  var props = this.props,\n      target = this.target,\n      style = target.style,\n      cache = target._gsap,\n      i,\n      p;\n\n  for (i = 0; i < props.length; i += 3) {\n    // stored like this: property, isNotCSS, value\n    if (!props[i + 1]) {\n      props[i + 2] ? style[props[i]] = props[i + 2] : style.removeProperty(props[i].substr(0, 2) === "--" ? props[i] : props[i].replace(_capsExp, "-$1").toLowerCase());\n    } else if (props[i + 1] === 2) {\n      // non-CSS value (function-based)\n      target[props[i]](props[i + 2]);\n    } else {\n      // non-CSS value (not function-based)\n      target[props[i]] = props[i + 2];\n    }\n  }\n\n  if (this.tfm) {\n    for (p in this.tfm) {\n      cache[p] = this.tfm[p];\n    }\n\n    if (cache.svg) {\n      cache.renderTransform();\n      target.setAttribute("data-svg-origin", this.svgo || "");\n    }\n\n    i = _reverting();\n\n    if ((!i || !i.isStart) && !style[_transformProp]) {\n      _removeIndependentTransforms(style);\n\n      if (cache.zOrigin && style[_transformOriginProp]) {\n        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.\n\n        cache.zOrigin = 0;\n        cache.renderTransform();\n      }\n\n      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.\n    }\n  }\n},\n    _getStyleSaver = function _getStyleSaver(target, properties) {\n  var saver = {\n    target: target,\n    props: [],\n    revert: _revertStyle,\n    save: _saveStyle\n  };\n  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.\n\n  properties && target.style && target.nodeType && properties.split(",").forEach(function (p) {\n    return saver.save(p);\n  }); // make sure it\'s a DOM node too.\n\n  return saver;\n},\n    _supports3D,\n    _createElement = function _createElement(type, ns) {\n  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.\n\n  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/).\n},\n    _getComputedProperty = function _getComputedProperty(target, property, skipPrefixFallback) {\n  var cs = getComputedStyle(target);\n  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.\n},\n    _prefixes = "O,Moz,ms,Ms,Webkit".split(","),\n    _checkPropPrefix = function _checkPropPrefix(property, element, preferPrefix) {\n  var e = element || _tempDiv,\n      s = e.style,\n      i = 5;\n\n  if (property in s && !preferPrefix) {\n    return property;\n  }\n\n  property = property.charAt(0).toUpperCase() + property.substr(1);\n\n  while (i-- && !(_prefixes[i] + property in s)) {}\n\n  return i < 0 ? null : (i === 3 ? "ms" : i >= 0 ? _prefixes[i] : "") + property;\n},\n    _initCore = function _initCore() {\n  if (_windowExists() && window.document) {\n    _win = window;\n    _doc = _win.document;\n    _docElement = _doc.documentElement;\n    _tempDiv = _createElement("div") || {\n      style: {}\n    };\n    _tempDivStyler = _createElement("div");\n    _transformProp = _checkPropPrefix(_transformProp);\n    _transformOriginProp = _transformProp + "Origin";\n    _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.\n\n    _supports3D = !!_checkPropPrefix("perspective");\n    _reverting = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.reverting;\n    _pluginInitted = 1;\n  }\n},\n    _getReparentedCloneBBox = function _getReparentedCloneBBox(target) {\n  //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).\n  var owner = target.ownerSVGElement,\n      svg = _createElement("svg", owner && owner.getAttribute("xmlns") || "http://www.w3.org/2000/svg"),\n      clone = target.cloneNode(true),\n      bbox;\n\n  clone.style.display = "block";\n  svg.appendChild(clone);\n\n  _docElement.appendChild(svg);\n\n  try {\n    bbox = clone.getBBox();\n  } catch (e) {}\n\n  svg.removeChild(clone);\n\n  _docElement.removeChild(svg);\n\n  return bbox;\n},\n    _getAttributeFallbacks = function _getAttributeFallbacks(target, attributesArray) {\n  var i = attributesArray.length;\n\n  while (i--) {\n    if (target.hasAttribute(attributesArray[i])) {\n      return target.getAttribute(attributesArray[i]);\n    }\n  }\n},\n    _getBBox = function _getBBox(target) {\n  var bounds, cloned;\n\n  try {\n    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\n  } catch (error) {\n    bounds = _getReparentedCloneBBox(target);\n    cloned = 1;\n  }\n\n  bounds && (bounds.width || bounds.height) || cloned || (bounds = _getReparentedCloneBBox(target)); //some browsers (like Firefox) misreport the bounds if the element has zero width and height (it just assumes i
1t\'s at x:0, y:0), thus we need to manually grab the position in that case.\n\n  return bounds && !bounds.width && !bounds.x && !bounds.y ? {\n    x: +_getAttributeFallbacks(target, ["x", "cx", "x1"]) || 0,\n    y: +_getAttributeFallbacks(target, ["y", "cy", "y1"]) || 0,\n    width: 0,\n    height: 0\n  } : bounds;\n},\n    _isSVG = function _isSVG(e) {\n  return !!(e.getCTM && (!e.parentNode || e.ownerSVGElement) && _getBBox(e));\n},\n    //reports if the element is an SVG on which getBBox() actually works\n_removeProperty = function _removeProperty(target, property) {\n  if (property) {\n    var style = target.style,\n        first2Chars;\n\n    if (property in _transformProps && property !== _transformOriginProp) {\n      property = _transformProp;\n    }\n\n    if (style.removeProperty) {\n      first2Chars = property.substr(0, 2);\n\n      if (first2Chars === "ms" || property.substr(0, 6) === "webkit") {\n        //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)\n        property = "-" + property;\n      }\n\n      style.removeProperty(first2Chars === "--" ? property : property.replace(_capsExp, "-$1").toLowerCase());\n    } else {\n      //note: old versions of IE use "removeAttribute()" instead of "removeProperty()"\n      style.removeAttribute(property);\n    }\n  }\n},\n    _addNonTweeningPT = function _addNonTweeningPT(plugin, target, property, beginning, end, onlySetAtEnd) {\n  var pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 1, onlySetAtEnd ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue);\n  plugin._pt = pt;\n  pt.b = beginning;\n  pt.e = end;\n\n  plugin._props.push(property);\n\n  return pt;\n},\n    _nonConvertibleUnits = {\n  deg: 1,\n  rad: 1,\n  turn: 1\n},\n    _nonStandardLayouts = {\n  grid: 1,\n  flex: 1\n},\n    //takes a single value like 20px and converts it to the unit specified, like "%", returning only the numeric amount.\n_convertToUnit = function _convertToUnit(target, property, value, unit) {\n  var curValue = parseFloat(value) || 0,\n      curUnit = (value + "").trim().substr((curValue + "").length) || "px",\n      // some browsers leave extra whitespace at the beginning of CSS variables, hence the need to trim()\n  style = _tempDiv.style,\n      horizontal = _horizontalExp.test(property),\n      isRootSVG = target.tagName.toLowerCase() === "svg",\n      measureProperty = (isRootSVG ? "client" : "offset") + (horizontal ? "Width" : "Height"),\n      amount = 100,\n      toPixels = unit === "px",\n      toPercent = unit === "%",\n      px,\n      parent,\n      cache,\n      isSVG;\n\n  if (unit === curUnit || !curValue || _nonConvertibleUnits[unit] || _nonConvertibleUnits[curUnit]) {\n    return curValue;\n  }\n\n  curUnit !== "px" && !toPixels && (curValue = _convertToUnit(target, property, value, "px"));\n  isSVG = target.getCTM && _isSVG(target);\n\n  if ((toPercent || curUnit === "%") && (_transformProps[property] || ~property.indexOf("adius"))) {\n    px = isSVG ? target.getBBox()[horizontal ? "width" : "height"] : target[measureProperty];\n    return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPercent ? curValue / px * amount : curValue / 100 * px);\n  }\n\n  style[horizontal ? "width" : "height"] = amount + (toPixels ? curUnit : unit);\n  parent = unit !== "rem" && ~property.indexOf("adius") || unit === "em" && target.appendChild && !isRootSVG ? target : target.parentNode;\n\n  if (isSVG) {\n    parent = (target.ownerSVGElement || {}).parentNode;\n  }\n\n  if (!parent || parent === _doc || !parent.appendChild) {\n    parent = _doc.body;\n  }\n\n  cache = parent._gsap;\n\n  if (cache && toPercent && cache.width && horizontal && cache.time === _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time && !cache.uncache) {\n    return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(curValue / cache.width * amount);\n  } else {\n    if (toPercent && (property === "height" || property === "width")) {\n      // 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.\n      var v = target.style[property];\n      target.style[property] = amount + unit;\n      px = target[measureProperty];\n      v ? target.style[property] = v : _removeProperty(target, property);\n    } else {\n      (toPercent || curUnit === "%") && !_nonStandardLayouts[_getComputedProperty(parent, "display")] && (style.position = _getComputedProperty(target, "position"));\n      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 
1which case it\'d go up the chain until it finds its offsetParent (bad). position: static protects against that.\n\n      parent.appendChild(_tempDiv);\n      px = _tempDiv[measureProperty];\n      parent.removeChild(_tempDiv);\n      style.position = "absolute";\n    }\n\n    if (horizontal && toPercent) {\n      cache = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(parent);\n      cache.time = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._ticker.time;\n      cache.width = parent[measureProperty];\n    }\n  }\n\n  return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(toPixels ? px * curValue / amount : px && curValue ? amount / px * curValue : 0);\n},\n    _get = function _get(target, property, unit, uncache) {\n  var value;\n  _pluginInitted || _initCore();\n\n  if (property in _propertyAliases && property !== "transform") {\n    property = _propertyAliases[property];\n\n    if (~property.indexOf(",")) {\n      property = property.split(",")[0];\n    }\n  }\n\n  if (_transformProps[property] && property !== "transform") {\n    value = _parseTransform(target, uncache);\n    value = property !== "transformOrigin" ? value[property] : value.svg ? value.origin : _firstTwoOnly(_getComputedProperty(target, _transformOriginProp)) + " " + value.zOrigin + "px";\n  } else {\n    value = target.style[property];\n\n    if (!value || value === "auto" || uncache || ~(value + "").indexOf("calc(")) {\n      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\n    }\n  }\n\n  return unit && !~(value + "").trim().indexOf(" ") ? _convertToUnit(target, property, value, unit) + unit : value;\n},\n    _tweenComplexCSSString = function _tweenComplexCSSString(target, prop, start, end) {\n  // 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.\n  if (!start || start === "none") {\n    // 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/\n    var p = _checkPropPrefix(prop, target, 1),\n        s = p && _getComputedProperty(target, p, 1);\n\n    if (s && s !== start) {\n      prop = p;\n      start = s;\n    } else if (prop === "borderColor") {\n      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/\n    }\n  }\n\n  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),\n      index = 0,\n      matchIndex = 0,\n      a,\n      result,\n      startValues,\n      startNum,\n      color,\n      startValue,\n      endValue,\n      endNum,\n      chunk,\n      endUnit,\n      startUnit,\n      endValues;\n  pt.b = start;\n  pt.e = end;\n  start += ""; // ensure values are strings\n\n  end += "";\n\n  if (end.substring(0, 6) === "var(--") {\n    end = _getComputedProperty(target, end.substring(4, end.indexOf(")")));\n  }\n\n  if (end === "auto") {\n    startValue = target.style[prop];\n    target.style[prop] = end;\n    end = _getComputedProperty(target, prop) || end;\n    startValue ? target.style[prop] = startValue : _removeProperty(target, prop);\n  }\n\n  a = [start, end];\n\n  (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().\n\n\n  start = a[0];\n  end = a[1];\n  startValues = start.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || [];\n  endValues = end.match(_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp) || [];\n\n  if (endValues.length) {\n    while (result = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.exec(end)) {\n      endValue = result[0];\n      chunk = end.substring(index, result.index);\n\n      if (color) {\n        color = (color + 1) % 5;\n      } else if (chunk.substr(-5) === "rgba(" || chunk.substr(-5) === "hsla(") {\n        color = 1;\n      }\n\n      if (endValue !== (startValue = startValues[matchIndex++] || "")) {\n        startNum = parseFloat(startValue) || 0;\n        startUnit = startValue.substr((startNum + "").length);\n        endValue.charAt(1) === "=" && (endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, endValue) + startUnit);\n        endNum = parseFloat(endValue);\n        endUnit = endValue.substr((endNum + "").length);\n        index = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._numWithUnitExp.lastIndex - endUnit.length;\n\n        if (!endUnit) {\n          //if something like "perspective:300" is passed in and we must add a unit to the end\n          endUnit = endUnit || _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[prop] || startUnit;\n\n          if (index === end.length) {\n            end += endUnit;\n            pt.e += endUnit;\n          }\n        }\n\n        if (startUnit !== endUnit) {\n          startNum = _convertToUnit(target, prop, startValue, endUnit) || 0;\n        } // 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.\n\n\n        pt._pt = {\n          _next: pt._pt,\n          p: chunk || matchIndex === 1 ? chunk : ",",\n          //note: SVG spec allows om
1ission 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.\n          s: startNum,\n          c: endNum - startNum,\n          m: color && color < 4 || prop === "zIndex" ? Math.round : 0\n        };\n      }\n    }\n\n    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)\n  } else {\n    pt.r = prop === "display" && end === "none" ? _renderNonTweeningValueOnlyAtEnd : _renderNonTweeningValue;\n  }\n\n  _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).\n\n  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.\n\n  return pt;\n},\n    _keywordToPercent = {\n  top: "0%",\n  bottom: "100%",\n  left: "0%",\n  right: "100%",\n  center: "50%"\n},\n    _convertKeywordsToPercentages = function _convertKeywordsToPercentages(value) {\n  var split = value.split(" "),\n      x = split[0],\n      y = split[1] || "50%";\n\n  if (x === "top" || x === "bottom" || y === "left" || y === "right") {\n    //the user provided them in the wrong order, so flip them\n    value = x;\n    x = y;\n    y = value;\n  }\n\n  split[0] = _keywordToPercent[x] || x;\n  split[1] = _keywordToPercent[y] || y;\n  return split.join(" ");\n},\n    _renderClearProps = function _renderClearProps(ratio, data) {\n  if (data.tween && data.tween._time === data.tween._dur) {\n    var target = data.t,\n        style = target.style,\n        props = data.u,\n        cache = target._gsap,\n        prop,\n        clearTransforms,\n        i;\n\n    if (props === "all" || props === true) {\n      style.cssText = "";\n      clearTransforms = 1;\n    } else {\n      props = props.split(",");\n      i = props.length;\n\n      while (--i > -1) {\n        prop = props[i];\n\n        if (_transformProps[prop]) {\n          clearTransforms = 1;\n          prop = prop === "transformOrigin" ? _transformOriginProp : _transformProp;\n        }\n\n        _removeProperty(target, prop);\n      }\n    }\n\n    if (clearTransforms) {\n      _removeProperty(target, _transformProp);\n\n      if (cache) {\n        cache.svg && target.removeAttribute("transform");\n        style.scale = style.rotate = style.translate = "none";\n\n        _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.\n\n\n        cache.uncache = 1;\n\n        _removeIndependentTransforms(style);\n      }\n    }\n  }\n},\n    // note: specialProps should return 1 if (and only if) they have a non-zero priority. It indicates we need to sort the linked list.\n_specialProps = {\n  clearProps: function clearProps(plugin, target, property, endValue, tween) {\n    if (tween.data !== "isFromStart") {\n      var pt = plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, 0, 0, _renderClearProps);\n      pt.u = endValue;\n      pt.pr = -10;\n      pt.tween = tween;\n\n      plugin._props.push(property);\n\n      return 1;\n    }\n  }\n  /* className feature (about 0.4kb gzipped).\n  , className(plugin, target, property, endValue, tween) {\n  \tlet _renderClassName = (ratio, data) => {\n  \t\t\tdata.css.render(ratio, data.css);\n  \t\t\tif (!ratio || ratio === 1) {\n  \t\t\t\tlet inline = data.rmv,\n  \t\t\t\t\ttarget = data.t,\n  \t\t\t\t\tp;\n  \t\t\t\ttarget.setAttribute("class", ratio ? data.e : data.b);\n  \t\t\t\tfor (p in inline) {\n  \t\t\t\t\t_removeProperty(target, p);\n  \t\t\t\t}\n  \t\t\t}\n  \t\t},\n  \t\t_getAllStyles = (target) => {\n  \t\t\tlet styles = {},\n  \t\t\t\tcomputed = getComputedStyle(target),\n  \t\t\t\tp;
1\n  \t\t\tfor (p in computed) {\n  \t\t\t\tif (isNaN(p) && p !== "cssText" && p !== "length") {\n  \t\t\t\t\tstyles[p] = computed[p];\n  \t\t\t\t}\n  \t\t\t}\n  \t\t\t_setDefaults(styles, _parseTransform(target, 1));\n  \t\t\treturn styles;\n  \t\t},\n  \t\tstartClassList = target.getAttribute("class"),\n  \t\tstyle = target.style,\n  \t\tcssText = style.cssText,\n  \t\tcache = target._gsap,\n  \t\tclassPT = cache.classPT,\n  \t\tinlineToRemoveAtEnd = {},\n  \t\tdata = {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) : "")},\n  \t\tchangingVars = {},\n  \t\tstartVars = _getAllStyles(target),\n  \t\ttransformRelated = /(transform|perspective)/i,\n  \t\tendVars, p;\n  \tif (classPT) {\n  \t\tclassPT.r(1, classPT.d);\n  \t\t_removeLinkedListItem(classPT.d.plugin, classPT, "_pt");\n  \t}\n  \ttarget.setAttribute("class", data.e);\n  \tendVars = _getAllStyles(target, true);\n  \ttarget.setAttribute("class", startClassList);\n  \tfor (p in endVars) {\n  \t\tif (endVars[p] !== startVars[p] && !transformRelated.test(p)) {\n  \t\t\tchangingVars[p] = endVars[p];\n  \t\t\tif (!style[p] && style[p] !== "0") {\n  \t\t\t\tinlineToRemoveAtEnd[p] = 1;\n  \t\t\t}\n  \t\t}\n  \t}\n  \tcache.classPT = plugin._pt = new PropTween(plugin._pt, target, "className", 0, 0, _renderClassName, data, 0, -11);\n  \tif (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/.\n  \t\tstyle.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).\n  \t}\n  \t_parseTransform(target, true); //to clear the caching of transforms\n  \tdata.css = new gsap.plugins.css();
1\n  \tdata.css.init(target, changingVars, tween);\n  \tplugin._props.push(...data.css._props);\n  \treturn 1;\n  }\n  */\n\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TRANSFORMS\n * --------------------------------------------------------------------------------------\n */\n_identity2DMatrix = [1, 0, 0, 1, 0, 0],\n    _rotationalProperties = {},\n    _isNullTransform = function _isNullTransform(value) {\n  return value === "matrix(1, 0, 0, 1, 0, 0)" || value === "none" || !value;\n},\n    _getComputedTransformMatrixAsArray = function _getComputedTransformMatrixAsArray(target) {\n  var matrixString = _getComputedProperty(target, _transformProp);\n\n  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);\n},\n    _getMatrix = function _getMatrix(target, force2D) {\n  var cache = target._gsap || (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._getCache)(target),\n      style = target.style,\n      matrix = _getComputedTransformMatrixAsArray(target),\n      parent,\n      nextSibling,\n      temp,\n      addedToDOM;\n\n  if (cache.svg && target.getAttribute("transform")) {\n    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.\n\n    matrix = [temp.a, temp.b, temp.c, temp.d, temp.e, temp.f];\n    return matrix.join(",") === "1,0,0,1,0,0" ? _identity2DMatrix : matrix;\n  } else if (matrix === _identity2DMatrix && !target.offsetParent && target !== _docElement && !cache.svg) {\n    //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\n    //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).\n    temp = style.display;\n    style.display = "block";\n    parent = target.parentNode;\n\n    if (!parent || !target.offsetParent && !target.getBoundingClientRect().width) {\n      // 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. Note: position: fixed elements report a null offsetParent but they could also be invisible because they\'re in an ancestor with display: none, so we check getBoundingClientRect(). We only want to alter the DOM if we absolutely have to because it can cause iframe content to reload, like a Vimeo video.\n      addedToDOM = 1; //flag\n\n      nextSibling = target.nextElementSibling;\n\n      _docElement.appendChild(target); //we must add it to the DOM in order to get values properly\n\n    }\n\n    matrix = _getComputedTransformMatrixAsArray(target);\n    temp ? style.display = temp : _removeProperty(target, "display");
1\n\n    if (addedToDOM) {\n      nextSibling ? parent.insertBefore(target, nextSibling) : parent ? parent.appendChild(target) : _docElement.removeChild(target);\n    }\n  }\n\n  return force2D && matrix.length > 6 ? [matrix[0], matrix[1], matrix[4], matrix[5], matrix[12], matrix[13]] : matrix;\n},\n    _applySVGOrigin = function _applySVGOrigin(target, origin, originIsAbsolute, smooth, matrixArray, pluginToAddPropTweensTo) {\n  var cache = target._gsap,\n      matrix = matrixArray || _getMatrix(target, true),\n      xOriginOld = cache.xOrigin || 0,\n      yOriginOld = cache.yOrigin || 0,\n      xOffsetOld = cache.xOffset || 0,\n      yOffsetOld = cache.yOffset || 0,\n      a = matrix[0],\n      b = matrix[1],\n      c = matrix[2],\n      d = matrix[3],\n      tx = matrix[4],\n      ty = matrix[5],\n      originSplit = origin.split(" "),\n      xOrigin = parseFloat(originSplit[0]) || 0,\n      yOrigin = parseFloat(originSplit[1]) || 0,\n      bounds,\n      determinant,\n      x,\n      y;\n\n  if (!originIsAbsolute) {\n    bounds = _getBBox(target);\n    xOrigin = bounds.x + (~originSplit[0].indexOf("%") ? xOrigin / 100 * boun
1ds.width : xOrigin);\n    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\n    // \txOrigin -= bounds.x;\n    // \tyOrigin -= bounds.y;\n    // }\n  } else if (matrix !== _identity2DMatrix && (determinant = a * d - b * c)) {\n    //if it\'s zero (like if scaleX and scaleY are zero), skip it to avoid errors with dividing by zero.\n    x = xOrigin * (d / determinant) + yOrigin * (-c / determinant) + (c * ty - d * tx) / determinant;\n    y = xOrigin * (-b / determinant) + yOrigin * (a / determinant) - (a * ty - b * tx) / determinant;\n    xOrigin = x;\n    yOrigin = y; // theory: we only had to do this for smoothing and it assumes that the previous one was not originIsAbsolute.\n  }\n\n  if (smooth || smooth !== false && cache.smooth) {\n    tx = xOrigin - xOriginOld;\n    ty = yOrigin - yOriginOld;\n    cache.xOffset = xOffsetOld + (tx * a + ty * c) - tx;\n    cache.yOffset = yOffsetOld + (tx * b + ty * d) - ty;\n  } else {\n    cache.xOffset = cache.yOffset = 0;\n  }\n\n  cache.xOrigin = xOrigin;\n  cache.yOrigin = yOrigin;\n  cache.smooth = !!smooth;\n  cache.origin = origin;\n  cache.originIsAbsolute = !!originIsAbsolute;\n  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).\n\n  if (pluginToAddPropTweensTo) {\n    _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOrigin", xOriginOld, xOrigin);\n\n    _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOrigin", yOriginOld, yOrigin);\n\n    _addNonTweeningPT(pluginToAddPropTweensTo, cache, "xOffset", xOffsetOld, cache.xOffset);\n\n    _addNonTweeningPT(pluginToAddPropTweensTo, cache, "yOffset", yOffsetOld, cache.yOffset);\n  }\n\n  target.setAttribute("data-svg-origin", xOrigin + " " + yOrigin);\n},\n    _parseTransform = function _parseTransform(target, uncache) {\n  var cache = target._gsap || new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.GSCache(target);\n\n  if ("x" in cache && !uncache && !cache.uncache) {\n    return cache;\n  }\n\n  var style = target.style,\n      invertedScaleX = cache.scaleX < 0,\n      px = "px",\n      deg = "deg",\n      cs = getComputedStyle(target),\n      origin = _getComputedProperty(target, _transformOriginProp) || "0",\n      x,\n      y,\n      z,\n      scaleX,\n      scaleY,\n      rotation,\n      rotationX,\n      rotationY,\n      skewX,\n      skewY,\n      perspective,\n      xOrigin,\n      yOrigin,\n      matrix,\n      angle,\n      cos,\n      sin,\n      a,\n      b,\n      c,\n      d,\n      a12,\n      a22,\n      t1,\n      t2,\n      t3,\n      a13,\n      a23,\n      a33,\n      a42,\n      a43,\n      a32;\n  x = y = z = rotation = rotationX = rotationY = skewX = skewY = perspective = 0;\n  scaleX = scaleY = 1;\n  cache.svg = !!(target.getCTM && _isSVG(target));\n\n  if (cs.translate) {\n    // accommodate independent transforms by combining them into normal ones.\n    if (cs.translate !== "none" || cs.scale !== "none" || cs.rotate !== "none") {\n      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] : "");\n    }\n\n    style.scale = style.rotate = style.translate = "none";\n  }\n\n  matrix = _getMatrix(target, cache.svg);\n\n  if (cache.svg) {\n    if (cache.uncache) {\n      // 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.\n      t2 = target.getBBox();\n      origin = cache.xOrigin - t2.x + "px " + (cache.yOrigin - t2.y) + "px";\n      t1 = "";\n    } else {\n      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.\n    }\n\n    _applySVGOrigin(target, t1 || origin, !!t1 || cache.originIsAbsolute, cache.smooth !== false, matrix
1);\n  }\n\n  xOrigin = cache.xOrigin || 0;\n  yOrigin = cache.yOrigin || 0;\n\n  if (matrix !== _identity2DMatrix) {\n    a = matrix[0]; //a11\n\n    b = matrix[1]; //a21\n\n    c = matrix[2]; //a31\n\n    d = matrix[3]; //a41\n\n    x = a12 = matrix[4];\n    y = a22 = matrix[5]; //2D matrix\n\n    if (matrix.length === 6) {\n      scaleX = Math.sqrt(a * a + b * b);\n      scaleY = Math.sqrt(d * d + c * c);\n      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).\n\n      skewX = c || d ? _atan2(c, d) * _RAD2DEG + rotation : 0;\n      skewX && (scaleY *= Math.abs(Math.cos(skewX * _DEG2RAD)));\n\n      if (cache.svg) {\n        x -= xOrigin - (xOrigin * a + yOrigin * c);\n        y -= yOrigin - (xOrigin * b + yOrigin * d);\n      } //3D matrix\n\n    } else {\n      a32 = matrix[6];\n      a42 = matrix[7];\n      a13 = matrix[8];\n      a23 = matrix[9];\n      a33 = matrix[10];\n      a43 = matrix[11];\n      x = matrix[12];\n      y = matrix[13];\n      z = matrix[14];\n      angle = _atan2(a32, a33);\n      rotationX = angle * _RAD2DEG; //rotationX\n\n      if (angle) {\n        cos = Math.cos(-angle);\n        sin = Math.sin(-angle);\n        t1 = a12 * cos + a13 * sin;\n        t2 = a22 * cos + a23 * sin;\n        t3 = a32 * cos + a33 * sin;\n        a13 = a12 * -sin + a13 * cos;\n        a23 = a22 * -sin + a23 * cos;\n        a33 = a32 * -sin + a33 * cos;\n        a43 = a42 * -sin + a43 * cos;\n        a12 = t1;\n        a22 = t2;\n        a32 = t3;\n      } //rotationY\n\n\n      angle = _atan2(-c, a33);\n      rotationY = angle * _RAD2DEG;\n\n      if (angle) {\n        cos = Math.cos(-angle);\n        sin = Math.sin(-angle);\n        t1 = a * cos - a13 * sin;\n        t2 = b * cos - a23 * sin;\n        t3 = c * cos - a33 * sin;\n        a43 = d * sin + a43 * cos;\n        a = t1;\n        b = t2;\n        c = t3;\n      } //rotationZ\n\n\n      angle = _atan2(b, a);\n      rotation = angle * _RAD2DEG;\n\n      if (angle) {\n        cos = Math.cos(angle);\n        sin = Math.sin(angle);\n        t1 = a * cos + b * sin;\n        t2 = a12 * cos + a22 * sin;\n        b = b * cos - a * sin;\n        a22 = a22 * cos - a12 * sin;\n        a = t1;\n        a12 = t2;\n      }\n\n      if (rotationX && Math.abs(rotationX) + Math.abs(rotation) > 359.9) {\n        //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.\n        rotationX = rotation = 0;\n        rotationY = 180 - rotationY;\n      }\n\n      scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a * a + b * b + c * c));\n      scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(Math.sqrt(a22 * a22 + a32 * a32));\n      angle = _atan2(a12, a22);\n      skewX = Math.abs(angle) > 0.0002 ? angle * _RAD2DEG : 0;\n      perspective = a43 ? 1 / (a43 < 0 ? -a43 : a43) : 0;\n    }\n\n    if (cache.svg) {\n      //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).\n      t1 = target.getAttribute("transform");\n      cache.forceCSS = target.setAttribute("transform", "") || !_isNullTransform(_getComputedProperty(target, _transformProp));\n      t1 && target.setAttribute("transform", t1);\n    }\n  }\n\n  if (Math.abs(skewX) > 90 && Math.abs(skewX) < 270) {\n    if (invertedScaleX) {\n      scaleX *= -1;\n      skewX += rotation <= 0 ? 180 : -180;\n      rotation += rotation <= 0 ? 180 : -180;\n    } else {\n      scaleY *= -1;\n      skewX += skewX <= 0 ? 180 : -180;\n    }\n  }\n\n  uncache = uncache || cache.uncache;\n  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;\n  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;\n  cache.z = z + px;\n  cache.scaleX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleX);\n  cache.scaleY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(scaleY);\n  cache.rotation = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotation) + deg;
1\n  cache.rotationX = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationX) + deg;\n  cache.rotationY = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(rotationY) + deg;\n  cache.skewX = skewX + deg;\n  cache.skewY = skewY + deg;\n  cache.transformPerspective = perspective + px;\n\n  if (cache.zOrigin = parseFloat(origin.split(" ")[2]) || !uncache && cache.zOrigin || 0) {\n    style[_transformOriginProp] = _firstTwoOnly(origin);\n  }\n\n  cache.xOffset = cache.yOffset = 0;\n  cache.force3D = _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.force3D;\n  cache.renderTransform = cache.svg ? _renderSVGTransforms : _supports3D ? _renderCSSTransforms : _renderNon3DTransforms;\n  cache.uncache = 0;\n  return cache;\n},\n    _firstTwoOnly = function _firstTwoOnly(value) {\n  return (value = value.split(" "))[0] + " " + value[1];\n},\n    //for handling transformOrigin values, stripping out the 3rd dimension\n_addPxTranslate = function _addPxTranslate(target, start, value) {\n  var unit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(start);\n  return (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(parseFloat(start) + parseFloat(_convertToUnit(target, "x", value + "px", unit))) + unit;\n},\n    _renderNon3DTransforms = function _renderNon3DTransforms(ratio, cache) {\n  cache.z = "0px";\n  cache.rotationY = cache.rotationX = "0deg";\n  cache.force3D = 0;\n\n  _renderCSSTransforms(ratio, cache);\n},\n    _zeroDeg = "0deg",\n    _zeroPx = "0px",\n    _endParenthesis = ") ",\n    _renderCSSTransforms = function _renderCSSTransforms(ratio, cache) {\n  var _ref = cache || this,\n      xPercent = _ref.xPercent,\n      yPercent = _ref.yPercent,\n      x = _ref.x,\n      y = _ref.y,\n      z = _ref.z,\n      rotation = _ref.rotation,\n      rotationY = _ref.rotationY,\n      rotationX = _ref.rotationX,\n      skewX = _ref.skewX,\n      skewY = _ref.skewY,\n      scaleX = _ref.scaleX,\n      scaleY = _ref.scaleY,\n      transformPerspective = _ref.transformPerspective,\n      force3D = _ref.force3D,\n      target = _ref.target,\n      zOrigin = _ref.zOrigin,\n      transforms = "",\n      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)\n\n\n  if (zOrigin && (rotationX !== _zeroDeg || rotationY !== _zeroDeg)) {\n    var angle = parseFloat(rotationY) * _DEG2RAD,\n        a13 = Math.sin(angle),\n        a33 = Math.cos(angle),\n        cos;\n\n    angle = parseFloat(rotationX) * _DEG2RAD;\n    cos = Math.cos(angle);\n    x = _addPxTranslate(target, x, a13 * cos * -zOrigin);\n    y = _addPxTranslate(target, y, -Math.sin(angle) * -zOrigin);\n    z = _addPxTranslate(target, z, a33 * cos * -zOrigin + zOrigin);\n  }\n\n  if (transformPerspective !== _zeroPx) {\n    transforms += "perspective(" + transformPerspective + _endParenthesis;\n  }\n\n  if (xPercent || yPercent) {\n    transforms += "translate(" + xPercent + "%, " + yPercent + "%) ";\n  }\n\n  if (use3D || x !== _zeroPx || y !== _zeroPx || z !== _zeroPx) {\n    transforms += z !== _zeroPx || use3D ? "translate3d(" + x + ", " + y + ", " + z + ") " : "translate(" + x + ", " + y + _endParenthesis;\n  }\n\n  if (rotation !== _zeroDeg) {\n    transforms += "rotate(" + rotation + _endParenthesis;\n  }\n\n  if (rotationY !== _zeroDeg) {\n    transforms += "rotateY(" + rotationY + _endParenthesis;\n  }\n\n  if (rotationX !== _zeroDeg) {\n    transforms += "rotateX(" + rotationX + _endParenthesis;\n  }\n\n  if (skewX !== _zeroDeg || skewY !== _zeroDeg) {\n    transforms += "skew(" + skewX + ", " + skewY + _endParenthesis;\n  }\n\n  if (scaleX !== 1 || scaleY !== 1) {\n    transforms += "scale(" + scaleX + ", " + scaleY + _endParenthesis;\n  }\n\n  target.style[_transformProp] = transforms || "translate(0, 0)";\n},\n    _renderSVGTransforms = function _renderSVGTransforms(ratio, cache) {\n  var _ref2 = cache || this,\n      xPercent = _ref2.xPercent,\n      yPercent = _ref2.yPercent,\n      x = _ref2.x,\n      y = _ref2.y,\n      rotation = _ref2.rotation,\n      skewX = _ref2.skewX,\n      skewY = _ref2.skewY,\n      scaleX = _ref2.scaleX,\n      scaleY = _ref2.scaleY,\n      target = _ref2.target,\n      xOrigin = _ref2.xOrigin,\n      yOrigin = _ref2.yOrigin,\n      xOffset = _ref2.xOffset,\n      yOffset = _ref2.yOffset,\n      forceCSS = _ref2.forceCSS,\n      tx = parseFloat(x),\n      ty = parseFloat(y),\n      a11,\n      a21,\n      a12,\n      a22,\n      temp;\n\n  rotation = parseFloat(rotation);\n  skewX = parseFloat(skewX);\n  skewY = parseFloat(skewY);
1\n\n  if (skewY) {\n    //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.\n    skewY = parseFloat(skewY);\n    skewX += skewY;\n    rotation += skewY;\n  }\n\n  if (rotation || skewX) {\n    rotation *= _DEG2RAD;\n    skewX *= _DEG2RAD;\n    a11 = Math.cos(rotation) * scaleX;\n    a21 = Math.sin(rotation) * scaleX;\n    a12 = Math.sin(rotation - skewX) * -scaleY;\n    a22 = Math.cos(rotation - skewX) * scaleY;\n\n    if (skewX) {\n      skewY *= _DEG2RAD;\n      temp = Math.tan(skewX - skewY);\n      temp = Math.sqrt(1 + temp * temp);\n      a12 *= temp;\n      a22 *= temp;\n\n      if (skewY) {\n        temp = Math.tan(skewY);\n        temp = Math.sqrt(1 + temp * temp);\n        a11 *= temp;\n        a21 *= temp;\n      }\n    }\n\n    a11 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a11);\n    a21 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a21);\n    a12 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a12);\n    a22 = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(a22);\n  } else {\n    a11 = scaleX;\n    a22 = scaleY;\n    a21 = a12 = 0;\n  }\n\n  if (tx && !~(x + "").indexOf("px") || ty && !~(y + "").indexOf("px")) {\n    tx = _convertToUnit(target, "x", x, "px");\n    ty = _convertToUnit(target, "y", y, "px");\n  }\n\n  if (xOrigin || yOrigin || xOffset || yOffset) {\n    tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xOrigin - (xOrigin * a11 + yOrigin * a12) + xOffset);\n    ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yOrigin - (xOrigin * a21 + yOrigin * a22) + yOffset);\n  }\n\n  if (xPercent || yPercent) {\n    //The SVG spec doesn\'t support percentage-based translation in the "transform" attribute, so we merge it into the translation to simulate it.\n    temp = target.getBBox();\n    tx = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(tx + xPercent / 100 * temp.width);\n    ty = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._round)(ty + yPercent / 100 * temp.height);\n  }\n\n  temp = "matrix(" + a11 + "," + a21 + "," + a12 + "," + a22 + "," + tx + "," + ty + ")";\n  target.setAttribute("transform", temp);\n  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!)\n},\n    _addRotationalPropTween = function _addRotationalPropTween(plugin, target, property, startNum, endValue) {\n  var cap = 360,\n      isString = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(endValue),\n      endNum = parseFloat(endValue) * (isString && ~endValue.indexOf("rad") ? _RAD2DEG : 1),\n      change = endNum - startNum,\n      finalValue = startNum + change + "deg",\n      direction,\n      pt;\n\n  if (isString) {\n    direction = endValue.split("_")[1];\n\n    if (direction === "short") {\n      change %= cap;\n\n      if (change !== change % (cap / 2)) {\n        change += change < 0 ? cap : -cap;\n      }\n    }\n\n    if (direction === "cw" && change < 0) {\n      change = (change + cap * _bigNum) % cap - ~~(change / cap) * cap;\n    } else if (direction === "ccw" && change > 0) {\n      change = (change - cap * _bigNum) % cap - ~~(change / cap) * cap;\n    }\n  }\n\n  plugin._pt = pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, target, property, startNum, change, _renderPropWithEnd);\n  pt.e = finalValue;\n  pt.u = "deg";\n\n  plugin._props.push(property);\n\n  return pt;\n},\n    _assign = function _assign(target, source) {\n  // Internet Explorer doesn\'t have Object.assign(), so we recreate it here.\n  for (var p in source) {\n    target[p] = source[p];\n  }\n\n  return target;\n},\n    _addRawTransformPTs = function _addRawTransformPTs(plugin, transforms, target) {\n  //for handling cases where someone passes in a whole transform string, like transform: "scale(2, 3) rotate(20deg) translateY(30em)"\n  var startCache = _assign({}, target._gsap),\n      exclude = "perspective,force3D,transformOrigin,svgOrigin",\n      style = target.style,\n      endCache,\n      p,\n      startValue,\n      endValue,\n      startNum,\n      endNum,\n      startUnit,\n      endUnit;\n\n  if (startCache.svg) {\n    startValue = target.getAttribute("transform");\n    target.setAttribute("transform", "");\n    style[_transformProp] = transforms;\n    endCache = _parseTransform(target, 1);\n\n    _removeProperty(target, _transformProp);\n\n    target.setAttribute("transform", startValue);\n  } else {\n    startValue = getComputedStyle(target)[_transformProp];\n    style[_transformProp] = transforms;\n    endCache = _parseTransform(target, 1);\n    style[_transformProp] = startValue;\n  }
1\n\n  for (p in _transformProps) {\n    startValue = startCache[p];\n    endValue = endCache[p];\n\n    if (startValue !== endValue && exclude.indexOf(p) < 0) {\n      //tweening to no perspective gives very unintuitive results - just keep the same perspective in that case.\n      startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue);\n      endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue);\n      startNum = startUnit !== endUnit ? _convertToUnit(target, p, startValue, endUnit) : parseFloat(startValue);\n      endNum = parseFloat(endValue);\n      plugin._pt = new _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.PropTween(plugin._pt, endCache, p, startNum, endNum - startNum, _renderCSSProp);\n      plugin._pt.u = endUnit || 0;\n\n      plugin._props.push(p);\n    }\n  }\n\n  _assign(endCache, startCache);\n}; // 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.\n\n\n(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)("padding,margin,Width,Radius", function (name, index) {\n  var t = "Top",\n      r = "Right",\n      b = "Bottom",\n      l = "Left",\n      props = (index < 3 ? [t, r, b, l] : [t + l, t + r, b + r, b + l]).map(function (side) {\n    return index < 2 ? name + side : "border" + side + name;\n  });\n\n  _specialProps[index > 1 ? "border" + name : name] = function (plugin, target, property, endValue, tween) {\n    var a, vars;\n\n    if (arguments.length < 4) {\n      // getter, passed target, property, and unit (from _get())\n      a = props.map(function (prop) {\n        return _get(plugin, prop, property);\n      });\n      vars = a.join(" ");\n      return vars.split(a[0]).length === 5 ? a[0] : vars;\n    }\n\n    a = (endValue + "").split(" ");\n    vars = {};\n    props.forEach(function (prop, i) {\n      return vars[prop] = a[i] = a[i] || a[(i - 1) / 2 | 0];\n    });\n    plugin.init(target, vars, tween);\n  };\n});\n\nvar CSSPlugin = {\n  name: "css",\n  register: _initCore,\n  targetTest: function targetTest(target) {\n    return target.style && target.nodeType;\n  },\n  init: function init(target, vars, tween, index, targets) {\n    var props = this._props,\n        style = target.style,\n        startAt = tween.vars.startAt,\n        startValue,\n        endValue,\n        endNum,\n        startNum,\n        type,\n        specialProp,\n        p,\n        startUnit,\n        endUnit,\n        relative,\n        isTransformRelated,\n        transformPropTween,\n        cache,\n        smooth,\n        hasPriority,\n        inlineProps,\n        finalTransformValue;\n    _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\n\n    this.styles = this.styles || _getStyleSaver(target);\n    inlineProps = this.styles.props;\n    this.tween = tween;\n\n    for (p in vars) {\n      if (p === "autoRound") {\n        continue;\n      }\n\n      endValue = vars[p];\n\n      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)) {\n        // plugins\n        continue;\n      }\n\n      type = typeof endValue;\n      specialProp = _specialProps[p];\n\n      if (type === "function") {\n        endValue = endValue.call(tween, index, target, targets);\n        type = typeof endValue;\n      }\n\n      if (type === "string" && ~endValue.indexOf("random(")) {\n        endValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(endValue);\n      }\n\n      if (specialProp) {\n        specialProp(this, target, p, endValue, tween) && (hasPriority = 1);\n      } else if (p.substr(0, 2) === "--") {\n        //CSS variable\n        startValue = (getComputedStyle(target).getPropertyValue(p) + "").trim();\n        endValue += "";\n        _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.lastIndex = 0;\n\n        if (!_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._colorExp.test(startValue)) {\n          // colors don\'t have units\n          startUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(startValue);\n          endUnit = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.getUnit)(endValue);\n          endUnit ? startUnit !== endUnit && (startValue = _convertToUnit(target, p, startValue, endUnit) + endUnit) : startUnit && (endValue += startUnit);\n        }\n\n        this.add(style, "setProperty", startValue, endValue, index, targets, 0, 0, p);\n        props.push(p);\n        inlineProps.push(p, 0, style[p]);\n      } else if (type !== "undefined") {\n        if (startAt && p in startAt) {\n          // 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)\n          startValue = typeof startAt[p] === "function" ? startAt[p].call(tween, index, target, targets) : startAt[p];\n          (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._isString)(startValue) && ~startValue.indexOf("random(") && (startValue = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._replaceRandom)(startValue));\n          (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.\n\n          (startValue + "").charAt(1) === "=" && (startValue = _get(target, p)); // can\'t work with relative values\n        } else {\n          startValue = _get(target, p);\n        }\n\n        startNum = parseFloat(startValue);\n        relative = type === "string" && endValue.charAt(1) === "=" && endValue.substr(0, 2);\n        relative && (endValue = endValue.substr(2));\n        endNum = parseFloat(endValue);\n\n        if (p in _propertyAliases) {\n          if (p === "autoAlpha") {\n            //special case where we control the visibility along with opacity. We still allow the opacity value to pass through and get tweened.\n            if (startNum === 1 && _get(target, "visibility") === "hidden" && endNum) {\n              //if visibility is initially set to "hidden", we should interpret that as intent to make opacity 0 (a convenience)\n              startNum = 0;\n            }\n\n            inlineProps.push("visibility", 0, style.visibility);\n\n            _addNonTweeningPT(this, style, "visibility", startNum ? "inherit" : "hidden", endNum ? "inherit" : "hidden", !endNum);\n          }\n\n          if (p !== "scale" && p !== "transform") {\n            p = _propertyAliases[p];\n            ~p.indexOf(",") && (p = p.split(",")[0]);\n          }\n        }
1\n\n        isTransformRelated = p in _transformProps; //--- TRANSFORM-RELATED ---\n\n        if (isTransformRelated) {\n          this.styles.save(p);\n          finalTransformValue = endValue; // this is always the same as endValue except when it\'s a var(--) value, in which case we need to calculate the end value.\n\n          if (type === "string" && endValue.substring(0, 6) === "var(--") {\n            endValue = _getComputedProperty(target, endValue.substring(4, endValue.indexOf(")")));\n\n            if (endValue.substring(0, 5) === "calc(") {\n              var origPerspective = target.style.perspective;\n              target.style.perspective = endValue;\n              endValue = _getComputedProperty(target, "perspective");\n              origPerspective ? target.style.perspective = origPerspective : _removeProperty(target, "perspective");\n            }\n\n            endNum = parseFloat(endValue);\n          }\n\n          if (!transformPropTween) {\n            cache = target._gsap;\n            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.\n\n            smooth = vars.smoothOrigin !== false && cache.smooth;\n            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)\n\n            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.\n          }\n\n          if (p === "scale") {\n            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);\n            this._pt.u = 0;\n            props.push("scaleY", p);\n            p += "X";\n          } else if (p === "transformOrigin") {\n            inlineProps.push(_transformOriginProp, 0, style[_transformOriginProp]);\n            endValue = _convertKeywordsToPercentages(endValue); //in case something like "left top" or "bottom right" is passed in. Convert to percentages.\n\n            if (cache.svg) {\n              _applySVGOrigin(target, endValue, 0, smooth, 0, this);\n            } else {\n              endUnit = parseFloat(endValue.split(" ")[2]) || 0; //handle the zOrigin separately!\n\n              endUnit !== cache.zOrigin && _addNonTweeningPT(this, cache, "zOrigin", cache.zOrigin, endUnit);\n\n              _addNonTweeningPT(this, style, p, _firstTwoOnly(startValue), _firstTwoOnly(endValue));\n            }\n\n            continue;\n          } else if (p === "svgOrigin") {\n            _applySVGOrigin(target, endValue, 1, smooth, 0, this);\n\n            continue;\n          } else if (p in _rotationalProperties) {\n            _addRotationalPropTween(this, cache, p, startNum, relative ? (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._parseRelative)(startNum, relative + endValue) : endValue);\n\n            continue;\n          } else if (p === "smoothOrigin") {\n            _addNonTweeningPT(this, cache, "smooth", cache.smooth, endValue);\n\n            continue;\n          } else if (p === "force3D") {\n            cache[p] = endValue;\n            continue;\n          } else if (p === "transform") {\n            _addRawTransformPTs(this, endValue, target);\n\n            continue;\n          }\n        } else if (!(p in style)) {\n          p = _checkPropPrefix(p) || p;\n        }\n\n        if (isTransformRelated || (endNum || endNum === 0) && (startNum || startNum === 0) && !_complexExp.test(endValue) && p in style) {\n          startUnit = (startValue + "").substr((startNum + "").length);\n          endNum || (endNum = 0); // protect against NaN\n\n          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);\n          startUnit !== endUnit && (startNum = _convertToUnit(target, p, startValue, endUnit));\n          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, 
1!isTransformRelated && (endUnit === "px" || p === "zIndex") && vars.autoRound !== false ? _renderRoundedCSSProp : _renderCSSProp);\n          this._pt.u = endUnit || 0;\n\n          if (isTransformRelated && finalTransformValue !== endValue) {\n            this._pt.b = startValue;\n            this._pt.e = finalTransformValue;\n            this._pt.r = _renderCSSPropWithBeginningAndEnd;\n          } else if (startUnit !== endUnit && endUnit !== "%") {\n            //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)\n            this._pt.b = startValue;\n            this._pt.r = _renderCSSPropWithBeginning;\n          }\n        } else if (!(p in style)) {\n          if (p in target) {\n            //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.\n            this.add(target, p, startValue || target[p], relative ? relative + endValue : endValue, index, targets);\n          } else if (p !== "parseTransform") {\n            (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._missingPlugin)(p, endValue);\n\n            continue;\n          }\n        } else {\n          _tweenComplexCSSString.call(this, target, p, startValue, relative ? relative + endValue : endValue);\n        }\n\n        isTransformRelated || (p in style ? inlineProps.push(p, 0, style[p]) : typeof target[p] === "function" ? inlineProps.push(p, 2, target[p]()) : inlineProps.push(p, 1, startValue || target[p]));\n        props.push(p);\n      }\n    }\n\n    hasPriority && (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._sortPropTweensByPriority)(this);\n  },\n  render: function render(ratio, data) {\n    if (data.tween._time || !_reverting()) {\n      var pt = data._pt;\n\n      while (pt) {\n        pt.r(ratio, pt.d);\n        pt = pt._next;\n      }\n    } else {\n      data.styles.revert();\n    }\n  },\n  get: _get,\n  aliases: _propertyAliases,\n  getSetter: function getSetter(target, property, plugin) {\n    //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.\n    var p = _propertyAliases[property];\n    p && p.indexOf(",") < 0 && (property = p);\n    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);\n  },\n  core: {\n    _removeProperty: _removeProperty,\n    _getMatrix: _getMatrix\n  }\n};\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.checkPrefix = _checkPropPrefix;\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.core.getStyleSaver = _getStyleSaver;\n\n(function (positionAndScale, rotation, others, aliases) {\n  var all = (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(positionAndScale + "," + rotation + "," + others, function (name) {\n    _transformProps[name] = 1;\n  });\n\n  (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(rotation, function (name) {\n    _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = "deg";\n    _rotationalProperties[name] = 1;\n  });\n\n  _propertyAliases[all[13]] = positionAndScale + "," + rotation;\n\n  (0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)(aliases, function (name) {\n    var split = name.split(":");\n    _propertyAliases[split[1]] = all[split[0]];\n  });\n})("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");\n\n(0,_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._forEachName)("x,y,z,top,right,bottom,left,width,height,fontSize,padding,margin,perspective", function (name) {\n  _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__._config.units[name] = "px";\n});\n\n_gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(CSSPlugin);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/CSSPlugin.js?\n}')},"./node_modules/gsap/DrawSVGPlugin.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   DrawSVGPlugin: () => (/* binding */ DrawSVGPlugin),\n/* harmony export */   "default": () => (/* binding */ DrawSVGPlugin)\n/* harmony export */ });\n/*!\n * DrawSVGPlugin 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar gsap,\n    _toArray,\n    _doc,\n    _win,\n    _isEdge,\n    _coreInitted,\n    _warned,\n    _getStyleSaver,\n    _reverting,\n    _windowExists = function _windowExists() {\n  return typeof window !== "undefined";\n},\n    _getGSAP = function _getGSAP() {\n  return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _numExp = /[-+=\\.]*\\d+[\\.e\\-\\+]*\\d*[e\\-\\+]*\\d*/gi,\n    //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8.\n_types = {\n  rect: ["width", "height"],\n  circle: ["r", "r"],\n  ellipse: ["rx", "ry"],\n  line: ["x2", "y2"]\n},\n    _round = function _round(value) {\n  return Math.round(value * 10000) / 10000;\n},\n    _parseNum = function _parseNum(value) {\n  return parseFloat(value) || 0;\n},\n    _parseSingleVal = function _parseSingleVal(value, length) {\n  var num = _parseNum(value);\n\n  return ~value.indexOf("%") ? num / 100 * length : num;\n},\n    _getAttributeAsNumber = function _getAttributeAsNumber(target, attr) {\n  return _parseNum(target.getAttribute(attr));\n},\n    _sqrt = Math.sqrt,\n    _getDistance = function _getDistance(x1, y1, x2, y2, scaleX, scaleY) {\n  return _sqrt(Math.pow((_parseNum(x2) - _parseNum(x1)) * scaleX, 2) + Math.pow((_parseNum(y2) - _parseNum(y1)) * scaleY, 2));\n},\n    _warn = function _warn(message) {\n  return console.warn(message);\n},\n    _hasNonScalingStroke = function _hasNonScalingStroke(target) {\n  return target.getAttribute("vector-effect") === "non-scaling-stroke";\n},\n    _bonusValidated = 1,\n    //<name>DrawSVGPlugin</name>\n//accepts values like "100%" or "20% 80%" or "20 50" and parses it into an absolute start and end position on the line/stroke based on its length. Returns an an array with the start and end values, like [0, 243]\n_parse = function _parse(value, length, defaultStart) {\n  var i = value.indexOf(" "),\n      s,\n      e;\n\n  if (i < 0) {\n    s = defaultStart !== undefined ? defaultStart + "" : value;\n    e = value;\n  } else {\n    s = value.substr(0, i);\n    e = value.substr(i + 1);\n  }\n\n  s = _parseSingleVal(s, length);\n  e = _parseSingleVal(e, length);\n  return s > e ? [e, s] : [s, e];\n},\n    _getLength = function _getLength(target) {\n  target = _toArray(target)[0];\n\n  if (!target) {\n    return 0;\n  }\n\n  var type = target.tagName.toLowerCase(),\n      style = target.style,\n      scaleX = 1,\n      scaleY = 1,\n      length,\n      bbox,\n      points,\n      prevPoint,\n      i,\n      rx,\n      ry;\n\n  if (_hasNonScalingStroke(target)) {\n    //non-scaling-stroke basically scales the shape and then strokes it at the screen-level (after transforms), thus we need to adjust the length accordingly.\n    scaleY = target.getScreenCTM();\n    scaleX = _sqrt(scaleY.a * scaleY.a + scaleY.b * scaleY.b);\n    scaleY = _sqrt(scaleY.d * scaleY.d + scaleY.c * scaleY.c);\n  }\n\n  try {\n    //IE bug: calling <path>.getTotalLength() locks the repaint area of the stroke to whatever its current dimensions are on that frame/tick. To work around that, we must call getBBox() to force IE to recalculate things.\n    bbox = target.getBBox(); //solely for fixing bug in IE - we don\'t actually use the bbox.\n  } catch (e) {\n    //firefox has a bug that throws an error if the element isn\'t visible.\n    _warn("Some browsers won\'t measure invisible elements (like display:none or masks inside defs).");\n  }\n\n  var _ref = bbox || {\n    x: 0,\n    y: 0,\n    width: 0,\n    height: 0\n  },\n      x = _ref.x,\n      y = _ref.y,\n      width = _ref.width,\n      height = _ref.height;\n\n  if ((!bbox || !width && !height) && _types[type]) {\n    //if the element isn\'t visible, try to discern width/height using its attributes.\n    width = _getAttributeAsNumber(target, _types[type][0]);\n    height = _getAttributeAsNumber(target, _types[type][1]);\n\n    if (type !== "rect" && type !== "line") {\n      //double the radius for circles and ellipses\n      width *= 2;\n      height *= 2;\n    }\n\n    if (type === "line") {\n      x = _getAttributeAsNumber(target, "x1");\n      y = _getAttributeAsNumber(target, "y1");\n      width = Math.abs(width - x);\n      height = Math.abs(height - y);\n    }\n  }\n\n  if (type === "path") {\n    prevPoint = style.strokeDasharray;\n    style.strokeDasharray = "none";\n    length = target.getTotalLength() || 0;\n    _round(scaleX) !== _round(scaleY) && !_warned && (_warned = 1) && _warn("Warning: <path> length cannot be measured when vector-effect is non-scaling-stroke and the element isn\'t proportionally scaled.");
1\n    length *= (scaleX + scaleY) / 2;\n    style.strokeDasharray = prevPoint;\n  } else if (type === "rect") {\n    length = width * 2 * scaleX + height * 2 * scaleY;\n  } else if (type === "line") {\n    length = _getDistance(x, y, x + width, y + height, scaleX, scaleY);\n  } else if (type === "polyline" || type === "polygon") {\n    points = target.getAttribute("points").match(_numExp) || [];\n    type === "polygon" && points.push(points[0], points[1]);\n    length = 0;\n\n    for (i = 2; i < points.length; i += 2) {\n      length += _getDistance(points[i - 2], points[i - 1], points[i], points[i + 1], scaleX, scaleY) || 0;\n    }\n  } else if (type === "circle" || type === "ellipse") {\n    rx = width / 2 * scaleX;\n    ry = height / 2 * scaleY;\n    length = Math.PI * (3 * (rx + ry) - _sqrt((3 * rx + ry) * (rx + 3 * ry)));\n  }\n\n  return length || 0;\n},\n    _getPosition = function _getPosition(target, length) {\n  target = _toArray(target)[0];\n\n  if (!target) {\n    return [0, 0];\n  }\n\n  length || (length = _getLength(target) + 1);\n\n  var cs = _win.getComputedStyle(target),\n      dash = cs.strokeDasharray || "",\n      offset = _parseNum(cs.strokeDashoffset),\n      i = dash.indexOf(",");\n\n  i < 0 && (i = dash.indexOf(" "));
1\n  dash = i < 0 ? length : _parseNum(dash.substr(0, i));\n  dash > length && (dash = length);\n  return [-offset || 0, dash - offset || 0];\n},\n    _initCore = function _initCore() {\n  if (_windowExists()) {\n    _doc = document;\n    _win = window;\n    _coreInitted = gsap = _getGSAP();\n    _toArray = gsap.utils.toArray;\n    _getStyleSaver = gsap.core.getStyleSaver;\n\n    _reverting = gsap.core.reverting || function () {};\n\n    _isEdge = ((_win.navigator || {}).userAgent || "").indexOf("Edge") !== -1; //Microsoft Edge has a bug that causes it not to redraw the path correctly if the stroke-linecap is anything other than "butt" (like "round") and it doesn\'t match the stroke-linejoin. A way to trigger it is to change the stroke-miterlimit, so we\'ll only do that if/when we have to (to maximize performance)\n  }\n};\n\nvar DrawSVGPlugin = {\n  version: "3.15.0",\n  name: "drawSVG",\n  register: function register(core) {\n    gsap = core;\n\n    _initCore();\n  },\n  init: function init(target, value, tween, index, targets) {\n    if (!target.getBBox) {\n      return false;\n    }\n\n    _coreInitted || _initCore();\n\n    var length = _getLength(target),\n        start,\n        end,\n        cs;\n\n    this.styles = _getStyleSaver && _getStyleSaver(target, "strokeDashoffset,strokeDasharray,strokeMiterlimit");\n    this.tween = tween;\n    this._style = target.style;\n    this._target = target;\n\n    if (value + "" === "true") {\n      value = "0 100%";\n    } else if (!value) {\n      value = "0 0";\n    } else if ((value + "").indexOf(" ") === -1) {\n      value = "0 " + value;\n    }\n\n    start = _getPosition(target, length);\n    end = _parse(value, length, start[0]);\n    this._length = _round(length);\n    this._dash = _round(start[1] - start[0]); //some browsers render artifacts if dash is 0, so we use a very small number in that case.\n\n    this._offset = _round(-start[0]);\n    this._dashPT = this.add(this, "_dash", this._dash, _round(end[1] - end[0]), 0, 0, 0, 0, 0, 1);\n    this._offsetPT = this.add(this, "_offset", this._offset, _round(-end[0]), 0, 0, 0, 0, 0, 1);\n\n    if (_isEdge) {\n      //to work around a bug in Microsoft Edge, animate the stroke-miterlimit by 0.0001 just to trigger the repaint (unnecessary if it\'s "round" and stroke-linejoin is also "round"). Imperceptible, relatively high-performance, and effective. Another option was to set the "d" <path> attribute to its current value on every tick, but that seems like it\'d be much less performant.\n      cs = _win.getComputedStyle(target);\n\n      if (cs.strokeLinecap !== cs.strokeLinejoin) {\n        end = _parseNum(cs.strokeMiterlimit);\n        this.add(target.style, "strokeMiterlimit", end, end + 0.01);\n      }\n    }\n\n    this._live = _hasNonScalingStroke(target) || ~(value + "").indexOf("live");\n    this._nowrap = ~(value + "").indexOf("nowrap");\n\n    this._props.push("drawSVG");\n\n    return _bonusValidated;\n  },\n  render: function render(ratio, data) {\n    if (data.tween._time || !_reverting()) {\n      var pt = data._pt,\n          style = data._style,\n          length,\n          lengthRatio,\n          dash,\n          offset;\n\n      if (pt) {\n        //when the element has vector-effect="non-scaling-stroke" and the SVG is resized (like on a window resize), it actually changes the length of the stroke! So we must sense that and make the proper adjustments.\n        if (data._live) {\n          length = _getLength(data._target);\n\n          if (length !== data._length) {\n            lengthRatio = length / data._length;\n            data._length = length;\n\n            if (data._offsetPT) {\n              data._offsetPT.s *= lengthRatio;\n              data._offsetPT.c *= lengthRatio;\n            }\n\n            if (data._dashPT) {\n              data._dashPT.s *= lengthRatio;\n              data._dashPT.c *= lengthRatio;\n            } else {\n              data._dash *= lengthRatio;\n            }\n          }\n        }\n\n        while (pt) {\n          pt.r(ratio, pt.d);\n          pt = pt._next;\n        }\n\n        dash = data._dash || ratio && ratio !== 1 && 0.0001 || 0; // only let it be zero if it\'s at the start or end of the tween.\n\n        length = data._length - dash + 0.1;\n        offset = data._offset;\n        dash && offset && dash + Math.abs(offset % data._length) > data._length - 0.05 && (offset += offset < 0 ? 0.005 : -0.005) && (length += 0.005);\n        style.strokeDashoffset = dash ? offset : offset + 0.001;\n        style.strokeDasharray = length < 0.1 ? "none" : dash ? dash + "px," + (data._nowrap ? 999999 : length) + "px" : "0px, 999999px";\n      }\n    } else {\n      data.styles.revert();\n    }\n  },\n  getLength: _getLength,\n  getPosition: _getPosition\n};\n_getGSAP() && gsap.registerPlugin(DrawSVGPlugin);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/DrawSVGPlugin.js?\n}')},"./node_modules/gsap/MorphSVGPlugin.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MorphSVGPlugin: () => (/* binding */ MorphSVGPlugin),\n/* harmony export */   "default": () => (/* binding */ MorphSVGPlugin)\n/* harmony export */ });\n/* harmony import */ var _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/paths.js */ "./node_modules/gsap/utils/paths.js");\nfunction _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\n/*!\n * MorphSVGPlugin 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\nvar gsap,\n    _toArray,\n    _lastLinkedAnchor,\n    _doc,\n    _coreInitted,\n    PluginClass,\n    _reverting,\n    _getGSAP = function _getGSAP() {\n  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _isFunction = function _isFunction(value) {\n  return typeof value === "function";\n},\n    _atan2 = Math.atan2,\n    _cos = Math.cos,\n    _sin = Math.sin,\n    _sqrt = Math.sqrt,\n    _PI = Math.PI,\n    _2PI = _PI * 2,\n    _angleMin = _PI * 0.3,\n    _angleMax = _PI * 0.7,\n    _bigNum = 1e20,\n    _numExp = /[-+=.]*\\d+[.e\\-+]*\\d*[e\\-+]*\\d*/gi,\n    // finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8.\n_selectorExp = /(^[#.][a-z]|[a-y][a-z])/i,\n    _commands = /[achlmqstvz]/i,\n    _log = function _log(message) {\n  return console && console.warn(message);\n},\n    _round = function _round(value) {\n  return Math.round(value * 1e5) / 1e5 || 0;\n},\n    _getAverageXY = function _getAverageXY(segment) {\n  var l = segment.length,\n      x = 0,\n      y = 0,\n      i;\n\n  for (i = 0; i < l;
1 i++) {\n    x += segment[i++];\n    y += segment[i];\n  }\n\n  return [x / (l / 2), y / (l / 2)];\n},\n    _getSize = function _getSize(segment) {\n  // rough estimate of the bounding box (based solely on the anchors) of a single segment. sets "size", "centerX", and "centerY" properties on the bezier array itself, and returns the size (width * height)\n  var l = segment.length,\n      xMax = segment[0],\n      xMin = xMax,\n      yMax = segment[1],\n      yMin = yMax,\n      x,\n      y,\n      i;\n\n  for (i = 6; i < l; i += 6) {\n    x = segment[i];\n    y = segment[i + 1];\n\n    if (x > xMax) {\n      xMax = x;\n    } else if (x < xMin) {\n      xMin = x;\n    }\n\n    if (y > yMax) {\n      yMax = y;\n    } else if (y < yMin) {\n      yMin = y;\n    }\n  }\n\n  segment.centerX = (xMax + xMin) / 2;\n  segment.centerY = (yMax + yMin) / 2;\n  return segment.size = (xMax - xMin) * (yMax - yMin);\n},\n    _getTotalSize = function _getTotalSize(rawPath, samplesPerBezier) {\n  if (samplesPerBezier === void 0) {\n    samplesPerBezier = 3;\n  }\n\n  // rough estimate of the bounding box of the entire list of Bezier segments (based solely on the anchors). sets "size", "centerX", and "centerY" properties on the bezier array itself, and returns the size (width * height)\n  var j = rawPath.length,\n      xMax = rawPath[0][0],\n      xMin = xMax,\n      yMax = rawPath[0][1],\n      yMin = yMax,\n      inc = 1 / samplesPerBezier,\n      l,\n      x,\n      y,\n      i,\n      segment,\n      k,\n      t,\n      inv,\n      x1,\n      y1,\n      x2,\n      x3,\n      x4,\n      y2,\n      y3,\n      y4;\n\n  while (--j > -1) {\n    segment = rawPath[j];\n    l = segment.length;\n\n    for (i = 6; i < l; i += 6) {\n      x1 = segment[i];\n      y1 = segment[i + 1];\n      x2 = segment[i + 2] - x1;\n      y2 = segment[i + 3] - y1;\n      x3 = segment[i + 4] - x1;\n      y3 = segment[i + 5] - y1;\n      x4 = segment[i + 6] - x1;\n      y4 = segment[i + 7] - y1;\n      k = samplesPerBezier;\n\n      while (--k > -1) {\n        t = inc * k;\n        inv = 1 - t;\n        x = (t * t * x4 + 3 * inv * (t * x3 + inv * x2)) * t + x1;\n        y = (t * t * y4 + 3 * inv * (t * y3 + inv * y2)) * t + y1;\n\n        if (x > xMax) {\n          xMax = x;\n        } else if (x < xMin) {\n          xMin = x;\n        }\n\n        if (y > yMax) {\n          yMax = y;\n        } else if (y < yMin) {\n          yMin = y;\n        }\n      }\n    }\n  }\n\n  rawPath.centerX = (xMax + xMin) / 2;\n  rawPath.centerY = (yMax + yMin) / 2;\n  rawPath.left = xMin;\n  rawPath.width = xMax - xMin;\n  rawPath.top = yMin;\n  rawPath.height = yMax - yMin;\n  return rawPath.size = (xMax - xMin) * (yMax - yMin);\n},\n    _sortByComplexity = function _sortByComplexity(a, b) {\n  return b.length - a.length;\n},\n    _sortBySize = function _sortBySize(a, b) {\n  var sizeA = a.size || _getSize(a),\n      sizeB = b.size || _getSize(b);\n\n  return Math.abs(sizeB - sizeA) < (sizeA + sizeB) / 20 ? b.centerX - a.centerX || b.centerY - a.centerY : sizeB - sizeA; //if the size is within 10% of each other, prioritize position from left to right, then top to bottom.\n},\n    _offsetSegment = function _offsetSegment(segment, shapeIndex) {\n  var a = segment.slice(0),\n      l = segment.length,\n      wrap = l - 2,\n      i,\n      index;\n  shapeIndex = shapeIndex | 0;\n\n  for (i = 0; i < l; i++) {\n    index = (i + shapeIndex) % wrap;\n    segment[i++] = a[index];\n    segment[i] = a[index + 1];\n  }\n},\n    _getTotalMovement = function _getTotalMovement(sb, eb, shapeIndex, offsetX, offsetY) {\n  var l = sb.length,\n      d = 0,\n      wrap = l - 2,\n      index,\n      i,\n      x,\n      y;\n  shapeIndex *= 6;\n\n  for (i = 0; i < l; i += 6) {\n    index = (i + shapeIndex) % wrap;\n    y = sb[index] - (eb[i] - offsetX);\n    x = sb[index + 1] - (eb[i + 1] - offsetY);\n    d += _sqrt(x * x + y * y);\n  }\n\n  return d;\n},\n    _getClosestShapeIndex = function _getClosestShapeIndex(sb, eb, checkReverse) {\n  //finds the index in a closed cubic bezier array that\'s closest to the angle provided (angle measured from the center or average x/y).\n  var l = sb.length,\n      sCenter = _getAverageXY(sb),\n      //when comparing distances, adjust the coordinates as if the shapes are centered with each other.\n  e
1Center = _getAverageXY(eb),\n      offsetX = eCenter[0] - sCenter[0],\n      offsetY = eCenter[1] - sCenter[1],\n      min = _getTotalMovement(sb, eb, 0, offsetX, offsetY),\n      minIndex = 0,\n      copy,\n      d,\n      i;\n\n  for (i = 6; i < l; i += 6) {\n    d = _getTotalMovement(sb, eb, i / 6, offsetX, offsetY);\n\n    if (d < min) {\n      min = d;\n      minIndex = i;\n    }\n  }\n\n  if (checkReverse) {\n    copy = sb.slice(0);\n    (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.reverseSegment)(copy);\n\n    for (i = 6; i < l; i += 6) {\n      d = _getTotalMovement(copy, eb, i / 6, offsetX, offsetY);\n\n      if (d < min) {\n        min = d;\n        minIndex = -i;\n      }\n    }\n  }\n\n  return minIndex / 6;\n},\n    _getClosestAnchor = function _getClosestAnchor(rawPath, x, y) {\n  // finds the x/y of the anchor that\'s closest to the provided x/y coordinate (returns an array, like [x, y]). The bezier should be the top-level type that contains an array for each segment.\n  var j = rawPath.length,\n      closestDistance = _bigNum,\n      closestX = 0,\n      closestY = 0,\n      segment,\n      dx,\n      dy,\n      d,\n      i,\n      l;\n\n  while (--j > -1) {\n    segment = rawPath[j];\n    l = segment.length;\n\n    for (i = 0; i < l; i += 6) {\n      dx = segment[i] - x;\n      dy = segment[i + 1] - y;\n      d = _sqrt(dx * dx + dy * dy);\n\n      if (d < closestDistance) {\n        closestDistance = d;\n        closestX = segment[i];\n        closestY = segment[i + 1];\n      }\n    }\n  }\n\n  return [closestX, closestY];\n},\n    _getClosestSegment = function _getClosestSegment(bezier, pool, startIndex, sortRatio, offsetX, offsetY) {\n  // matches the bezier to the closest one in a pool (array) of beziers, assuming they are in order of size and we shouldn\'t drop more than 20% of the size, otherwise prioritizing location (total distance to the center). Extracts the segment out of the pool array and returns it.\n  var l = pool.length,\n      index = 0,\n      minSize = Math.min(bezier.size || _getSize(bezier), pool[startIndex].size || _getSize(pool[startIndex])) * sortRatio,\n      // limit things based on a percentage of the size of either the bezier or the next element in the array, whichever is smaller.\n  min = _bigNum,\n      cx = bezier.centerX + offsetX,\n      cy = bezier.centerY + offsetY,\n      size,\n      i,\n      dx,\n      dy,\n      d;\n\n  for (i = startIndex; i < l; i++) {\n    size = pool[i].size || _getSize(pool[i]);\n\n    if (size < minSize) {\n      break;\n    }\n\n    dx = pool[i].centerX - cx;\n    dy = pool[i].centerY - cy;\n    d = _sqrt(dx * dx + dy * dy);\n\n    if (d < min) {\n      index = i;\n      min = d;\n    }\n  }\n\n  d = pool[index];\n  pool.splice(index, 1);\n  return d;\n},\n    _addAnchorsToBezier = function _addAnchorsToBezier(segment, i, quantity) {\n  if (quantity === void 0) {\n    quantity = 1;\n  }\n\n  var ax = segment[i],\n      ay = segment[i + 1],\n      cp1x = segment[i + 2],\n      cp1y = segment[i + 3],\n      cp2x = segment[i + 4],\n      cp2y = segment[i + 5],\n      bx = segment[i + 6],\n      by = segment[i + 7],\n      t,\n      x1a,\n      x2,\n      y1a,\n      y2,\n      x1,\n      y1,\n      x2a,\n      y2a;\n\n  while (quantity-- > 0) {\n    t = 1 - 1 / (quantity + 2);\n    x1a = ax + (cp1x - ax) * t;\n    x2 = cp1x + (cp2x - cp1x) * t;\n    y1a = ay + (cp1y - ay) * t;\n    y2 = cp1y + (cp2y - cp1y) * t;\n    x1 = x1a + (x2 - x1a) * t;\n    y1 = y1a + (y2 - y1a) * t;\n    x2a = cp2x + (bx - cp2x) * t;\n    y2a = cp2y + (by - cp2y) * t;\n    x2 += (x2a - x2) * t;\n    y2 += (y2a - y2) * t;\n    segment.splice(i + 2, 4, cp1x = _round(x1a), // first control point\n    cp1y = _round(y1a), cp2x = _round(x1), // second control point\n    cp2y = _round(y1), bx = _round(x1 + (x2 - x1) * t), // new fabricated anchor\n    by = _round(y1 + (y2 - y1) * t), _round(x2), // third control point\n    _round(y2), _round(x2a), // fourth control point\n    _round(y2a));\n  }\n},\n    _getLargestIndex = function _getLargestIndex(a) {\n  var i = a.length,\n      max = -_bigNum,\n      largestIndex;\n\n  while (i--) {\n    if (a[i] > max) {\n      max = a[i];\n      largestIndex = i;\n    }\n  }\n\n  return largestIndex;\n}
1,\n    // adds a certain number of anchors to a segment (made up of cubic Beziers), distributed as evenly as possible so that the longer Beziers get subdivided more. Even distribution of anchors leads to smoother morphs/interpolation\n_subdivideSegmentQty = function _subdivideSegmentQty(segment, quantity) {\n  var distances = [],\n      anchorsToAdd = [],\n      // number of anchors to add to each bezier.\n  l = segment.length - 2,\n      i = 0;\n\n  for (; i < l; i += 6) {\n    distances.push(Math.pow(segment[i] - segment[i + 6], 2) + Math.pow(segment[i + 1] - segment[i + 7], 2));\n  }\n\n  while (quantity--) {\n    i = _getLargestIndex(distances);\n    anchorsToAdd[i] = l = (anchorsToAdd[i] || 0) + 1;\n    distances[i] *= l / (l + 1);\n  }\n\n  i = distances.length;\n\n  while (i--) {\n    // always go backwards because adding an anchor shoves new numbers into the segment Array, altering the index of subsequent Beziers\n    anchorsToAdd[i] && _addAnchorsToBezier(segment, i * 6, anchorsToAdd[i]);\n  }\n},\n    _getDefaultSmoothPoints = function _getDefaultSmoothPoints(rawPath, skipMeasure) {\n  skipMeasure || (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements)(rawPath);\n  return Math.max(4, Math.round(rawPath.totalLength / 4));\n},\n    _cloneAndSortRawPath = function _cloneAndSortRawPath(ar) {\n  return ar.slice(0).sort(_sortByComplexity);\n},\n    _segmentCanBeIgnored = function _segmentCanBeIgnored(segment) {\n  // senses if the segment is basically invisible (the x/y values don\'t move much at all)\n  var x = segment[0],\n      y = segment[1],\n      i = 2;\n\n  for (; i < segment.length; i += 2) {\n    if (Math.abs(segment[i] - x) > 0.01 || Math.abs(segment[i + 1] - y) > 0.01) {\n      return false;\n    }\n  }\n\n  return true;\n},\n    _smoothRawPath = function _smoothRawPath(rawPath, config) {\n  config = config || {};\n  var _config = config,\n      redraw = _config.redraw,\n      points = _config.points,\n      _config$maxSegments = _config.maxSegments,\n      maxSegments = _config$maxSegments === void 0 ? 999 : _config$maxSegments,\n      pointsAdded = 0,\n      sortedRawPath = rawPath,\n      templateRawPath = Array.isArray(points) ? points : 0,\n      segmentPointsToAdd,\n      j,\n      segment,\n      smoothSegment,\n      anchorDistance;\n  redraw = redraw !== false; // redrawing forces the points to be more evenly distributed across the entire path, which leads to smoother morphs/interpolations but also sacrifices fidelity to the original shape. We must measure the path to do all the calculations properly.\n\n  if (redraw) {\n    (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements)(rawPath); // only burn CPU cycles for measuring if we\'re redrawing\n  } else {\n    // ensure the rawPath has a totalPoints property.\n    rawPath.totalPoints = 0;\n    j = rawPath.length;\n\n    while (j--) {\n      rawPath.totalPoints += rawPath[j].length;\n    }\n  }\n\n  if (templateRawPath) {\n    // if there\'s a template to match (if "points" is a RawPath), create copies that are sorted by complexity so that we can match them in the proper order. For example, if the template has a 100-anchor segment and a 20-point segment, we\'d want to make sure the most complex segment in the RawPath gets the 100 points.\n    sortedRawPath = _cloneAndSortRawPath(rawPath);\n    templateRawPath = _cloneAndSortRawPath(templateRawPath);\n    anchorDistance = templateRawPath[0].totalLength / Math.round(templateRawPath[0].length / 6);\n  } else {\n    if (!points || points === "auto") {\n      points = _getDefaultSmoothPoints(rawPath, redraw);\n      redraw || (points -= Math.round(rawPath.totalPoints / 6));\n    }\n\n    points = Math.max(redraw ? 10 : 4, Math.min(999, points));\n  }\n\n  for (j = 0; j < sortedRawPath.length; j++) {\n    segment = sortedRawPath[j];\n    segmentPointsToAdd = Math.max(redraw ? 10 : 4, templateRawPath ? Math.round(templateRawPath[j] ? templateRawPath[j].length / 6 : sortedRawPath[j].totalLength / anchorDistance || 0) : Math.round((pointsAdded / points + (redraw ? segment.totalLength / rawPath.totalLength : segment.length / rawPath.totalPoints)) * points) - pointsAdded);\n\n    if (j >= maxSegments || templateRawPath && (!templateRawPath[j] || _segmentCanBeIgnored(templateRawPath[j]))) {// do nothing (skip) if the segment is too small or if it is beyond the maximum number of segments to process (like when the corresponding segment in the start/end RawPath doesn\'t exist)\n    } else if (redraw) {\n      var _segment;\n\n      // evenly distribute new anchor points across the segment so that the morphing looks smoother.\n      smoothSegment = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.pointsToSegment)((0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.segmentToDistributedPoints)(segment, segmentPointsToAdd), config.curviness);\n      segment.length = 0;\n\n      (_segment = segment).push.apply(_segment, smoothSegment);\n    } else {\n      _subdivideSegmentQty(segment, segmentPointsToAdd);\n    }\n\n    pointsAdded += segmentPointsToAdd;\n  }\n\n  return rawPath;\n},\n    _equalizeSegmentQuantity = function _equalizeSegmentQuantity(start, end, shapeIndex, map, fillSafe) {\n  // returns an array of shape indexes, 1 for each segment.\n  var dif = end.length - start.length,\n      longer = dif > 0 ? end : start,\n      shorter = dif > 0 ? start : end,\n      added = 0,\n      sortMethod = map === "complexity" ? _sortByComplexity : _sortBySize,\n      sortRatio = map === "position" ? 0 : typeof map === "number" ? map : 0.8,\n      i = shorter.length,\n      shapeIndices = typeof shapeIndex === "object" && shapeIndex.push ? shapeIndex.slice(0) : [shapeIndex],\n      reverse = shapeIndices[0] === "reverse" || shapeIndices[0] < 0,\n      log = shapeIndex === "log",\n      eb,\n      sb,\n      b,\n      x,\n      y,\n      offsetX,\n      offsetY;\n\n  if (!shorter[0]) {\n    return;\n  }\n\n  if (longer.length > 1) {\n    start.sort(sortMethod);\n    end.sort(sortMethod);\n    longer.size || _getTotalSize(longer); // ensures centerX and centerY are defined (used below).\n\n    shorter.size || _getTotalSize(shorter);\n    offsetX = longer.centerX - shorter.centerX;\n    offsetY = longer.centerY - shorter.centerY;\n\n    if (sortMethod === _sortBySize) {\n      for (i = 0; i < shorter.length;
1 i++) {\n        longer.splice(i, 0, _getClosestSegment(shorter[i], longer, i, sortRatio, offsetX, offsetY));\n      }\n    }\n  }\n\n  if (dif) {\n    dif < 0 && (dif = -dif);\n    longer[0].length > shorter[0].length && _subdivideSegmentQty(shorter[0], (longer[0].length - shorter[0].length) / 6 | 0); // since we use shorter[0] as the one to map the origination point of any brand new fabricated segments, do any subdividing first so that there are more points to choose from (if necessary)\n\n    i = shorter.length;\n\n    while (added < dif) {\n      x = longer[i].size || _getSize(longer[i]); //just to ensure centerX and centerY are calculated which we use on the next line.\n\n      b = _getClosestAnchor(shorter, longer[i].centerX, longer[i].centerY);\n      x = b[0];\n      y = b[1];\n      shorter[i++] = [x, y, x, y, x, y, x, y];\n      shorter.totalPoints += 8;\n      added++;\n    }\n  }\n\n  for (i = 0; i < start.length; i++) {\n    eb = end[i];\n    sb = start[i];\n    dif = eb.length - sb.length;\n\n    if (dif < 0) {\n      _subdivideSegmentQty(eb, -dif / 6 | 0);\n    } else if (dif > 0) {\n      _subdivideSegmentQty(sb, dif / 6 | 0);\n    }\n\n    if (reverse && fillSafe !== false && !sb.reversed) {\n      (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.reverseSegment)(sb);\n    }\n\n    shapeIndex = shapeIndices[i] || shapeIndices[i] === 0 ? shapeIndices[i] : "auto";\n\n    if (shapeIndex) {\n      // if the start shape is closed, find the closest point to the start/end, and re-organize the bezier points accordingly so that the shape morphs in a more intuitive way.\n      if (sb.closed || Math.abs(sb[0] - sb[sb.length - 2]) < 0.5 && Math.abs(sb[1] - sb[sb.length - 1]) < 0.5) {\n        if (shapeIndex === "auto" || shapeIndex === "log") {\n          shapeIndices[i] = shapeIndex = _getClosestShapeIndex(sb, eb, !i || fillSafe === false);\n\n          if (shapeIndex < 0) {\n            reverse = true;\n            (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.reverseSegment)(sb);\n            shapeIndex = -shapeIndex;\n          }\n\n          _offsetSegment(sb, shapeIndex * 6);\n        } else if (shapeIndex !== "reverse") {\n          if (i && shapeIndex < 0) {\n            // only happens if an array is passed as shapeIndex and a negative value is defined for an index beyond 0. Very rare, but helpful sometimes.\n            (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.reverseSegment)(sb);\n          }\n\n          _offsetSegment(sb, (shapeIndex < 0 ? -shapeIndex : shapeIndex) * 6);\n        } // otherwise, if it\'s not a closed shape, consider reversing it if that would make the overall travel less\n\n      } else if (!reverse && (shapeIndex === "auto" && Math.abs(eb[0] - sb[0]) + Math.abs(eb[1] - sb[1]) + Math.abs(eb[eb.length - 2] - sb[sb.length - 2]) + Math.abs(eb[eb.length - 1] - sb[sb.length - 1]) > Math.abs(eb[0] - sb[sb.length - 2]) + Math.abs(eb[1] - sb[sb.length - 1]) + Math.abs(eb[eb.length - 2] - sb[0]) + Math.abs(eb[eb.length - 1] - sb[1]) || shapeIndex % 2)) {\n        (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.reverseSegment)(sb);\n        shapeIndices[i] = -1;\n        reverse = true;\n      } else if (shapeIndex === "auto") {\n        shapeIndices[i] = 0;\n      } else if (shapeIndex === "reverse") {\n        shapeIndices[i] = -1;\n      }\n\n      if (sb.closed !== eb.closed) {\n        //if one is closed and one isn\'t, don\'t close either one otherwise the tweening will look weird (but remember, the beginning and final states will honor the actual values, so this only affects the inbetween state)\n        sb.closed = eb.closed = false;\n      }\n    }\n  }\n\n  log && _log("shapeIndex:[" + shapeIndices.join(",") + "]");\n  start.shapeIndex = shapeIndices;\n  return shapeIndices;\n},\n    _pathFilter = function _pathFilter(a, shapeIndex, map, precompile, fillSafe) {\n  var start = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath)(a[0]),\n      end = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath)(a[1]);\n\n  if (!_equalizeSegmentQuantity(start, end, shapeIndex || shapeIndex === 0 ? shapeIndex : "auto", map, fillSafe)) {\n    return; // malformed path data or null target\n  }\n\n  a[0] = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString)(start);\n  a[1] = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString)(end);\n  (precompile === "log" || precompile === true) && _log(\'precompile:["\' + a[0] + \'","\' + a[1] + \'"]\');\n},\n    _offsetPoints = function _offsetPoints(text, offset) {\n  if (!offset) {\n    return text;\n  }\n\n  var a = text.match(_numExp) || [],\n      l = a.length,\n      s = "",\n      inc,\n      i,\n      j;\n\n  if (offset === "reverse") {\n    i = l - 1;\n    inc = -2;\n  } else {\n    i = ((parseInt(offset, 10) || 0) * 2 + 1 + l * 100) % l;\n    inc = 2;\n  }\n\n  for (j = 0; j < l; j += 2) {\n    s += a[i - 1] + "," + a[i] + " ";\n    i = (i + inc) % l;\n  }\n\n  return s;\n}
1,\n    // adds a certain number of points while maintaining the polygon/polyline shape (so that the start/end values can have a matching quantity of points to animate). Returns the revised string.\n_equalizePointQuantity = function _equalizePointQuantity(a, quantity) {\n  var tally = 0,\n      x = parseFloat(a[0]),\n      y = parseFloat(a[1]),\n      s = x + "," + y + " ",\n      max = 0.999999,\n      newPointsPerSegment,\n      i,\n      l,\n      j,\n      factor,\n      nextX,\n      nextY;\n  l = a.length;\n  newPointsPerSegment = quantity * 0.5 / (l * 0.5 - 1);\n\n  for (i = 0; i < l - 2; i += 2) {\n    tally += newPointsPerSegment;\n    nextX = parseFloat(a[i + 2]);\n    nextY = parseFloat(a[i + 3]);\n\n    if (tally > max) {\n      //compare with 0.99999 instead of 1 in order to prevent rounding errors\n      factor = 1 / (Math.floor(tally) + 1);\n      j = 1;\n\n      while (tally > max) {\n        s += (x + (nextX - x) * factor * j).toFixed(2) + "," + (y + (nextY - y) * factor * j).toFixed(2) + " ";\n        tally--;\n        j++;\n      }\n    }\n\n    s += nextX + "," + nextY + " ";\n    x = nextX;\n    y = nextY;\n  }\n\n  return s;\n},\n    _pointsFilter = function _pointsFilter(a) {\n  var startNums = a[0].match(_numExp) || [],\n      endNums = a[1].match(_numExp) || [],\n      dif = endNums.length - startNums.length;\n\n  if (dif > 0) {\n    a[0] = _equalizePointQuantity(startNums, dif);\n  } else {\n    a[1] = _equalizePointQuantity(endNums, -dif);\n  }\n},\n    _buildPointsFilter = function _buildPointsFilter(shapeIndex) {\n  return !isNaN(shapeIndex) ? function (a) {\n    _pointsFilter(a);\n\n    a[1] = _offsetPoints(a[1], parseInt(shapeIndex, 10));\n  } : _pointsFilter;\n},\n    _parseShape = function _parseShape(shape, forcePath, target) {\n  var isString = typeof shape === "string",\n      e,\n      type;\n\n  if (!isString || _selectorExp.test(shape) || (shape.match(_numExp) || []).length < 3) {\n    e = _toArray(shape)[0];\n\n    if (e) {\n      type = (e.nodeName + "").toUpperCase();\n\n      if (forcePath && type !== "PATH") {\n        // if we were passed an element (or selector text for an element) that isn\'t a path, convert it.\n        e = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.convertToPath)(e, false);\n        type = "PATH";\n      }\n\n      shape = e.getAttribute(type === "PATH" ? "d" : "points") || "";\n\n      if (e === target) {\n        // if the shape matches the target element, the user wants to revert to the original which should have been stored in the data-original attribute\n        shape = e.getAttributeNS(null, "data-original") || shape;\n      }\n    } else {\n      _log("WARNING: invalid morph to: " + shape);\n\n      shape = false;\n    }\n  }\n\n  return shape;\n},\n    // adds a "cpData" property to each segment that\'s an Array with the angle to each control point (in radians) and length so that we can maintain smooth anchors (interpolating the raw control point coordinates could lead to sharp angles in the middle). So [undefined, undefined, angle, length, angle, length, undefined, undefined, angle, length, angle, length, ...] (anchor slots are undefined)\n_recordControlPointData = function _recordControlPointData(rawPath) {\n  var j = rawPath.length,\n      segment,\n      x,\n      y,\n      x2,\n      y2,\n      i,\n      l,\n      cpData;\n\n  while (--j > -1) {\n    segment = rawPath[j];\n    cpData = segment.cpData = segment.cpData || [];\n    cpData.length = 0;\n    l = segment.length - 2;\n\n    for (i = 0; i < l; i += 6) {\n      x = segment[i] - segment[i + 2];\n      y = segment[i + 1] - segment[i + 3];\n      x2 = segment[i + 6] - segment[i + 4];\n      y2 = segment[i + 7] - segment[i + 5];\n      cpData[i + 2] = _atan2(y, x);\n      cpData[i + 3] = _sqrt(x * x + y * y);\n      cpData[i + 4] = _atan2(y2, x2);\n      cpData[i + 5] = _sqrt(x2 * x2 + y2 * y2);\n    }\n  }\n\n  return rawPath;\n},\n    _parseOriginFactors = function _parseOriginFactors(v) {\n  var a = v.trim().split(" "),\n      x = ~v.indexOf("left") ? 0 : ~v.indexOf("right") ? 100 : isNaN(parseFloat(a[0])) ? 50 : parseFloat(a[0]),\n      y = ~v.indexOf("top") ? 0 : ~v.indexOf("bottom") ? 100 : isNaN(parseFloat(a[1])) ? 50 : parseFloat(a[1]);\n  return {\n    x: x / 100,\n    y: y / 100\n  };\n},\n    _shortAngle = function _shortAngle(dif) {\n  return dif !== dif % _PI ? dif + (dif < 0 ? _2PI : -_2PI) : dif;\n},\n    _morphMessage = "Use MorphSVGPlugin.convertToPath() to convert to a path before morphing.",\n    _tweenRotation = function _tweenRotation(start, end, i, linkedPT) {\n  var so = this._origin,\n      // starting origin\n  eo = this._eOrigin,\n      // ending origin\n  dx = start[i] - so.x,\n      dy = start[i + 1] - so.y,\n      d = _sqrt(dx * dx + dy * dy),\n      // length from starting origin to starting point\n  sa = _atan2(dy, dx),\n      angleDif,\n      _short;\n\n  dx = end[i] - eo.x;\n  dy = end[i + 1] - eo.y;\n  angleDif = _atan2(dy, dx) - sa;\n  _short = _shortAngle(angleDif); // in the case of control points, we ALWAYS link them to their anchor so that they don\'t get torn apart and rotate the opposite direction. If it\'s not a control point, we look at the most recently linked point as long as they\'re within a certain rotational range of each other.\n\n  if (!linkedPT && _lastLinkedAnchor && Math.abs(_short + _lastLinkedAnchor.ca) < _angleMin) {\n    linkedPT = _lastLinkedAnchor;\n  }\n\n  return this._anchorPT = _lastLinkedAnchor = {\n    _next: this._anchorPT,\n    t: start,\n    sa: sa,\n    // starting angle\n    ca: linkedPT && _short * linkedPT.ca < 0 && Math.abs(_short) > _angleMax ? angleDif : _short,\n    //change in angle\n    sl: d,\n    // starting length\n    cl: _sqrt(dx * dx + dy * dy) - d,\n    // change in length\n    i: i\n  };\n},\n    _initCore = function _initCore(required) {\n  gsap = _getGSAP();\n  PluginClass = PluginClass || gsap && gsap.plugins.morphSVG;\n\n  if (gsap && PluginClass) {\n    _toArray = gsap.utils.toArray;\n\n    _reverting = gsap.core.reverting || function () {};\n\n    _doc = document;\n    PluginClass.prototype._tweenRotation = _tweenRotation;\n    _coreInitted = 1;\n  } else if (required) {\n    _log("Please gsap.registerPlugin(MorphSVGPlugin)");\n  }\n};\n\nvar MorphSVGPlugin = {\n  version: "3.15.0",\n  name: "morphSVG",\n  rawVars: 1,\n  // otherwise "render" would be interpreted as a function-based value.\n  register: function register(core, Plugin) {\n    gsap = core;\n    PluginClass = Plugin;\n\n    _initCore();\n  },\n  init: function init(target, value, tween, index, targets) {\n    _coreInitted || _initCore(1);\n\n    if (!value) {\n      _log("invalid shape");\n\n      return false;\n    }\n\n    _isFunction(value) && (value = value.call(tween, index, target, targets));\n    var type, p, pt, shape, isPoly, shapeIndex, map, startCPData, endCPData, start, end, i, j, l, startSeg, endSeg, precompiled, originFactors, useRotation, curveMode;\n\n    if (typeof value === "string" || value.getBBox || value[0]) {\n      value = {\n        shape: value\n      };\n    } else if (typeof value === "object") {\n      // if there are any function-based values, parse them here (and make a copy of the object so we\'re not modifying the original)\n      type = {};\n\n      for (p in value) {\n        type[p] = _isFunction(value[p]) && p !== "render" ? value[p].call(tween, index, target, targets) : value[p];\n      }\n\n      value = type;\n    }\n\n    var cs = target.nodeType ? window.getComputedStyle(target) : {},\n        fill = cs.fill + "",\n        fillSafe = !(fill === "none" || (fill.match(_numExp) || [])[3] === "0" || cs.fillRule === "evenodd"),\n        smooth = value.smooth,\n        origins = (value.origin || "50 50").split(",");\n    smooth === true || smooth === "auto" ? smooth = {} : typeof smooth === "number" && (smooth = {\n      points: smooth\n    });\n    type = (target.nodeName + "").toUpperCase();\n    isPoly = type === "POLYLINE" || type === "POLYGON";\n\n    if (type !== "PATH" && !isPoly && !value.prop) {\n      _log("Cannot morph a <" + type + "> element. " + _morphMessage);\n\n      return false;\n    }\n\n    p = type === "PATH" ? "d" : "points";\n\n    if (!value.prop && !_isFunction(target.setAttribute)) {\
1n      return false;\n    }\n\n    shape = _parseShape(value.shape || value.d || value.points || "", p === "d", target);\n\n    if (isPoly && _commands.test(shape)) {\n      _log("A <" + type + "> cannot accept path data. " + _morphMessage);\n\n      return false;\n    }\n\n    shapeIndex = value.shapeIndex || value.shapeIndex === 0 ? value.shapeIndex : "auto";\n    map = value.map || MorphSVGPlugin.defaultMap;\n    this._prop = value.prop;\n    this._render = value.render || MorphSVGPlugin.defaultRender;\n    this._apply = "updateTarget" in value ? value.updateTarget : MorphSVGPlugin.defaultUpdateTarget;\n    this._rnd = Math.pow(10, isNaN(value.precision) ? 2 : +value.precision);\n    this._tween = tween;\n\n    if (shape) {\n      this._target = target;\n      precompiled = typeof value.precompile === "object";\n      start = this._original = this._prop ? target[this._prop] : target.getAttribute(p);\n\n      if (!this._prop && !target.getAttributeNS(null, "data-original")) {\n        target.setAttributeNS(null, "data-original", start); // record the original state in a data-original attribute so that we can revert to it later.\n      }\n\n      if (p === "d" || this._prop) {\n        start = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath)(precompiled ? value.precompile[0] : start);\n        end = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath)(precompiled ? value.precompile[1] : shape);\n\n        if (smooth) {\n          j = start.length;\n\n          while (--j) {\n            // check all the segments AFTER the first one and if they\'re basically invisible, remove them.\n            _segmentCanBeIgnored(start[j]) && start.splice(j, 1);\n          }\n\n          _smoothRawPath(start, _extends({}, smooth, {\n            points: +smooth.points || Math.max(_getDefaultSmoothPoints(start), _getDefaultSmoothPoints(end)),\n            maxSegments: end.length\n          }));\n\n          _smoothRawPath(end, smooth.redraw === false ? smooth : _extends({}, smooth, {\n            points: start\n          }));\n        }\n\n        if (!precompiled && !_equalizeSegmentQuantity(start, end, shapeIndex, map, fillSafe)) {\n          return false; //malformed path data or null target\n        }\n\n        if (value.precompile === "log" || value.precompile === true) {\n          _log(\'precompile:["\' + (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString)(start) + \'","\' + (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString)(end) + \'"]\');\n        }\n\n        useRotation = (value.type || MorphSVGPlugin.defaultType) !== "linear";\n        curveMode = value.curveMode || useRotation; // curveMode means animating the angle and length of control points rather than the raw coordinates.\n\n        _recordControlPointData(start);\n\n        _recordControlPointData(end);\n\n        if (useRotation) {\n          start.size || _getTotalSize(start); // adds top/left/width/height values\n\n          end.size || _getTotalSize(end);\n          originFactors = _parseOriginFactors(origins[0]);\n          this._origin = start.origin = {\n            x: start.left + originFactors.x * start.width,\n            y: start.top + originFactors.y * start.height\n          };\n          origins[1] && (originFactors = _parseOriginFactors(origins[1]));\n          this._eOrigin = {\n            x: end.left + originFactors.x * end.width,\n            y: end.top + originFactors.y * end.height\n          };\n        }\n\n        this._rawPath = target._gsRawPath = start;\n        j = start.length;\n\n        while (--j > -1) {\n          startSeg = start[j];\n          endSeg = end[j];\n          startCPData = startSeg.cpData;\n          endCPData = endSeg.cpData;\n          l = startSeg.length;\n          _lastLinkedAnchor = 0; // reset; we use _lastLinkedAnchor in the _tweenRotation() method to help make sure that close points don\'t get ripped apart and rotate opposite directions. Typically we want to go the shortest direction, but if the previous anchor is going a different direction, we override this logic (within certain thresholds)\n\n          for (i = 0; i < l; i += 6) {\n            if (endSeg[i] !== startSeg[i] || endSeg[i + 1] !== startSeg[i + 1]) {\n              if (useRotation) {\n                pt = this._tweenRotation(start
1Seg, endSeg, i);\n              } else {\n                pt = this.add(startSeg, i, startSeg[i], endSeg[i], 0, 0, 0, 0, 0, 1);\n                pt = this.add(startSeg, i + 1, startSeg[i + 1], endSeg[i + 1], 0, 0, 0, 0, 0, 1) || pt;\n              }\n            }\n          }\n\n          for (i = 0; i < l; i += 2) {\n            if (curveMode && (startCPData[i] !== endCPData[i] || startCPData[i + 1] !== endCPData[i + 1]) && startCPData[i + 1] && endCPData[i + 1]) {\n              // if the angle or length has changed, animate...unless the length of either is 0, in which case we\'ll just do a direct animation rather than the angle/length interpolation because it\'s generally more aesthetically pleasing.\n              this._controlPT = {\n                _next: this._controlPT,\n                i: i,\n                j: j,\n                ai: i % 6 > 3 ? i + 2 : i - 2,\n                sa: startCPData[i],\n                ca: _shortAngle(endCPData[i] - startCPData[i]),\n                sl: startCPData[i + 1],\n                cl: endCPData[i + 1] - startCPData[i + 1]\n              };\n            } else {\n              // the angles/lengths may match, but if the coordinates have changed, do the less expensive animation of just coordinates.\n              endSeg[i] !== startSeg[i] && (pt = this.add(startSeg, i, startSeg[i], endSeg[i], 0, 0, 0, 0, 0, 1));\n              endSeg[i + 1] !== startSeg[i + 1] && (pt = this.add(startSeg, i + 1, startSeg[i + 1], endSeg[i + 1], 0, 0, 0, 0, 0, 1) || pt);\n            }\n          }\n        }\n      } else {\n        pt = this.add(target, "setAttribute", target.getAttribute(p) + "", shape + "", index, targets, 0, _buildPointsFilter(shapeIndex), p);\n      }\n\n      if (useRotation) {\n        this.add(this._origin, "x", this._origin.x, this._eOrigin.x, 0, 0, 0, 0, 0, 1);\n        pt = this.add(this._origin, "y", this._origin.y, this._eOrigin.y, 0, 0, 0, 0, 0, 1);\n      }\n\n      if (pt) {\n        this._props.push("morphSVG");\n\n        pt.end = smooth && smooth.persist !== false ? (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString)(end) : shape;\n        pt.endProp = p;\n      }\n    }\n\n    return 1;\n  },\n  render: function render(ratio, data) {\n    var rawPath = data._rawPath,\n        controlPT = data._controlPT,\n        anchorPT = data._anchorPT,\n        rnd = data._rnd,\n        target = data._target,\n        pt = data._pt,\n        s,\n        space,\n        segment,\n        l,\n        angle,\n        i,\n        j,\n        sin,\n        cos;\n\n    while (pt) {\n      pt.r(ratio, pt.d);\n      pt = pt._next;\n    }\n\n    if (ratio === 1 && data._apply) {\n      pt = data._pt;\n\n      while (pt) {\n        if (pt.end) {\n          if (data._prop) {\n            target[data._prop] = pt.end;\n          } else {\n            target.setAttribute(pt.endProp, pt.end); // make sure the end value is exactly as specified (in case we had to add fabricated points during the tween)\n          }\n        }\n\n        pt = pt._next;\n      }\n    } else if (rawPath) {\n      // rotationally position the anchors\n      while (anchorPT) {\n        angle = anchorPT.sa + ratio * anchorPT.ca;\n        l = anchorPT.sl + ratio * anchorPT.cl; // length\n\n        anchorPT.t[anchorPT.i] = data._origin.x + _cos(angle) * l;\n        anchorPT.t[anchorPT.i + 1] = data._origin.y + _sin(angle) * l;\n        anchorPT = anchorPT._next;\n      }\n\n      while (controlPT) {\n        segment = rawPath[controlPT.j];\n        i = controlPT.i;\n        angle = controlPT.sa + ratio * controlPT.ca;\n        sin = _sin(angle);\n        cos = _cos(angle);\n        l = controlPT.sl + ratio * controlPT.cl;\n        segment[i] = segment[controlPT.ai] - cos * l;\n        segment[i + 1] = segment[controlPT.ai + 1] - sin * l;\n        controlPT = controlPT._next;\n      }\n\n      if (!ratio && _reverting()) {\n        rawPath = (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath)(data._original);\n      }\n\n      target._gsRawPath = rawPath;\n\n      if (data._apply) {\n        s = "";\n        space = " ";\n\n        for (j = 0; j < rawPath.length;
1 j++) {\n          segment = rawPath[j];\n          l = segment.length;\n          s += "M" + (segment[0] * rnd | 0) / rnd + space + (segment[1] * rnd | 0) / rnd + " C";\n\n          for (i = 2; i < l; i++) {\n            // this is actually faster than just doing a join() on the array, possibly because the numbers have so many decimal places\n            s += (segment[i] * rnd | 0) / rnd + space;\n          }\n\n          segment.closed && (s += "z");\n        }\n\n        if (data._prop) {\n          target[data._prop] = s;\n        } else {\n          target.setAttribute("d", s);\n        }\n      }\n    }\n\n    data._render && rawPath && data._render.call(data._tween, rawPath, target);\n  },\n  kill: function kill(property) {\n    this._pt = this._rawPath = 0;\n  },\n  getRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getRawPath,\n  stringToRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath,\n  rawPathToString: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString,\n  smoothRawPath: _smoothRawPath,\n  normalizeStrings: function normalizeStrings(shape1, shape2, _ref) {\n    var shapeIndex = _ref.shapeIndex,\n        map = _ref.map;\n    var result = [shape1, shape2];\n\n    _pathFilter(result, shapeIndex, map);\n\n    return result;\n  },\n  pathFilter: _pathFilter,\n  pointsFilter: _pointsFilter,\n  getTotalSize: _getTotalSize,\n  equalizeSegmentQuantity: _equalizeSegmentQuantity,\n  convertToPath: function convertToPath(targets, swap) {\n    return _toArray(targets).map(function (target) {\n      return (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.convertToPath)(target, swap !== false);\n    });\n  },\n  defaultType: "linear",\n  defaultUpdateTarget: true,\n  defaultMap: "size"\n};\n_getGSAP() && gsap.registerPlugin(MorphSVGPlugin);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/MorphSVGPlugin.js?\n}')},"./node_modules/gsap/MotionPathPlugin.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   MotionPathPlugin: () => (/* binding */ MotionPathPlugin),\n/* harmony export */   "default": () => (/* binding */ MotionPathPlugin)\n/* harmony export */ });\n/* harmony import */ var _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils/paths.js */ "./node_modules/gsap/utils/paths.js");\n/* harmony import */ var _utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./utils/matrix.js */ "./node_modules/gsap/utils/matrix.js");\n/*!\n * MotionPathPlugin 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\n\nvar _xProps = "x,translateX,left,marginLeft,xPercent".split(","),\n    _yProps = "y,translateY,top,marginTop,yPercent".split(","),\n    _DEG2RAD = Math.PI / 180,\n    gsap,\n    PropTween,\n    _getUnit,\n    _toArray,\n    _getStyleSaver,\n    _reverting,\n    _getGSAP = function _getGSAP() {\n  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _populateSegmentFromArray = function _populateSegmentFromArray(segment, values, property, mode) {\n  //mode: 0 = x but don\'t fill y yet, 1 = y, 2 = x and fill y with 0.\n  var l = values.length,\n      si = mode === 2 ? 0 : mode,\n      i = 0,\n      v;\n\n  for (; i < l; i++) {\n    segment[si] = v = parseFloat(values[i][property]);\n    mode === 2 && (segment[si + 1] = 0);\n    si += 2;\n  }\n\n  return segment;\n},\n    _getPropNum = function _getPropNum(target, prop, unit) {\n  return parseFloat(target._gsap.get(target, prop, unit || "px")) || 0;\n},\n    _relativize = function _relativize(segment) {\n  var x = segment[0],\n      y = segment[1],\n      i;\n\n  for (i = 2; i < segment.length; i += 2) {\n    x = segment[i] += x;\n    y = segment[i + 1] += y;\n  }\n},\n    // feed in an array of quadratic bezier points like [{x: 0, y: 0}, ...] and it\'ll convert it to cubic bezier\n// _quadToCubic = points =>
1 {\n// \tlet cubic = [],\n// \t\tl = points.length - 1,\n// \t\ti = 1,\n// \t\ta, b, c;\n// \tfor (; i < l; i+=2) {\n// \t\ta = points[i-1];\n// \t\tb = points[i];\n// \t\tc = points[i+1];\n// \t\tcubic.push(a, {x: (2 * b.x + a.x) / 3, y: (2 * b.y + a.y) / 3}, {x: (2 * b.x + c.x) / 3, y: (2 * b.y + c.y) / 3});\n// \t}\n// \tcubic.push(points[l]);\n// \treturn cubic;\n// },\n_segmentToRawPath = function _segmentToRawPath(plugin, segment, target, x, y, slicer, vars, unitX, unitY) {\n  if (vars.type === "cubic") {\n    segment = [segment];\n  } else {\n    vars.fromCurrent !== false && segment.unshift(_getPropNum(target, x, unitX), y ? _getPropNum(target, y, unitY) : 0);\n    vars.relative && _relativize(segment);\n    var pointFunc = y ? _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.pointsToSegment : _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.flatPointsToSegment;\n    segment = [pointFunc(segment, vars.curviness)];\n  }\n\n  segment = slicer(_align(segment, target, vars));\n\n  _addDimensionalPropTween(plugin, target, x, segment, "x", unitX);\n\n  y && _addDimensionalPropTween(plugin, target, y, segment, "y", unitY);\n  return (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements)(segment, vars.resolution || (vars.curviness === 0 ? 20 : 12)); //when curviness is 0, it creates control points right on top of the anchors which makes it more sensitive to resolution, thus we change the default accordingly.\n},\n    _emptyFunc = function _emptyFunc(v) {\n  return v;\n},\n    _numExp = /[-+\\.]*\\d+\\.?(?:e-|e\\+)?\\d*/g,\n    _originToPoint = function _originToPoint(element, origin, parentMatrix) {\n  // origin is an array of normalized values (0-1) in relation to the width/height, so [0.5, 0.5] would be the center. It can also be "auto" in which case it will be the top left unless it\'s a <path>, when it will start at the beginning of the path itself.\n  var m = (0,_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix)(element),\n      x = 0,\n      y = 0,\n      svg;\n\n  if ((element.tagName + "").toLowerCase() === "svg") {\n    svg = element.viewBox.baseVal;\n    svg.width || (svg = {\n      width: +element.getAttribute("width"),\n      height: +element.getAttribute("height")\n    });\n  } else {\n    svg = origin && element.getBBox && element.getBBox();\n  }\n\n  if (origin && origin !== "auto") {\n    x = origin.push ? origin[0] * (svg ? svg.width : element.offsetWidth || 0) : origin.x;\n    y = origin.push ? origin[1] * (svg ? svg.height : element.offsetHeight || 0) : origin.y;\n  }\n\n  return parentMatrix.apply(x || y ? m.apply({\n    x: x,\n    y: y\n  }) : {\n    x: m.e,\n    y: m.f\n  });\n},\n    _getAlignMatrix = function _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin) {\n  var parentMatrix = (0,_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix)(fromElement.parentNode, true, true),\n      m = parentMatrix.clone().multiply((0,_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix)(toElement)),\n      fromPoint = _originToPoint(fromElement, fromOrigin, parentMatrix),\n      _originToPoint2 = _originToPoint(toElement, toOrigin, parentMatrix),\n      x = _originToPoint2.x,\n      y = _originToPoint2.y,\n      p;\n\n  m.e = m.f = 0;\n\n  if (toOrigin === "auto" && toElement.getTotalLength && toElement.tagName.toLowerCase() === "path") {\n    p = toElement.getAttribute("d").match(_numExp) || [];\n    p = m.apply({\n      x: +p[0],\n      y: +p[1]\n    });\n    x += p.x;\n    y += p.y;\n  } //if (p || (toElement.getBBox && fromElement.getBBox && toElement.ownerSVGElement === fromElement.ownerSVGElement)) {\n\n\n  if (p) {\n    p = m.apply(toElement.getBBox());\n    x -= p.x;\n    y -= p.y;\n  }\n\n  m.e = x - fromPoint.x;\n  m.f = y - fromPoint.y;\n  return m;\n},\n    _align = function _align(rawPath, target, _ref) {\n  var align = _ref.align,\n      matrix = _ref.matrix,\n      offsetX = _ref.offsetX,\n      offsetY = _ref.offsetY,\n      alignOrigin = _ref.alignOrigin;\n\n  var x = rawPath[0][0],\n      y = rawPath[0][1],\n      curX = _getPropNum(target, "x"),\n      curY = _getPropNum(target, "y"),\n      alignTarget,\n      m,\n      p;\n\n  if (!rawPath || !rawPath.length) {\n    return (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getRawPath)("M0,0L0,0");\n  }\n\n  if (align) {\n    if (align === "self" || (alignTarget = _toArray(align)[0] || target) === target) {\n      (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.transformRawPath)(rawPath, 1, 0, 0, 1, curX - x, curY - y);\n    } else {\n      if (alignOrigin && alignOrigin[2] !== false) {\n        gsap.set(target, {\n          transformOrigin: alignOrigin[0] * 100 + "% " + alignOrigin[1] * 100 + "%"\n        });\n      } else {\n        alignOrigin = [_getPropNum(target, "xPercent") / -100, _getPropNum(target, "yPercent") / -100];\n      }\n\n      m = _getAlignMatrix(target, alignTarget, alignOrigin, "auto");\n      p = m.apply({\n        x: x,\n        y: y\n      });\n      (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.transformRawPath)(rawPath, m.a, m.b, m.c, m.d, curX + m.e - (p.x - m.e), curY + m.f - (p.y - m.f));\n    }\n  }\n\n  if (matrix) {\n    (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.transformRawPath)(rawPath, matrix.a, matrix.b, matrix.c, matrix.d, matrix.e, matrix.f);\n  } else if (offsetX || offsetY) {\n    (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.transformRawPath)(rawPath, 1, 0, 0, 1, offsetX || 0, offsetY || 0
1);\n  }\n\n  return rawPath;\n},\n    _addDimensionalPropTween = function _addDimensionalPropTween(plugin, target, property, rawPath, pathProperty, forceUnit) {\n  var cache = target._gsap,\n      harness = cache.harness,\n      alias = harness && harness.aliases && harness.aliases[property],\n      prop = alias && alias.indexOf(",") < 0 ? alias : property,\n      pt = plugin._pt = new PropTween(plugin._pt, target, prop, 0, 0, _emptyFunc, 0, cache.set(target, prop, plugin));\n  pt.u = _getUnit(cache.get(target, prop, forceUnit)) || 0;\n  pt.path = rawPath;\n  pt.pp = pathProperty;\n\n  plugin._props.push(prop);\n},\n    _sliceModifier = function _sliceModifier(start, end) {\n  return function (rawPath) {\n    return start || end !== 1 ? (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.sliceRawPath)(rawPath, start, end) : rawPath;\n  };\n};\n\nvar MotionPathPlugin = {\n  version: "3.15.0",\n  name: "motionPath",\n  register: function register(core, Plugin, propTween) {\n    gsap = core;\n    _getUnit = gsap.utils.getUnit;\n    _toArray = gsap.utils.toArray;\n    _getStyleSaver = gsap.core.getStyleSaver;\n\n    _reverting = gsap.core.reverting || function () {};\n\n    PropTween = propTween;\n  },\n  init: function init(target, vars, tween) {\n    if (!gsap) {\n      console.warn("Please gsap.registerPlugin(MotionPathPlugin)");\n      return false;\n    }\n\n    if (!(typeof vars === "object" && !vars.style) || !vars.path) {\n      vars = {\n        path: vars\n      };\n    }\n\n    var rawPaths = [],\n        _vars = vars,\n        path = _vars.path,\n        autoRotate = _vars.autoRotate,\n        unitX = _vars.unitX,\n        unitY = _vars.unitY,\n        x = _vars.x,\n        y = _vars.y,\n        firstObj = path[0],\n        slicer = _sliceModifier(vars.start, "end" in vars ? vars.end : 1),\n        rawPath,\n        p;\n\n    this.rawPaths = rawPaths;\n    this.target = target;\n    this.tween = tween;\n    this.styles = _getStyleSaver && _getStyleSaver(target, "transform");\n\n    if (this.rotate = autoRotate || autoRotate === 0) {\n      //get the rotational data FIRST so that the setTransform() method is called in the correct order in the render() loop - rotation gets set last.\n      this.rOffset = parseFloat(autoRotate) || 0;\n      this.radians = !!vars.useRadians;\n      this.rProp = vars.rotation || "rotation"; // rotation property\n\n      this.rSet = target._gsap.set(target, this.rProp, this); // rotation setter\n\n      this.ru = _getUnit(target._gsap.get(target, this.rProp)) || 0; // rotation units\n    }\n\n    if (Array.isArray(path) && !("closed" in path) && typeof firstObj !== "number") {\n      for (p in firstObj) {\n        if (!x && ~_xProps.indexOf(p)) {\n          x = p;\n        } else if (!y && ~_yProps.indexOf(p)) {\n          y = p;\n        }\n      }\n\n      if (x && y) {\n        //correlated values\n        rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray(_populateSegmentFromArray([], path, x, 0), path, y, 1), target, x, y, slicer, vars, unitX || _getUnit(path[0][x]), unitY || _getUnit(path[0][y])));\n      } else {\n        x = y = 0;\n      }\n\n      for (p in firstObj) {\n        p !== x && p !== y && rawPaths.push(_segmentToRawPath(this, _populateSegmentFromArray([], path, p, 2), target, p, 0, slicer, vars, _getUnit(path[0][p])));\n      }\n    } else {\n      rawPath = slicer(_align((0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getRawPath)(vars.path), target, vars));\n      (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements)(rawPath, vars.resolution);\n      rawPaths.push(rawPath);\n\n      _addDimensionalPropTween(this, target, vars.x || "x", rawPath, "x", vars.unitX || "px");\n\n      _addDimensionalPropTween(this, target, vars.y || "y", rawPath, "y", vars.unitY || "px");\n    }\n\n    tween.vars.immediateRender && this.render(tween.progress(), this);\n  },\n  render: function render(ratio, data) {\n    var rawPaths = data.rawPaths,\n        i = rawPaths.length,\n        pt = data._pt;\n\n    if (data.tween._time || !_reverting()) {\n      if (ratio > 1) {\n        ratio = 1;\n      } else if (ratio < 0) {\n        ratio = 0;\n      }\n\n      while (i--) {\n        (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getPositionOnPath)(rawPaths[i], ratio, !i && data.rotate, rawPaths[i]);\n      }\n\n      while (pt) {\n        pt.set(pt.t, pt.p, pt.path[pt.pp] + pt.u, pt.d, ratio);\n        pt = pt._next;\n      }\n\n      data.rotate && data.rSet(data.target, data.rProp, rawPaths[0].angle * (data.radians ? _DEG2RAD : 1) + data.rOffset + data.ru, data, ratio);\n    } else {\n      data.styles.revert();\n    }\n  },\n  getLength: function getLength(path) {\n    return (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements)((0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getRawPath)(path)).totalLength;\n  },\n  sliceRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.sliceRawPath,\n  getRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getRawPath,\n  pointsToSegment: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.pointsToSegment,\n  stringToRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.stringToRawPath,\n  rawPathToString: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.rawPathToString,\n  transformRawPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.transformRawPath,\n  getGlobalMatrix: _utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix,\n  getPositionOnPath: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.getPositionOnPath,\n  cacheRawPathMeasurements: _utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.cacheRawPathMeasurements,\n  convertToPath: function convertToPath(targets, swap) {\n    return _toArray(targets).map(function (target) {\n      return (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.convertToPath)(target, swap !== false);\n    });\n  },\n  convertCoordinates: function convertCoordinates(fromElement, toElement, point) {\n    var m = (0,_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix)(toElement, true, true).multiply((0,_utils_matrix_js__WEBPACK_IMPORTED_MODULE_1__.getGlobalMatrix)(fromElement));\n    return point ? m.apply(point) : m;\n  },\n  getAlignMatrix: _getAlignMatrix,\n  getRelativePosition: function getRelativePosition(fromElement, toElement, fromOrigin, toOrigin) {\n    var m = _getAlignMatrix(fromElement, toElement, fromOrigin, toOrigin);\n\n    return {\n      x: m.e,\n      y: m.f\n    };\n  },\n  arrayToRawPath: function arrayToRawPath(value, vars) {\n    vars = vars || {};\n\n    var segment = _populateSegmentFromArray(_populateSegmentFromArray([], value, vars.x || "x", 0), value, vars.y || "y", 1);\n\n    vars.relative && _relativize(segment);\n    return [vars.type === "cubic" ? segment : (0,_utils_paths_js__WEBPACK_IMPORTED_MODULE_0__.pointsToSegment)(segment, vars.curviness)];\n  }\n};\n_getGSAP() && gsap.registerPlugin(MotionPathPlugin);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/MotionPathPlugin.js?\n}')},"./node_modules/gsap/Observer.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Ob
1server: () => (/* binding */ Observer),\n/* harmony export */   _getProxyProp: () => (/* binding */ _getProxyProp),\n/* harmony export */   _getScrollFunc: () => (/* binding */ _getScrollFunc),\n/* harmony export */   _getTarget: () => (/* binding */ _getTarget),\n/* harmony export */   _getVelocityProp: () => (/* binding */ _getVelocityProp),\n/* harmony export */   _horizontal: () => (/* binding */ _horizontal),\n/* harmony export */   _isViewport: () => (/* binding */ _isViewport),\n/* harmony export */   _proxies: () => (/* binding */ _proxies),\n/* harmony export */   _scrollers: () => (/* binding */ _scrollers),\n/* harmony export */   _vertical: () => (/* binding */ _vertical),\n/* harmony export */   "default": () => (/* binding */ Observer)\n/* harmony export */ });\nfunction _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); } }\n\nfunction _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }\n\n/*!\n * Observer 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar gsap,\n    _coreInitted,\n    _clamp,\n    _win,\n    _doc,\n    _docEl,\n    _body,\n    _isTouch,\n    _pointerType,\n    ScrollTrigger,\n    _root,\n    _normalizer,\n    _eventTypes,\n    _context,\n    _getGSAP = function _getGSAP() {\n  return gsap || typeof window !== "undefined" && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _startup = 1,\n    _observers = [],\n    _scrollers = [],\n    _proxies = [],\n    _getTime = Date.now,\n    _bridge = function _bridge(name, value) {\n  return value;\n},\n    _integrate = function _integrate() {\n  var core = ScrollTrigger.core,\n      data = core.bridge || {},\n      scrollers = core._scrollers,\n      proxies = core._proxies;\n  scrollers.push.apply(scrollers, _scrollers);\n  proxies.push.apply(proxies, _proxies);\n  _scrollers = scrollers;\n  _proxies = proxies;\n\n  _bridge = function _bridge(name, value) {\n    return data[name](value);\n  };\n},\n    _getProxyProp = function _getProxyProp(element, property) {\n  return ~_proxies.indexOf(element) && _proxies[_proxies.indexOf(element) + 1][property];\n},\n    _isViewport = function _isViewport(el) {\n  return !!~_root.indexOf(el);\n},\n    _addListener = function _addListener(element, type, func, passive, capture) {\n  return element.addEventListener(type, func, {\n    passive: passive !== false,\n    capture: !!capture\n  });\n},\n    _removeListener = function _removeListener(element, type, func, capture) {\n  return element.removeEventListener(type, func, !!capture);\n},\n    _scrollLeft = "scrollLeft",\n    _scrollTop = "scrollTop",\n    _onScroll = function _onScroll() {\n  return _normalizer && _normalizer.isPressed || _scrollers.cache++;\n},\n    _scrollCacheFunc = function _scrollCacheFunc(f, doNotCache) {\n  var cachingFunc = function cachingFunc(value) {\n    // 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)\n    if (value || value === 0) {\n      _startup && (_win.history.scrollRestoration = "manual"); // otherwise the new position will get overwritten by the browser onload.\n\n      var isNormalizing = _normalizer && _normalizer.isPressed;\n      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!\n\n      f(value);\n      cachingFunc.cacheID = _scrollers.cache;\n      isNormalizing && _bridge("ss", value);
1 // set scroll (notify ScrollTrigger so it can dispatch a "scrollStart" event if necessary\n    } else if (doNotCache || _scrollers.cache !== cachingFunc.cacheID || _bridge("ref")) {\n      cachingFunc.cacheID = _scrollers.cache;\n      cachingFunc.v = f();\n    }\n\n    return cachingFunc.v + cachingFunc.offset;\n  };\n\n  cachingFunc.offset = 0;\n  return f && cachingFunc;\n},\n    _horizontal = {\n  s: _scrollLeft,\n  p: "left",\n  p2: "Left",\n  os: "right",\n  os2: "Right",\n  d: "width",\n  d2: "Width",\n  a: "x",\n  sc: _scrollCacheFunc(function (value) {\n    return arguments.length ? _win.scrollTo(value, _vertical.sc()) : _win.pageXOffset || _doc[_scrollLeft] || _docEl[_scrollLeft] || _body[_scrollLeft] || 0;\n  })\n},\n    _vertical = {\n  s: _scrollTop,\n  p: "top",\n  p2: "Top",\n  os: "bottom",\n  os2: "Bottom",\n  d: "height",\n  d2: "Height",\n  a: "y",\n  op: _horizontal,\n  sc: _scrollCacheFunc(function (value) {\n    return arguments.length ? _win.scrollTo(_horizontal.sc(), value) : _win.pageYOffset || _doc[_scrollTop] || _docEl[_scrollTop] || _body[_scrollTop] || 0;\n  })\n},\n    _getTarget = function _getTarget(t, self) {\n  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);\n},\n    _isWithin = function _isWithin(element, list) {\n  // check if the element is in the list or is a descendant of an element in the list.\n  var i = list.length;\n\n  while (i--) {\n    if (list[i] === element || list[i].contains(element)) {\n      return true;\n    }\n  }\n\n  return false;\n},\n    _getScrollFunc = function _getScrollFunc(element, _ref) {\n  var s = _ref.s,\n      sc = _ref.sc;\n  // 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.\n  _isViewport(element) && (element = _doc.scrollingElement || _docEl);\n\n  var i = _scrollers.indexOf(element),\n      offset = sc === _vertical.sc ? 1 : 2;\n\n  !~i && (i = _scrollers.push(element) - 1);\n  _scrollers[i + offset] || _addListener(element, "scroll", _onScroll); // clear the cache when a scroll occurs\n\n  var prev = _scrollers[i + offset],\n      func = prev || (_scrollers[i + offset] = _scrollCacheFunc(_getProxyProp(element, s), true) || (_isViewport(element) ? sc : _scrollCacheFunc(function (value) {\n    return arguments.length ? element[s] = value : element[s];\n  })));\n  func.target = element;\n  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.\n\n  return func;\n},\n    _getVelocityProp = function _getVelocityProp(value, minTimeRefresh, useDelta) {\n  var v1 = value,\n      v2 = value,\n      t1 = _getTime(),\n      t2 = t1,\n      min = minTimeRefresh || 50,\n      dropToZeroTime = Math.max(500, min * 3),\n      update = function update(value, force) {\n    var t = _getTime();\n\n    if (force || t - t1 > min) {\n      v2 = v1;\n      v1 = value;\n      t2 = t1;\n      t1 = t;\n    } else if (useDelta) {\n      v1 += value;\n    } else {\n      // 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.\n      v1 = v2 + (value - v2) / (t - t2) * (t1 - t2);\n    }\n  },\n      reset = function reset() {\n    v2 = v1 = useDelta ? 0 : v1;\n    t2 = t1 = 0;\n  },\n      getVelocity = function getVelocity(latestValue) {\n    var tOld = t2,\n        vOld = v2,\n        t = _getTime();\n\n    (latestValue || latestValue === 0) && latestValue !== v1 && update(latestValue);\n    return t1 === t2 || t - t2 > dropToZeroTime ? 0 : (v1 + (useDelta ? vOld : -vOld)) / ((useDelta ? t : t1) - tOld) * 1000;\n  };\n\n  return {\n    update: update,\n    reset: reset,\n    getVelocity: getVelocity\n  };\n},\n    _getEvent = function _getEvent(e, preventDefault) {\n  preventDefault && !e._gsapAllow && e.cancelable !== false && e.preventDefault();\n  return e.changedTouches ? e.changedTouches[0] : e;
1\n},\n    _getAbsoluteMax = function _getAbsoluteMax(a) {\n  var max = Math.max.apply(Math, a),\n      min = Math.min.apply(Math, a);\n  return Math.abs(max) >= Math.abs(min) ? max : min;\n},\n    _setScrollTrigger = function _setScrollTrigger() {\n  ScrollTrigger = gsap.core.globals().ScrollTrigger;\n  ScrollTrigger && ScrollTrigger.core && _integrate();\n},\n    _initCore = function _initCore(core) {\n  gsap = core || _getGSAP();\n\n  if (!_coreInitted && gsap && typeof document !== "undefined" && document.body) {\n    _win = window;\n    _doc = document;\n    _docEl = _doc.documentElement;\n    _body = _doc.body;\n    _root = [_win, _doc, _docEl, _body];\n    _clamp = gsap.utils.clamp;\n\n    _context = gsap.core.context || function () {};\n\n    _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.\n\n    _isTouch = Observer.isTouch = _win.matchMedia && _win.matchMedia("(hover: none), (pointer: coarse)").matches ? 1 : "ontouchstart" in _win || navigator.maxTouchPoints > 0 || navigator.msMaxTouchPoints > 0 ? 2 : 0;\n    _eventTypes = Observer.eventTypes = ("ontouchstart" in _docEl ? "touchstart,touchmove,touchcancel,touchend" : !("onpointerdown" in _docEl) ? "mousedown,mousemove,mouseup,mouseup" : "pointerdown,pointermove,pointercancel,pointerup").split(",");\n    setTimeout(function () {\n      return _startup = 0;\n    }, 500);\n    _coreInitted = 1;\n  }\n\n  ScrollTrigger || _setScrollTrigger(); // Observer might be initted BEFORE ScrollTrigger, so don\'t put this with the initting code. ScrollTrigger will call Observer.register() when it inits.\n\n  return _coreInitted;\n};\n\n_horizontal.op = _vertical;\n_scrollers.cache = 0;\nvar Observer = /*#__PURE__*/function () {\n  function Observer(vars) {\n    this.init(vars);\n  }\n\n  var _proto = Observer.prototype;\n\n  _proto.init = function init(vars) {\n    _coreInitted || _initCore(gsap) || console.warn("Please gsap.registerPlugin(Observer)");\n    ScrollTrigger || _setScrollTrigger();\n    var tolerance = vars.tolerance,\n        dragMinimum = vars.dragMinimum,\n        type = vars.type,\n        target = vars.target,\n        lineHeight = vars.lineHeight,\n        debounce = vars.debounce,\n        preventDefault = vars.preventDefault,\n        onStop = vars.onStop,\n        onStopDelay = vars.onStopDelay,\n        ignore = vars.ignore,\n        wheelSpeed = vars.wheelSpeed,\n        event = vars.event,\n        onDragStart = vars.onDragStart,\n        onDragEnd = vars.onDragEnd,\n        onDrag = vars.onDrag,\n        onPress = vars.onPress,\n        onRelease = vars.onRelease,\n        onRight = vars.onRight,\n        onLeft = vars.onLeft,\n        onUp = vars.onUp,\n        onDown = vars.onDown,\n        onChangeX = vars.onChangeX,\n        onChangeY = vars.onChangeY,\n        onChange = vars.onChange,\n        onToggleX = vars.onToggleX,\n        onToggleY = vars.onToggleY,\n        onHover = vars.onHover,\n        onHoverEnd = vars.onHoverEnd,\n        onMove = vars.onMove,\n        ignoreCheck = vars.ignoreCheck,\n        isNormalizer = vars.isNormalizer,\n        onGestureStart = vars.onGestureStart,\n        onGestureEnd = vars.onGestureEnd,\n        onWheel = vars.onWheel,\n        onEnable = vars.onEnable,\n        onDisable = vars.onDisable,\n        onClick = vars.onClick,\n        scrollSpeed = vars.scrollSpeed,\n        capture = vars.capture,\n        allowClicks = vars.allowClicks,\n        lockAxis = vars.lockAxis,\n        onLockAxis = vars.onLockAxis;\n    this.target = target = _getTarget(target) || _docEl;\n    this.vars = vars;\n    ignore && (ignore = gsap.utils.toArray(ignore));\n    tolerance = tolerance || 1e-9;\n    dragMinimum = dragMinimum || 0;\n    wheelSpeed = wheelSpeed || 1;\n    scrollSpeed = scrollSpeed || 1;\n    type = type || "wheel,touch,pointer";\n    debounce = debounce !== false;\n    lineHeight || (lineHeight = parseFloat(_win.getComputedStyle(_body).lineHeight) || 22); // note: browser may report "normal", so default to 22.\n\n    var id,\n        onStopDelayedCall,\n        dragged,\n        moved,\n        wheeled,\n        locked,\n        axis,\n        self = this,\n        prevDeltaX = 0,\n        prevDeltaY = 0,\n        passive = vars.passive || !preventDefault && vars.passive !== false,\n        scrollFuncX = _getScrollFunc(target, _horizontal),\n        scrollFuncY = _getScrollFunc(target, _vertical),\n        scrollX = scrollFuncX(),\n        scrollY = scrollFuncY(),\n        limitToTouch = ~type.indexOf("touch") && !~type.indexOf("pointer") && _eventTypes[0] === "pointerdown",\n        // for devices that accommodate mouse events and touch events, we need to distinguish.\n    isViewport = _isViewport(target),\n        ownerDoc = target.ownerDocument || _doc,\n        deltaX = [0, 0, 0],\n        // wheel, scroll, pointer/touch\n    deltaY = [0, 0, 0],\n        onClickTime = 0,\n        clickCapture = function clickCapture() {\n      return onClickTime = _getTime();\n    },\n        _ignoreCheck = function _ignoreCheck(e, isPointerOrTouch) {\n      return (self.event = e) && ignore && _isWithin(e.target, ignore) || isPointerOrTouch && limitToTouch && e.pointerType !== "touch" || ignoreCheck && ignoreCheck(e, isPointerOrTouch);\n    },\n        onStopFunc = function onStopFunc() {\n      self._vx.reset();\n\n      self._vy.reset();\n\n      onStopDelayedCall.pause();\n      onStop && onStop(self);\n    }
1,\n        update = function update() {\n      var dx = self.deltaX = _getAbsoluteMax(deltaX),\n          dy = self.deltaY = _getAbsoluteMax(deltaY),\n          changedX = Math.abs(dx) >= tolerance,\n          changedY = Math.abs(dy) >= tolerance;\n\n      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.\n\n      if (changedX) {\n        onRight && self.deltaX > 0 && onRight(self);\n        onLeft && self.deltaX < 0 && onLeft(self);\n        onChangeX && onChangeX(self);\n        onToggleX && self.deltaX < 0 !== prevDeltaX < 0 && onToggleX(self);\n        prevDeltaX = self.deltaX;\n        deltaX[0] = deltaX[1] = deltaX[2] = 0;\n      }\n\n      if (changedY) {\n        onDown && self.deltaY > 0 && onDown(self);\n        onUp && self.deltaY < 0 && onUp(self);\n        onChangeY && onChangeY(self);\n        onToggleY && self.deltaY < 0 !== prevDeltaY < 0 && onToggleY(self);\n        prevDeltaY = self.deltaY;\n        deltaY[0] = deltaY[1] = deltaY[2] = 0;\n      }\n\n      if (moved || dragged) {\n        onMove && onMove(self);\n\n        if (dragged) {\n          onDragStart && dragged === 1 && onDragStart(self);\n          onDrag && onDrag(self);\n          dragged = 0;\n        }\n\n        moved = false;\n      }\n\n      locked && !(locked = false) && onLockAxis && onLockAxis(self);\n\n      if (wheeled) {\n        onWheel(self);\n        wheeled = false;\n      }\n\n      id = 0;\n    },\n        onDelta = function onDelta(x, y, index) {\n      deltaX[index] += x;\n      deltaY[index] += y;\n\n      self._vx.update(x);\n\n      self._vy.update(y);\n\n      debounce ? id || (id = requestAnimationFrame(update)) : update();\n    },\n        onTouchOrPointerDelta = function onTouchOrPointerDelta(x, y) {\n      if (lockAxis && !axis) {\n        self.axis = axis = Math.abs(x) > Math.abs(y) ? "x" : "y";\n        locked = true;\n      }\n\n      if (axis !== "y") {\n        deltaX[2] += x;\n\n        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.\n\n      }\n\n      if (axis !== "x") {\n        deltaY[2] += y;\n\n        self._vy.update(y, true);\n      }\n\n      debounce ? id || (id = requestAnimationFrame(update)) : update();\n    },\n        _onDrag = function _onDrag(e) {\n      if (_ignoreCheck(e, 1)) {\n        return;\n      }\n\n      e = _getEvent(e, preventDefault);\n      var x = e.clientX,\n          y = e.clientY,\n          dx = x - self.x,\n          dy = y - self.y,\n          isDragging = self.isDragging;\n      self.x = x;\n      self.y = y;\n\n      if (isDragging || (dx || dy) && (Math.abs(self.startX - x) >= dragMinimum || Math.abs(self.startY - y) >= dragMinimum)) {\n        dragged || (dragged = isDragging ? 2 : 1); // dragged: 0 = not dragging, 1 = first drag, 2 = normal drag\n\n        isDragging || (self.isDragging = true);\n        onTouchOrPointerDelta(dx, dy);\n      }\n    },\n        _onPress = self.onPress = function (e) {\n      if (_ignoreCheck(e, 1) || e && e.button) {\n        return;\n      }\n\n      self.axis = axis = null;\n      onStopDelayedCall.pause();\n      self.isPressed = true;\n      e = _getEvent(e); // note: may need to preventDefault(?) Won\'t side-scroll on iOS Safari if we do, though.\n\n      prevDeltaX = prevDeltaY = 0;\n      self.startX = self.x = e.clientX;\n      self.startY = self.y = e.clientY;\n\n      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.\n\n\n      self._vy.reset();\n\n      _addListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, passive, true);\n\n      self.deltaX = self.deltaY = 0;\n      onPress && onPress(self);\n    },\n        _onRelease = self.onRelease = function (e) {\n      if (_ignoreCheck(e, 1)) {\n        return;\n      }\n\n      _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n\n      var isTrackingDrag = !isNaN(self.y - self.startY),\n          wasDragging = self.isDragging,\n          isDragNotClick = wasDragging && (Math.abs(self.x - self.startX) > 3 || Math.abs(self.y - self.startY) > 3),\n          // some touch devices need some wiggle room in terms of sensing clicks - the finger may move a few pixels.\n      eventData = _getEvent(e);\n\n      if (!isDragNotClick && isTrackingDrag) {\n        self._vx.reset();\n\n        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.\n\n\n        if (preventDefault && allowClicks) {\n          gsap.delayedCall(0.08, function () {\n            // 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.\n            if (_getTime() - onClickTime > 300 && !e.defaultPrevented) {\n              if (e.target.click) {\
1n                //some browsers (like mobile Safari) don\'t properly trigger the click event\n                e.target.click();\n              } else if (ownerDoc.createEvent) {\n                var syntheticEvent = ownerDoc.createEvent("MouseEvents");\n                syntheticEvent.initMouseEvent("click", true, true, _win, 1, eventData.screenX, eventData.screenY, eventData.clientX, eventData.clientY, false, false, false, false, 0, null);\n                e.target.dispatchEvent(syntheticEvent);\n              }\n            }\n          });\n        }\n      }\n\n      self.isDragging = self.isGesturing = self.isPressed = false;\n      onStop && wasDragging && !isNormalizer && onStopDelayedCall.restart(true);\n      dragged && update(); // in case debouncing, we don\'t want onDrag to fire AFTER onDragEnd().\n\n      onDragEnd && wasDragging && onDragEnd(self);\n      onRelease && onRelease(self, isDragNotClick);\n    },\n        _onGestureStart = function _onGestureStart(e) {\n      return e.touches && e.touches.length > 1 && (self.isGesturing = true) && onGestureStart(e, self.isDragging);\n    },\n        _onGestureEnd = function _onGestureEnd() {\n      return (self.isGesturing = false) || onGestureEnd(self);\n    },\n        onScroll = function onScroll(e) {\n      if (_ignoreCheck(e)) {\n        return;\n      }\n\n      var x = scrollFuncX(),\n          y = scrollFuncY();\n      onDelta((x - scrollX) * scrollSpeed, (y - scrollY) * scrollSpeed, 1);\n      scrollX = x;\n      scrollY = y;\n      onStop && onStopDelayedCall.restart(true);\n    },\n        _onWheel = function _onWheel(e) {\n      if (_ignoreCheck(e)) {\n        return;\n      }\n\n      e = _getEvent(e, preventDefault);\n      onWheel && (wheeled = true);\n      var multiplier = (e.deltaMode === 1 ? lineHeight : e.deltaMode === 2 ? _win.innerHeight : 1) * wheelSpeed;\n      onDelta(e.deltaX * multiplier, e.deltaY * multiplier, 0);\n      onStop && !isNormalizer && onStopDelayedCall.restart(true);\n    },\n        _onMove = function _onMove(e) {\n      if (_ignoreCheck(e)) {\n        return;\n      }\n\n      var x = e.clientX,\n          y = e.clientY,\n          dx = x - self.x,\n          dy = y - self.y;\n      self.x = x;\n      self.y = y;\n      moved = true;\n      onStop && onStopDelayedCall.restart(true);\n      (dx || dy) && onTouchOrPointerDelta(dx, dy);\n    },\n        _onHover = function _onHover(e) {\n      self.event = e;\n      onHover(self);\n    },\n        _onHoverEnd = function _onHoverEnd(e) {\n      self.event = e;\n      onHoverEnd(self);\n    },\n        _onClick = function _onClick(e) {\n      return _ignoreCheck(e) || _getEvent(e, preventDefault) && onClick(self);\n    };\n\n    onStopDelayedCall = self._dc = gsap.delayedCall(onStopDelay || 0.25, onStopFunc).pause();\n    self.deltaX = self.deltaY = 0;\n    self._vx = _getVelocityProp(0, 50, true);\n    self._vy = _getVelocityProp(0, 50, true);\n    self.scrollX = scrollFuncX;\n    self.scrollY = scrollFuncY;\n    self.isDragging = self.isGesturing = self.isPressed = false;\n\n    _context(this);\n\n    self.enable = function (e) {\n      if (!self.isEnabled) {\n        _addListener(isViewport ? ownerDoc : target, "scroll", _onScroll);\n\n        type.indexOf("scroll") >= 0 && _addListener(isViewport ? ownerDoc : target, "scroll", onScroll, passive, capture);\n        type.indexOf("wheel") >= 0 && _addListener(target, "wheel", _onWheel, passive, capture);\n\n        if (type.indexOf("touch") >= 0 && _isTouch || type.indexOf("pointer") >= 0) {\n          _addListener(target, _eventTypes[0], _onPress, passive, capture);\n\n          _addListener(ownerDoc, _eventTypes[2], _onRelease);\n\n          _addListener(ownerDoc, _eventTypes[3], _onRelease);\n\n          allowClicks && _addListener(target, "click", clickCapture, true, true);\n          onClick && _addListener(target, "click", _onClick);\n          onGestureStart && _addListener(ownerDoc, "gesturestart", _onGestureStart);\n          onGestureEnd && _addListener(ownerDoc, "gestureend", _onGestureEnd);\n          onHover && _addListener(target, _pointerType + "enter", _onHover);\n          onHoverEnd && _addListener(target, _pointerType + "leave", _onHoverEnd);\n          onMove && _addListener(target, _pointerType + "move", _onMove);\n        }\n\n        self.isEnabled = true;\n        self.isDragging = self.isGesturing = self.isPressed = moved = dragged = false;\n\n        self._vx.reset();\n\n        self._vy.reset();\n\n        scrollX = scrollFuncX();\n        scrollY = scrollFuncY();\n        e && e.type && _onPress(e);\n        onEnable && onEnable(self);\n      }\n\n      return self;\n    };\n\n    self.disable = function () {\n      if (self.isEnabled) {\n        // only remove the _onScroll listener if there aren\'t any others that rely on the functionality.\n        _observers.filter(function (o) {\n          return o !== self && _isViewport(o.target);\n        }).length || _removeListener(isViewport ? ownerDoc : target, "scroll", _onScroll);\n\n        if (self.isPressed) {\n          self._vx.reset();\n\n          self._vy.reset();\n\n          _removeListener(isNormalizer ? target : ownerDoc, _eventTypes[1], _onDrag, true);\n        }\n\n        _removeListener(isViewport ? ownerDoc : target, "scroll", onScroll, capture);\n\n        _removeListener(target, "wheel", _onWheel, capture);\n\n        _removeListener(target, _eventTypes[0], _onPress, capture);\n\n        _removeListener(ownerDoc, _eventTypes[2], _onRelease);\n\n        _removeListener(ownerDoc, _eventTypes[3], _onRelease);\n\n        _removeListener(target, "click", clickCapture, true);\n\n        _removeListener(target, "click", _onClick);\n\n        _removeListener(ownerDoc, "gesturestart", _onGestureStart);\n\n        _removeListener(ownerDoc, "gestureend", _onGestureEnd);\n\n        _removeListener(target, _pointerType + "enter", _onHover);\n\n        _removeListener(target, _pointerType + "leave", _onHoverEnd);\n\n        _removeListener(target, _pointerType + "move", _onMove);\n\n        self.isEnabled = self.isPressed = self.isDragging = false;\n        onDisable && onDisable(self);\n      }\n    };\n\n    self.kill = self.revert = function () {\n      self.disable();\n\n      var i = _observers.indexOf(self);\n\n      i >= 0 && _observers.splice(i, 1);\n      _normalizer === self && (_normalizer = 0);\n    };\n\n    _observers.push(self);\n\n    isNormalizer && _isViewport(target) && (_normalizer = self);\n    self.enable(event);\n  };\n\n  _createClass(Observer, [{\n    key: "velocityX",\n    get: function get() {\n      return this._vx.getVelocity();\n    }\n  }, {\n    key: "velocityY",\n    get: function get() {\n      return this._vy.getVelocity();\n    }\n  }]);\n\n  return Observer;\n}();\nObserver.version = "3.15.0";\n\nObserver.create = function (vars) {\n  return new Observer(vars);\n};\n\nObserver.register = _initCore;\n\nObserver.getAll = function () {\n  return _observers.slice();\n};\n\nObserver.getById = function (id) {\n  return _observers.filter(function (o) {\n    return o.vars.id === id;\n  })[0];\n};\n\n_getGSAP() && gsap.registerPlugin(Observer);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/Observer.js?\n}')},"./node_modules/gsap/ScrollToPlugin.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   ScrollToPlugin: () => (/* binding */ ScrollToPlugin),\n/* harmony export */   "default": () => (/* binding */ ScrollToPlugin)\n/* harmony export */ });\n/*!\n * ScrollToPlugin 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar gsap,\n    _coreInitted,\n    _window,\n    _docEl,\n    _body,\n    _toArray,\n    _config,\n    ScrollTrigger,\n    _windowExists = function _windowExists() {\n  return typeof window !== "undefined";\n},\n    _getGSAP = function _getGSAP() {\n  return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _isString = function _isString(value) {\n  return typeof value === "string";\n},\n    _isFunction = function _isFunction(value) {\n  return typeof value === "function";\n},\n    _max = function _max(element, axis) {\n  var dim = axis === "x" ? "Width" : "Height",\n      scroll = "scroll" + dim,\n      client = "client" + dim;\n  return element === _window || element === _docEl || element === _body ? Math.max(_docEl[scroll], _body[scroll]) - (_window["inner" + dim] || _docEl[client] || _body[client]) : element[scroll] - element["offset" + dim];\n},\n    _buildGetter = function _buildGetter(e, axis) {\n  //pass in an element and an axis ("x" or "y") and it\'ll return a getter function for the scroll position of that element (like scrollTop or scrollLeft, although if the element is the window, it\'ll use the pageXOffset/pageYOffset or the documentElement\'s scrollTop/scrollLeft or document.body\'s. Basically this streamlines things and makes a very fast getter across browsers.\n  var p = "scroll" + (axis === "x" ? "Left" : "Top");
1\n\n  if (e === _window) {\n    if (e.pageXOffset != null) {\n      p = "page" + axis.toUpperCase() + "Offset";\n    } else {\n      e = _docEl[p] != null ? _docEl : _body;\n    }\n  }\n\n  return function () {\n    return e[p];\n  };\n},\n    _clean = function _clean(value, index, target, targets) {\n  _isFunction(value) && (value = value(index, target, targets));\n\n  if (typeof value !== "object") {\n    return _isString(value) && value !== "max" && value.charAt(1) !== "=" ? {\n      x: value,\n      y: value\n    } : {\n      y: value\n    }; //if we don\'t receive an object as the parameter, assume the user intends "y".\n  } else if (value.nodeType) {\n    return {\n      y: value,\n      x: value\n    };\n  } else {\n    var result = {},\n        p;\n\n    for (p in value) {\n      result[p] = p !== "onAutoKill" && _isFunction(value[p]) ? value[p](index, target, targets) : value[p];\n    }\n\n    return result;\n  }\n},\n    _getOffset = function _getOffset(element, container) {\n  element = _toArray(element)[0];\n\n  if (!element || !element.getBoundingClientRect) {\n    return console.warn("scrollTo target doesn\'t exist. Using 0") || {\n      x: 0,\n      y: 0\n    };\n  }\n\n  var rect = element.getBoundingClientRect(),\n      isRoot = !container || container === _window || container === _body,\n      cRect = isRoot ? {\n    top: _docEl.clientTop - (_window.pageYOffset || _docEl.scrollTop || _body.scrollTop || 0),\n    left: _docEl.clientLeft - (_window.pageXOffset || _docEl.scrollLeft || _body.scrollLeft || 0)\n  } : container.getBoundingClientRect(),\n      offsets = {\n    x: rect.left - cRect.left,\n    y: rect.top - cRect.top\n  };\n\n  if (!isRoot && container) {\n    //only add the current scroll position if it\'s not the window/body.\n    offsets.x += _buildGetter(container, "x")();\n    offsets.y += _buildGetter(container, "y")();\n  }\n\n  return offsets;\n},\n    _parseVal = function _parseVal(value, target, axis, currentVal, offset) {\n  return !isNaN(value) && typeof value !== "object" ? parseFloat(value) - offset : _isString(value) && value.charAt(1) === "=" ? parseFloat(value.substr(2)) * (value.charAt(0) === "-" ? -1 : 1) + currentVal - offset : value === "max" ? _max(target, axis) - offset : Math.min(_max(target, axis), _getOffset(value, target)[axis] - offset);\n},\n    _initCore = function _initCore() {\n  gsap = _getGSAP();\n\n  if (_windowExists() && gsap && typeof document !== "undefined" && document.body) {\n    _window = window;\n    _body = document.body;\n    _docEl = document.documentElement;\n    _toArray = gsap.utils.toArray;\n    gsap.config({\n      autoKillThreshold: 7\n    });\n    _config = gsap.config();\n    _coreInitted = 1;\n  }\n};\n\nvar ScrollToPlugin = {\n  version: "3.15.0",\n  name: "scrollTo",\n  rawVars: 1,\n  register: function register(core) {\n    gsap = core;\n\n    _initCore();\n  },\n  init: function init(target, value, tween, index, targets) {\n    _coreInitted || _initCore();\n    var data = this,\n        snapType = gsap.getProperty(target, "scrollSnapType");\n    data.isWin = target === _window;\n    data.target = target;\n    data.tween = tween;\n    value = _clean(value, index, target, targets);\n    data.vars = value;\n    data.autoKill = !!("autoKill" in value ? value : _config).autoKill;\n    data.getX = _buildGetter(target, "x");\n    data.getY = _buildGetter(target, "y");\n    data.x = data.xPrev = data.getX();\n    data.y = data.yPrev = data.getY();\n    ScrollTrigger || (ScrollTrigger = gsap.core.globals().ScrollTrigger);\n    gsap.getProperty(target, "scrollBehavior") === "smooth" && gsap.set(target, {\n      scrollBehavior: "auto"\n    });\n\n    if (snapType && snapType !== "none") {\n      // disable scroll snapping to avoid strange behavior\n      data.snap = 1;\n      data.snapInline = target.style.scrollSnapType;\n      target.style.scrollSnapType = "none";\n    }\n\n    if (value.x != null) {\n      data.add(data, "x", data.x, _parseVal(value.x, target, "x", data.x, value.offsetX || 0), index, targets);\n\n      data._props.push("scrollTo_x");\n    } else {\n      data.skipX = 1;\n    }\n\n    if (value.y != null) {\n      data.add(data, "y", data.y, _parseVal(value.y, target, "y", data.y, value.offsetY || 0
1), index, targets);\n\n      data._props.push("scrollTo_y");\n    } else {\n      data.skipY = 1;\n    }\n  },\n  render: function render(ratio, data) {\n    var pt = data._pt,\n        target = data.target,\n        tween = data.tween,\n        autoKill = data.autoKill,\n        xPrev = data.xPrev,\n        yPrev = data.yPrev,\n        isWin = data.isWin,\n        snap = data.snap,\n        snapInline = data.snapInline,\n        x,\n        y,\n        yDif,\n        xDif,\n        threshold;\n\n    while (pt) {\n      pt.r(ratio, pt.d);\n      pt = pt._next;\n    }\n\n    x = isWin || !data.skipX ? data.getX() : xPrev;\n    y = isWin || !data.skipY ? data.getY() : yPrev;\n    yDif = y - yPrev;\n    xDif = x - xPrev;\n    threshold = _config.autoKillThreshold;\n\n    if (data.x < 0) {\n      //can\'t scroll to a position less than 0! Might happen if someone uses a Back.easeOut or Elastic.easeOut when scrolling back to the top of the page (for example)\n      data.x = 0;\n    }\n\n    if (data.y < 0) {\n      data.y = 0;\n    }\n\n    if (autoKill) {\n      //note: iOS has a bug that throws off the scroll by several pixels, so we need to check if it\'s within 7 pixels of the previous one that we set instead of just looking for an exact match.\n      if (!data.skipX && (xDif > threshold || xDif < -threshold) && x < _max(target, "x")) {\n        data.skipX = 1; //if the user scrolls separately, we should stop tweening!\n      }\n\n      if (!data.skipY && (yDif > threshold || yDif < -threshold) && y < _max(target, "y")) {\n        data.skipY = 1; //if the user scrolls separately, we should stop tweening!\n      }\n\n      if (data.skipX && data.skipY) {\n        tween.kill();\n        data.vars.onAutoKill && data.vars.onAutoKill.apply(tween, data.vars.onAutoKillParams || []);\n      }\n    }\n\n    if (isWin) {\n      _window.scrollTo(!data.skipX ? data.x : x, !data.skipY ? data.y : y);\n    } else {\n      data.skipY || (target.scrollTop = data.y);\n      data.skipX || (target.scrollLeft = data.x);\n    }\n\n    if (snap && (ratio === 1 || ratio === 0)) {\n      y = target.scrollTop;\n      x = target.scrollLeft;\n      snapInline ? target.style.scrollSnapType = snapInline : target.style.removeProperty("scroll-snap-type");\n      target.scrollTop = y + 1; // bug in Safari causes the element to totally reset its scroll position when scroll-snap-type changes, so we need to set it to a slightly different value and then back again to work around this bug.\n\n      target.scrollLeft = x + 1;\n      target.scrollTop = y;\n      target.scrollLeft = x;\n    }\n\n    data.xPrev = data.x;\n    data.yPrev = data.y;
1\n    ScrollTrigger && ScrollTrigger.update();\n  },\n  kill: function kill(property) {\n    var both = property === "scrollTo",\n        i = this._props.indexOf(property);\n\n    if (both || property === "scrollTo_x") {\n      this.skipX = 1;\n    }\n\n    if (both || property === "scrollTo_y") {\n      this.skipY = 1;\n    }\n\n    i > -1 && this._props.splice(i, 1);\n    return !this._props.length;\n  }\n};\nScrollToPlugin.max = _max;\nScrollToPlugin.getOffset = _getOffset;\nScrollToPlugin.buildGetter = _buildGetter;\n\nScrollToPlugin.config = function (vars) {\n  _config || _initCore() || (_config = gsap.config()); // in case the window hasn\'t been defined yet.\n\n  for (var p in vars) {\n    _config[p] = vars[p];\n  }\n};\n\n_getGSAP() && gsap.registerPlugin(ScrollToPlugin);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/ScrollToPlugin.js?\n}')},"./node_modules/gsap/ScrollTrigger.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   ScrollTrigger: () => (/* binding */ ScrollTrigger),\n/* harmony export */   "default": () => (/* binding */ ScrollTrigger)\n/* harmony export */ });\n/* harmony import */ var _Observer_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./Observer.js */ "./node_modules/gsap/Observer.js");\n/*!\n * ScrollTrigger 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\n\n\nvar gsap,\n    _coreInitted,\n    _win,\n    _doc,\n    _docEl,\n    _body,\n    _root,\n    _resizeDelay,\n    _toArray,\n    _clamp,\n    _time2,\n    _syncInterval,\n    _refreshing,\n    _pointerIsDown,\n    _transformProp,\n    _i,\n    _prevWidth,\n    _prevHeight,\n    _autoRefresh,\n    _sort,\n    _suppressOverwrites,\n    _ignoreResize,\n    _normalizer,\n    _ignoreMobileResize,\n    _baseScreenHeight,\n    _baseScreenWidth,\n    _fixIOSBug,\n    _context,\n    _scrollRestoration,\n    _div100vh,\n    _100vh,\n    _isReverted,\n    _clampingMax,\n    _limitCallbacks,\n    // 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.\n_startup = 1,\n    _getTime = Date.now,\n    _time1 = _getTime(),\n    _lastScrollTime = 0,\n    _enabled = 0,\n    _parseClamp = function _parseClamp(value, type, self) {\n  var clamp = _isString(value) && (value.substr(0, 6) === "clamp(" || value.indexOf("max") > -1);\n  self["_" + type + "Clamp"] = clamp;\n  return clamp ? value.substr(6, value.length - 7) : value;\n},\n    _keepClamp = function _keepClamp(value, clamp) {\n  return clamp && (!_isString(value) || value.substr(0, 6) !== "clamp(") ? "clamp(" + value + ")" : value;\n},\n    _rafBugFix = function _rafBugFix() {\n  return _enabled && requestAnimationFrame(_rafBugFix);\n},\n    // 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.\n_pointerDownHandler = function _pointerDownHandler() {\n  return _pointerIsDown = 1;\n},\n    _pointerUpHandler = function _pointerUpHandler() {\n  return _pointerIsDown = 0;\n},\n    _passThrough = function _passThrough(v) {\n  return v;\n},\n    _round = function _round(value) {\n  return Math.round(value * 100000) / 100000 || 0;\n},\n    _windowExists = function _windowExists() {\n  return typeof window !== "undefined";\n},\n    _getGSAP = function _getGSAP() {\n  return gsap || _windowExists() && (gsap = window.gsap) && gsap.registerPlugin && gsap;\n},\n    _isViewport = function _isViewport(e) {\n  return !!~_root.indexOf(e);\n},\n    _getViewportDimension = function _getViewportDimension(dimensionProperty) {\n  return (dimensionProperty === "Height" ? _100vh : _win["inner" + dimensionProperty]) || _docEl["client" + dimensionProperty] || _body["client" + dimensionProperty];\n},\n    _getBoundsFunc = function _getBoundsFunc(element) {\n  return (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(element, "getBoundingClientRect") || (_isViewport(element) ? function () {\n    _winOffsets.width = _win.innerWidth;\n    _winOffsets.height = _100vh;\n    return _winOffsets;\n  } : function () {\n    return _getBounds(element);\n  });\n},\n    _getSizeFunc = function _getSizeFunc(scroller, isViewport, _ref) {\n  var d = _ref.d,\n      d2 = _ref.d2,\n      a = _ref.a;\n  return (a = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "getBoundingClientRect")) ? function () {\n    return a()[d];\n  } : function () {\n    return (isViewport ? _getViewportDimension(d2) : scroller["client" + d2]) || 0;\n  };\n},\n    _getOffsetsFunc = function _getOffsetsFunc(element, isViewport) {\n  return !isViewport || ~_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.indexOf(element) ? _getBoundsFunc(element) : function () {\n    return _winOffsets;\n  };\n},\n    _maxScroll = function _maxScroll(element, _ref2) {\n  var s = _ref2.s,\n      d2 = _ref2.d2,\n      d = _ref2.d,\n      a = _ref2.a;\n  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]);\n},\n    _iterateAutoRefresh = function _iterateAutoRefresh(func, events) {\n  for (var i = 0; i < _autoRefresh.length; i += 3) {\n    (!events || ~events.indexOf(_autoRefresh[i + 1])
1) && func(_autoRefresh[i], _autoRefresh[i + 1], _autoRefresh[i + 2]);\n  }\n},\n    _isString = function _isString(value) {\n  return typeof value === "string";\n},\n    _isFunction = function _isFunction(value) {\n  return typeof value === "function";\n},\n    _isNumber = function _isNumber(value) {\n  return typeof value === "number";\n},\n    _isObject = function _isObject(value) {\n  return typeof value === "object";\n},\n    _endAnimation = function _endAnimation(animation, reversed, pause) {\n  return animation && animation.progress(reversed ? 0 : 1) && pause && animation.pause();\n},\n    _callback = function _callback(self, func, extraParam) {\n  if (self.enabled) {\n    var result = self._ctx ? self._ctx.add(function () {\n      return func(self, extraParam);\n    }) : func(self, extraParam);\n    result && result.totalTime && (self.callbackAnimation = result);\n  }\n},\n    _abs = Math.abs,\n    _left = "left",\n    _top = "top",\n    _right = "right",\n    _bottom = "bottom",\n    _width = "width",\n    _height = "height",\n    _Right = "Right",\n    _Left = "Left",\n    _Top = "Top",\n    _Bottom = "Bottom",\n    _padding = "padding",\n    _margin = "margin",\n    _Width = "Width",\n    _Height = "Height",\n    _px = "px",\n    _getComputedStyle = function _getComputedStyle(element) {\n  return _win.getComputedStyle(element.nodeType === Node.DOCUMENT_NODE ? element.scrollingElement : element);\n},\n    _makePositionable = function _makePositionable(element) {\n  // if the element already has position: absolute or fixed, leave that, otherwise make it position: relative\n  var position = _getComputedStyle(element).position;\n\n  element.style.position = position === "absolute" || position === "fixed" ? position : "relative";\n},\n    _setDefaults = function _setDefaults(obj, defaults) {\n  for (var p in defaults) {\n    p in obj || (obj[p] = defaults[p]);\n  }\n\n  return obj;\n},\n    _getBounds = function _getBounds(element, withoutTransforms) {\n  var tween = withoutTransforms && _getComputedStyle(element)[_transformProp] !== "matrix(1, 0, 0, 1, 0, 0)" && gsap.to(element, {\n    x: 0,\n    y: 0,\n    xPercent: 0,\n    yPercent: 0,\n    rotation: 0,\n    rotationX: 0,\n    rotationY: 0,\n    scale: 1,\n    skewX: 0,\n    skewY: 0\n  }).progress(1),\n      bounds = element.getBoundingClientRect ? element.getBoundingClientRect() : element.scrollingElement.getBoundingClientRect();\n  tween && tween.progress(0).kill();\n  return bounds;\n},\n    _getSize = function _getSize(element, _ref3) {\n  var d2 = _ref3.d2;\n  return element["offset" + d2] || element["client" + d2] || 0;\n},\n    _getLabelRatioArray = function _getLabelRatioArray(timeline) {\n  var a = [],\n      labels = timeline.labels,\n      duration = timeline.duration(),\n      p;\n\n  for (p in labels) {\n    a.push(labels[p] / duration);\n  }\n\n  return a;\n},\n    _getClosestLabel = function _getClosestLabel(animation) {\n  return function (value) {\n    return gsap.utils.snap(_getLabelRatioArray(animation), value);\n  };\n},\n    _snapDirectional = function _snapDirectional(snapIncrementOrArray) {\n  var snap = gsap.utils.snap(snapIncrementOrArray),\n      a = Array.isArray(snapIncrementOrArray) && snapIncrementOrArray.slice(0).sort(function (a, b) {\n    return a - b;\n  });\n  return a ? function (value, direction, threshold) {\n    if (threshold === void 0) {\n      threshold = 1e-3;\n    }\n\n    var i;\n\n    if (!direction) {\n      return snap(value);\n    }\n\n    if (direction > 0) {\n      value -= threshold; // to avoid rounding errors. If we\'re too strict, it might snap forward, then immediately again, and again.\n\n      for (i = 0; i < a.length; i++) {\n        if (a[i] >= value) {\n          return a[i];\n        }\n      }\n\n      return a[i - 1];\n    } else {\n      i = a.length;\n      value += threshold;\n\n      while (i--) {\n        if (a[i] <= value) {\n          return a[i];\n        }\n      }\n    }\n\n    return a[0];\n  } : function (value, direction, threshold) {\n    if (threshold === void 0) {\n      threshold = 1e-3;\n    }\n\n    var snapped = snap(value);\n    return !direction || Math.abs(snapped - value) < threshold || snapped - value < 0 === direction < 0 ? snapped : snap(direction < 0 ? value - snapIncrementOrArray : value + snapIncrementOrArray);\n  };\n},\n    _getLabelAtDirection = function _getLabelAtDirection(timeline) {\n  return function (value, st) {\n    return _snapDirectional(_getLabelRatioArray(timeline))(value, st.direction);\n  };\n},\n    _multiListener = function _multiListener(func, element, types, callback) {\n  return types.split(",").forEach(function (type) {\n    return func(element, type, callback);\n  });\n},\n    _addListener = function _addListener(element, type, func, nonPassive, capture) {\n  return element.addEventListener(type, func, {\n    passive: !nonPassive,\n    capture: !!capture\n  });\n},\n    _removeListener = function _removeListener(element, type, func, capture) {\n  return element.removeEventListener(type, func, !!capture);\n},\n    _wheelListener = function _wheelListener(func, el, scrollFunc) {\n  scrollFunc = scrollFunc && scrollFunc.wheelHandler;\n\n  if (scrollFunc) {\n    func(el, "wheel", scrollFunc);\n    func(el, "touchmove", scrollFunc);\n  }\n},\n    _markerDefaults = {\n  startColor: "green",\n  endColor: "red",\n  indent: 0,\n  fontSize: "16px",\n  fontWeight: "normal"\n},\n    _defaults = {\n  toggleActions: "play",\n  anticipatePin: 0\n},\n    _keywords = {\n  top: 0,\n  left: 0,\n  center: 0.5,\n  bottom: 1,\n  right: 1\n},\n    _offsetToPx = function _offsetToPx(value, size) {\n  if (_isString(value)) {\n    var eqIndex = value.indexOf("="),\n        relative = ~eqIndex ? +(value.charAt(eqIndex - 1) + 1) * parseFloat(value.substr(eqIndex + 1)) : 0;\n\n    if (~eqIndex) {\n      value.indexOf("%") > eqIndex && (relative *= size / 100);\n      value = value.substr(0, eqIndex - 1);\n    }\n\n    value = relative + (value in _keywords ? _keywords[value] * size : ~value.indexOf("%") ? parseFloat(value) * size / 100 : parseFloat(value) || 0);\n  }\n\n  return value;\n},\n    _createMarker = function _createMarker(type, name, container, direction, _ref4, offset, matchWidthEl, containerAnimation) {\n  var startColor = _ref4.startColor,\n      endColor = _ref4.endColor,\n      fontSize = _ref4.fontSize,\n      indent = _ref4.indent,\n      fontWeight = _ref4.fontWeight;\n\n  var e = _doc.createElement("div"),\n      useFixedPosition = _isViewport(container) || (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(container, "pinType") === "fixed",\n      isScroller = type.indexOf("scroller") !== -1,\n      parent = useFixedPosition ? _body : container.tagName === "IFRAME" ? container.contentDocument.body : container,\n      isStart = type.indexOf("start") !== -1,\n      color = isStart ? startColor : endColor,\n      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;";\n\n  css += "position:" + ((isScroller || containerAnimation) && useFixedPosition ? "fixed;" : "absolute;");\n  (isScroller || containerAnimation || !useFixedPosition) && (css += (direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical ? _right : _bottom) + ":" + (offset + parseFloat(indent)) + "px;");\n  matchWidthEl && (css += "box-sizing:border-box;text-align:left;
1width:" + matchWidthEl.offsetWidth + "px;");\n  e._isStart = isStart;\n  e.setAttribute("class", "gsap-marker-" + type + (name ? " marker-" + name : ""));\n  e.style.cssText = css;\n  e.innerText = name || name === 0 ? type + "-" + name : type;\n  parent.children[0] ? parent.insertBefore(e, parent.children[0]) : parent.appendChild(e);\n  e._offset = e["offset" + direction.op.d2];\n\n  _positionMarker(e, 0, direction, isStart);\n\n  return e;\n},\n    _positionMarker = function _positionMarker(marker, start, direction, flipped) {\n  var vars = {\n    display: "block"\n  },\n      side = direction[flipped ? "os2" : "p2"],\n      oppositeSide = direction[flipped ? "p2" : "os2"];\n  marker._isFlipped = flipped;\n  vars[direction.a + "Percent"] = flipped ? -100 : 0;\n  vars[direction.a] = flipped ? "1px" : 0;\n  vars["border" + side + _Width] = 1;\n  vars["border" + oppositeSide + _Width] = 0;\n  vars[direction.p] = start + "px";\n  gsap.set(marker, vars);\n},\n    _triggers = [],\n    _ids = {},\n    _rafID,\n    _sync = function _sync() {\n  return _getTime() - _lastScrollTime > 34 && (_rafID || (_rafID = requestAnimationFrame(_updateAll)));\n},\n    _onScroll = function _onScroll() {\n  // 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\n  if (!_normalizer || !_normalizer.isPressed || _normalizer.startX > _body.clientWidth) {\n    // if the user is dragging the scrollbar, allow it.\n    _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n\n    if (_normalizer) {\n      _rafID || (_rafID = requestAnimationFrame(_updateAll));\n    } else {\n      _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\n\n    }\n\n    _lastScrollTime || _dispatch("scrollStart");\n    _lastScrollTime = _getTime();\n  }\n},\n    _setBaseDimensions = function _setBaseDimensions() {\n  _baseScreenWidth = _win.innerWidth;\n  _baseScreenHeight = _win.innerHeight;\n},\n    _onResize = function _onResize(force) {\n  _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n  (force === true || !_refreshing && !_ignoreResize && !_doc.fullscreenElement && !_doc.webkitFullscreenElement && (!_ignoreMobileResize || _baseScreenWidth !== _win.innerWidth || Math.abs(_win.innerHeight - _baseScreenHeight) > _win.innerHeight * 0.25)) && _resizeDelay.restart(true);\n},\n    // ignore resizes triggered by refresh()\n_listeners = {},\n    _emptyArray = [],\n    _softRefresh = function _softRefresh() {\n  return _removeListener(ScrollTrigger, "scrollEnd", _softRefresh) || _refreshAll(true);\n},\n    _dispatch = function _dispatch(type) {\n  return _listeners[type] && _listeners[type].map(function (f) {\n    return f();\n  }) || _emptyArray;\n},\n    _savedStyles = [],\n    // 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.\n_revertRecorded = function _revertRecorded(media) {\n  for (var i = 0; i < _savedStyles.length; i += 5) {\n    if (!media || _savedStyles[i + 4] && _savedStyles[i + 4].query === media) {\n      _savedStyles[i].style.cssText = _savedStyles[i + 1];\n      _savedStyles[i].getBBox && _savedStyles[i].setAttribute("transform", _savedStyles[i + 2] || "");\n      _savedStyles[i + 3].uncache = 1;\n    }\n  }\n},\n    _recordScrollPositions = function _recordScrollPositions() {\n  return _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEac
1h(function (obj) {\n    return _isFunction(obj) && ++obj.cacheID && (obj.rec = obj());\n  });\n},\n    // record the current scroll position. Also 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\n_revertAll = function _revertAll(kill, media) {\n  var trigger;\n\n  for (_i = 0; _i < _triggers.length; _i++) {\n    trigger = _triggers[_i];\n\n    if (trigger && (!media || trigger._ctx === media)) {\n      if (kill) {\n        trigger.kill(1);\n      } else {\n        trigger.revert(true, true);\n      }\n    }\n  }\n\n  _isReverted = true;\n  media && _revertRecorded(media);\n  media || _dispatch("revert");\n},\n    _clearScrollMemory = function _clearScrollMemory(scrollRestoration, force) {\n  // 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.\n  _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n  (force || !_refreshingAll) && _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n    return _isFunction(obj) && obj.cacheID++ && (obj.rec = 0);\n  });\n  _isString(scrollRestoration) && (_win.history.scrollRestoration = _scrollRestoration = scrollRestoration);\n},\n    _refreshingAll,\n    _refreshID = 0,\n    _queueRefreshID,\n    _queueRefreshAll = function _queueRefreshAll() {\n  // 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.\n  if (_queueRefreshID !== _refreshID) {\n    var id = _queueRefreshID = _refreshID;\n    requestAnimationFrame(function () {\n      return id === _refreshID && _refreshAll(true);\n    });\n  }\n},\n    _refresh100vh = function _refresh100vh() {\n  _body.appendChild(_div100vh);\n\n  _100vh = !_normalizer && _div100vh.offsetHeight || _win.innerHeight;\n\n  _body.removeChild(_div100vh);\n},\n    _hideAllMarkers = function _hideAllMarkers(hide) {\n  return _toArray(".gsap-marker-start, .gsap-marker-end, .gsap-marker-scroller-start, .gsap-marker-scroller-end").forEach(function (el) {\n    return el.style.display = hide ? "none" : "block";\n  });\n},\n    _refreshAll = function _refreshAll(force, skipRevert) {\n  _docEl = _doc.documentElement; // some frameworks like Astro may cache the <body> and replace it during routing, so we\'ll just re-record the _docEl and _body for safety (otherwise, the markers may not get added properly).\n\n  _body = _doc.body;\n  _root = [_win, _doc, _docEl, _body];\n\n  if (_lastScrollTime && !force && !_isReverted) {\n    _addListener(ScrollTrigger, "scrollEnd", _softRefresh);\n\n    return;\n  }\n\n  _refresh100vh();\n\n  _refreshingAll = ScrollTrigger.isRefreshing = true;\n  _isReverted || _recordScrollPositions();\n\n  var refreshInits = _dispatch("refreshInit");\n\n  _sort && ScrollTrigger.sort();\n  skipRevert || _revertAll();\n\n  _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n    if (_isFunction(obj)) {\n      obj.smooth && (obj.target.style.scrollBehavior = "auto"); // smooth scrolling interferes\n\n      obj(0);\n    }\n  });\n\n  _triggers.slice(0).forEach(function (t) {\n    return t.refresh();\n  }); // don\'t loop with _i because during a refresh() someone could call ScrollTrigger.update(
1) which would iterate through _i resulting in a skip.\n\n\n  _isReverted = false;\n\n  _triggers.forEach(function (t) {\n    // nested pins (pinnedContainer) with pinSpacing may expand the container, so we must accommodate that here.\n    if (t._subPinOffset && t.pin) {\n      var prop = t.vars.horizontal ? "offsetWidth" : "offsetHeight",\n          original = t.pin[prop];\n      t.revert(true, 1);\n      t.adjustPinSpacing(t.pin[prop] - original);\n      t.refresh();\n    }\n  });\n\n  _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.\n\n  _hideAllMarkers(true);\n\n  _triggers.forEach(function (t) {\n    // 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\n    var max = _maxScroll(t.scroller, t._dir),\n        endClamp = t.vars.end === "max" || t._endClamp && t.end > max,\n        startClamp = t._startClamp && t.start >= max;\n\n    (endClamp || startClamp) && t.setPositions(startClamp ? max - 1 : t.start, endClamp ? Math.max(startClamp ? max : t.start + 1, max) : t.end, true);\n  });\n\n  _hideAllMarkers(false);\n\n  _clampingMax = 0;\n  refreshInits.forEach(function (result) {\n    return result && result.render && result.render(-1);\n  }); // 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.\n\n  _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (obj) {\n    if (_isFunction(obj)) {\n      obj.smooth && requestAnimationFrame(function () {\n        return obj.target.style.scrollBehavior = "smooth";\n      });\n      obj.rec && obj(obj.rec);\n    }\n  });\n\n  _clearScrollMemory(_scrollRestoration, 1);\n\n  _resizeDelay.pause();\n\n  _refreshID++;\n  _refreshingAll = 2;\n\n  _updateAll(2);\n\n  _triggers.forEach(function (t) {\n    return _isFunction(t.vars.onRefresh) && t.vars.onRefresh(t);\n  });\n\n  _refreshingAll = ScrollTrigger.isRefreshing = false;\n\n  _dispatch("refresh");\n},\n    _lastScroll = 0,\n    _direction = 1,\n    _primary,\n    _updateAll = function _updateAll(force) {\n  if (force === 2 || !_refreshingAll && !_isReverted) {\n    // _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.\n    ScrollTrigger.isUpdating = true;\n    _primary && _primary.update(0); // ScrollSmoother uses refreshPriority -9999 to become the primary that gets updated before all others because it affects the scroll position.\n\n    var l = _triggers.length,\n        time = _getTime(),\n        recordVelocity = time - _time1 >= 50,\n        scroll = l && _triggers[0].scroll();\n\n    _direction = _lastScroll > scroll ? -1 : 1;\n    _refreshingAll || (_lastScroll = scroll);\n\n    if (recordVelocity) {\n      if (_lastScrollTime && !_pointerIsDown && time - _lastScrollTime > 200) {\n        _lastScrollTime = 0;\n\n        _dispatch("scrollEnd");\n      }\n\n      _time2 = _time1;\n      _time1 = time;\n    }\n\n    if (_direction < 0) {\n      _i = l;\n\n      while (_i-- > 0) {\n        _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n      }\n\n      _direction = 1;\n    } else {\n      for (_i = 0; _i < l; _i++) {\n        _triggers[_i] && _triggers[_i].update(0, recordVelocity);\n      }\n    }\n\n    ScrollTrigger.isUpdating = false;\n  }\n\n  _rafID = 0;\n},\n    _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"],\n    _stateProps = _propNamesToCopy.concat([_width, _height, "boxSizing", "max" + _Width, "max" + _Height, "position", _margin, _padding, _padding + _Top, _padding + _Right, _padding + _Bottom, _padding + _Left]),\n    _swapPinOut = function _swapPinOut(pin, spacer, state) {\n  _setState(state);\n\n  var cache = pin._gsap;\n\n  if (cache.spacerIsNative) {\n    _setState(cache.spacerState);\n  } else if (pin._gsap.swappedIn) {\n    var parent = spacer.parentNode;\n\n    if (parent) {\n      parent.insertBefore(pin, spacer);\n      parent.removeChild(spacer);\n    }\n  }\n\n  pin._gsap.swappedIn = false;\n},\n    _swapPinIn = function _swapPinIn(pin, spacer, cs, spacerState) {\n  if (!pin._gsap.swappedIn) {\n    var i = _propNamesToCopy.length,\n        spacerStyle = spacer.style,\n        pinStyle = pin.style,\n        p;\n\n    while (i--) {\n      p = _propNamesToCopy[i];\n      spacerStyle[p] = cs[p];\n    }\n\n    spacerStyle.position = cs.position === "absolute" ? "absolute" : "relative";\n    cs.display === "inline" && (spacerStyle.display = "inline-block");\n    pinStyle[_bottom] = pinStyle[_right] = "auto";\n    spacerStyle.flexBasis = cs.flexBasis || "auto";\n    spacerStyle.overflow = "visible";\n    spacerStyle.boxSizing = "border-box";\n    spacerStyle[_width] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal) + _px;\n    spacerStyle[_height] = _getSize(pin, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical) + _px;\n    spacerStyle[_padding] = pinStyle[_margin] = pinStyle[_top] = pinStyle[_left] = "0";\n\n    _setState(spacerState);\n\n    pinStyle[_width] = pinStyle["max" + _Width] = cs[_width];\n    pinStyle[_height] = pinStyle["max" + _Height] = cs[_height];\n    pinStyle[_padding] = cs[_padding];\n\n    if (pin.parentNode !== spacer) {\n      pin.parentNode.insertBefore(spacer, pin);\n      spacer.appendChild(pin);\n    }\n\n    pin._gsap.swappedIn = true;\n  }\n},\n    _capsExp = /([A-Z])/g,\n    _setState = function _setState(state) {\n  if (state) {\n    var style = state.t.style,\n        l = state.length,\n        i = 0,\n        p,\n        value;\n    (state.t._gsap || gsap.core.getCache(state.t)).uncache = 1; // otherwise transforms may be off\n\n    for (; i < l; i += 2) {\n      value = state[i + 1];\n      p = state[i];\n\n      if (value) {\n        style[p] = value;\n      } else if (style[p]) {\n        style.removeProperty(p.replace(_capsExp, "-$1").toLowerCase());\n      }\n    }\n  }\n},\n    _getState = function _getState(element) {\n  // 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.\n  var l = _stateProps.length,\n      style = element.style,\n      state = [],\n      i = 0;\n\n  for (; i < l;
1 i++) {\n    state.push(_stateProps[i], style[_stateProps[i]]);\n  }\n\n  state.t = element;\n  return state;\n},\n    _copyState = function _copyState(state, override, omitOffsets) {\n  var result = [],\n      l = state.length,\n      i = omitOffsets ? 8 : 0,\n      // skip top, left, right, bottom if omitOffsets is true\n  p;\n\n  for (; i < l; i += 2) {\n    p = state[i];\n    result.push(p, p in override ? override[p] : state[i + 1]);\n  }\n\n  result.t = state.t;\n  return result;\n},\n    _winOffsets = {\n  left: 0,\n  top: 0\n},\n    // // potential future feature (?) Allow users to calculate where a trigger hits (scroll position) like getScrollPosition("#id", "top bottom")\n// _getScrollPosition = (trigger, position, {scroller, containerAnimation, horizontal}) => {\n// \tscroller = _getTarget(scroller || _win);\n// \tlet direction = horizontal ? _horizontal : _vertical,\n// \t\tisViewport = _isViewport(scroller);\n// \t_getSizeFunc(scroller, isViewport, direction);\n// \treturn _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);\n// },\n_parsePosition = function _parsePosition(value, trigger, scrollerSize, direction, scroll, marker, markerScroller, self, scrollerBounds, borderWidth, useFixedPosition, scrollerMax, containerAnimation, clampZeroProp) {\n  _isFunction(value) && (value = value(self));\n\n  if (_isString(value) && value.substr(0, 3) === "max") {\n    value = scrollerMax + (value.charAt(4) === "=" ? _offsetToPx("0" + value.substr(3), scrollerSize) : 0);\n  }\n\n  var time = containerAnimation ? containerAnimation.time() : 0,\n      p1,\n      p2,\n      element;\n  containerAnimation && containerAnimation.seek(0);\n  isNaN(value) || (value = +value); // convert a string number like "45" to an actual number\n\n  if (!_isNumber(value)) {\n    _isFunction(trigger) && (trigger = trigger(self));\n    var offsets = (value || "0").split(" "),\n        bounds,\n        localOffset,\n        globalOffset,\n        display;\n    element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(trigger, self) || _body;\n    bounds = _getBounds(element) || {};\n\n    if ((!bounds || !bounds.left && !bounds.top) && _getComputedStyle(element).display === "none") {\n      // if display is "none", it won\'t report getBoundingClientRect() properly\n      display = element.style.display;\n      element.style.display = "block";\n      bounds = _getBounds(element);\n      display ? element.style.display = display : element.style.removeProperty("display");\n    }\n\n    localOffset = _offsetToPx(offsets[0], bounds[direction.d]);\n    globalOffset = _offsetToPx(offsets[1] || "0", scrollerSize);\n    value = bounds[direction.p] - scrollerBounds[direction.p] - borderWidth + localOffset + scroll - globalOffset;\n    markerScroller && _positionMarker(markerScroller, globalOffset, direction, scrollerSize - globalOffset < 20 || markerScroller._isStart && globalOffset > 20);\n    scrollerSize -= scrollerSize - globalOffset; // adjust for the marker\n  } else {\n    containerAnimation && (value = gsap.utils.mapRange(containerAnimation.scrollTrigger.start, containerAnimation.scrollTrigger.end, 0, scrollerMax, value));\n    markerScroller && _positionMarker(markerScroller, scrollerSize, direction, true);\n  }\n\n  if (clampZeroProp) {\n    self[clampZeroProp] = value || -0.001;\n    value < 0 && (value = 0);\n  }\n\n  if (marker) {\n    var position = value + scrollerSize,\n        isStart = marker._isStart;\n    p1 = "scroll" + direction.d2;\n\n    _positionMarker(marker, position, direction, isStart && position > 20 || !isStart && (useFixedPosition ? Math.max(_body[p1], _docEl[p1]) : marker.parentNode[p1]) <= position + 1);\n\n    if (useFixedPosition) {\n      scrollerBounds = _getBounds(markerScroller);\n      useFixedPosition && (marker.style[direction.op.p] = scrollerBounds[direction.op.p] - direction.op.m - marker._offset + _px);\n    }\n  }\n\n  if (containerAnimation && element) {\n    p1 = _getBounds(element);
1\n    containerAnimation.seek(scrollerMax);\n    p2 = _getBounds(element);\n    containerAnimation._caScrollDist = p1[direction.p] - p2[direction.p];\n    value = value / containerAnimation._caScrollDist * scrollerMax;\n  }\n\n  containerAnimation && containerAnimation.seek(time);\n  return containerAnimation ? value : Math.round(value);\n},\n    _prefixExp = /(webkit|moz|length|cssText|inset)/i,\n    _reparent = function _reparent(element, parent, top, left) {\n  if (element.parentNode !== parent) {\n    var style = element.style,\n        p,\n        cs;\n\n    if (parent === _body) {\n      element._stOrig = style.cssText; // record original inline styles so we can revert them later\n\n      cs = _getComputedStyle(element);\n\n      for (p in cs) {\n        // must copy all relevant styles to ensure that nothing changes visually when we reparent to the <body>. Skip the vendor prefixed ones.\n        if (!+p && !_prefixExp.test(p) && cs[p] && typeof style[p] === "string" && p !== "0") {\n          style[p] = cs[p];\n        }\n      }\n\n      style.top = top;\n      style.left = left;\n    } else {\n      style.cssText = element._stOrig;\n    }\n\n    gsap.core.getCache(element).uncache = 1;\n    parent.appendChild(element);\n  }\n},\n    _interruptionTracker = function _interruptionTracker(getValueFunc, initialValue, onInterrupt) {\n  var last1 = initialValue,\n      last2 = last1;\n  return function (value) {\n    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.\n\n    if (current !== last1 && current !== last2 && Math.abs(current - last1) > 3 && Math.abs(current - last2) > 3) {\n      // 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.\n      value = current;\n      onInterrupt && onInterrupt();\n    }\n\n    last2 = last1;\n    last1 = Math.round(value);\n    return last1;\n  };\n},\n    _shiftMarker = function _shiftMarker(marker, direction, value) {\n  var vars = {};\n  vars[direction.p] = "+=" + value;\n  gsap.set(marker, vars);\n},\n    // _mergeAnimations = animations => {\n// \tlet tl = gsap.timeline({smoothChildTiming: true}).startTime(Math.min(...animations.map(a => a.globalTime(0))));\n// \tanimations.forEach(a => {let time = a.totalTime(); tl.add(a); a.totalTime(time); });\n// \ttl.smoothChildTiming = false;\n// \treturn tl;\n// },\n// 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)\n_getTweenCreator = function _getTweenCreator(scroller, direction) {\n  var getScroll = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction),\n      prop = "_scroll" + direction.p2,\n      // 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.\n  getTween = function getTween(scrollTo, vars, initialValue, change1, change2) {\n    var tween = getTween.tween,\n        onComplete = vars.onComplete,\n        modifiers = {};\n    initialValue = initialValue || getScroll();\n\n    var checkForInterruption = _interruptionTracker(getScroll, initialValue, function () {\n      tween.kill();\n      getTween.tween = 0;\n    });\n\n    change2 = change1 && change2 || 0; // if change1 is 0, we set that to the difference and ignore change2. Otherwise, there would be a compound effect.\n\n    change1 = change1 || scrollTo - initialValue;\n    tween && tween.kill();\n    vars[prop] = scrollTo;\n    vars.inherit = false;\n    vars.modifiers = modifiers;\n\n    modifiers[prop] = function () {\n      return checkForInterruption(initialValue + change1 * tween.ratio + change2 * tween.ratio * tween.ratio);\n    };
1\n\n    vars.onUpdate = function () {\n      _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++;\n      getTween.tween && _updateAll(); // if it was interrupted/killed, like in a context.revert(), don\'t force an updateAll()\n    };\n\n    vars.onComplete = function () {\n      getTween.tween = 0;\n      onComplete && onComplete.call(tween);\n    };\n\n    tween = getTween.tween = gsap.to(scroller, vars);\n    return tween;\n  };\n\n  scroller[prop] = getScroll;\n\n  getScroll.wheelHandler = function () {\n    return getTween.tween && getTween.tween.kill() && (getTween.tween = 0);\n  };\n\n  _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.\n\n\n  ScrollTrigger.isTouch && _addListener(scroller, "touchmove", getScroll.wheelHandler);\n  return getTween;\n};\n\nvar ScrollTrigger = /*#__PURE__*/function () {\n  function ScrollTrigger(vars, animation) {\n    _coreInitted || ScrollTrigger.register(gsap) || console.warn("Please gsap.registerPlugin(ScrollTrigger)");\n\n    _context(this);\n\n    this.init(vars, animation);\n  }\n\n  var _proto = ScrollTrigger.prototype;\n\n  _proto.init = function init(vars, animation) {\n    this.progress = this.start = 0;\n    this.vars && this.kill(true, true); // in case it\'s being initted again\n\n    if (!_enabled) {\n      this.update = this.refresh = this.kill = _passThrough;\n      return;\n    }\n\n    vars = _setDefaults(_isString(vars) || _isNumber(vars) || vars.nodeType ? {\n      trigger: vars\n    } : vars, _defaults);\n\n    var _vars = vars,\n        onUpdate = _vars.onUpdate,\n        toggleClass = _vars.toggleClass,\n        id = _vars.id,\n        onToggle = _vars.onToggle,\n        onRefresh = _vars.onRefresh,\n        scrub = _vars.scrub,\n        trigger = _vars.trigger,\n        pin = _vars.pin,\n        pinSpacing = _vars.pinSpacing,\n        invalidateOnRefresh = _vars.invalidateOnRefresh,\n        anticipatePin = _vars.anticipatePin,\n        onScrubComplete = _vars.onScrubComplete,\n        onSnapComplete = _vars.onSnapComplete,\n        once = _vars.once,\n        snap = _vars.snap,\n        pinReparent = _vars.pinReparent,\n        pinSpacer = _vars.pinSpacer,\n        containerAnimation = _vars.containerAnimation,\n        fastScrollEnd = _vars.fastScrollEnd,\n        preventOverlaps = _vars.preventOverlaps,\n        direction = vars.horizontal || vars.containerAnimation && vars.horizontal !== false ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical,\n        isToggle = !scrub && scrub !== 0,\n        scroller = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.scroller || _win),\n        scrollerCache = gsap.core.getCache(scroller),\n        isViewport = _isViewport(scroller),\n        useFixedPosition = ("pinType" in vars ? vars.pinType : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "pinType") || isViewport && "fixed") === "fixed",\n        callbacks = [vars.onEnter, vars.onLeave, vars.onEnterBack, vars.onLeaveBack],\n        toggleActions = isToggle && vars.toggleActions.split(" "),\n        markers = "markers" in vars ? vars.markers : _defaults.markers,\n        borderWidth = isViewport ? 0 : parseFloat(_getComputedStyle(scroller)["border" + direction.p2 + _Width]) || 0,\n        self = this,\n        onRefreshInit = vars.onRefreshInit && function () {\n      return vars.onRefreshInit(self);\n    },\n        getScrollerSize = _getSizeFunc(scroller, isViewport, direction),\n        getScrollerOffsets = _getOffsetsFunc(scroller, isViewport),\n        lastSnap = 0,\n        lastRefresh = 0,\n        prevProgress = 0,\n        scrollFunc = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(scroller, direction),\n        tweenTo,\n        pinCache,\n        snapFunc,\n        scroll1,\n        scroll2,\n        start,\n        end,\n        markerStart,\n        markerEnd,\n        markerStartTrigger,\n        markerEndTrigger,\n        markerVars,\n        executingOnRefresh,\n        change,\n        pinOr
1iginalState,\n        pinActiveState,\n        pinState,\n        spacer,\n        offset,\n        pinGetter,\n        pinSetter,\n        pinStart,\n        pinChange,\n        spacingStart,\n        spacerState,\n        markerStartSetter,\n        pinMoves,\n        markerEndSetter,\n        cs,\n        snap1,\n        snap2,\n        scrubTween,\n        scrubSmooth,\n        snapDurClamp,\n        snapDelayedCall,\n        prevScroll,\n        prevAnimProgress,\n        caMarkerSetter,\n        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.\n\n\n    self._startClamp = self._endClamp = false;\n    self._dir = direction;\n    anticipatePin *= 45;\n    self.scroller = scroller;\n    self.scroll = containerAnimation ? containerAnimation.time.bind(containerAnimation) : scrollFunc;\n    scroll1 = scrollFunc();\n    self.vars = vars;\n    animation = animation || vars.animation;\n\n    if ("refreshPriority" in vars) {\n      _sort = 1;\n      vars.refreshPriority === -9999 && (_primary = self); // used by ScrollSmoother\n    }\n\n    scrollerCache.tweenScroll = scrollerCache.tweenScroll || {\n      top: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical),\n      left: _getTweenCreator(scroller, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal)\n    };\n    self.tweenTo = tweenTo = scrollerCache.tweenScroll[direction.p];\n\n    self.scrubDuration = function (value) {\n      scrubSmooth = _isNumber(value) && value;\n\n      if (!scrubSmooth) {\n        scrubTween && scrubTween.progress(1).kill();\n        scrubTween = 0;\n      } else {\n        scrubTween ? scrubTween.duration(value) : scrubTween = gsap.to(animation, {\n          ease: "expo",\n          totalProgress: "+=0",\n          inherit: false,\n          duration: scrubSmooth,\n          paused: true,\n          onComplete: function onComplete() {\n            return onScrubComplete && onScrubComplete(self);\n          }\n        });\n      }\n    };\n\n    if (animation) {\n      animation.vars.lazy = false;\n      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\n\n      self.animation = animation.pause();\n      animation.scrollTrigger = self;\n      self.scrubDuration(scrub);\n      snap1 = 0;\n      id || (id = animation.vars.id);\n    }\n\n    if (snap) {\n      // 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.\n      if (!_isObject(snap) || snap.push) {\n        snap = {\n          snapTo: snap\n        };\n      }\n\n      "scrollBehavior" in _body.style && gsap.set(isViewport ? [_body, _docEl] : scroller, {\n        scrollBehavior: "auto"\n      }); // smooth scrolling doesn\'t work with snap.\n\n      _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.forEach(function (o) {\n        return _isFunction(o) && o.target === (isViewport ? _doc.scrollingElement || _docEl : scroller) && (o.smooth = false);\n      }); // note: set smooth to false on both the vertical and horizontal scroll getters/setters\n\n\n      snapFunc = _isFunction(snap.snapTo) ? snap.snapTo : snap.snapTo === "labels" ? _getClosestLabel(animation) : snap.snapTo === "labelsDirectional" ? _getLabelAtDirection(animation) : snap.directional !== false ? function (value, st) {\n        return _snapDirectional(snap.snapTo)(value, _getTime() - lastRefresh < 500 ? 0 : st.direction);\n      } : gsap.utils.snap(snap.snapTo);\n      snapDurClamp = snap.duration || {\n        min: 0.1,\n        max: 2\n      };\n      snapDurClamp = _isObject(snapDurClamp) ? _clamp(snapDurClamp.min, snapDurClamp.max) : _clamp(snapDurClamp, snapDurClamp);\n      snapDelayedCall = gsap.delayedCall(snap.delay || scrubSmooth / 2 || 0.1, function () {\n        var scroll = scrollFunc(),\n            refreshedRecently = _getTime() - lastRefresh < 500,\n            tween = tweenTo.tween;\n\n        if ((refreshedRecently || Math.abs(self.getVelocity()) < 10) && !tween && !_pointerIsDown && lastSnap !== scroll) {\n          var progress = (scroll - start) / change,\n              totalProgress = animation && !isToggle ? animation.totalProgress() : progress,\n              velocity = refreshedRecently ? 0 : (totalProgress - snap2) / (_getTime() - _time2) * 1000 || 0,\n              change1 = gsap.utils.clamp(-progress, 1 - progress, _abs(velocity / 2) * velocity / 0.185),\n              naturalEnd = progress + (snap.inertia === false ? 0 : change1),\n              endValue,\n              endScroll,\n              _snap = snap,\n              onStart = _snap.onStart,\n              _onInterrupt = _snap.onInterrupt,\n              _onComplete = _snap.onComplete;\n          endValue = snapFunc(naturalEnd, self);\n          _isNumber(endValue) || (endValue = naturalEnd); // in case the function didn\'t return a number, fall back to using the naturalEnd\n\n          endScroll = Math.max(0, Math.round(start + endValue * change));\n\n          if (scroll <= end && scroll >= start && endScroll !== scroll) {\n            if (tween && !tween._initted && tween.data <= _abs(endScroll - scroll)) {\n              // there\'s an overlapping snap! So we must figure out which one is closer and let that tween live.\n              return;\n            }\n\n            if (snap.inertia === false) {\n              change1 = endValue - progress;\n            }\n\n            tweenTo(endScroll, {\n              duration: snapDurClamp(_abs(Math.max(_abs(naturalEnd - totalProgress), _abs(endValue - totalProgress)) * 0.185 / velocity / 0.05 || 0)),\n              ease: snap.ease || "power3",\n              data: _abs(endScroll - scroll),\n              // record the distance so that if another snap tween occurs (conflict) we 
1can prioritize the closest snap.\n              onInterrupt: function onInterrupt() {\n                return snapDelayedCall.restart(true) && _onInterrupt && _callback(self, _onInterrupt);\n              },\n              onComplete: function onComplete() {\n                self.update();\n                lastSnap = scrollFunc();\n\n                if (animation && !isToggle) {\n                  // 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\n                  scrubTween ? scrubTween.resetTo("totalProgress", endValue, animation._tTime / animation._tDur) : animation.progress(endValue);\n                }\n\n                snap1 = snap2 = animation && !isToggle ? animation.totalProgress() : self.progress;\n                onSnapComplete && onSnapComplete(self);\n                _onComplete && _callback(self, _onComplete);\n              }\n            }, scroll, change1 * change, endScroll - scroll - change1 * change);\n            onStart && _callback(self, onStart, tweenTo.tween);\n          }\n        } else if (self.isActive && lastSnap !== scroll) {\n          snapDelayedCall.restart(true);\n        }\n      }).pause();\n    }\n\n    id && (_ids[id] = self);\n    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.\n\n    customRevertReturn = trigger && trigger._gsap && trigger._gsap.stRevert;\n    customRevertReturn && (customRevertReturn = customRevertReturn(self));\n    pin = pin === true ? trigger : (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pin);\n    _isString(toggleClass) && (toggleClass = {\n      targets: trigger,\n      className: toggleClass\n    });\n\n    if (pin) {\n      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)\n\n      self.pin = pin;\n      pinCache = gsap.core.getCache(pin);\n\n      if (!pinCache.spacer) {\n        // 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.\n        if (pinSpacer) {\n          pinSpacer = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(pinSpacer);\n          pinSpacer && !pinSpacer.nodeType && (pinSpacer = pinSpacer.current || pinSpacer.nativeElement); // for React & Angular\n\n          pinCache.spacerIsNative = !!pinSpacer;\n          pinSpacer && (pinCache.spacerState = _getState(pinSpacer));\n        }\n\n        pinCache.spacer = spacer = pinSpacer || _doc.createElement("div");\n        spacer.classList.add("pin-spacer");\n        id && spacer.classList.add("pin-spacer-" + id);\n        pinCache.pinState = pinOriginalState = _getState(pin);\n      } else {\n        pinOriginalState = pinCache.pinState;\n      }\n\n      vars.force3D !== false && gsap.set(pin, {\n        force3D: true\n      });\n      self.spacer = spacer = pinCache.spacer;\n      cs = _getComputedStyle(pin);\n      spacingStart = cs[pinSpacing + direction.os2];\n      pinGetter = gsap.getProperty(pin);\n      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).\n\n      _swapPinIn(pin, spacer, cs);
1\n\n      pinState = _getState(pin);\n    }\n\n    if (markers) {\n      markerVars = _isObject(markers) ? _setDefaults(markers, _markerDefaults) : _markerDefaults;\n      markerStartTrigger = _createMarker("scroller-start", id, scroller, direction, markerVars, 0);\n      markerEndTrigger = _createMarker("scroller-end", id, scroller, direction, markerVars, 0, markerStartTrigger);\n      offset = markerStartTrigger["offset" + direction.op.d2];\n\n      var content = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)((0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "content") || scroller);\n\n      markerStart = this.markerStart = _createMarker("start", id, content, direction, markerVars, offset, 0, containerAnimation);\n      markerEnd = this.markerEnd = _createMarker("end", id, content, direction, markerVars, offset, 0, containerAnimation);\n      containerAnimation && (caMarkerSetter = gsap.quickSetter([markerStart, markerEnd], direction.a, _px));\n\n      if (!useFixedPosition && !(_Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies.length && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getProxyProp)(scroller, "fixedMarkers") === true)) {\n        _makePositionable(isViewport ? _body : scroller);\n\n        gsap.set([markerStartTrigger, markerEndTrigger], {\n          force3D: true\n        });\n        markerStartSetter = gsap.quickSetter(markerStartTrigger, direction.a, _px);\n        markerEndSetter = gsap.quickSetter(markerEndTrigger, direction.a, _px);\n      }\n    }\n\n    if (containerAnimation) {\n      var oldOnUpdate = containerAnimation.vars.onUpdate,\n          oldParams = containerAnimation.vars.onUpdateParams;\n      containerAnimation.eventCallback("onUpdate", function () {\n        self.update(0, 0, 1);\n        oldOnUpdate && oldOnUpdate.apply(containerAnimation, oldParams || []);\n      });\n    }\n\n    self.previous = function () {\n      return _triggers[_triggers.indexOf(self) - 1];\n    };\n\n    self.next = function () {\n      return _triggers[_triggers.indexOf(self) + 1];\n    };\n\n    self.revert = function (revert, temp) {\n      if (!temp) {\n        return self.kill(true);\n      } // for compatibility with gsap.context() and gsap.matchMedia() which call revert()\n\n\n      var r = revert !== false || !self.enabled,\n          prevRefreshing = _refreshing;\n\n      if (r !== self.isReverted) {\n        if (r) {\n          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.\n\n          prevProgress = self.progress;\n          prevAnimProgress = animation && animation.progress();\n        }\n\n        markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n          return m.style.display = r ? "none" : "block";\n        });\n\n        if (r) {\n          _refreshing = self;\n          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\n        }\n\n        if (pin && (!pinReparent || !self.isActive)) {\n          if (r) {\n            _swapPinOut(pin, spacer, pinOriginalState);\n          } else {\n            _swapPinIn(pin, spacer, _getComputedStyle(pin), spacerState);\n          }\n        }\n\n        r || self.update(r); // when we\'re restoring, the update should run AFTER swapping the pin into its pin-spacer.\n\n        _refreshing = prevRefreshing; // restore. We set it to true during the update() so that things fire properly in there.\n\n        self.isReverted = r;\n      }\n    };\n\n    self.refresh = function (soft, force, position, pinOffset) {\n      // 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\n      if ((_refreshing || !self.enabled) && !force) {\n        return;\n      }\n\n      if (pin && soft && _lastScrollTime) {\n        _addListener(ScrollTrigger, "scrollEnd", _softRefresh);\n\n        return;\n      }\n\n      !_refreshingAll && onRefreshInit && onRefreshInit(self);\n      _refreshing = self;\n\n      if (tweenTo.tween && !position) {\n        // 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.\n        tweenTo.tween.kill();\n        tweenTo.tween = 0;\n      }\n\n      scrubTween && scrubTween.pause();\n\n      if (invalidateOnRefresh && animation) {\n        animation.revert({\n          kill: false\n        }).invalidate();\n        animation.getChildren ? animation.getChildren(true, true, false).forEach(function (t) {\n          return t.vars.immediateRender && t.render(0, true, true);\n        }) : animation.vars.immediateRender && animation.render(0, true, true); // any from() or fromTo() tweens should render immediately (well, unless they have immediateRender: false)\n      }\n\n      self.isReverted || self.revert(true, true);\n      self._subPinOffset = false; // we\'ll set this to true in the sub-pins if we find any\n\n      var size = getScrollerSize(),\n          scrollerBounds = getScrollerOffsets(),\n          max = containerAnimation ? c
1ontainerAnimation.duration() : _maxScroll(scroller, direction),\n          isFirstRefresh = change <= 0.01 || !change,\n          offset = 0,\n          otherPinOffset = pinOffset || 0,\n          parsedEnd = _isObject(position) ? position.end : vars.end,\n          parsedEndTrigger = vars.endTrigger || trigger,\n          parsedStart = _isObject(position) ? position.start : vars.start || (vars.start === 0 || !trigger ? 0 : pin ? "0 0" : "0 100%"),\n          pinnedContainer = self.pinnedContainer = vars.pinnedContainer && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.pinnedContainer, self),\n          triggerIndex = trigger && Math.max(0, _triggers.indexOf(self)) || 0,\n          i = triggerIndex,\n          cs,\n          bounds,\n          scroll,\n          isVertical,\n          override,\n          curTrigger,\n          curPin,\n          oppositeScroll,\n          initted,\n          revertedPins,\n          forcedOverflow,\n          markerStartOffset,\n          markerEndOffset;\n\n      if (markers && _isObject(position)) {\n        // 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.\n        markerStartOffset = gsap.getProperty(markerStartTrigger, direction.p);\n        markerEndOffset = gsap.getProperty(markerEndTrigger, direction.p);\n      }\n\n      while (i-- > 0) {\n        // 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.\n        curTrigger = _triggers[i];\n        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.\n\n        curPin = curTrigger.pin;\n\n        if (curPin && (curPin === trigger || curPin === pin || curPin === pinnedContainer) && !curTrigger.isReverted) {\n          revertedPins || (revertedPins = []);\n          revertedPins.unshift(curTrigger); // we\'ll revert from first to last to make sure things reach their end state properly\n\n          curTrigger.revert(true, true);\n        }\n\n        if (curTrigger !== _triggers[i]) {\n          // in case it got removed.\n          triggerIndex--;\n          i--;\n        }\n      }\n\n      _isFunction(parsedStart) && (parsedStart = parsedStart(self));\n      parsedStart = _parseClamp(parsedStart, "start", self);\n      start = _parsePosition(parsedStart, trigger, size, direction, scrollFunc(), markerStart, markerStartTrigger, self, scrollerBounds, borderWidth, useFixedPosition, max, containerAnimation, self._startClamp && "_startClamp") || (pin ? -0.001 : 0);\n      _isFunction(parsedEnd) && (parsedEnd = parsedEnd(self));\n\n      if (_isString(parsedEnd) && !parsedEnd.indexOf("+=")) {\n        if (~parsedEnd.indexOf(" ")) {\n          parsedEnd = (_isString(parsedStart) ? parsedStart.split(" ")[0] : "") + parsedEnd;\n        } else {\n          offset = _offsetToPx(parsedEnd.substr(2), size);\n          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.\n\n          parsedEndTrigger = trigger;\n        }\n      }\n\n      parsedEnd = _parseClamp(parsedEnd, "end", self);\n      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;\n      offset = 0;\n      i = triggerIndex;\n\n      while (i--) {\n        curTrigger = _triggers[i] || {};\n        curPin = curTrigger.pin;\n\n        if (curPin && curTrigger.start - curTrigger._pinPush <= start && !containerAnimation && curTrigger.end > 0) {\n          cs = curTrigger.end - (self._startClamp ? Math.max(0, curTr
1igger.start) : curTrigger.start);\n\n          if ((curPin === trigger && curTrigger.start - curTrigger._pinPush < start || curPin === pinnedContainer) && isNaN(parsedStart)) {\n            // numeric start values shouldn\'t be offset at all - treat them as absolute\n            offset += cs * (1 - curTrigger.progress);\n          }\n\n          curPin === pin && (otherPinOffset += cs);\n        }\n      }\n\n      start += offset;\n      end += offset;\n      self._startClamp && (self._startClamp += offset);\n\n      if (self._endClamp && !_refreshingAll) {\n        self._endClamp = end || -0.001;\n        end = Math.min(end, _maxScroll(scroller, direction));\n      }\n\n      change = end - start || (start -= 0.01) && 0.001;\n\n      if (isFirstRefresh) {\n        // 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.\n        prevProgress = gsap.utils.clamp(0, 1, gsap.utils.normalize(start, end, prevScroll));\n      }\n\n      self._pinPush = otherPinOffset;\n\n      if (markerStart && offset) {\n        // offset the markers if necessary\n        cs = {};\n        cs[direction.a] = "+=" + offset;\n        pinnedContainer && (cs[direction.p] = "-=" + scrollFunc());\n        gsap.set([markerStart, markerEnd], cs);\n      }\n\n      if (pin && !(_clampingMax && self.end >= _maxScroll(scroller, direction))) {\n        cs = _getComputedStyle(pin);\n        isVertical = direction === _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical;\n        scroll = scrollFunc(); // recalculate because the triggers can affect the scroll\n\n        pinStart = parseFloat(pinGetter(direction.a)) + otherPinOffset;\n\n        if (!max && end > 1) {\n          // 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/\n          forcedOverflow = (isViewport ? _doc.scrollingElement || _docEl : scroller).style;\n          forcedOverflow = {\n            style: forcedOverflow,\n            value: forcedOverflow["overflow" + direction.a.toUpperCase()]\n          };\n\n          if (isViewport && _getComputedStyle(_body)["overflow" + direction.a.toUpperCase()] !== "scroll") {\n            // avoid an extra scrollbar if BOTH <html> and <body> have overflow set to "scroll"\n            forcedOverflow.style["overflow" + direction.a.toUpperCase()] = "scroll";\n          }\n        }\n\n        _swapPinIn(pin, spacer, cs);\n\n        pinState = _getState(pin); // transforms will interfere with the top/left/right/bottom placement, so remove them temporarily. getBoundingClientRect() factors in transforms.\n\n        bounds = _getBounds(pin, true);\n        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)();\n\n        if (pinSpacing) {\n          spacerState = [pinSpacing + direction.os2, change + otherPinOffset + _px];\n          spacerState.t = spacer;\n          i = pinSpacing === _padding ? _getSize(pin, direction) + change + otherPinOffset : 0;\n\n          if (i) {\n            spacerState.push(direction.d, i + _px); // for box-sizing: border-box (must include padding).\n\n            spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);\n          }\n\n          _setState(spacerState);\n\n          if (pinnedContainer) {\n            // 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.\n            _triggers.forEach(function (t) {\n              if (t.pin === pinnedContainer && t.vars.pinSpacing !== false) {\n                t._subPinOffset = true;\n              }\n            });\n          }\n\n          useFixedPosition && scrollFunc(prevScroll);\n        } else {\n          i = _getSize(pin, direction);\n          i && spacer.style.flexBasis !== "auto" && (spacer.style.flexBasis = i + _px);\n        }\n\n        if (useFixedPosition) {\n          override = {\n            top: bounds.top + (isVertical ? scroll - start : oppositeScroll) + _px,\n            left: bounds.left + (isVertical ? oppositeScroll : scroll - start) + _px,\n            boxSizing: "border-box",\n            position: "fixed"\n          };\n          override[_width] = override["max" + _Width] = Math.ceil(bounds.width) + _px;\n          override[_height] = override["max" + _Height] = Math.ceil(bounds.height) + _px;\n          override[_margin] = override[_margin + _Top] = override[_margin + _Right] = override[_margin + _Bottom] = override[_margin + _Left] = "0";\n          override[_padding] = cs[_padding];\n          override[_padding + _Top] = cs[_padding + _Top];\n          override[_padding + _Right] = cs[_padding + _Right];\n          override[_padding + _Bottom] = cs[_padding + _Bottom];\n          override[_padding + _Left] = cs[_padding + _Left];\n          pinActiveState = _copyState(pinOriginalState, override, pinReparent);\n          _refreshingAll && scrollFunc(0);\n        }\n\n        if (animation) {\n          // 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.\n          initted = animation._initted; // if not, we must invalidate() after this step, otherwise it could lock 
1in starting values prematurely.\n\n          _suppressOverwrites(1);\n\n          animation.render(animation.duration(), true, true);\n          pinChange = pinGetter(direction.a) - pinStart + change + otherPinOffset;\n          pinMoves = Math.abs(change - pinChange) > 1;\n          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.\n\n          animation.render(0, true, true);\n          initted || animation.invalidate(true);\n          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.\n\n          _suppressOverwrites(0);\n        } else {\n          pinChange = change;\n        }\n\n        forcedOverflow && (forcedOverflow.value ? forcedOverflow.style["overflow" + direction.a.toUpperCase()] = forcedOverflow.value : forcedOverflow.style.removeProperty("overflow-" + direction.a));\n      } else if (trigger && scrollFunc() && !containerAnimation) {\n        // 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()\n        bounds = trigger.parentNode;\n\n        while (bounds && bounds !== _body) {\n          if (bounds._pinOffset) {\n            start -= bounds._pinOffset;\n            end -= bounds._pinOffset;\n          }\n\n          bounds = bounds.parentNode;\n        }\n      }\n\n      revertedPins && revertedPins.forEach(function (t) {\n        return t.revert(false, true);\n      });\n      self.start = start;\n      self.end = end;\n      scroll1 = scroll2 = _refreshingAll ? prevScroll : scrollFunc(); // reset velocity\n\n      if (!containerAnimation && !_refreshingAll) {\n        scroll1 < prevScroll && scrollFunc(prevScroll);\n        self.scroll.rec = 0;\n      }\n\n      self.revert(false, true);\n      lastRefresh = _getTime();\n\n      if (snapDelayedCall) {\n        lastSnap = -1; // just so snapping gets re-enabled, clear out any recorded last value\n        // 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.\n\n        snapDelayedCall.restart(true);\n      }\n\n      _refreshing = 0;\n      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().\n\n      if (isFirstRefresh || prevProgress !== self.progress || containerAnimation || invalidateOnRefresh || animation && !animation._initted) {\n        // 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.\n        animation && !isToggle && (animation._initted || prevProgress || animation.vars.immediateRender !== false) && 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.\n\n        self.progress = isFirstRefresh || (scroll1 - start) / change === prevProgress ? 0 : prevProgress;\n      }\n\n      pin && pinSpacing && (spacer._pinOffset = Math.round(self.progress * pinChange));\n      scrubTween && scrubTween.invalidate();\n\n      if (!isNaN(markerStartOffset)) {\n        // 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.\n        markerStartOffset -= gsap.getProperty(markerStartTrigger, direction.p);\n        markerEndOffset -= gsap.getProperty(markerEndTrigger, direction.p);\n\n        _shiftMarker(markerStartTrigger, direction, markerStartOffset);\n\n        _shiftMarker(markerStart, direction, markerStartOffset - (pinOffset || 0));\n\n        _shiftMarker(markerEndTrigger, direction, markerEndOffset);\n\n        _shiftMarker(markerEnd, direction, markerEndOffset - (pinOffset || 0));\n      }
1\n\n      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.\n\n      if (onRefresh && !_refreshingAll && !executingOnRefresh) {\n        // 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.\n        executingOnRefresh = true;\n        onRefresh(self);\n        executingOnRefresh = false;\n      }\n    };\n\n    self.getVelocity = function () {\n      return (scrollFunc() - scroll2) / (_getTime() - _time2) * 1000 || 0;\n    };\n\n    self.endAnimation = function () {\n      _endAnimation(self.callbackAnimation);\n\n      if (animation) {\n        scrubTween ? scrubTween.progress(1) : !animation.paused() ? _endAnimation(animation, animation.reversed()) : isToggle || _endAnimation(animation, self.direction < 0, 1);\n      }\n    };\n\n    self.labelToScroll = function (label) {\n      return animation && animation.labels && (start || self.refresh() || start) + animation.labels[label] / animation.duration() * change || 0;\n    };\n\n    self.getTrailing = function (name) {\n      var i = _triggers.indexOf(self),\n          a = self.direction > 0 ? _triggers.slice(0, i).reverse() : _triggers.slice(i + 1);\n\n      return (_isString(name) ? a.filter(function (t) {\n        return t.vars.preventOverlaps === name;\n      }) : a).filter(function (t) {\n        return self.direction > 0 ? t.end <= start : t.start >= end;\n      });\n    };\n\n    self.update = function (reset, recordVelocity, forceFake) {\n      if (containerAnimation && !forceFake && !reset) {\n        return;\n      }\n\n      var scroll = _refreshingAll === true ? prevScroll : self.scroll(),\n          p = reset ? 0 : (scroll - start) / change,\n          clipped = p < 0 ? 0 : p > 1 ? 1 : p || 0,\n          prevProgress = self.progress,\n          isActive,\n          wasActive,\n          toggleState,\n          action,\n          stateChanged,\n          toggled,\n          isAtMax,\n          isTakingAction;\n\n      if (recordVelocity) {\n        scroll2 = scroll1;\n        scroll1 = containerAnimation ? scrollFunc() : scroll;\n\n        if (snap) {\n          snap2 = snap1;\n          snap1 = animation && !isToggle ? animation.totalProgress() : clipped;\n        }\n      } // 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).\n\n\n      if (anticipatePin && pin && !_refreshing && !_startup && _lastScrollTime) {\n        if (!clipped && start < scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin) {\n          clipped = 0.0001;\n        } else if (clipped === 1 && end > scroll + (scroll - scroll2) / (_getTime() - _time2) * anticipatePin) {\n          clipped = 0.9999;\n        }\n      }\n\n      if (clipped !== prevProgress && self.enabled) {\n        isActive = self.isActive = !!clipped && clipped < 1;\n        wasActive = !!prevProgress && prevProgress < 1;\n        toggled = isActive !== wasActive;\n        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)\n\n        self.direction = clipped > prevProgress ? 1 : -1;\n        self.progress = clipped;\n\n        if (stateChanged && !_refreshing) {\n          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.\n\n          if (isToggle) {\n            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)\n\n            isTakingAction = animation && (action === "complete" || action === "reset" || action in animation);\n          }\n        }\n\n        preventOverlaps && (toggled || isTakingAction) && (isTakingAction || scrub || !animation) && (_isFunction(preventOverlaps) ? preventOverlaps(self) : self.getTrailing(preventOverlaps).forEac
1h(function (t) {\n          return t.endAnimation();\n        }));\n\n        if (!isToggle) {\n          if (scrubTween && !_refreshing && !_startup) {\n            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.\n\n            if (scrubTween.resetTo) {\n              scrubTween.resetTo("totalProgress", clipped, animation._tTime / animation._tDur);\n            } else {\n              // legacy support (courtesy), before 3.10.0\n              scrubTween.vars.totalProgress = clipped;\n              scrubTween.invalidate().restart();\n            }\n          } else if (animation) {\n            animation.totalProgress(clipped, !!(_refreshing && (lastRefresh || reset)));\n          }\n        }\n\n        if (pin) {\n          reset && pinSpacing && (spacer.style[pinSpacing + direction.os2] = spacingStart);\n\n          if (!useFixedPosition) {\n            pinSetter(_round(pinStart + pinChange * clipped));\n          } else if (stateChanged) {\n            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)\n\n            if (pinReparent) {\n              if (!reset && (isActive || isAtMax)) {\n                var bounds = _getBounds(pin, true),\n                    _offset = scroll - start;\n\n                _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);\n              } else {\n                _reparent(pin, spacer);\n              }\n            }\n\n            _setState(isActive || isAtMax ? pinActiveState : pinState);\n\n            pinMoves && clipped < 1 && isActive || pinSetter(pinStart + (clipped === 1 && !isAtMax ? pinChange : 0));\n          }\n        }\n\n        snap && !tweenTo.tween && !_refreshing && !_startup && snapDelayedCall.restart(true);\n        toggleClass && (toggled || once && clipped && (clipped < 1 || !_limitCallbacks)) && _toArray(toggleClass.targets).forEach(function (el) {\n          return el.classList[isActive || once ? "add" : "remove"](toggleClass.className);\n        }); // classes could affect positioning, so do it even if reset or refreshing is true.\n\n        onUpdate && !isToggle && !reset && onUpdate(self);\n\n        if (stateChanged && !_refreshing) {\n          if (isToggle) {\n            if (isTakingAction) {\n              if (action === "complete") {\n                animation.pause().totalProgress(1);\n              } else if (action === "reset") {\n                animation.restart(true).pause();\n              } else if (action === "restart") {\n                animation.restart(true);\n              } else {\n                animation[action]();\n              }\n            }\n\n            onUpdate && onUpdate(self);\n          }\n\n          if (toggled || !_limitCallbacks) {\n            // 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.\n            onToggle && toggled && _callback(self, onToggle);\n            callbacks[toggleState] && _callback(self, callbacks[toggleState]);\n            once && (clipped === 1 ? self.kill(false, 1) : callbacks[toggleState] = 0); // a callback shouldn\'t be called again if once is true.\n\n            if (!toggled) {\n              // 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\n              toggleState = clipped === 1 ? 1 : 3;\n              callbacks[toggleState] && _callback(self, callbacks[toggleState]);\n            }\n          }\n\n          if (fastScrollEnd && !isActive && Math.abs(self.getVelocity()) > (_isNumber(fastScrollEnd) ? fastScrollEnd : 2500)) {\n            _endAnimation(self.callbackA
1nimation);\n\n            scrubTween ? scrubTween.progress(1) : _endAnimation(animation, action === "reverse" ? 1 : !clipped, 1);\n          }\n        } else if (isToggle && onUpdate && !_refreshing) {\n          onUpdate(self);\n        }\n      } // update absolutely-positioned markers (only if the scroller isn\'t the viewport)\n\n\n      if (markerEndSetter) {\n        var n = containerAnimation ? scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0) : scroll;\n        markerStartSetter(n + (markerStartTrigger._isFlipped ? 1 : 0));\n        markerEndSetter(n);\n      }\n\n      caMarkerSetter && caMarkerSetter(-scroll / containerAnimation.duration() * (containerAnimation._caScrollDist || 0));\n    };\n\n    self.enable = function (reset, refresh) {\n      if (!self.enabled) {\n        self.enabled = true;\n\n        _addListener(scroller, "resize", _onResize);\n\n        isViewport || _addListener(scroller, "scroll", _onScroll);\n        onRefreshInit && _addListener(ScrollTrigger, "refreshInit", onRefreshInit);\n\n        if (reset !== false) {\n          self.progress = prevProgress = 0;\n          scroll1 = scroll2 = lastSnap = scrollFunc();\n        }\n\n        refresh !== false && self.refresh();\n      }\n    };\n\n    self.getTween = function (snap) {\n      return snap && tweenTo ? tweenTo.tween : scrubTween;\n    };\n\n    self.setPositions = function (newStart, newEnd, keepClamp, pinOffset) {\n      // 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()\n      if (containerAnimation) {\n        // convert ratios into scroll positions. Remember, start/end values on ScrollTriggers that have a containerAnimation refer to the time (in seconds), NOT scroll positions.\n        var st = containerAnimation.scrollTrigger,\n            duration = containerAnimation.duration(),\n            _change = st.end - st.start;\n\n        newStart = st.start + _change * newStart / duration;\n        newEnd = st.start + _change * newEnd / duration;\n      }\n\n      self.refresh(false, false, {\n        start: _keepClamp(newStart, keepClamp && !!self._startClamp),\n        end: _keepClamp(newEnd, keepClamp && !!self._endClamp)\n      }, pinOffset);\n      self.update();\n    };\n\n    self.adjustPinSpacing = function (amount) {\n      if (spacerState && amount) {\n        var i = spacerState.indexOf(direction.d) + 1;\n        spacerState[i] = parseFloat(spacerState[i]) + amount + _px;\n        spacerState[1] = parseFloat(spacerState[1]) + amount + _px;\n\n        _setState(spacerState);\n      }\n    };\n\n    self.disable = function (reset, allowAnimation) {\n      reset !== false && self.revert(true, true);\n\n      if (self.enabled) {\n        self.enabled = self.isActive = false;\n        allowAnimation || scrubTween && scrubTween.pause();\n        prevScroll = 0;\n        pinCache && (pinCache.uncache = 1);\n        onRefreshInit && _removeListener(ScrollTrigger, "refreshInit", onRefreshInit);\n\n        if (snapDelayedCall) {\n          snapDelayedCall.pause();\n          tweenTo.tween && tweenTo.tween.kill() && (tweenTo.tween = 0);\n        }\n\n        if (!isViewport) {\n          var i = _triggers.length;\n\n          while (i--) {\n            if (_triggers[i].scroller === scroller && _triggers[i] !== self) {\n              return; //don\'t remove the listeners if there are still other triggers referencing it.\n            }\n          }\n\n          _removeListener(scroller, "resize", _onResize);\n\n          isViewport || _removeListener(scroller, "scroll", _onScroll);\n        }\n      }\n    };\n\n    self.kill = function (revert, allowAnimation) {\n      self.disable(revert, allowAnimation);\n      scrubTween && !allowAnimation && scrubTween.kill();\n      id && delete _ids[id];\n\n      var i = _triggers.indexOf(self);\n\n      i >= 0 && _triggers.splice(i, 1);\n      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...\n      // if no other ScrollTrigger instances of the same scroller are found, wipe out any re
1corded scroll position. Otherwise, in a single page application, for example, it could maintain scroll position when it really shouldn\'t.\n\n      i = 0;\n\n      _triggers.forEach(function (t) {\n        return t.scroller === self.scroller && (i = 1);\n      });\n\n      i || _refreshingAll || (self.scroll.rec = 0);\n\n      if (animation) {\n        animation.scrollTrigger = null;\n        revert && animation.revert({\n          kill: false\n        });\n        allowAnimation || animation.kill();\n      }\n\n      markerStart && [markerStart, markerEnd, markerStartTrigger, markerEndTrigger].forEach(function (m) {\n        return m.parentNode && m.parentNode.removeChild(m);\n      });\n      _primary === self && (_primary = 0);\n\n      if (pin) {\n        pinCache && (pinCache.uncache = 1);\n        i = 0;\n\n        _triggers.forEach(function (t) {\n          return t.pin === pin && i++;\n        });\n\n        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.\n      }\n\n      vars.onKill && vars.onKill(self);\n    };\n\n    _triggers.push(self);\n\n    self.enable(false, false);\n    customRevertReturn && customRevertReturn(self);\n\n    if (animation && animation.add && !change) {\n      // 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.\n      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().\n\n      self.update = function () {\n        self.update = updateFunc;\n        _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; // otherwise a cached scroll position may get used in the refresh() in a very rare scenario, like if ScrollTriggers are created inside a DOMContentLoaded event and the queued requestAnimationFrame() fires beforehand. See https://gsap.com/community/forums/topic/41267-scrolltrigger-breaks-on-refresh-when-using-domcontentloaded/\n\n        start || end || self.refresh();\n      };\n\n      gsap.delayedCall(0.01, self.update);\n      change = 0.01;\n      start = end = 0;\n    } else {\n      self.refresh();\n    }\n\n    pin && _queueRefreshAll(); // pinning could affect the positions of other things, so make sure we queue a full refresh()\n  };\n\n  ScrollTrigger.register = function register(core) {\n    if (!_coreInitted) {\n      gsap = core || _getGSAP();\n      _windowExists() && window.document && ScrollTrigger.enable();\n      _coreInitted = _enabled;\n    }\n\n    return _coreInitted;\n  };\n\n  ScrollTrigger.defaults = function defaults(config) {\n    if (config) {\n      for (var p in config) {\n        _defaults[p] = config[p];\n      }\n    }\n\n    return _defaults;\n  };\n\n  ScrollTrigger.disable = function disable(reset, kill) {\n    _enabled = 0;\n\n    _triggers.forEach(function (trigger) {\n      return trigger[kill ? "kill" : "disable"](reset);\n    });\n\n    _removeListener(_win, "wheel", _onScroll);\n\n    _removeListener(_doc, "scroll", _onScroll);\n\n    clearInterval(_syncInterval);\n\n    _removeListener(_doc, "touchcancel", _passThrough);\n\n    _removeListener(_body, "touchstart", _passThrough);\n\n    _multiListener(_removeListener, _doc, "pointerdown,touchstart,mousedown", _pointerDownHandler);\n\n    _multiListener(_removeListener, _doc, "pointerup,touchend,mouseup", _pointerUpHandler);\n\n    _resizeDelay.kill();\n\n    _iterateAutoRefresh(_removeListener);\n\n    for (var i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) {\n      _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]);\n\n      _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]);\n    }\n  };\n\n  ScrollTrigger.enable = function enable() {\n    _win = window;\n    _doc = document;\n    _docEl = _doc.documentElement;\n    _body = _doc.body;\n\n    if (gsap) {\n      _toArray = gsap.utils.toArray;\n      _clamp = gsap.utils.clamp;\n      _context = gsap.core.context || _passThrough;\n      _suppressOverwrites = gsap.core.suppressOverwrites || _passThrough;\n      _scrollRestoration = _win.history.scrollRestoration || "auto";\n      _lastScroll = _win.pageYOffset || 0;\n      gsap.core.globals("ScrollTrigger", ScrollTrigger); // must register the global manually because in Internet Explorer, functions (classes) don\'t have a "name" property.\n\n      if (_body) {\
1n        _enabled = 1;\n        _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.\n\n        _div100vh.style.height = "100vh";\n        _div100vh.style.position = "absolute";\n\n        _refresh100vh();\n\n        _rafBugFix();\n\n        _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.\n\n        ScrollTrigger.isTouch = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch;\n        _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\n\n        _ignoreMobileResize = _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch === 1;\n\n        _addListener(_win, "wheel", _onScroll); // mostly for 3rd party smooth scrolling libraries.\n\n\n        _root = [_win, _doc, _docEl, _body];\n\n        if (gsap.matchMedia) {\n          ScrollTrigger.matchMedia = function (vars) {\n            var mm = gsap.matchMedia(),\n                p;\n\n            for (p in vars) {\n              mm.add(p, vars[p]);\n            }\n\n            return mm;\n          };\n\n          gsap.addEventListener("matchMediaInit", function () {\n            _recordScrollPositions();\n\n            _revertAll();\n          });\n          gsap.addEventListener("matchMediaRevert", function () {\n            return _revertRecorded();\n          });\n          gsap.addEventListener("matchMedia", function () {\n            _refreshAll(0, 1);\n\n            _dispatch("matchMedia");\n          });\n          gsap.matchMedia().add("(orientation: portrait)", function () {\n            // when orientation changes, we should take new base measurements for the ignoreMobileResize feature.\n            _setBaseDimensions();\n\n            return _setBaseDimensions;\n          });\n        } else {\n          console.warn("Requires GSAP 3.11.0 or later");\n        }\n\n        _setBaseDimensions();\n\n        _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!\n\n\n        var bodyHasStyle = _body.hasAttribute("style"),\n            bodyStyle = _body.style,\n            border = bodyStyle.borderTopStyle,\n            AnimationProto = gsap.core.Animation.prototype,\n            bounds,\n            i;\n\n        AnimationProto.revert || Object.defineProperty(AnimationProto, "revert", {\n          value: function value() {\n            return this.time(-0.01, true);\n          }\n        }); // only for backwards compatibility (Animation.revert() was added after 3.10.4)\n\n        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.\n\n        bounds = _getBounds(_body);\n        _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\n\n        _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.m = Math.round(bounds.left + _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal.sc()) || 0;\n        border ? bodyStyle.borderTopStyle = border : bodyStyle.removeProperty("border-top-style");\n\n        if (!bodyHasStyle) {\n          // SSR frameworks like Next.js complain if this attribute gets added.\n          _body.setAttribute("style", ""); // it\'s not enough to just removeAttribute() - we must first set it to empty, otherwise Next.js complains.\n\n\n          _body.removeAttribute("style");\n        } // TODO: (?) maybe move to leveraging the velocity mechanism in Observer and skip intervals.\n\n\n        _syncInterval = setInterval(_sync, 250);\n        gsap.delayedCall(0.5, function () {\n          return _startup = 0;\n        });\n\n        _addListener(_doc, "touchcancel", _passThrough); // some older Android devices intermittently stop dispatching "touchmove" events if we don\'t listen for "touchcancel" on the document.\n\n\n        _addListener(_body, "touchstart", _passThrough); //works around Safari bug: https://gsap.com/forums/topic/21450-draggable-in-iframe-on-mobile-is-buggy/\n\n\n        _multiListener(_addListener, _doc, "pointerdown,touchstart,mousedown", _pointerDownHandler);\n\n        _multiListener(_addListener, _doc, "pointerup,touchend,mouseup", _pointerUpHandler);\n\n        _transformProp = gsap.utils.checkPrefix("transform");\n\n        _stateProps.push(_transformProp);\n\n        _coreInitted = _getTime();\n        _resizeDelay = gsap.delayedCall(0.2, _refreshAll).pause();\n        _autoRefresh = [_doc, "visibilitychange", function () {\n          var w = _win.innerWidth,\n              h = _win.innerHeight;\n\n          if (_doc.hidden) {\n            _prevWidth = w;\n            _prevHeight = h;\n          }
1 else if (_prevWidth !== w || _prevHeight !== h) {\n            _onResize();\n          }\n        }, _doc, "DOMContentLoaded", _refreshAll, _win, "load", _refreshAll, _win, "resize", _onResize];\n\n        _iterateAutoRefresh(_addListener);\n\n        _triggers.forEach(function (trigger) {\n          return trigger.enable(0, 1);\n        });\n\n        for (i = 0; i < _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.length; i += 3) {\n          _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 1]);\n\n          _wheelListener(_removeListener, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i], _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers[i + 2]);\n        }\n      } else if (_doc) {\n        var onLoad = function onLoad() {\n          ScrollTrigger.enable();\n\n          _doc.removeEventListener("DOMContentLoaded", onLoad);\n        };\n\n        _doc.addEventListener("DOMContentLoaded", onLoad);\n      }\n    }\n  };\n\n  ScrollTrigger.config = function config(vars) {\n    "limitCallbacks" in vars && (_limitCallbacks = !!vars.limitCallbacks);\n    var ms = vars.syncInterval;\n    ms && clearInterval(_syncInterval) || (_syncInterval = ms) && setInterval(_sync, ms);\n    "ignoreMobileResize" in vars && (_ignoreMobileResize = ScrollTrigger.isTouch === 1 && vars.ignoreMobileResize);\n\n    if ("autoRefreshEvents" in vars) {\n      _iterateAutoRefresh(_removeListener) || _iterateAutoRefresh(_addListener, vars.autoRefreshEvents || "none");\n      _ignoreResize = (vars.autoRefreshEvents + "").indexOf("resize") === -1;\n    }\n  };\n\n  ScrollTrigger.scrollerProxy = function scrollerProxy(target, vars) {\n    var t = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(target),\n        i = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.indexOf(t),\n        isViewport = _isViewport(t);\n\n    if (~i) {\n      _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.splice(i, isViewport ? 6 : 2);\n    }\n\n    if (vars) {\n      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);\n    }\n  };\n\n  ScrollTrigger.clearMatchMedia = function clearMatchMedia(query) {\n    _triggers.forEach(function (t) {\n      return t._ctx && t._ctx.query === query && t._ctx.kill(true, true);\n    });\n  };\n\n  ScrollTrigger.isInViewport = function isInViewport(element, ratio, horizontal) {\n    var bounds = (_isString(element) ? (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element) : element).getBoundingClientRect(),\n        offset = bounds[horizontal ? _width : _height] * ratio || 0;\n    return horizontal ? bounds.right - offset > 0 && bounds.left + offset < _win.innerWidth : bounds.bottom - offset > 0 && bounds.top + offset < _win.innerHeight;\n  };\n\n  ScrollTrigger.positionInViewport = function positionInViewport(element, referencePoint, horizontal) {\n    _isString(element) && (element = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(element));\n    var bounds = element.getBoundingClientRect(),\n        size = bounds[horizontal ? _width : _height],\n        offset = referencePoint == null ? size / 2 : referencePoint in _keywords ? _keywords[referencePoint] * size : ~referencePoint.indexOf("%") ? parseFloat(referencePoint) * size / 100 : parseFloat(referencePoint) || 0;\n    return horizontal ? (bounds.left + offset) / _win.innerWidth : (bounds.top + offset) / _win.innerHeight;\n  };\n\n  ScrollTrigger.killAll = function killAll(allowListeners) {\n    _triggers.slice(0).forEach(function (t) {\n      return t.vars.id !== "ScrollSmoother" && t.kill();\n    });\n\n    if (allowListeners !== true) {\n      var listeners = _listeners.killAll || [];\n      _listeners = {};\n      listeners.forEach(function (f) {\n        return f();\n      });\n    }\n  };\n\n  return ScrollTrigger;\n}();\nScrollTrigger.version = "3.15.0";\n\nScrollTrigger.saveStyles = function (targets) {\n  return targets ? _toArray(targets).forEac
1h(function (target) {\n    // saved styles are recorded in a consecutive alternating Array, like [element, cssText, transform attribute, cache, matchMedia, ...]\n    if (target && target.style) {\n      var i = _savedStyles.indexOf(target);\n\n      i >= 0 && _savedStyles.splice(i, 5);\n\n      _savedStyles.push(target, target.style.cssText, target.getBBox && target.getAttribute("transform"), gsap.core.getCache(target), _context());\n    }\n  }) : _savedStyles;\n};\n\nScrollTrigger.revert = function (soft, media) {\n  return _revertAll(!soft, media);\n};\n\nScrollTrigger.create = function (vars, animation) {\n  return new ScrollTrigger(vars, animation);\n};\n\nScrollTrigger.refresh = function (safe) {\n  return safe ? _onResize(true) : (_coreInitted || ScrollTrigger.register()) && _refreshAll(true);\n};\n\nScrollTrigger.update = function (force) {\n  return ++_Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache && _updateAll(force === true ? 2 : 0);\n};\n\nScrollTrigger.clearScrollMemory = _clearScrollMemory;\n\nScrollTrigger.maxScroll = function (element, horizontal) {\n  return _maxScroll(element, horizontal ? _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal : _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical);\n};\n\nScrollTrigger.getScrollFunc = function (element, horizontal) {\n  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);\n};\n\nScrollTrigger.getById = function (id) {\n  return _ids[id];\n};\n\nScrollTrigger.getAll = function () {\n  return _triggers.filter(function (t) {\n    return t.vars.id !== "ScrollSmoother";\n  });\n}; // 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.\n\n\nScrollTrigger.isScrolling = function () {\n  return !!_lastScrollTime;\n};\n\nScrollTrigger.snapDirectional = _snapDirectional;\n\nScrollTrigger.addEventListener = function (type, callback) {\n  var a = _listeners[type] || (_listeners[type] = []);\n  ~a.indexOf(callback) || a.push(callback);\n};\n\nScrollTrigger.removeEventListener = function (type, callback) {\n  var a = _listeners[type],\n      i = a && a.indexOf(callback);\n  i >= 0 && a.splice(i, 1);\n};\n\nScrollTrigger.batch = function (targets, vars) {\n  var result = [],\n      varsCopy = {},\n      interval = vars.interval || 0.016,\n      batchMax = vars.batchMax || 1e9,\n      proxyCallback = function proxyCallback(type, callback) {\n    var elements = [],\n        triggers = [],\n        delay = gsap.delayedCall(interval, function () {\n      callback(elements, triggers);\n      elements = [];\n      triggers = [];\n    }).pause();\n    return function (self) {\n      elements.length || delay.restart(true);\n      elements.push(self.trigger);\n      triggers.push(self);\n      batchMax <= elements.length && delay.progress(1);\n    };\n  },\n      p;\n\n  for (p in vars) {\n    varsCopy[p] = p.substr(0, 2) === "on" && _isFunction(vars[p]) && p !== "onRefreshInit" ? proxyCallback(p, vars[p]) : vars[p];\n  }\n\n  if (_isFunction(batchMax)) {\n    batchMax = batchMax();\n\n    _addListener(ScrollTrigger, "refresh", function () {\n      return batchMax = vars.batchMax();\n    });\n  }\n\n  _toArray(targets).forEach(function (target) {\n    var config = {};\n\n    for (p in varsCopy) {\n      config[p] = varsCopy[p];\n    }\n\n    config.trigger = target;\n    result.push(ScrollTrigger.create(config));\n  });\n\n  return result;\n}; // 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).\n\n\nvar _clampScrollAndGetDurationMultiplier = function _clampScrollAndGetDurationMultiplier(scrollFunc, current, end, max) {\n  current > max ? scrollFunc(max) : current < 0 && scrollFunc(0);\n  return end > max ? (max - current) / (end - current) : end < 0 ? current / (current - end) : 1;\n},\n    _allowNativePanning = function _allowNativePanning(target, direction) {\n  if (direction === true) {\n    target.style.removeProperty("touch-action");\n  } else {\n    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.\n  }\n\n  target === _docEl && _allowNativePanning(_body, direction);\n},\n    _overflow = {\n  auto: 1,\n  scroll: 1\n},\n    _nestedScroll = function _nestedScroll(_ref5) {\n  var event = _ref5.event,\n      target = _ref5.target,\n      axis = _ref5.axis;\n\n  var node = (event.changedTouches ? event.changedTouches[0] : event).target,\n      cache = node._gsap || gsap.core.getCache(node),\n      time = _getTime(),\n      cs;\n\n  if (!cache._isScrollT || time - cache._isScrollT > 2000) {\n    // cache for 2 seconds to improve performance.\n    while (node && node !== _body && (node.scrollHeight <= node.clientHeight && node.scrollWidth <= node.clientWidth || !(_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]))) {\n      node = node.parentNode;\n    }\n\n    cache._isScroll = node && node !== target && !_isViewport(node) && (_overflow[(cs = _getComputedStyle(node)).overflowY] || _overflow[cs.overflowX]);\n    cache._isScrollT = time;\n  }\n\n  if (cache._isScroll || axis === "x") {\n    event.stopPropagation();\n    event._gsapAllow = true;\n  }\n},\n    // capture events on scrollable elements INSIDE the <body> and allow those by calling stopPropagation() when we find a scrollable ancestor\n_inputObserver = function _inputObserver(target, type, inputs, nested) {\n  return _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.create({\n    target: target,\n    capture: true,\n    debounce: false,\n    lockAxis: true,\n    type: type,\n    onWheel: nested = nested && _nestedScroll,\n    onPress: nested,\n    onDrag: nested,\n    onScroll: nested,\n    onEnable: function onEnable() {\n      return input
1s && _addListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, false, true);\n    },\n    onDisable: function onDisable() {\n      return _removeListener(_doc, _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.eventTypes[0], _captureInputs, true);\n    }\n  });\n},\n    _inputExp = /(input|label|select|textarea)/i,\n    _inputIsFocused,\n    _captureInputs = function _captureInputs(e) {\n  var isInput = _inputExp.test(e.target.tagName);\n\n  if (isInput || _inputIsFocused) {\n    e._gsapAllow = true;\n    _inputIsFocused = isInput;\n  }\n},\n    _getScrollNormalizer = function _getScrollNormalizer(vars) {\n  _isObject(vars) || (vars = {});\n  vars.preventDefault = vars.isNormalizer = vars.allowClicks = true;\n  vars.type || (vars.type = "wheel,touch");\n  vars.debounce = !!vars.debounce;\n  vars.id = vars.id || "normalizer";\n\n  var _vars2 = vars,\n      normalizeScrollX = _vars2.normalizeScrollX,\n      momentum = _vars2.momentum,\n      allowNestedScroll = _vars2.allowNestedScroll,\n      onRelease = _vars2.onRelease,\n      self,\n      maxY,\n      target = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.target) || _docEl,\n      smoother = gsap.core.globals().ScrollSmoother,\n      smootherInstance = smoother && smoother.get(),\n      content = _fixIOSBug && (vars.content && (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getTarget)(vars.content) || smootherInstance && vars.content !== false && !smootherInstance.smooth() && smootherInstance.content()),\n      scrollFuncY = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical),\n      scrollFuncX = (0,_Observer_js__WEBPACK_IMPORTED_MODULE_0__._getScrollFunc)(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal),\n      scale = 1,\n      initialScale = (_Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer.isTouch && _win.visualViewport ? _win.visualViewport.scale * _win.visualViewport.width : _win.outerWidth) / _win.innerWidth,\n      wheelRefresh = 0,\n      resolveMomentumDuration = _isFunction(momentum) ? function () {\n    return momentum(self);\n  } : function () {\n    return momentum || 2.8;\n  },\n      lastRefreshID,\n      skipTouchMove,\n      inputObserver = _inputObserver(target, vars.type, true, allowNestedScroll),\n      resumeTouchMove = function resumeTouchMove() {\n    return skipTouchMove = false;\n  },\n      scrollClampX = _passThrough,\n      scrollClampY = _passThrough,\n      updateClamps = function updateClamps() {\n    maxY = _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical);\n    scrollClampY = _clamp(_fixIOSBug ? 1 : 0, maxY);\n    normalizeScrollX && (scrollClampX = _clamp(0, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal)));\n    lastRefreshID = _refreshID;\n  },\n      removeContentOffset = function removeContentOffset() {\n    content._gsap.y = _round(parseFloat(content._gsap.y) + scrollFuncY.offset) + "px";\n    content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + parseFloat(content._gsap.y) + ", 0, 1)";\n    scrollFuncY.offset = scrollFuncY.cacheID = 0;\n  },\n      ignoreDrag = function ignoreDrag() {\n    if (skipTouchMove) {\n      requestAnimationFrame(resumeTouchMove);\n\n      var offset = _round(self.deltaY / 2),\n          scroll = scrollClampY(scrollFuncY.v - offset);\n\n      if (content && scroll !== scrollFuncY.v + scrollFuncY.offset) {\n        scrollFuncY.offset = scroll - scrollFuncY.v;\n\n        var y = _round((parseFloat(content && content._gsap.y) || 0) - scrollFuncY.offset);\n\n        content.style.transform = "matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, " + y + ", 0, 1)";\n        content._gsap.y = y + "px";\n        scrollFuncY.cacheID = _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache;\n\n        _updateAll();\n      }\n\n      return true;\n    }\n\n    scrollFuncY.offset && removeContentOffset();\n    skipTouchMove = true;\n  },\n      tween,\n      startScrollX,\n      startScrollY,\n      onStopDelayedCall,\n      onResize = function onResize() {\n    // 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.\n    updateClamps();\n\n    if (tween.isActive() && tween.vars.scrollY > maxY) {\n      scrollFuncY() > maxY ? tween.progress(1) && scrollFuncY(maxY) : tween.resetTo("scrollY", maxY);\n    }\n  };\n\n  content && gsap.set(content, {\n    y: "+=0"\n  }); // to ensure there\'s a cache (element._gsap)\n\n  vars.ignoreCheck = function (e) {\n    return _fixIOSBug && e.type === "touchmove" && ignoreDrag(e) || scale > 1.05 && e.type !== "touchstart" || self.isGesturing || e.touches && e.touches.length > 1;\n  };\n\n  vars.onPress = function () {\n    skipTouchMove = false;\n    var prevScale = scale;
1\n    scale = _round((_win.visualViewport && _win.visualViewport.scale || 1) / initialScale);\n    tween.pause();\n    prevScale !== scale && _allowNativePanning(target, scale > 1.01 ? true : normalizeScrollX ? false : "x");\n    startScrollX = scrollFuncX();\n    startScrollY = scrollFuncY();\n    updateClamps();\n    lastRefreshID = _refreshID;\n  };\n\n  vars.onRelease = vars.onGestureStart = function (self, wasDragging) {\n    scrollFuncY.offset && removeContentOffset();\n\n    if (!wasDragging) {\n      onStopDelayedCall.restart(true);\n    } else {\n      _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers.cache++; // make sure we\'re pulling the non-cached value\n      // alternate algorithm: durX = Math.min(6, Math.abs(self.velocityX / 800)),\tdur = Math.max(durX, Math.min(6, Math.abs(self.velocityY / 800))); dur = dur * (0.4 + (1 - _power4In(dur / 6)) * 0.6)) * (momentumSpeed || 1)\n\n      var dur = resolveMomentumDuration(),\n          currentScroll,\n          endScroll;\n\n      if (normalizeScrollX) {\n        currentScroll = scrollFuncX();\n        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.\n\n        dur *= _clampScrollAndGetDurationMultiplier(scrollFuncX, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._horizontal));\n        tween.vars.scrollX = scrollClampX(endScroll);\n      }\n\n      currentScroll = scrollFuncY();\n      endScroll = currentScroll + dur * 0.05 * -self.velocityY / 0.227; // the constant .227 is from power4(0.05)\n\n      dur *= _clampScrollAndGetDurationMultiplier(scrollFuncY, currentScroll, endScroll, _maxScroll(target, _Observer_js__WEBPACK_IMPORTED_MODULE_0__._vertical));\n      tween.vars.scrollY = scrollClampY(endScroll);\n      tween.invalidate().duration(dur).play(0.01);\n\n      if (_fixIOSBug && tween.vars.scrollY >= maxY || currentScroll >= maxY - 1) {\n        // 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.\n        gsap.to({}, {\n          onUpdate: onResize,\n          duration: dur\n        });\n      }\n    }\n\n    onRelease && onRelease(self);\n  };\n\n  vars.onWheel = function () {\n    tween._ts && tween.pause();\n\n    if (_getTime() - wheelRefresh > 1000) {\n      // after 1 second, refresh the clamps otherwise that\'ll only happen when ScrollTrigger.refresh() is called or for touch-scrolling.\n      lastRefreshID = 0;\n      wheelRefresh = _getTime();\n    }\n  };\n\n  vars.onChange = function (self, dx, dy, xArray, yArray) {\n    _refreshID !== lastRefreshID && updateClamps();\n    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.\n\n    if (dy) {\n      scrollFuncY.offset && removeContentOffset();\n      var isTouch = yArray[2] === dy,\n          y = isTouch ? startScrollY + self.startY - self.y : scrollFuncY() + dy - yArray[1],\n          yClamped = scrollClampY(y);\n      isTouch && y !== yClamped && (startScrollY += yClamped - y);\n      scrollFuncY(yClamped);\n    }\n\n    (dy || dx) && _updateAll();\n  };\n\n  vars.onEnable = function () {\n    _allowNativePanning(target, normalizeScrollX ? false : "x");\n\n    ScrollTrigger.addEventListener("refresh", onResize);\n\n    _addListener(_win, "resize", onResize);\n\n    if (scrollFuncY.smooth) {\n      scrollFuncY.target.style.scrollBehavior = "auto";\n      scrollFuncY.smooth = scrollFuncX.smooth = false;\n    }\n\n    inputObserver.enable();\n  };\n\n  vars.onDisable = function () {\n    _allowNativePanning(target, true);\n\n    _removeListener(_win, "resize", onResize);\n\n    ScrollTrigger.removeEventListener("refresh", onResize);\n    inputObserver.kill();\n  };\n\n  vars.lockAxis = vars.lockAxis !== false;\n  self = new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars);\n  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.\n\n  _fixIOSBug && !scrollFuncY() && scrollFuncY(1); // iOS bug causes event.clientY values to freak out (wildly inaccurate) if the scroll position is exactly 0.\n\n  _fixIOSBug && gsap.ticker.add(_passThrough); // prevent the ticker from sleeping\n\n  onStopDelayedCall = self._dc;\n  tween = gsap.to(self, {\n    ease: "power4",\n    paused: true,\n    inherit: false,\n    scrollX: normalizeScrollX ? "+=0.1" : "+=0",\n    scrollY: "+=0.1",\n    modifiers: {\n      scrollY: _interruptionTracker(scrollFuncY, scrollFuncY(), function () {\n        return tween.pause();\n      })\n    },\n    onUpdate: _updateAll,\n    onComplete: onStopDelayedCall.vars.onComplete\n  }); // 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.\n\n  return self;\n};\n\nScrollTrigger.sort = function (func) {\n  if (_isFunction(func)) {\n    return _triggers.sort(func);\n  }\n\n  var scroll = _win.pageYOffset || 0;
1\n  ScrollTrigger.getAll().forEach(function (t) {\n    return t._sortY = t.trigger ? scroll + t.trigger.getBoundingClientRect().top : t.start + _win.innerHeight;\n  });\n  return _triggers.sort(func || function (a, b) {\n    return (a.vars.refreshPriority || 0) * -1e6 + (a.vars.containerAnimation ? 1e6 : a._sortY) - ((b.vars.containerAnimation ? 1e6 : b._sortY) + (b.vars.refreshPriority || 0) * -1e6);\n  }); // anything with a containerAnimation should refresh last.\n};\n\nScrollTrigger.observe = function (vars) {\n  return new _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer(vars);\n};\n\nScrollTrigger.normalizeScroll = function (vars) {\n  if (typeof vars === "undefined") {\n    return _normalizer;\n  }\n\n  if (vars === true && _normalizer) {\n    return _normalizer.enable();\n  }\n\n  if (vars === false) {\n    _normalizer && _normalizer.kill();\n    _normalizer = vars;\n    return;\n  }\n\n  var normalizer = vars instanceof _Observer_js__WEBPACK_IMPORTED_MODULE_0__.Observer ? vars : _getScrollNormalizer(vars);\n  _normalizer && _normalizer.target === normalizer.target && _normalizer.kill();\n  _isViewport(normalizer.target) && (_normalizer = normalizer);\n  return normalizer;\n};\n\nScrollTrigger.core = {\n  // smaller file size way to leverage in ScrollSmoother and Observer\n  _getVelocityProp: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._getVelocityProp,\n  _inputObserver: _inputObserver,\n  _scrollers: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._scrollers,\n  _proxies: _Observer_js__WEBPACK_IMPORTED_MODULE_0__._proxies,\n  bridge: {\n    // when normalizeScroll sets the scroll position (ss = setScroll)\n    ss: function ss() {\n      _lastScrollTime || _dispatch("scrollStart");\n      _lastScrollTime = _getTime();\n    },\n    // a way to get the _refreshing value in Observer\n    ref: function ref() {\n      return _refreshing;\n    }\n  }\n};\n_getGSAP() && gsap.registerPlugin(ScrollTrigger);\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/ScrollTrigger.js?\n}')},"./node_modules/gsap/SplitText.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   SplitText: () => (/* binding */ SplitText),\n/* harmony export */   "default": () => (/* binding */ SplitText)\n/* harmony export */ });\n/*!\n * SplitText 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2026, GreenSock. All rights reserved. Subject to the terms at https://gsap.com/standard-license.\n * @author: Jack Doyle\n */\n\nlet gsap, _fonts, _splitProp = typeof Symbol === "function" ? Symbol() : "_split", _coreInitted, _initIfNecessary = () => _coreInitted || SplitText.register(window.gsap), _charSegmenter = typeof Intl !== "undefined" && "Segmenter" in Intl ? new Intl.Segmenter() : 0, _toArray = (r) => !r ? [] : typeof r === "string" ? _toArray(document.querySelectorAll(r)) : "length" in r ? Array.from(r).reduce((acc, cur) => {\n  typeof cur === "string" ? acc.push(..._toArray(cur)) : acc.push(cur);\n  return acc;\n}, []) : [r], _elements = (targets) => _toArray(targets).filter((e) => e && e.nodeType === 1), _emptyArray = [], _context = function() {\n}, _defaultContext = { add: (f) => f() }, _spacesRegEx = /\\s+/g, _emojiSafeRegEx = new RegExp("\\\\p{RI}\\\\p{RI}|\\\\p{Emoji}(\\\\p{EMod}|\\\\u{FE0F}\\\\u{20E3}?|[\\\\u{E0020}-\\\\u{E007E}]+\\\\u{E007F})?(\\\\u{200D}\\\\p{Emoji}(\\\\p{EMod}|\\\\u{FE0F}\\\\u{20E3}?|[\\\\u{E0020}-\\\\u{E007E}]+\\\\u{E007F})?)*|.", "gu"), _emptyBounds = { left: 0, top: 0, width: 0, height: 0 }, _findNextValidBounds = (allBounds, startIndex) => {\n  while (++startIndex < allBounds.length && allBounds[startIndex] === _emptyBounds) {\n  }\n  return allBounds[startIndex] || _emptyBounds;\n}, _revertOriginal = ({ element, html, ariaL, ariaH }) => {\n  element.innerHTML = html;\n  ariaL ? element.setAttribute("aria-label", ariaL) : element.removeAttribute("aria-label");\n  ariaH ? element.setAttribute("aria-hidden", ariaH) : element.removeAttribute("aria-hidden");\n}, _stretchToFitSpecialChars = (collection, specialCharsRegEx) =>
1 {\n  if (specialCharsRegEx) {\n    let charsFound = new Set(collection.join("").match(specialCharsRegEx) || _emptyArray), i = collection.length, slots, word, char, combined;\n    if (charsFound.size) {\n      while (--i > -1) {\n        word = collection[i];\n        for (char of charsFound) {\n          if (char.startsWith(word) && char.length > word.length) {\n            slots = 0;\n            combined = word;\n            while (char.startsWith(combined += collection[i + ++slots]) && combined.length < char.length) {\n            }\n            if (slots && combined.length === char.length) {\n              collection[i] = char;\n              collection.splice(i + 1, slots);\n              break;\n            }\n          }\n        }\n      }\n    }\n  }\n  return collection;\n}, _disallowInline = (element) => window.getComputedStyle(element).display === "inline" && (element.style.display = "inline-block"), _insertNodeBefore = (newChild, parent, existingChild) => parent.insertBefore(typeof newChild === "string" ? document.createTextNode(newChild) : newChild, existingChild), _getWrapper = (type, config, collection) => {\n  let className = config[type + "sClass"] || "", { tag = "div", aria = "auto", propIndex = false } = config, display = type === "line" ? "block" : "inline-block", incrementClass = className.indexOf("++") > -1, wrapper = (text) => {\n    let el = document.createElement(tag), i = collection.length + 1;\n    className && (el.className = className + (incrementClass ? " " + className + i : ""));\n    propIndex && el.style.setProperty("--" + type, i + "");\n    aria !== "none" && el.setAttribute("aria-hidden", "true");\n    if (tag !== "span") {\n      el.style.position = "relative";\n      el.style.display = display;\n    }\n    el.textContent = text;\n    collection.push(el);\n    return el;\n  };\n  incrementClass && (className = className.replace("++", ""));\n  wrapper.collection = collection;\n  return wrapper;\n}, _getLineWrapper = (element, nodes, config, collection) => {\n  let lineWrapper = _getWrapper("line", config, collection), textAlign = window.getComputedStyle(element).textAlign || "left";\n  return (startIndex, endIndex) => {\n    let newLine = lineWrapper("");\n    newLine.style.textAlign = textAlign;\n    element.insertBefore(newLine, nodes[startIndex]);\n    for (; startIndex < endIndex; startIndex++) {\n      newLine.appendChild(nodes[startIndex]);\n    }\n    newLine.normalize();\n  };\n}, _splitWordsAndCharsRecursively = (element, config, wordWrapper, charWrapper, prepForCharsOnly, deepSlice, ignore, charSplitRegEx, specialCharsRegEx, isNested) => {\n  var _a;\n  let nodes = Array.from(element.childNodes), i = 0, { wordDelimiter, reduceWhiteSpace = true, prepareText } = config, elementBounds = element.getBoundingClientRect(), lastBounds = elementBounds, isPreformatted = !reduceWhiteSpace && window.getComputedStyle(element).whiteSpace.substring(0, 3) === "pre", ignoredPreviousSibling = 0, wordsCollection = wordWrapper.collection, wordDelimIsNotSpace, wordDelimString, wordDelimSplitter, curNode, words, curWordEl, startsWithSpace, endsWithSpace, j, bounds, curWordChars, clonedNode, curSubNode, tempSubNode, curTextContent, wordText, lastWordText, k;\n  if (typeof wordDelimiter === "object") {\n    wordDelimSplitter = wordDelimiter.delimiter || wordDelimiter;\n    wordDelimString = wordDelimiter.replaceWith || "";\n  } else {\n    wordDelimString = wordDelimiter === "" ? "" : wordDelimiter || " ";\n  }\n  wordDelimIsNotSpace = wordDelimString !== " ";\n  for (; i < nodes.length; i++) {\n    curNode = nodes[i];\n    if (curNode.nodeType === 3) {\n      curTextContent = curNode.textContent || "";\n      if (reduceWhiteSpace) {\n        curTextContent = curTextContent.replace(_spacesRegEx, " ");\n      } else if (isPreformatted) {\n        curTextContent = curTextContent.replace(/\\n
1/g, wordDelimString + "\\n");\n      }\n      prepareText && (curTextContent = prepareText(curTextContent, element));\n      curNode.textContent = curTextContent;\n      words = wordDelimString || wordDelimSplitter ? curTextContent.split(wordDelimSplitter || wordDelimString) : curTextContent.match(charSplitRegEx) || _emptyArray;\n      lastWordText = words[words.length - 1];\n      endsWithSpace = wordDelimIsNotSpace ? lastWordText.slice(-1) === " " : !lastWordText;\n      lastWordText || words.pop();\n      lastBounds = elementBounds;\n      startsWithSpace = wordDelimIsNotSpace ? words[0].charAt(0) === " " : !words[0];\n      startsWithSpace && _insertNodeBefore(" ", element, curNode);\n      words[0] || words.shift();\n      _stretchToFitSpecialChars(words, specialCharsRegEx);\n      deepSlice && isNested || (curNode.textContent = "");\n      for (j = 1; j <= words.length; j++) {\n        wordText = words[j - 1];\n        if (!reduceWhiteSpace && isPreformatted && wordText.charAt(0) === "\\n") {\n          (_a = curNode.previousSibling) == null ? void 0 : _a.remove();\n          _insertNodeBefore(document.createElement("br"), element, curNode);\n          wordText = wordText.slice(1);\n        }\n        if (!reduceWhiteSpace && wordText === "") {\n          _insertNodeBefore(wordDelimString, element, curNode);\n        } else if (wordText === " ") {\n          element.insertBefore(document.createTextNode(" "), curNode);\n        } else {\n          wordDelimIsNotSpace && wordText.charAt(0) === " " && _insertNodeBefore(" ", element, curNode);\n          if (ignoredPreviousSibling && j === 1 && !startsWithSpace && wordsCollection.indexOf(ignoredPreviousSibling.parentNode) > -1) {\n            curWordEl = wordsCollection[wordsCollection.length - 1];\n            curWordEl.appendChild(document.createTextNode(charWrapper ? "" : wordText));\n          } else {\n            curWordEl = wordWrapper(charWrapper ? "" : wordText);\n            _insertNodeBefore(curWordEl, element, curNode);\n            ignoredPreviousSibling && j === 1 && !startsWithSpace && curWordEl.insertBefore(ignoredPreviousSibling, curWordEl.firstChild);\n          }\n          if (charWrapper) {\n            curWordChars = _charSegmenter ? _stretchToFitSpecialChars([..._charSegmenter.segment(wordText)].map((s) => s.segment), specialCharsRegEx) : wordText.match(charSplitRegEx) || _emptyArray;\n            for (k = 0; k < curWordChars.length; k++) {\n              curWordEl.appendChild(curWordChars[k] === " " ? document.createTextNode(" ") : charWrapper(curWordChars[k]));\n            }\n          }\n          if (deepSlice && isNested) {\n            curTextContent = curNode.textContent = curTextContent.substring(wordText.length + 1, curTextContent.length);\n            bounds = curWordEl.getBoundingClientRect();\n            if (bounds.top > lastBounds.top && bounds.left <= lastBounds.left) {\n              clonedNode = element.cloneNode();\n              curSubNode = element.childNodes[0];\n              while (curSubNode && curSubNode !== curWordEl) {\n                tempSubNode = curSubNode;\n                curSubNode = curSubNode.nextSibling;\n                clonedNode.appendChild(tempSubNode);\n              }\n              element.parentNode.insertBefore(clonedNode, element);\n              prepForCharsOnly && _disallowInline(clonedNode);\n            }\n            lastBounds = bounds;\n          }\n          if (j < words.length || endsWithSpace) {\n            _insertNodeBefore(j >= words.length ? " " : wordDelimIsNotSpace && wordText.slice(-1) === " " ? " " + wordDelimString : wordDelimString, element, curNode);\n          }\n        }\n      }\n      element.removeChild(curNode);\n      ignoredPreviousSibling = 0;\n    } else if (curNode.nodeType === 1) {\n      if (ignore && ignore.indexOf(curNode) > -1) {\n        wordsCollection.indexOf(curNode.previousSibling) > -1 && wordsCollection[wordsCollection.length - 1].appendChild(curNode);\n        ignoredPreviousSibling = curNode;\n      } else {\n        _splitWordsAndCharsRecursively(curNode, config, wordWrapper, charWrapper, prepForCharsOnly, deepSlice, ignore, charSplitRegEx, specialCharsRegEx, true);\n        ignoredPreviousSibling = 0;\n      }\n      prepForCharsOnly && _disallowInline(curNode);\n    }\n  }\n};\nconst _SplitText = class _SplitText {\n  constructor(elements, config) {\n    this.isSplit = false;\n    _initIfNecessary();\n    this.elements = _elements(elements);\n    this.chars = [];\n    this.words = [];\n    this.lines = [];\n    this.masks = [];\n    this.vars = config;
1\n    this.elements.forEach((el) => {\n      var _a;\n      config.overwrite !== false && ((_a = el[_splitProp]) == null ? void 0 : _a._data.orig.filter(({ element }) => element === el).forEach(_revertOriginal));\n      el[_splitProp] = this;\n    });\n    this._split = () => this.isSplit && this.split(this.vars);\n    let orig = [], timerId, checkWidths = () => {\n      let i = orig.length, o;\n      while (i--) {\n        o = orig[i];\n        let w = o.element.offsetWidth;\n        if (w !== o.width) {\n          o.width = w;\n          this._split();\n          return;\n        }\n      }\n    };\n    this._data = { orig, obs: typeof ResizeObserver !== "undefined" && new ResizeObserver(() => {\n      clearTimeout(timerId);\n      timerId = setTimeout(checkWidths, 200);\n    }) };\n    _context(this);\n    this.split(config);\n  }\n  split(config) {\n    (this._ctx || _defaultContext).add(() => {\n      this.isSplit && this.revert();\n      this.vars = config = config || this.vars || {};\n      let { type = "chars,words,lines", aria = "auto", deepSlice = true, smartWrap, onSplit, autoSplit = false, specialChars, mask } = this.vars, splitLines = type.indexOf("lines") > -1, splitCharacters = type.indexOf("chars") > -1, splitWords = type.indexOf("words") > -1, onlySplitCharacters = splitCharacters && !splitWords && !splitLines, specialCharsRegEx = specialChars && ("push" in specialChars ? new RegExp("(?:" + specialChars.join("|") + ")", "gu") : specialChars), finalCharSplitRegEx = specialCharsRegEx ? new RegExp(specialCharsRegEx.source + "|" + _emojiSafeRegEx.source, "gu") : _emojiSafeRegEx, ignore = !!config.ignore && _elements(config.ignore), { orig, animTime, obs } = this._data, onSplitResult;\n      if (splitCharacters || splitWords || splitLines) {\n        this.elements.forEach((element, index) => {\n          orig[index] = {\n            element,\n            html: element.innerHTML,\n            ariaL: element.getAttribute("aria-label"),\n            ariaH: element.getAttribute("aria-hidden")\n          };\n          aria === "auto" ? element.setAttribute("aria-label", (element.textContent || "").trim()) : aria === "hidden" && element.setAttribute("aria-hidden", "true");\n          let chars = [], words = [], lines = [], charWrapper = splitCharacters ? _getWrapper("char", config, chars) : null, wordWrapper = _getWrapper("word", config, words), i, curWord, smartWrapSpan, nextSibling;\n          _splitWordsAndCharsRecursively(element, config, wordWrapper, charWrapper, onlySplitCharacters, deepSlice && (splitLines || onlySplitCharacters), ignore, finalCharSplitRegEx, specialCharsRegEx, false);\n          if (splitLines) {\n            let nodes = _toArray(element.childNodes), wrapLine = _getLineWrapper(element, nodes, config, lines), curNode, toRemove = [], lineStartIndex = 0, allBounds = nodes.map((n) => n.nodeType === 1 ? n.getBoundingClientRect() : _emptyBounds), lastBounds = _emptyBounds, curBounds;\n            for (i = 0; i < nodes.length; i++) {\n              curNode = nodes[i];\n              if (curNode.nodeType === 1) {\n                if (curNode.nodeName === "BR") {\n                  if (!i || nodes[i - 1].nodeName !== "BR") {\n                    toRemove.push(curNode);\n                    wrapLine(lineStartIndex, i + 1);\n                  }\n                  lineStartIndex = i + 1;\n                  lastBounds = _findNextValidBounds(allBounds, i);\n                } else {\n                  curBounds = allBounds[i];\n                  if (i && curBounds.top > lastBounds.top && curBounds.left < lastBounds.left + lastBounds.width - 1) {\n                    wrapLine(lineStartIndex, i);\n                    lineStartIndex = i;\n                  }\n                  lastBounds = curBounds;\n                }\n              }\n            }\n            lineStartIndex < i && wrapLine(lineStartIndex, i);\n            toRemove.forEach((el) => {\n              var _a;\n              return (_a = el.parentNode) == null ? void 0 : _a.removeChild(el);\n            });\n          }\n          if (!splitWords) {\n            for (i = 0; i < words.length;
1 i++) {\n              curWord = words[i];\n              if (splitCharacters || !curWord.nextSibling || curWord.nextSibling.nodeType !== 3) {\n                if (smartWrap && !splitLines) {\n                  smartWrapSpan = document.createElement("span");\n                  smartWrapSpan.style.whiteSpace = "nowrap";\n                  while (curWord.firstChild) {\n                    smartWrapSpan.appendChild(curWord.firstChild);\n                  }\n                  curWord.replaceWith(smartWrapSpan);\n                } else {\n                  curWord.replaceWith(...curWord.childNodes);\n                }\n              } else {\n                nextSibling = curWord.nextSibling;\n                if (nextSibling && nextSibling.nodeType === 3) {\n                  nextSibling.textContent = (curWord.textContent || "") + (nextSibling.textContent || "");\n                  curWord.remove();\n                }\n              }\n            }\n            words.length = 0;\n            element.normalize();\n          }\n          this.lines.push(...lines);\n          this.words.push(...words);\n          this.chars.push(...chars);\n        });\n        mask && this[mask] && this.masks.push(...this[mask].map((el) => {\n          let maskEl = el.cloneNode();\n          el.replaceWith(maskEl);\n          maskEl.appendChild(el);\n          el.className && (maskEl.className = el.className.trim().split(" ").map((s) => s + "-mask").join(" "));\n          maskEl.style.overflow = "clip";\n          return maskEl;\n        }));\n      }\n      this.isSplit = true;\n      _fonts && splitLines && autoSplit && _fonts.addEventListener("loadingdone", this._split);\n      if ((onSplitResult = onSplit && onSplit(this)) && onSplitResult.totalTime) {\n        this._data.anim = animTime ? onSplitResult.totalTime(animTime) : onSplitResult;\n      }\n      splitLines && autoSplit && this.elements.forEach((element, index) => {\n        orig[index].width = element.offsetWidth;\n        obs && obs.observe(element);\n      });\n    });\n    return this;\n  }\n  kill() {\n    let { obs } = this._data;\n    obs && obs.disconnect();\n    _fonts == null ? void 0 : _fonts.removeEventListener("loadingdone", this._split);\n  }\n  revert() {\n    var _a, _b;\n    if (this.isSplit) {\n      let { orig, anim } = this._data;\n      this.kill();\n      orig.forEach(_revertOriginal);\n      this.chars.length = this.words.length = this.lines.length = orig.length = this.masks.length = 0;\n      this.isSplit = false;\n      if (anim) {\n        this._data.animTime = anim.totalTime();\n        anim.revert();\n      }\n      (_b = (_a = this.vars).onRevert) == null ? void 0 : _b.call(_a, this);\n    }\n    return this;\n  }\n  static create(elements, config) {\n    return new _SplitText(elements, config);\n  }\n  static register(core) {\n    gsap = gsap || core || window.gsap;\n    if (gsap) {\n      _toArray = gsap.utils.toArray;\n      _context = gsap.core.context || _context;\n    }\n    if (!_coreInitted && window.innerWidth > 0) {\n      _fonts = document.fonts;\n      _coreInitted = true;\n    }\n  }\n};\n_SplitText.version = "3.15.0";\nlet SplitText = _SplitText;\n\n\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/SplitText.js?\n}')},"./node_modules/gsap/gsap-core.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Animation: () => (/* binding */ Animation),\n/* harmony export */   Back: () => (/* binding */ Back),\n/* harmony export */   Bounce: () => (/* binding */ Bounce),\n/* harmony export */   Circ: () => (/* binding */ Circ),\n/* harmony export */   Cubic: () => (/* binding */ Cubic),\n/* harmony export */   Elastic: () => (/* binding */ Elastic),\n/* harmony export */   Expo: () => (/* binding */ Expo),\n/* harmony export */   GSCache: () => (/* binding */ GSCache),\n/* harmony export */   Linear: () => (/* binding */ Linear),\n/* harmony export */   Power0: () =>
1 (/* binding */ Power0),\n/* harmony export */   Power1: () => (/* binding */ Power1),\n/* harmony export */   Power2: () => (/* binding */ Power2),\n/* harmony export */   Power3: () => (/* binding */ Power3),\n/* harmony export */   Power4: () => (/* binding */ Power4),\n/* harmony export */   PropTween: () => (/* binding */ PropTween),\n/* harmony export */   Quad: () => (/* binding */ Quad),\n/* harmony export */   Quart: () => (/* binding */ Quart),\n/* harmony export */   Quint: () => (/* binding */ Quint),\n/* harmony export */   Sine: () => (/* binding */ Sine),\n/* harmony export */   SteppedEase: () => (/* binding */ SteppedEase),\n/* harmony export */   Strong: () => (/* binding */ Strong),\n/* harmony export */   Timeline: () => (/* binding */ Timeline),\n/* harmony export */   TimelineLite: () => (/* binding */ Timeline),\n/* harmony export */   TimelineMax: () => (/* binding */ Timeline),\n/* harmony export */   Tween: () => (/* binding */ Tween),\n/* harmony export */   TweenLite: () => (/* binding */ Tween),\n/* harmony export */   TweenMax: () => (/* binding */ Tween),\n/* harmony export */   _checkPlugin: () => (/* binding */ _checkPlugin),\n/* harmony export */   _colorExp: () => (/* binding */ _colorExp),\n/* harmony export */   _colorStringFilter: () => (/* binding */ _colorStringFilter),\n/* harmony export */   _config: () => (/* binding */ _config),\n/* harmony export */   _forEachName: () => (/* binding */ _forEachName),\n/* harmony export */   _getCache: () => (/* binding */ _getCache),\n/* harmony export */   _getProperty: () => (/* binding */ _getProperty),\n/* harmony export */   _getSetter: () => (/* binding */ _getSetter),\n/* harmony export */   _isString: () => (/* binding */ _isString),\n/* harmony export */   _isUndefined: () => (/* binding */ _isUndefined),\n/* harmony export */   _missingPlugin: () => (/* binding */ _missingPlugin),\n/* harmony export */   _numExp: () => (/* binding */ _numExp),\n/* harmony export */   _numWithUnitExp: () => (/* binding */ _numWithUnitExp),\n/* harmony export */   _parseRelative: () => (/* binding */ _parseRelative),\n/* harmony export */   _plugins: () => (/* binding */ _plugins),\n/* harmony export */   _relExp: () => (/* binding */ _relExp),\n/* harmony export */   _removeLinkedListItem: () => (/* binding */ _removeLinkedListItem),\n/* harmony export */   _renderComplexString: () => (/* binding */ _renderComplexString),\n/* harmony export */   _replaceRandom: () => (/* binding */ _replaceRandom),\n/* harmony export */   _round: () => (/* binding */ _round),\n/* harmony export */   _roundModifier: () => (/* binding */ _roundModifier),\n/* harmony export */   _setDefaults: () => (/* binding */ _setDefaults),\n/* harmony export */   _sortPropTweensByPriority: () => (/* binding */ _sortPropTweensByPriority),\n/* harmony export */   _ticker: () => (/* binding */ _ticker),\n/* harmony export */   clamp: () => (/* binding */ clamp),\n/* harmony export */   "default": () => (/* binding */ gsap),\n/* harmony export */   distribute: () => (/* binding */ distribute),\n/* harmony export */   getUnit: () => (/* binding */ getUnit),\n/* harmony export */   gsap: () => (/* binding */ gsap),\n/* harmony export */   interpolate: () => (/* binding */ interpolate),\n/* harmony export */   mapRange: () => (/* binding */ mapRange),\n/* harmony export */   normalize: () => (/* binding */ normalize),\n/* harmony export */   pipe: () => (/* binding */ pipe),\n/* harmony export */   random: () => (/* binding */ random),\n/* harmony export */   selector: () => (/* binding */ selector),\n/* harmony export */   shuffle: () => (/* binding */ shuffle),\n/* harmony export */   snap: () => (/* binding */ snap),\n/* harmony export */   splitColor: () => (/* binding */ splitColor),\n/* harmony export */   toArray: () => (/* binding */ toArray),\n/* harmony export */   unitize: () => (/* binding */ unitize),\n/* harmony export */   wrap: () => (/* binding */ wrap),\n/* harmony export */   wrapYoyo: () => (/* binding */ wrapYoyo)\n/* harmony export */ });\nfunction _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn\'t been initialised - super() hasn\'t been called"); } return self; }\n\nfunction _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }\n\n/*!\n * GSAP 3.15.0\n * https://gsap.com\n *\n * @license Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar _config = {\n  autoSleep: 120,\n  force3D: "auto",\n  nullTargetWarn: 1,\n  units: {\n    lineHeight: ""\n  }\n},\n    _defaults = {\n  duration: .5,\n  overwrite: false,\n  delay: 0\n},\n    _suppressOverwrites,\n    _reverting,\n    _context,\n    _bigNum = 1e8,\n    _tinyNum = 1 / _bigNum,\n    _2PI = Math.PI * 2,\n    _HALF_PI = _2PI / 4,\n    _gsID = 0,\n    _sqrt = Math.sqrt,\n    _cos = Math.cos,\n    _sin = Math.sin,\n    _isString = function _isString(value) {\n  return typeof value === "string";\n},\n    _isFunction = function _isFunction(value) {\n  return typeof value === "function";\n},\n    _isNumber = function _isNumber(value) {\n  return typeof value === "number";\n},\n    _isUndefined = function _isUndefined(value) {\n  return typeof value === "undefined";\n},\n    _isObject = function _isObject(value) {\n  return typeof value === "object";\n},\n    _isNotFalse = function _isNotFalse(value) {\n  return value !== false;\n},\n    _windowExists = function _windowExists() {\n  return typeof window !== "undefined";\n},\n    _isFuncOrString = function _isFuncOrString(value) {\n  return _isFunction(value) || _isString(value);\n},\n    _isTypedArray = typeof ArrayBuffer === "function" && ArrayBuffer.isView || function () {},\n    // note: IE10 has ArrayBuffer, but NOT ArrayBuffer.isView().\
1n_isArray = Array.isArray,\n    _randomExp = /random\\([^)]+\\)/g,\n    _commaDelimExp = /,\\s*/g,\n    _strictNumExp = /(?:-?\\.?\\d|\\.)+/gi,\n    //only numbers (including negatives and decimals) but NOT relative values.\n_numExp = /[-+=.]*\\d+[.e\\-+]*\\d*[e\\-+]*\\d*/g,\n    //finds any numbers, including ones that start with += or -=, negative numbers, and ones in scientific notation like 1e-8.\n_numWithUnitExp = /[-+=.]*\\d+[.e-]*\\d*[a-z%]*/g,\n    _complexStringNumExp = /[-+=.]*\\d+\\.?\\d*(?:e-|e\\+)?\\d*/gi,\n    //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.\n_relExp = /[+-]=-?[.\\d]+/,\n    _delimitedValueExp = /[^,\'"\\[\\]\\s]+/gi,\n    // previously /[#\\-+.]*\\b[a-z\\d\\-=+%.]+/gi but didn\'t catch special characters.\n_unitExp = /^[+\\-=e\\s\\d]*\\d+[.\\d]*([a-z]*|%)\\s*$/i,\n    _globalTimeline,\n    _win,\n    _coreInitted,\n    _doc,\n    _globals = {},\n    _installScope = {},\n    _coreReady,\n    _install = function _install(scope) {\n  return (_installScope = _merge(scope, _globals)) && gsap;\n},\n    _missingPlugin = function _missingPlugin(property, value) {\n  return console.warn("Invalid property", property, "set to", value, "Missing plugin? gsap.registerPlugin()");\n},\n    _warn = function _warn(message, suppress) {\n  return !suppress && console.warn(message);\n},\n    _addGlobal = function _addGlobal(name, obj) {\n  return name && (_globals[name] = obj) && _installScope && (_installScope[name] = obj) || _globals;\n},\n    _emptyFunc = function _emptyFunc() {\n  return 0;\n},\n    _startAtRevertConfig = {\n  suppressEvents: true,\n  isStart: true,\n  kill: false\n},\n    _revertConfigNoKill = {\n  suppressEvents: true,\n  kill: false\n},\n    _revertConfig = {\n  suppressEvents: true\n},\n    _reservedProps = {},\n    _lazyTweens = [],\n    _lazyLookup = {},\n    _lastRenderedFrame,\n    _plugins = {},\n    _effects = {},\n    _nextGCFrame = 30,\n    _harnessPlugins = [],\n    _callbackNames = "",\n    _harness = function _harness(targets) {\n  var target = targets[0],\n      harnessPlugin,\n      i;\n  _isObject(target) || _isFunction(target) || (targets = [targets]);\n\n  if (!(harnessPlugin = (target._gsap || {}).harness)) {\n    // 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)\n    i = _harnessPlugins.length;\n\n    while (i-- && !_harnessPlugins[i].targetTest(target)) {}\n\n    harnessPlugin = _harnessPlugins[i];\n  }\n\n  i = targets.length;\n\n  while (i--) {\n    targets[i] && (targets[i]._gsap || (targets[i]._gsap = new GSCache(targets[i], harnessPlugin))) || targets.splice(i, 1);\n  }\n\n  return targets;\n},\n    _getCache = function _getCache(target) {\n  return target._gsap || _harness(toArray(target))[0]._gsap;\n},\n    _getProperty = function _getProperty(target, property, v) {\n  return (v = target[property]) && _isFunction(v) ? target[property]() : _isUndefined(v) && target.getAttribute && target.getAttribute(property) || v;\n},\n    _forEachName = function _forEachName(names, func) {\n  return (names = names.split(",")).forEach(func) || names;\n},\n    //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).\n_round = function _round(value) {\n  return Math.round(value * 100000) / 100000 || 0;\n},\n    _roundPrecise = function _roundPrecise(value) {\n  return Math.round(value * 10000000) / 10000000 || 0;\n}
1,\n    // increased precision mostly for timing values.\n_parseRelative = function _parseRelative(start, value) {\n  var operator = value.charAt(0),\n      end = parseFloat(value.substr(2));\n  start = parseFloat(start);\n  return operator === "+" ? start + end : operator === "-" ? start - end : operator === "*" ? start * end : start / end;\n},\n    _arrayContainsAny = function _arrayContainsAny(toSearch, toFind) {\n  //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.\n  var l = toFind.length,\n      i = 0;\n\n  for (; toSearch.indexOf(toFind[i]) < 0 && ++i < l;) {}\n\n  return i < l;\n},\n    _lazyRender = function _lazyRender() {\n  var l = _lazyTweens.length,\n      a = _lazyTweens.slice(0),\n      i,\n      tween;\n\n  _lazyLookup = {};\n  _lazyTweens.length = 0;\n\n  for (i = 0; i < l; i++) {\n    tween = a[i];\n    tween && tween._lazy && (tween.render(tween._lazy[0], tween._lazy[1], true)._lazy = 0);\n  }\n},\n    _isRevertWorthy = function _isRevertWorthy(animation) {\n  return !!(animation._initted || animation._startAt || animation.add);\n},\n    _lazySafeRender = function _lazySafeRender(animation, time, suppressEvents, force) {\n  _lazyTweens.length && !_reverting && _lazyRender();\n  animation.render(time, suppressEvents, force || !!(_reverting && time < 0 && _isRevertWorthy(animation)));\n  _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.\n},\n    _numericIfPossible = function _numericIfPossible(value) {\n  var n = parseFloat(value);\n  return (n || n === 0) && (value + "").match(_delimitedValueExp).length < 2 ? n : _isString(value) ? value.trim() : value;\n},\n    _passThrough = function _passThrough(p) {\n  return p;\n},\n    _setDefaults = function _setDefaults(obj, defaults) {\n  for (var p in defaults) {\n    p in obj || (obj[p] = defaults[p]);\n  }\n\n  return obj;\n},\n    _setKeyframeDefaults = function _setKeyframeDefaults(excludeDuration) {\n  return function (obj, defaults) {\n    for (var p in defaults) {\n      p in obj || p === "duration" && excludeDuration || p === "ease" || (obj[p] = defaults[p]);\n    }\n  };\n},\n    _merge = function _merge(base, toMerge) {\n  for (var p in toMerge) {\n    base[p] = toMerge[p];\n  }\n\n  return base;\n},\n    _mergeDeep = function _mergeDeep(base, toMerge) {\n  for (var p in toMerge) {\n    p !== "__proto__" && p !== "constructor" && p !== "prototype" && (base[p] = _isObject(toMerge[p]) ? _mergeDeep(base[p] || (base[p] = {}), toMerge[p]) : toMerge[p]);\n  }\n\n  return base;\n},\n    _copyExcluding = function _copyExcluding(obj, excluding) {\n  var copy = {},\n      p;\n\n  for (p in obj) {\n    p in excluding || (copy[p] = obj[p]);\n  }\n\n  return copy;\n},\n    _inheritDefaults = function _inheritDefaults(vars) {\n  var parent = vars.parent || _globalTimeline,\n      func = vars.keyframes ? _setKeyframeDefaults(_isArray(vars.keyframes)) : _setDefaults;\n\n  if (_isNotFalse(vars.inherit)) {\n    while (parent) {\n      func(vars, parent.vars.defaults);\n      parent = parent.parent || parent._dp;\n    }\n  }\n\n  return vars;\n},\n    _arraysMatch = function _arraysMatch(a1, a2) {\n  var i = a1.length,\n      match = i === a2.length;\n\n  while (match && i-- && a1[i] === a2[i]) {}\n\n  return i < 0;\n},\n    _addLinkedListItem = function _addLinkedListItem(parent, child, firstProp, lastProp, sortBy) {\n  if (firstProp === void 0) {\n    firstProp = "_first";\n  }\n\n  if (lastProp === void 0) {\n    lastProp = "_last";\n  }\n\n  var prev = parent[lastProp],\n      t;\n\n  if (sortBy) {\n    t = child[sortBy];\n\n    while (prev && prev[sortBy] > t) {\n      prev = prev._prev;\n    }\n  }\n\n  if (prev) {\n    child._next = prev._next;\n    prev._next = child;\n  } else {\n    child._next = parent[firstProp];\n    parent[firstProp] = child;\n  }\n\n  if (child._next) {\n    child._next._prev = child;\n  } else {\n    parent[lastProp] = child;\n  }\n\n  child._prev = prev;\n  child.parent = child._dp = parent;\n  return child;\n},\n    _removeLinkedListItem = function _removeLinkedListItem(parent, child, firstProp, lastProp) {\n  if (firstProp === void 0) {\n    firstProp = "_first";\n  }\n\n  if (lastProp === void 0) {\n    lastProp = "_last";\n  }\n\n  var prev = child._prev,\n      next = child._next;\n\n  if (prev) {\n    prev._next = next;\n  } else if (parent[firstProp] === child) {\n    parent[firstProp] = next;\n  }\n\n  if (next) {\n    next._prev = prev;\n  } else if (parent[lastProp] === child) {\n    parent[lastProp] = prev;\n  }\n\n  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.\n},\n    _removeFromParent = function _removeFromParent(child, onlyIfParentHasAutoRemove) {\n  child.parent && (!onlyIfParentHasAutoRemove || child.parent.autoRemoveChildren) && child.parent.remove && child.parent.remove(child);\n  child._act = 0;\n},\n    _uncache = function _uncache(animation, child) {\n  if (animation && (!child || child._end > animation._dur || child._start < 0)) {\n    // 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)\n    var a = animation;\n\n    while (a) {\n      a._dirty = 1;\n      a = a.parent;\n    }\n  }\n\n  return animation;\n},\n    _recacheAncestors = function _recacheAncestors(animation) {\n  var parent = animation.parent;\n\n  while (parent && parent.parent) {\n    //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.\n    parent._dirty = 1;\n    parent.totalDuration();\n    parent = parent.parent;\n  }\n\n  return animation;\n},\n    _rewindStartAt = function _rewindStartAt(tween, totalTime, suppressEvents, force) {\n  return tween._startAt && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween.vars.immediateRender && !tween.vars.autoRevert || tween._startAt.render(totalTime, true, force));\n},\n    _hasNoPausedAncestors = function _hasNoPausedAncestors(animation) {\n  return !animation || animation._ts && _hasNoPausedAncestors(animation.parent);\n},\n    _elapsedCycleDuration = function _elapsedCycleDuration(animation) {\n  return animation._repeat ? _animationCycle(animation._tTime, animation = animation.duration() + animation._rDelay) * animation : 0;\n},\n    // 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.\n_animationCycle = function _animationCycle(tTime, cycleDuration) {\n  var whole = Math.floor(tTime = _roundPrecise(tTime / cycleDuration));\n  return tTime && whole === tTime ? whole - 1 : whole;
1\n},\n    _parentToChildTotalTime = function _parentToChildTotalTime(parentTime, child) {\n  return (parentTime - child._start) * child._ts + (child._ts >= 0 ? 0 : child._dirty ? child.totalDuration() : child._tDur);\n},\n    _setEnd = function _setEnd(animation) {\n  return animation._end = _roundPrecise(animation._start + (animation._tDur / Math.abs(animation._ts || animation._rts || _tinyNum) || 0));\n},\n    _alignPlayhead = function _alignPlayhead(animation, totalTime) {\n  // 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.\n  var parent = animation._dp;\n\n  if (parent && parent.smoothChildTiming && animation._ts) {\n    animation._start = _roundPrecise(parent._time - (animation._ts > 0 ? totalTime / animation._ts : ((animation._dirty ? animation.totalDuration() : animation._tDur) - totalTime) / -animation._ts));\n\n    _setEnd(animation);\n\n    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.\n  }\n\n  return animation;\n},\n\n/*\n_totalTimeToTime = (clampedTotalTime, duration, repeat, repeatDelay, yoyo) => {\n\tlet cycleDuration = duration + repeatDelay,\n\t\ttime = _round(clampedTotalTime % cycleDuration);\n\tif (time > duration) {\n\t\ttime = duration;\n\t}\n\treturn (yoyo && (~~(clampedTotalTime / cycleDuration) & 1)) ? duration - time : time;\n},\n*/\n_postAddChecks = function _postAddChecks(timeline, child) {\n  var t;\n\n  if (child._time || !child._dur && child._initted || child._start < timeline._time && (child._dur || !child.add)) {\n    // 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).\n    t = _parentToChildTotalTime(timeline.rawTime(), child);\n\n    if (!child._dur || _clamp(0, child.totalDuration(), t) - child._tTime > _tinyNum) {\n      child.render(t, true);\n    }\n  } //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.\n\n\n  if (_uncache(timeline, child)._dp && timeline._initted && timeline._time >= timeline._dur && timeline._ts) {\n    //in case any of the ancestors had completed but should now be enabled...\n    if (timeline._dur < timeline.duration()) {\n      t = timeline;\n\n      while (t._dp) {\n        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.\n\n        t = t._dp;\n      }\n    }\n\n    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 w
1ould 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.\n  }\n},\n    _addToTimeline = function _addToTimeline(timeline, child, position, skipChecks) {\n  child.parent && _removeFromParent(child);\n  child._start = _roundPrecise((_isNumber(position) ? position : position || timeline !== _globalTimeline ? _parsePosition(timeline, position, child) : timeline._time) + child._delay);\n  child._end = _roundPrecise(child._start + (child.totalDuration() / Math.abs(child.timeScale()) || 0));\n\n  _addLinkedListItem(timeline, child, "_first", "_last", timeline._sort ? "_start" : 0);\n\n  _isFromOrFromStart(child) || (timeline._recent = child);\n  skipChecks || _postAddChecks(timeline, child);\n  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)\n\n  return timeline;\n},\n    _scrollTrigger = function _scrollTrigger(animation, trigger) {\n  return (_globals.ScrollTrigger || _missingPlugin("scrollTrigger", trigger)) && _globals.ScrollTrigger.create(trigger, animation);\n},\n    _attemptInitTween = function _attemptInitTween(tween, time, force, suppressEvents, tTime) {\n  _initTween(tween, time, tTime);\n\n  if (!tween._initted) {\n    return 1;\n  }\n\n  if (!force && tween._pt && !_reverting && (tween._dur && tween.vars.lazy !== false || !tween._dur && tween.vars.lazy) && _lastRenderedFrame !== _ticker.frame) {\n    _lazyTweens.push(tween);\n\n    tween._lazy = [tTime, suppressEvents];\n    return 1;\n  }\n},\n    _parentPlayheadIsBeforeStart = function _parentPlayheadIsBeforeStart(_ref) {\n  var parent = _ref.parent;\n  return parent && parent._ts && parent._initted && !parent._lock && (parent.rawTime() < 0 || _parentPlayheadIsBeforeStart(parent));\n},\n    // check parent\'s _lock because when a timeline repeats/yoyos and does its artificial wrapping, we shouldn\'t force the ratio back to 0\n_isFromOrFromStart = function _isFromOrFromStart(_ref2) {\n  var data = _ref2.data;\n  return data === "isFromStart" || data === "isStart";\n},\n    _renderZeroDurationTween = function _renderZeroDurationTween(tween, totalTime, suppressEvents, force) {\n  var prevRatio = tween.ratio,\n      ratio = totalTime < 0 || !totalTime && (!tween._start && _parentPlayheadIsBeforeStart(tween) && !(!tween._initted && _isFromOrFromStart(tween)) || (tween._ts < 0 || tween._dp._ts < 0) && !_isFromOrFromStart(tween)) ? 0 : 1,\n      // 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.\n  repeatDelay = tween._rDelay,\n      tTime = 0,\n      pt,\n      iteration,\n      prevIteration;\n\n  if (repeatDelay && tween._repeat) {\n    // in case there\'s a zero-duration tween that has a repeat with a repeatDelay\n    tTime = _clamp(0, tween._tDur, totalTime);\n    iteration = _animationCycle(tTime, repeatDelay);\n    tween._yoyo && iteration & 1 && (ratio = 1 - ratio);\n\n    if (iteration !== _animationCycle(tween._tTime, repeatDelay)) {\n      // if iteration changed\n      prevRatio = 1 - ratio;\n      tween.vars.repeatRefresh && tween._initted && tween.invalidate();\n    }\n  }\n\n  if (ratio !== prevRatio || _reverting || force || tween._zTime === _tinyNum || !totalTime && tween._zTime) {\n    if (!tween._initted && _attemptInitTween(tween, totalTime, force, suppressEvents, tTime)) {\
1n      // 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.\n      return;\n    }\n\n    prevIteration = tween._zTime;\n    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.\n\n    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.\n\n    tween.ratio = ratio;\n    tween._from && (ratio = 1 - ratio);\n    tween._time = 0;\n    tween._tTime = tTime;\n    pt = tween._pt;\n\n    while (pt) {\n      pt.r(ratio, pt.d);\n      pt = pt._next;\n    }\n\n    totalTime < 0 && _rewindStartAt(tween, totalTime, suppressEvents, true);
1\n    tween._onUpdate && !suppressEvents && _callback(tween, "onUpdate");\n    tTime && tween._repeat && !suppressEvents && tween.parent && _callback(tween, "onRepeat");\n\n    if ((totalTime >= tween._tDur || totalTime < 0) && tween.ratio === ratio) {\n      ratio && _removeFromParent(tween, 1);\n\n      if (!suppressEvents && !_reverting) {\n        _callback(tween, ratio ? "onComplete" : "onReverseComplete", true);\n\n        tween._prom && tween._prom();\n      }\n    }\n  } else if (!tween._zTime) {\n    tween._zTime = totalTime;\n  }\n},\n    _findNextPauseTween = function _findNextPauseTween(animation, prevTime, time) {\n  var child;\n\n  if (time > prevTime) {\n    child = animation._first;\n\n    while (child && child._start <= time) {\n      if (child.data === "isPause" && child._start > prevTime) {\n        return child;\n      }\n\n      child = child._next;\n    }\n  } else {\n    child = animation._last;\n\n    while (child && child._start >= time) {\n      if (child.data === "isPause" && child._start < prevTime) {\n        return child;\n      }\n\n      child = child._prev;\n    }\n  }\n},\n    _setDuration = function _setDuration(animation, duration, skipUncache, leavePlayhead) {\n  var repeat = animation._repeat,\n      dur = _roundPrecise(duration) || 0,\n      totalProgress = animation._tTime / animation._tDur;\n  totalProgress && !leavePlayhead && (animation._time *= dur / animation._dur);\n  animation._dur = dur;\n  animation._tDur = !repeat ? dur : repeat < 0 ? 1e10 : _roundPrecise(dur * (repeat + 1) + animation._rDelay * repeat);\n  totalProgress > 0 && !leavePlayhead && _alignPlayhead(animation, animation._tTime = animation._tDur * totalProgress);\n  animation.parent && _setEnd(animation);\n  skipUncache || _uncache(animation.parent, animation);\n  return animation;\n},\n    _onUpdateTotalDuration = function _onUpdateTotalDuration(animation) {\n  return animation instanceof Timeline ? _uncache(animation) : _setDuration(animation, animation._dur);\n},\n    _zeroPosition = {\n  _start: 0,\n  endTime: _emptyFunc,\n  totalDuration: _emptyFunc\n},\n    _parsePosition = function _parsePosition(animation, position, percentAnimation) {\n  var labels = animation.labels,\n      recent = animation._recent || _zeroPosition,\n      clippedDuration = animation.duration() >= _bigNum ? recent.endTime(false) : animation._dur,\n      //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.\n  i,\n      offset,\n      isPercent;\n\n  if (_isString(position) && (isNaN(position) || position in labels)) {\n    //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).\n    offset = position.charAt(0);\n    isPercent = position.substr(-1) === "%";\n    i = position.indexOf("=");\n\n    if (offset === "<" || offset === ">") {\n      i >= 0 && (position = position.replace(/=/, ""));\n      return (offset === "<" ? recent._start : recent.endTime(recent._repeat >= 0)) + (parseFloat(position.substr(1)) || 0) * (isPercent ? (i < 0 ? recent : percentAnimation).totalDuration() / 100 : 1);\n    }\n\n    if (i < 0) {\n      position in labels || (labels[position] = clippedDuration);\n      return labels[position];\n    }\n\n    offset = parseFloat(position.charAt(i - 1) + position.substr(i + 1));\n\n    if (isPercent && percentAnimation) {\n      offset = offset / 100 * (_isArray(percentAnimation) ? percentAnimation[0] : percentAnimation).totalDuration();\n    }\n\n    return i > 1 ? _parsePosition(animation, position.substr(0, i - 1), percentAnimation) + offset : clippedDuration + offset;\n  }\n\n  return position == null ? clippedDuration : +position;\n},\n    _createTweenType = function _createTweenType(type, params, timeline) {\n  var isLegacy = _isNumber(params[1]),\n      varsIndex = (isLegacy ? 2 : 1) + (type < 2 ? 0 : 1),\n      vars = params[varsIndex],\n      irVars,\n      parent;\n\n  isLegacy && (vars.duration = params[1]);\n  vars.parent = timeline;\n\n  if (type) {\n    irVars = vars;\n    parent = timeline;
1\n\n    while (parent && !("immediateRender" in irVars)) {\n      // 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.\n      irVars = parent.vars.defaults || {};\n      parent = _isNotFalse(parent.vars.inherit) && parent.parent;\n    }\n\n    vars.immediateRender = _isNotFalse(irVars.immediateRender);\n    type < 2 ? vars.runBackwards = 1 : vars.startAt = params[varsIndex - 1]; // "from" vars\n  }\n\n  return new Tween(params[0], vars, params[varsIndex + 1]);\n},\n    _conditionalReturn = function _conditionalReturn(value, func) {\n  return value || value === 0 ? func(value) : func;\n},\n    _clamp = function _clamp(min, max, value) {\n  return value < min ? min : value > max ? max : value;\n},\n    getUnit = function getUnit(value, v) {\n  return !_isString(value) || !(v = _unitExp.exec(value)) ? "" : v[1];\n},\n    // 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.\nclamp = function clamp(min, max, value) {\n  return _conditionalReturn(value, function (v) {\n    return _clamp(min, max, v);\n  });\n},\n    _slice = [].slice,\n    _isArrayLike = function _isArrayLike(value, nonEmpty) {\n  return value && _isObject(value) && "length" in value && (!nonEmpty && !value.length || value.length - 1 in value && _isObject(value[0])) && !value.nodeType && value !== _win;\n},\n    _flatten = function _flatten(ar, leaveStrings, accumulator) {\n  if (accumulator === void 0) {\n    accumulator = [];\n  }\n\n  return ar.forEach(function (value) {\n    var _accumulator;\n\n    return _isString(value) && !leaveStrings || _isArrayLike(value, 1) ? (_accumulator = accumulator).push.apply(_accumulator, toArray(value)) : accumulator.push(value);\n  }) || accumulator;\n},\n    // 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.\ntoArray = function toArray(value, scope, leaveStrings) {\n  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] : [];\n},\n    selector = function selector(value) {\n  value = toArray(value)[0] || _warn("Invalid scope") || {};\n  return function (v) {\n    var el = value.current || value.nativeElement || value;\n    return toArray(v, el.querySelectorAll ? el : el === value ? _warn("Invalid scope") || _doc.createElement("div") : value);\n  };\n},\n    shuffle = function shuffle(a) {\n  return a.sort(function () {\n    return .5 - Math.random();\n  });\n},\n    // alternative that\'s a bit faster and more reliably diverse but bigger:   for (let j, v, i = a.length; i; j = (Math.random() * i) | 0, v = a[--i], a[i] = a[j], a[j] = v); return a;\n// for distributing values across an Array. Can accept a number, a function or (most commonly) an object 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.\n
1distribute = function distribute(v) {\n  if (_isFunction(v)) {\n    return v;\n  }\n\n  var vars = _isObject(v) ? v : {\n    each: v\n  },\n      //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.\n  ease = _parseEase(vars.ease),\n      from = vars.from || 0,\n      base = parseFloat(vars.base) || 0,\n      cache = {},\n      isDecimal = from > 0 && from < 1,\n      ratios = isNaN(from) || isDecimal,\n      axis = vars.axis,\n      ratioX = from,\n      ratioY = from;\n\n  if (_isString(from)) {\n    ratioX = ratioY = {\n      center: .5,\n      edges: .5,\n      end: 1\n    }[from] || 0;\n  } else if (!isDecimal && ratios) {\n    ratioX = from[0];\n    ratioY = from[1];\n  }\n\n  return function (i, target, a) {\n    var l = (a || vars).length,\n        distances = cache[l],\n        originX,\n        originY,\n        x,\n        y,\n        d,\n        j,\n        max,\n        min,\n        wrapAt;\n\n    if (!distances) {\n      wrapAt = vars.grid === "auto" ? 0 : (vars.grid || [1, _bigNum])[1];\n\n      if (!wrapAt) {\n        max = -_bigNum;\n\n        while (max < (max = a[wrapAt++].getBoundingClientRect().left) && wrapAt < l) {}\n\n        wrapAt < l && wrapAt--;\n      }\n\n      distances = cache[l] = [];\n      originX = ratios ? Math.min(wrapAt, l) * ratioX - .5 : from % wrapAt;\n      originY = wrapAt === _bigNum ? 0 : ratios ? l * ratioY / wrapAt - .5 : from / wrapAt | 0;\n      max = 0;\n      min = _bigNum;\n\n      for (j = 0; j < l;
1 j++) {\n        x = j % wrapAt - originX;\n        y = originY - (j / wrapAt | 0);\n        distances[j] = d = !axis ? _sqrt(x * x + y * y) : Math.abs(axis === "y" ? y : x);\n        d > max && (max = d);\n        d < min && (min = d);\n      }\n\n      from === "random" && shuffle(distances);\n      distances.max = max - min;\n      distances.min = min;\n      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);\n      distances.b = l < 0 ? base - l : base;\n      distances.u = getUnit(vars.amount || vars.each) || 0; //unit\n\n      ease = ease && l < 0 ? _invertEase(ease) : ease;\n    }\n\n    l = (distances[i] - distances.min) / distances.max || 0;\n    return _roundPrecise(distances.b + (ease ? ease(l) : l) * distances.v) + distances.u; //round in order to work around floating point errors\n  };\n},\n    _roundModifier = function _roundModifier(v) {\n  //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.\n  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())\n\n  return function (raw) {\n    var n = _roundPrecise(Math.round(parseFloat(raw) / v) * v * p);\n\n    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!\n  };\n},\n    snap = function snap(snapTo, value) {\n  var isArray = _isArray(snapTo),\n      radius,\n      is2D;\n\n  if (!isArray && _isObject(snapTo)) {\n    radius = isArray = snapTo.radius || _bigNum;\n\n    if (snapTo.values) {\n      snapTo = toArray(snapTo.values);\n\n      if (is2D = !_isNumber(snapTo[0])) {\n        radius *= radius; //performance optimization so we don\'t have to Math.sqrt() in the loop.\n      }\n    } else {\n      snapTo = _roundModifier(snapTo.increment);\n    }\n  }\n\n  return _conditionalReturn(value, !isArray ? _roundModifier(snapTo) : _isFunction(snapTo) ? function (raw) {\n    is2D = snapTo(raw);\n    return Math.abs(is2D - raw) <= radius ? is2D : raw;\n  } : function (raw) {\n    var x = parseFloat(is2D ? raw.x : raw),\n        y = parseFloat(is2D ? raw.y : 0),\n        min = _bigNum,\n        closest = 0,\n        i = snapTo.length,\n        dx,\n        dy;\n\n    while (i--) {\n      if (is2D) {\n        dx = snapTo[i].x - x;\n        dy = snapTo[i].y - y;\n        dx = dx * dx + dy * dy;\n      } else {\n        dx = Math.abs(snapTo[i] - x);\n      }\n\n      if (dx < min) {\n        min = dx;\n        closest = i;\n      }\n    }\n\n    closest = !radius || min <= radius ? snapTo[closest] : raw;\n    return is2D || closest === raw || _isNumber(raw) ? closest : closest + getUnit(raw);\n  });\n},\n    random = function random(min, max, roundingIncrement, returnFunction) {\n  return _conditionalReturn(_isArray(min) ? !max : roundingIncrement === true ? !!(roundingIncrement = 0) : !returnFunction, function () {\n    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;\n  });\n},\n    pipe = function pipe() {\n  for (var _len = arguments.length, functions = new Array(_len), _key = 0; _key < _len; _key++) {\n    functions[_key] = arguments[_key];\n  }\n\n  return function (value) {\n    return functions.reduce(function (v, f) {\n      return f(v);\n    }, value);\n  };\n},\n    unitize = function unitize(func, unit) {\n  return function (value) {\n    return func(parseFloat(value)) + (unit || getUnit(value));\n  };\n},\n    normalize = function normalize(min, max, value) {\n  return mapRange(min, max, 0, 1, value);\n},\n    _wrapArray = function _wrapArray(a, wrapper, value) {\n  return _conditionalReturn(value, function (index) {\n    return a[~~wrapper(index)];\n  });\n},\n    wrap = function wrap(min, max, value) {\n  // NOTE: wrap() CANNOT be an arrow function! A very odd compiling bug 
1causes problems (unrelated to GSAP).\n  var range = max - min;\n  return _isArray(min) ? _wrapArray(min, wrap(0, min.length), max) : _conditionalReturn(value, function (value) {\n    return (range + (value - min) % range) % range + min;\n  });\n},\n    wrapYoyo = function wrapYoyo(min, max, value) {\n  var range = max - min,\n      total = range * 2;\n  return _isArray(min) ? _wrapArray(min, wrapYoyo(0, min.length - 1), max) : _conditionalReturn(value, function (value) {\n    value = (total + (value - min) % total) % total || 0;\n    return min + (value > range ? total - value : value);\n  });\n},\n    _replaceRandom = function _replaceRandom(s) {\n  return s.replace(_randomExp, function (match) {\n    //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])\n    var arIndex = match.indexOf("[") + 1,\n        values = match.substring(arIndex || 7, arIndex ? match.indexOf("]") : match.length - 1).split(_commaDelimExp);\n    return random(arIndex ? values : +values[0], arIndex ? 0 : +values[1], +values[2] || 1e-5);\n  });\n},\n    mapRange = function mapRange(inMin, inMax, outMin, outMax, value) {\n  var inRange = inMax - inMin,\n      outRange = outMax - outMin;\n  return _conditionalReturn(value, function (value) {\n    return outMin + ((value - inMin) / inRange * outRange || 0);\n  });\n},\n    interpolate = function interpolate(start, end, progress, mutate) {\n  var func = isNaN(start + end) ? 0 : function (p) {\n    return (1 - p) * start + p * end;\n  };\n\n  if (!func) {\n    var isString = _isString(start),\n        master = {},\n        p,\n        i,\n        interpolators,\n        l,\n        il;\n\n    progress === true && (mutate = 1) && (progress = null);\n\n    if (isString) {\n      start = {\n        p: start\n      };\n      end = {\n        p: end\n      };\n    } else if (_isArray(start) && !_isArray(end)) {\n      interpolators = [];\n      l = start.length;\n      il = l - 2;\n\n      for (i = 1; i < l; i++) {\n        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.\n      }\n\n      l--;\n\n      func = function func(p) {\n        p *= l;\n        var i = Math.min(il, ~~p);\n        return interpolators[i](p - i);\n      };\n\n      progress = end;\n    } else if (!mutate) {\n      start = _merge(_isArray(start) ? [] : {}, start);\n    }\n\n    if (!interpolators) {\n      for (p in end) {\n        _addPropTween.call(master, start, p, "get", end[p]);\n      }\n\n      func = function func(p) {\n        return _renderPropTweens(p, master) || (isString ? start.p : start);\n      };\n    }\n  }\n\n  return _conditionalReturn(progress, func);\n},\n    _getLabelInDirection = function _getLabelInDirection(timeline, fromTime, backward) {\n  //used for nextLabel() and previousLabel()\n  var labels = timeline.labels,\n      min = _bigNum,\n      p,\n      distance,\n      label;\n\n  for (p in labels) {\n    distance = labels[p] - fromTime;\n\n    if (distance < 0 === !!backward && distance && min > (distance = Math.abs(distance))) {\n      label = p;\n      min = distance;\n    }\n  }\n\n  return label;\n},\n    _callback = function _callback(animation, type, executeLazyFirst) {\n  var v = animation.vars,\n      callback = v[type],\n      prevContext = _context,\n      context = animation._ctx,\n      params,\n      scope,\n      result;\n\n  if (!callback) {\n    return;\n  }\n\n  params = v[type + "Params"];\n  scope = v.callbackScope || animation;\n  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.\n\n  context && (_context = context);\n  result = params ? callback.apply(scope, params) : callback.call(scope);\n  _context = prevContext;\n  return result;\n}
1,\n    _interrupt = function _interrupt(animation) {\n  _removeFromParent(animation);\n\n  animation.scrollTrigger && animation.scrollTrigger.kill(!!_reverting);\n  animation.progress() < 1 && _callback(animation, "onInterrupt");\n  return animation;\n},\n    _quickTween,\n    _registerPluginQueue = [],\n    _createPlugin = function _createPlugin(config) {\n  if (!config) return;\n  config = !config.name && config["default"] || config; // UMD packaging wraps things oddly, so for example MotionPathHelper becomes {MotionPathHelper:MotionPathHelper, default:MotionPathHelper}.\n\n  if (_windowExists() || config.headless) {\n    // edge case: some build tools may pass in a null/undefined value\n    var name = config.name,\n        isFunc = _isFunction(config),\n        Plugin = name && !isFunc && config.init ? function () {\n      this._props = [];\n    } : config,\n        //in case someone passes in an object that\'s not a plugin, like CustomEase\n    instanceDefaults = {\n      init: _emptyFunc,\n      render: _renderPropTweens,\n      add: _addPropTween,\n      kill: _killPropTweensOf,\n      modifier: _addPluginModifier,\n      rawVars: 0\n    },\n        statics = {\n      targetTest: 0,\n      get: 0,\n      getSetter: _getSetter,\n      aliases: {},\n      register: 0\n    };\n\n    _wake();\n\n    if (config !== Plugin) {\n      if (_plugins[name]) {\n        return;\n      }\n\n      _setDefaults(Plugin, _setDefaults(_copyExcluding(config, instanceDefaults), statics)); //static methods\n\n\n      _merge(Plugin.prototype, _merge(instanceDefaults, _copyExcluding(config, statics))); //instance methods\n\n\n      _plugins[Plugin.prop = name] = Plugin;\n\n      if (config.targetTest) {\n        _harnessPlugins.push(Plugin);\n\n        _reservedProps[name] = 1;\n      }\n\n      name = (name === "css" ? "CSS" : name.charAt(0).toUpperCase() + name.substr(1)) + "Plugin"; //for the global name. "motionPath" should become MotionPathPlugin\n    }\n\n    _addGlobal(name, Plugin);\n\n    config.register && config.register(gsap, Plugin, PropTween);\n  } else {\n    _registerPluginQueue.push(config);\n  }\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * COLORS\n * --------------------------------------------------------------------------------------\n */\n_255 = 255,\n    _colorLookup = {\n  aqua: [0, _255, _255],\n  lime: [0, _255, 0],\n  silver: [192, 192, 192],\n  black: [0, 0, 0],\n  maroon: [128, 0, 0],\n  teal: [0, 128, 128],\n  blue: [0, 0, _255],\n  navy: [0, 0, 128],\n  white: [_255, _255, _255],\n  olive: [128, 128, 0],\n  yellow: [_255, _255, 0],\n  orange: [_255, 165, 0],\n  gray: [128, 128, 128],\n  purple: [128, 0, 128],\n  green: [0, 128, 0],\n  red: [_255, 0, 0],\n  pink: [_255, 192, 203],\n  cyan: [0, _255, _255],\n  transparent: [_255, _255, _255, 0]\n},\n    // possible future idea to replace the hard-coded color name values - put this in the ticker.wake() where we set the _doc:\n// let ctx = _doc.createElement("canvas").getContext("2d");\n// _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)});\n_hue = function _hue(h, m1, m2) {\n  h += h < 0 ? 1 : h > 1 ? -1 : 0;\n  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;\n},\n    splitColor = function splitColor(v, toHSL, forceAlpha) {\n  var a = !v ? _colorLookup.black : _isNumber(v) ? [v >> 16, v >> 8 & _255, v & _255] : 0,\n      r,\n      g,\n      b,\n      h,\n      s,\n      l,\n      max,\n      min,\n      d,\n      wasHSL;\n\n  if (!a) {\n    if (v.substr(-1) === ",") {\n      //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.\n      v = v.substr(0, v.length - 1);\n    }\n\n    if (_colorLookup[v]) {\n      a = _colorLookup[v];\n    } else if (v.charAt(0) === "#") {\n      if (v.length < 6) {\n        //for shorthand like #9F0 or #9F0F (could have alpha)\n        r = v.charAt(1);\n        g = v.charAt(2);\n        b = v.charAt(3);\n        v = "#" + r + r + g + g + b + b + (v.length === 5 ? v.charAt(4) + v.charAt(4) : "");\n      }\n\n      if (v.length === 9) {\n        // hex with alpha, like #fd5e53ff\n        a = parseInt(v.substr(1, 6), 16);\n        return [a >> 16, a >>
1 8 & _255, a & _255, parseInt(v.substr(7), 16) / 255];\n      }\n\n      v = parseInt(v.substr(1), 16);\n      a = [v >> 16, v >> 8 & _255, v & _255];\n    } else if (v.substr(0, 3) === "hsl") {\n      a = wasHSL = v.match(_strictNumExp);\n\n      if (!toHSL) {\n        h = +a[0] % 360 / 360;\n        s = +a[1] / 100;\n        l = +a[2] / 100;\n        g = l <= .5 ? l * (s + 1) : l + s - l * s;\n        r = l * 2 - g;\n        a.length > 3 && (a[3] *= 1); //cast as number\n\n        a[0] = _hue(h + 1 / 3, r, g);\n        a[1] = _hue(h, r, g);\n        a[2] = _hue(h - 1 / 3, r, g);\n      } else if (~v.indexOf("=")) {\n        //if relative values are found, just return the raw strings with the relative prefixes in place.\n        a = v.match(_numExp);\n        forceAlpha && a.length < 4 && (a[3] = 1);\n        return a;\n      }\n    } else {\n      a = v.match(_strictNumExp) || _colorLookup.transparent;\n    }\n\n    a = a.map(Number);\n  }\n\n  if (toHSL && !wasHSL) {\n    r = a[0] / _255;\n    g = a[1] / _255;\n    b = a[2] / _255;\n    max = Math.max(r, g, b);\n    min = Math.min(r, g, b);\n    l = (max + min) / 2;\n\n    if (max === min) {\n      h = s = 0;\n    } else {\n      d = max - min;\n      s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n      h = max === r ? (g - b) / d + (g < b ? 6 : 0) : max === g ? (b - r) / d + 2 : (r - g) / d + 4;\n      h *= 60;\n    }\n\n    a[0] = ~~(h + .5);\n    a[1] = ~~(s * 100 + .5);\n    a[2] = ~~(l * 100 + .5);\n  }\n\n  forceAlpha && a.length < 4 && (a[3] = 1);\n  return a;\n},\n    _colorOrderData = function _colorOrderData(v) {\n  // 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()\n  var values = [],\n      c = [],\n      i = -1;\n  v.split(_colorExp).forEach(function (v) {\n    var a = v.match(_numWithUnitExp) || [];\n    values.push.apply(values, a);\n    c.push(i += a.length + 1);\n  });\n  values.c = c;\n  return values;\n},\n    _formatColors = function _formatColors(s, toHSL, orderMatchData) {\n  var result = "",\n      colors = (s + result).match(_colorExp),\n      type = toHSL ? "hsla(" : "rgba(",\n      i = 0,\n      c,\n      shell,\n      d,\n      l;\n\n  if (!colors) {\n    return s;\n  }\n\n  colors = colors.map(function (color) {\n    return (color = splitColor(color, toHSL, 1)) && type + (toHSL ? color[0] + "," + color[1] + "%," + color[2] + "%," + color[3] : color.join(",")) + ")";\n  });\n\n  if (orderMatchData) {\n    d = _colorOrderData(s);\n    c = orderMatchData.c;\n\n    if (c.join(result) !== d.c.join(result)) {\n      shell = s.replace(_colorExp, "1").split(_numWithUnitExp);\n      l = shell.length - 1;\n\n      for (; i < l; i++) {\n        result += shell[i] + (~c.indexOf(i) ? colors.shift() || type + "0,0,0,0)" : (d.length ? d : colors.length ? colors : orderMatchData).shift());\n      }\n    }\n  }\n\n  if (!shell) {\n    shell = s.split(_colorExp);\n    l = shell.length - 1;\n\n    for (; i < l; i++) {\n      result += shell[i] + colors[i];\n    }\n  }\n\n  return result + shell[l];\n},\n    _colorExp = function () {\n  var s = "(?:\\\\b(?:(?:rgb|rgba|hsl|hsla)\\\\(.+?\\\\))|\\\\B#(?:[0-9a-f]{3,4}){1,2}\\\\b",\n      //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.,\n  p;\n\n  for (p in _colorLookup) {\n    s += "|" + p + "\\\\b";\n  }\n\n  return new RegExp(s + ")", "gi");\n}(),\n    _hslExp = /hsl[a]?\\(/,\n    _colorStringFilter = function _colorStringFilter(a) {\n  var combined = a.join(" "),\n      toHSL;\n  _colorExp.lastIndex = 0;\n\n  if (_colorExp.test(combined)) {\n    toHSL = _hslExp.test(combined);\n    a[1] = _formatColors(a[1], toHSL);\n    a[0] = _formatColors(a[0], toHSL, _colorOrderData(a[1])); // make sure the order of numbers/colors match with the END value.\n\n    return true;\n  }\n},\n\n/*\n * --------------------------------------------------------------------------------------\n * TICKER\n * --------------------------------------------------------------------------------------\n */\n_tickerActive,\n    _ticker = function () {\n  var _getTime = Date.now,\n      _lagThreshold = 500,\n      _adjustedLag = 33,\n      _startTime = _getTime(),\n      _lastUpdate = _startTime,\n      _gap = 1000 / 240,\n      _nextTime = _gap,\n      _listeners = [],\n      _id,\n      _req,\n      _raf,\n      _self,\n      _delta,\n      _i,\n      _tick = function _tick(v) {\n    var elapsed 
1= _getTime() - _lastUpdate,\n        manual = v === true,\n        overlap,\n        dispatch,\n        time,\n        frame;\n\n    (elapsed > _lagThreshold || elapsed < 0) && (_startTime += elapsed - _adjustedLag);\n    _lastUpdate += elapsed;\n    time = _lastUpdate - _startTime;\n    overlap = time - _nextTime;\n\n    if (overlap > 0 || manual) {\n      frame = ++_self.frame;\n      _delta = time - _self.time * 1000;\n      _self.time = time = time / 1000;\n      _nextTime += overlap + (overlap >= _gap ? 4 : _gap - overlap);\n      dispatch = 1;\n    }\n\n    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.\n\n    if (dispatch) {\n      for (_i = 0; _i < _listeners.length; _i++) {\n        // 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.\n        _listeners[_i](time, _delta, frame, v);\n      }\n    }\n  };\n\n  _self = {\n    time: 0,\n    frame: 0,\n    tick: function tick() {\n      _tick(true);\n    },\n    deltaRatio: function deltaRatio(fps) {\n      return _delta / (1000 / (fps || 60));\n    },\n    wake: function wake() {\n      if (_coreReady) {\n        if (!_coreInitted && _windowExists()) {\n          _win = _coreInitted = window;\n          _doc = _win.document || {};\n          _globals.gsap = gsap;\n          (_win.gsapVersions || (_win.gsapVersions = [])).push(gsap.version);\n\n          _install(_installScope || _win.GreenSockGlobals || !_win.gsap && _win || {});\n\n          _registerPluginQueue.forEach(_createPlugin);\n        }\n\n        _raf = typeof requestAnimationFrame !== "undefined" && requestAnimationFrame;\n        _id && _self.sleep();\n\n        _req = _raf || function (f) {\n          return setTimeout(f, _nextTime - _self.time * 1000 + 1 | 0);\n        };\n\n        _tickerActive = 1;\n\n        _tick(2);\n      }\n    },\n    sleep: function sleep() {\n      (_raf ? cancelAnimationFrame : clearTimeout)(_id);\n      _tickerActive = 0;\n      _req = _emptyFunc;\n    },\n    lagSmoothing: function lagSmoothing(threshold, adjustedLag) {\n      _lagThreshold = threshold || Infinity; // zero should be interpreted as basically unlimited\n\n      _adjustedLag = Math.min(adjustedLag || 33, _lagThreshold);\n    },\n    fps: function fps(_fps) {\n      _gap = 1000 / (_fps || 240);\n      _nextTime = _self.time * 1000 + _gap;\n    },\n    add: function add(callback, once, prioritize) {\n      var func = once ? function (t, d, f, v) {\n        callback(t, d, f, v);\n\n        _self.remove(func);\n      } : callback;\n\n      _self.remove(callback);\n\n      _listeners[prioritize ? "unshift" : "push"](func);\n\n      _wake();\n\n      return func;\n    },\n    remove: function remove(callback, i) {\n      ~(i = _listeners.indexOf(callback)) && _listeners.splice(i, 1) && _i >= i && _i--;\n    },\n    _listeners: _listeners\n  };\n  return _self;\n}(),\n    _wake = function _wake() {\n  return !_tickerActive && _ticker.wake();\n},\n    //also ensures the core classes are initialized.\n\n/*\n* -------------------------------------------------\n* EASING\n* -------------------------------------------------\n*/\n_easeMap = {},\n    _customEaseExp = /^[\\d.\\-M][\\d.\\-,\\s]/,\n    _quotesExp = /["\']/g,\n    _parseObjectInString = function _parseObjectInString(value) {\n  //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.\n  var obj = {},\n      split = value.substr(1, value.length - 3).split(":"),\n      key = split[0],\n      i = 1,\n      l = split.length,\n      index,\n      val,\n      parsedVal;\n\n  for (; i < l;
1 i++) {\n    val = split[i];\n    index = i !== l - 1 ? val.lastIndexOf(",") : val.length;\n    parsedVal = val.substr(0, index);\n    obj[key] = isNaN(parsedVal) ? parsedVal.replace(_quotesExp, "").trim() : +parsedVal;\n    key = val.substr(index + 1).trim();\n  }\n\n  return obj;\n},\n    _valueInParentheses = function _valueInParentheses(value) {\n  var open = value.indexOf("(") + 1,\n      close = value.indexOf(")"),\n      nested = value.indexOf("(", open);\n  return value.substring(open, ~nested && nested < close ? value.indexOf(")", close + 1) : close);\n},\n    _configEaseFromString = function _configEaseFromString(name) {\n  //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).\n  var split = (name + "").split("("),\n      ease = _easeMap[split[0]];\n  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;\n},\n    _invertEase = function _invertEase(ease) {\n  return function (p) {\n    return 1 - ease(1 - p);\n  };\n},\n    _parseEase = function _parseEase(ease, defaultEase) {\n  return !ease ? defaultEase : (_isFunction(ease) ? ease : _easeMap[ease] || _configEaseFromString(ease)) || defaultEase;\n},\n    _insertEase = function _insertEase(names, easeIn, easeOut, easeInOut) {\n  if (easeOut === void 0) {\n    easeOut = function easeOut(p) {\n      return 1 - easeIn(1 - p);\n    };\n  }\n\n  if (easeInOut === void 0) {\n    easeInOut = function easeInOut(p) {\n      return p < .5 ? easeIn(p * 2) / 2 : 1 - easeIn((1 - p) * 2) / 2;\n    };\n  }\n\n  var ease = {\n    easeIn: easeIn,\n    easeOut: easeOut,\n    easeInOut: easeInOut\n  },\n      lowercaseName;\n\n  _forEachName(names, function (name) {\n    _easeMap[name] = _globals[name] = ease;\n    _easeMap[lowercaseName = name.toLowerCase()] = easeOut;\n\n    for (var p in ease) {\n      _easeMap[lowercaseName + (p === "easeIn" ? ".in" : p === "easeOut" ? ".out" : ".inOut")] = _easeMap[name + "." + p] = ease[p];\n    }\n  });\n\n  return ease;\n},\n    _easeInOutFromOut = function _easeInOutFromOut(easeOut) {\n  return function (p) {\n    return p < .5 ? (1 - easeOut(1 - p * 2)) / 2 : .5 + easeOut((p - .5) * 2) / 2;\n  };\n},\n    _configElastic = function _configElastic(type, amplitude, period) {\n  var p1 = amplitude >= 1 ? amplitude : 1,\n      //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.\n  p2 = (period || (type ? .3 : .45)) / (amplitude < 1 ? amplitude : 1),\n      p3 = p2 / _2PI * (Math.asin(1 / p1) || 0),\n      easeOut = function easeOut(p) {\n    return p === 1 ? 1 : p1 * Math.pow(2, -10 * p) * _sin((p - p3) * p2) + 1;\n  },\n      ease = type === "out" ? easeOut : type === "in" ? function (p) {\n    return 1 - easeOut(1 - p);\n  } : _easeInOutFromOut(easeOut);\n\n  p2 = _2PI / p2; //precalculate to optimize\n\n  ease.config = function (amplitude, period) {\n    return _configElastic(type, amplitude, period);\n  };\n\n  return ease;\n},\n    _configBack = function _configBack(type, overshoot) {\n  if (overshoot === void 0) {\n    overshoot = 1.70158;\n  }\n\n  var easeOut = function easeOut(p) {\n    return p ? --p * p * ((overshoot + 1) * p + overshoot) + 1 : 0;\n  },\n      ease = type === "out" ? easeOut : type === "in" ? function (p) {\n    return 1 - easeOut(1 - p);\n  } : _easeInOutFromOut(easeOut);\n\n  ease.config = function (overshoot) {\n    return _configBack(type, overshoot);\n  };\n\n  return ease;\n}; // 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.\n// _weightedEase = ratio => {\n// \tlet y = 0.5 + ratio / 2;\n// \treturn p => (2 * (1 - p) * p * y + p * p);\n// },\n// 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.\n// _weightedEaseStrong = ratio => {\n// \tratio = .5 + ratio / 2;\n// \tlet o = 1 / 3 * (ratio < .5 ? ratio : 1 - ratio),\n// \t\tb = ratio - o,\n// \t\tc = ratio + o;\n// \treturn p => p === 1 ? p : 3 * b * (1 - p) * (1 - p) * p + 3 * c * (1 - p) * p * p + p * p * p;\n// };\n\n\n_forEachName("Linear,Quad,Cubic,Quart,Quint,Strong", function (name, i) {\n  var power = i < 5 ? i + 1 : i;\n\n  _insertEase(name + ",Power" + (power - 1), i ? function (p) {\n    return Math.pow(p, power);\n  }
1 : function (p) {\n    return p;\n  }, function (p) {\n    return 1 - Math.pow(1 - p, power);\n  }, function (p) {\n    return p < .5 ? Math.pow(p * 2, power) / 2 : 1 - Math.pow((1 - p) * 2, power) / 2;\n  });\n});\n\n_easeMap.Linear.easeNone = _easeMap.none = _easeMap.Linear.easeIn;\n\n_insertEase("Elastic", _configElastic("in"), _configElastic("out"), _configElastic());\n\n(function (n, c) {\n  var n1 = 1 / c,\n      n2 = 2 * n1,\n      n3 = 2.5 * n1,\n      easeOut = function easeOut(p) {\n    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;\n  };\n\n  _insertEase("Bounce", function (p) {\n    return 1 - easeOut(1 - p);\n  }, easeOut);\n})(7.5625, 2.75);\n\n_insertEase("Expo", function (p) {\n  return Math.pow(2, 10 * (p - 1)) * p + p * p * p * p * p * p * (1 - p);\n}); // previously 2 ** (10 * (p - 1)) but that doesn\'t end up with the value quite at the right spot so we do a blended ease to ensure it lands where it should perfectly.\n\n\n_insertEase("Circ", function (p) {\n  return -(_sqrt(1 - p * p) - 1);\n});\n\n_insertEase("Sine", function (p) {\n  return p === 1 ? 1 : -_cos(p * _HALF_PI) + 1;\n});\n\n_insertEase("Back", _configBack("in"), _configBack("out"), _configBack());\n\n_easeMap.SteppedEase = _easeMap.steps = _globals.SteppedEase = {\n  config: function config(steps, immediateStart) {\n    if (steps === void 0) {\n      steps = 1;\n    }\n\n    var p1 = 1 / steps,\n        p2 = steps + (immediateStart ? 0 : 1),\n        p3 = immediateStart ? 1 : 0,\n        max = 1 - _tinyNum;\n    return function (p) {\n      return ((p2 * _clamp(0, max, p) | 0) + p3) * p1;\n    };\n  }\n};\n_defaults.ease = _easeMap["quad.out"];\n\n_forEachName("onComplete,onUpdate,onStart,onRepeat,onReverseComplete,onInterrupt", function (name) {\n  return _callbackNames += name + "," + name + "Params,";\n});\n/*\n * --------------------------------------------------------------------------------------\n * CACHE\n * --------------------------------------------------------------------------------------\n */\n\n\nvar GSCache = function GSCache(target, harness) {\n  this.id = _gsID++;\n  target._gsap = this;\n  this.target = target;\n  this.harness = harness;\n  this.get = harness ? harness.get : _getProperty;\n  this.set = harness ? harness.getSetter : _getSetter;\n};\n/*\n * --------------------------------------------------------------------------------------\n * ANIMATION\n * --------------------------------------------------------------------------------------\n */\n\nvar Animation = /*#__PURE__*/function () {\n  function Animation(vars) {\n    this.vars = vars;\n    this._delay = +vars.delay || 0;\n\n    if (this._repeat = vars.repeat === Infinity ? -2 : vars.repeat || 0) {\n      // 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.\n      this._rDelay = vars.repeatDelay || 0;\n      this._yoyo = !!vars.yoyo || !!vars.yoyoEase;\n    }\n\n    this._ts = 1;\n\n    _setDuration(this, +vars.duration, 1, 1);\n\n    this.data = vars.data;\n\n    if (_context) {\n      this._ctx = _context;\n\n      _context.data.push(this);\n    }\n\n    _tickerActive || _ticker.wake();\n  }\n\n  var _proto = Animation.prototype;\n\n  _proto.delay = function delay(value) {\n    if (value || value === 0) {\n      this.parent && this.parent.smoothChildTiming && this.startTime(this._start + value - this._delay);\n      this._delay = value;\n      return this;\n    }\n\n    return this._delay;\n  };\n\n  _proto.duration = function duration(value) {\n    return arguments.length ? this.totalDuration(this._repeat > 0 ? value + (value + this._rDelay) * this._repeat : value) : this.totalDuration() && this._dur;\n  };\n\n  _proto.totalDuration = function totalDuration(value) {\n    if (!arguments.length) {\n      return this._tDur;\n    }\n\n    this._dirty = 0;\n    return _setDuration(this, this._repeat < 0 ? value : (value - this._repeat * this._rDelay) / (this._repeat + 1));\n  };\n\n  _proto.totalTime = function totalTime(_totalTime, suppressEvents) {\n    _wake();\n\n    if (!arguments.length) {\n      return this._tTime;\n    }\n\n    var parent = this._dp;\n\n    if (parent && parent.smoothChildTiming && this._ts) {\n      _alignPlayhead(this, _totalTime);\n\n      !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.\n      //in case any of the ancestor timelines had completed but should now be enabled, we should reset the
1ir 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.\n\n      while (parent && parent.parent) {\n        if (parent.parent._time !== parent._start + (parent._ts >= 0 ? parent._tTime / parent._ts : (parent.totalDuration() - parent._tTime) / -parent._ts)) {\n          parent.totalTime(parent._tTime, true);\n        }\n\n        parent = parent.parent;\n      }\n\n      if (!this.parent && this._dp.autoRemoveChildren && (this._ts > 0 && _totalTime < this._tDur || this._ts < 0 && _totalTime > 0 || !this._tDur && !_totalTime)) {\n        //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.\n        _addToTimeline(this._dp, this, this._start - this._delay);\n      }\n    }\n\n    if (this._tTime !== _totalTime || !this._dur && !suppressEvents || this._initted && Math.abs(this._zTime) === _tinyNum || !this._initted && this._dur && _totalTime || !_totalTime && !this._initted && (this.add || this._ptLookup)) {\n      // 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)\n      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\n      //if (!this._lock) { // avoid endless recursion (not sure we need this yet or if it\'s worth the performance hit)\n      //   this._lock = 1;\n\n      _lazySafeRender(this, _totalTime, suppressEvents); //   this._lock = 0;\n      //}\n\n    }\n\n    return this;\n  };\n\n  _proto.time = function time(value, suppressEvents) {\n    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!\n  };\n\n  _proto.totalProgress = function totalProgress(value, suppressEvents) {\n    return arguments.length ? this.totalTime(this.totalDuration() * value, suppressEvents) : this.totalDuration() ? Math.min(1, this._tTime / this._tDur) : this.rawTime() >= 0 && this._initted ? 1 : 0;\n  };\n\n  _proto.progress = function progress(value, suppressEvents) {\n    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;\n  };\n\n  _proto.iteration = function iteration(value, suppressEvents) {\n    var cycleDuration = this.duration() + this._rDelay;\n\n    return arguments.length ? this.totalTime(this._time + (value - 1) * cycleDuration, suppressEvents) : this._repeat ? _animationCycle(this._tTime, cycleDuration) + 1 : 1;\n  } // potential future addition:\n  // isPlayingBackwards() {\n  // \tlet animation = this,\n  // \t\torientation = 1; // 1 = forward, -1 = backward\n  // \twhile (animation) {\n  // \t\torientation *= animation.reversed() || (animation.repeat() && !(animation.iteration() & 1)) ? -1 : 1;\n  // \t\tanimation = animation.parent;\n  // \t}\n  // \treturn orientation < 0;\n  // }\n  ;\n\n  _proto.timeScale = function timeScale(value, suppressEvents) {\n    if (!arguments.length) {\n      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.\n    }\n\n    if (this._rts === value) {\n      return this;\n    }\n\n    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.\n    // future addition? Up side: fast and minimal file size. Down side: only w
1orks on this animation; if a timeline is reversed, for example, its childrens\' onReverse wouldn\'t get called.\n    //(+value < 0 && this._rts >= 0) && _callback(this, "onReverse", true);\n    // 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.\n\n    this._rts = +value || 0;\n    this._ts = this._ps || value === -_tinyNum ? 0 : this._rts; // _ts is the functional timeScale which would be 0 if the animation is paused.\n\n    this.totalTime(_clamp(-Math.abs(this._delay), this.totalDuration(), tTime), suppressEvents !== false);\n\n    _setEnd(this); // if parent.smoothChildTiming was false, the end time didn\'t get updated in the _alignPlayhead() method, so do it here.\n\n\n    return _recacheAncestors(this);\n  };\n\n  _proto.paused = function paused(value) {\n    if (!arguments.length) {\n      return this._ps;\n    } // possible future addition - if an animation is removed from its parent and then .restart() or .play() or .resume() is called, perhaps we should force it back into the globalTimeline but be careful because what if it\'s already at its end? We don\'t want it to just persist forever and not get released for GC.\n    // !this.parent && !value && this._tTime < this._tDur && this !== _globalTimeline && _globalTimeline.add(this);\n\n\n    if (this._ps !== value) {\n      this._ps = value;\n\n      if (value) {\n        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.\n\n        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)\n      } else {\n        _wake();\n\n        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.\n\n        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.\n      }\n    }\n\n    return this;\n  };\n\n  _proto.startTime = function startTime(value) {\n    if (arguments.length) {\n      this._start = _roundPrecise(value);\n      var parent = this.parent || this._dp;\n      parent && (parent._sort || !this.parent) && _addToTimeline(parent, this, this._start - this._delay);\n      return this;\n    }\n\n    return this._start;\n  };\n\n  _proto.endTime = function endTime(includeRepeats) {\n    return this._start + (_isNotFalse(includeRepeats) ? this.totalDuration() : this.duration()) / Math.abs(this._ts || 1);\n  };\n\n  _proto.rawTime = function rawTime(wrapRepeats) {\n    var parent = this.parent || this._dp; // _dp = detached parent\n\n    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);\n  };\n\n  _proto.revert = function revert(config) {\n    if (config === void 0) {\n      config = _revertConfig;\n    }\n\n    var prevIsReverting = _reverting;\n    _reverting = config;\n\n    if (_isRevertWorthy(this)) {\n      this.timeline && this.timeline.revert(config);\n      this.totalTime(-0.01, config.suppressEvents);\n    }\n\n    this.data !== "nested" && config.kill !== false && this.kill();\n    _reverting = prevIsReverting;\n    return this;\n  };\n\n  _proto.globalTime = function globalTime(rawTime) {\n    var animation = this,\n        time = arguments.length ? rawTime : animation.rawTime();\n\n    while (animation) {\n      time = animation._start + time / (Math.abs(animation._ts) || 1
1);\n      animation = animation._dp;\n    }\n\n    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().\n  };\n\n  _proto.repeat = function repeat(value) {\n    if (arguments.length) {\n      this._repeat = value === Infinity ? -2 : value;\n      return _onUpdateTotalDuration(this);\n    }\n\n    return this._repeat === -2 ? Infinity : this._repeat;\n  };\n\n  _proto.repeatDelay = function repeatDelay(value) {\n    if (arguments.length) {\n      var time = this._time;\n      this._rDelay = value;\n\n      _onUpdateTotalDuration(this);\n\n      return time ? this.time(time) : this;\n    }\n\n    return this._rDelay;\n  };\n\n  _proto.yoyo = function yoyo(value) {\n    if (arguments.length) {\n      this._yoyo = value;\n      return this;\n    }\n\n    return this._yoyo;\n  };\n\n  _proto.seek = function seek(position, suppressEvents) {\n    return this.totalTime(_parsePosition(this, position), _isNotFalse(suppressEvents));\n  };\n\n  _proto.restart = function restart(includeDelay, suppressEvents) {\n    this.play().totalTime(includeDelay ? -this._delay : 0, _isNotFalse(suppressEvents));\n    this._dur || (this._zTime = -_tinyNum); // ensures onComplete fires on a zero-duration animation that gets restarted.\n\n    return this;\n  };\n\n  _proto.play = function play(from, suppressEvents) {\n    from != null && this.seek(from, suppressEvents);\n    return this.reversed(false).paused(false);\n  };\n\n  _proto.reverse = function reverse(from, suppressEvents) {\n    from != null && this.seek(from || this.totalDuration(), suppressEvents);\n    return this.reversed(true).paused(false);\n  };\n\n  _proto.pause = function pause(atTime, suppressEvents) {\n    atTime != null && this.seek(atTime, suppressEvents);\n    return this.paused(true);\n  };\n\n  _proto.resume = function resume() {\n    return this.paused(false);\n  };\n\n  _proto.reversed = function reversed(value) {\n    if (arguments.length) {\n      !!value !== this.reversed() && this.timeScale(-this._rts || (value ? -_tinyNum : 0)); // in case timeScale is zero, reversing would have no effect so we use _tinyNum.\n\n      return this;\n    }\n\n    return this._rts < 0;\n  };
1\n\n  _proto.invalidate = function invalidate() {\n    this._initted = this._act = 0;\n    this._zTime = -_tinyNum;\n    return this;\n  };\n\n  _proto.isActive = function isActive() {\n    var parent = this.parent || this._dp,\n        start = this._start,\n        rawTime;\n    return !!(!parent || this._ts && this._initted && parent.isActive() && (rawTime = parent.rawTime(true)) >= start && rawTime < this.endTime(true) - _tinyNum);\n  };\n\n  _proto.eventCallback = function eventCallback(type, callback, params) {\n    var vars = this.vars;\n\n    if (arguments.length > 1) {\n      if (!callback) {\n        delete vars[type];\n      } else {\n        vars[type] = callback;\n        params && (vars[type + "Params"] = params);\n        type === "onUpdate" && (this._onUpdate = callback);\n      }\n\n      return this;\n    }\n\n    return vars[type];\n  };\n\n  _proto.then = function then(onFulfilled) {\n    var self = this,\n        prevProm = self._prom;\n    return new Promise(function (resolve) {\n      var f = _isFunction(onFulfilled) ? onFulfilled : _passThrough,\n          _resolve = function _resolve() {\n        var _then = self.then;\n        self.then = null; // temporarily null the then() method to avoid an infinite loop (see https://github.com/greensock/GSAP/issues/322)\n\n        prevProm && prevProm();\n        _isFunction(f) && (f = f(self)) && (f.then || f === self) && (self.then = _then);\n        resolve(f);\n        self.then = _then;\n      };\n\n      if (self._initted && self.totalProgress() === 1 && self._ts >= 0 || !self._tTime && self._ts < 0) {\n        _resolve();\n      } else {\n        self._prom = _resolve;\n      }\n    });\n  };\n\n  _proto.kill = function kill() {\n    _interrupt(this);\n  };\n\n  return Animation;\n}();\n\n_setDefaults(Animation.prototype, {\n  _time: 0,\n  _start: 0,\n  _end: 0,\n  _tTime: 0,\n  _tDur: 0,\n  _dirty: 0,\n  _repeat: 0,\n  _yoyo: false,\n  parent: null,\n  _initted: false,\n  _rDelay: 0,\n  _ts: 1,\n  _dp: 0,\n  ratio: 0,\n  _zTime: -_tinyNum,\n  _prom: 0,\n  _ps: false,\n  _rts: 1\n});\n/*\n * -------------------------------------------------\n * TIMELINE\n * -------------------------------------------------\n */\n\n\nvar Timeline = /*#__PURE__*/function (_Animation) {\n  _inheritsLoose(Timeline, _Animation);\n\n  function Timeline(vars, position) {\n    var _this;\n\n    if (vars === void 0) {\n      vars = {};\n    }\n\n    _this = _Animation.call(this, vars) || this;\n    _this.labels = {};\n    _this.smoothChildTiming = !!vars.smoothChildTiming;\n    _this.autoRemoveChildren = !!vars.autoRemoveChildren;\n    _this._sort = _isNotFalse(vars.sortChildren);\n    _globalTimeline && _addToTimeline(vars.parent || _globalTimeline, _assertThisInitialized(_this), position);\n    vars.reversed && _this.reverse();\n    vars.paused && _this.paused(true);\n    vars.scrollTrigger && _scrollTrigger(_assertThisInitialized(_this), vars.scrollTrigger);\n    return _this;\n  }\n\n  var _proto2 = Timeline.prototype;\n\n  _proto2.to = function to(targets, vars, position) {\n    _createTweenType(0, arguments, this);\n\n    return this;\n  };\n\n  _proto2.from = function from(targets, vars, position) {\n    _createTweenType(1, arguments, this);\n\n    return this;\n  };\n\n  _proto2.fromTo = function fromTo(targets, fromVars, toVars, position) {\n    _createTweenType(2, arguments, this);\n\n    return this;\n  };\n\n  _proto2.set = function set(targets, vars, position) {\n    vars.duration = 0;\n    vars.parent = this;\n    _inheritDefaults(vars).repeatDelay || (vars.repeat = 0);\n    vars.immediateRender = !!vars.immediateRender;\n    new Tween(targets, vars, _parsePosition(this, position), 1);\n    return this;\n  };\n\n  _proto2.call = function call(callback, params, position) {\n    return _addToTimeline(this, Tween.delayedCall(0, callback, params), position);\n  } //ONLY for backward compatibility! Maybe delete?\n  ;\n\n  _proto2.staggerTo = function staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n    vars.duration = duration;\n    vars.stagger = vars.stagger || stagger;\n    vars.onComplete = onCompleteAll;\n    vars.onCompleteParams = onCompleteAllParams;\n    vars.parent = this;\n    new Tween(targets, vars, _parsePosition(this, position));\n    return this;\n  };\n\n  _proto2.staggerFrom = function staggerFrom(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams) {\n    vars.runBackwards = 1;\n    _inheritDefaults(vars).immediateRender = _isNotFalse(vars.immediateRender);\n    return this.staggerTo(targets, duration, vars, stagger, position, onCompleteAll, onCompleteAllParams);\n  };\n\n  _proto2.staggerFromTo = function staggerFromTo(targets, duration, fromVars, toVars, stagger, position, onCompleteAll, onCompleteAllParams) {\n    toVars.startAt = fromVars;\n    _inheritDefaults(toVars).immediateRender = _isNotFalse(toVars.immediateRender);\n    return this.staggerTo(targets, duration, toVars, stagger, position, onCompleteAll, onCompleteAllParams);\n  };\n\n  _proto2.render = function render(totalTime, suppressEvents, force) {\n    var prevTime = this._time,\n        tDur = this._dirty ? this.totalDuration() : this._tDur,\n        dur = this._dur,\n        tTime = totalTime <= 0 ? 0 : _roundPrecise(totalTime),\n        // 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.\n    crossingStart = this._zTime < 0 !== totalTime < 0 && (this._initted || !dur),\n        time,\n        child,\n        next,\n        iteration,\n        cycleDuration,\n        prevPaused,\n        pauseTween,\n        timeScale,\n        prevStart,\n        prevIteration,\n        yoyo,\n        isYoyo;\n    this !== _globalTimeline && tTime > tDur && totalTime >= 0 && (tTime = tDur);\n\n    if (tTime !== this._tTime || force || crossingStart) {\n      if (prevTime !== this._time && dur) {\n        //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).\n        tTime += this._time - prevTime;
1\n        totalTime += this._time - prevTime;\n      }\n\n      time = tTime;\n      prevStart = this._start;\n      timeScale = this._ts;\n      prevPaused = !timeScale;\n\n      if (crossingStart) {\n        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.\n\n        (totalTime || !suppressEvents) && (this._zTime = totalTime);\n      }\n\n      if (this._repeat) {\n        //adjust the time for repeats and yoyos\n        yoyo = this._yoyo;\n        cycleDuration = dur + this._rDelay;\n\n        if (this._repeat < -1 && totalTime < 0) {\n          return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n        }\n\n        time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n        if (tTime === tDur) {\n          // 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)\n          iteration = this._repeat;\n          time = dur;\n        } else {\n          prevIteration = _roundPrecise(tTime / cycleDuration); // full decimal version of iterations, not the previous iteration (we\'re reusing prevIteration variable for efficiency)\n\n          iteration = ~~prevIteration;\n\n          if (iteration && iteration === prevIteration) {\n            time = dur;\n            iteration--;\n          }\n\n          time > dur && (time = dur);\n        }\n\n        prevIteration = _animationCycle(this._tTime, cycleDuration);\n        !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\n\n        if (yoyo && iteration & 1) {\n          time = dur - time;\n          isYoyo = 1;\n        }\n        /*\n        make sure children at the end/beginning of the timeline are rendered properly. If, for example,\n        a 3-second long timeline rendered at 2.9 seconds previously, and now renders at 3.2 seconds (which\n        would get translated to 2.8 seconds if the timeline yoyos or 0.2 seconds if it just repeats), there\n        could be a callback or a short tween that\'s at 2.95 or 3 seconds in which wouldn\'t render. So\n        we need to push the timeline to the end (and/or beginning depending on its yoyo value). Also we must\n        ensure that zero-duration tweens at the very beginning or end of the Timeline work.\n        */\n\n\n        if (iteration !== prevIteration && !this._lock) {\n          var rewinding = yoyo && prevIteration & 1,\n              doesWrap = rewinding === (yoyo && iteration & 1);\n          iteration < prevIteration && (rewinding = !rewinding);\n          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.\n\n          this._lock = 1;\n          this.render(prevTime || (isYoyo ? 0 : _roundPrecise(iteration * cycleDuration)), suppressEvents, !dur)._lock = 0;\n          this._tTime = tTime; // if a user gets the iteration() inside the onRepeat, for example, it should be accurate.\n\n          !suppressEvents && this.parent && _callback(this, "onRepeat");\n\n          if (this.vars.repeatRefresh && !isYoyo) {\n            this.invalidate()._lock = 1;\n            prevIteration = iteration; // otherwise, the onStart() may fire on the 2nd iteration.\n          }\n\n          if (prevTime && prevTime !== this._time || prevPaused !== !this._ts || this.vars.onRepeat && !this.parent && !this._act) {\n            // if prevTime is 0 and we render at the very end, _time will be the end, thus won\'t match. So in this edge c
1ase, prevTime won\'t match _time but that\'s okay. If it gets killed in the onRepeat, eject as well.\n            return this;\n          }\n\n          dur = this._dur; // in case the duration changed in the onRepeat\n\n          tDur = this._tDur;\n\n          if (doesWrap) {\n            this._lock = 2;\n            prevTime = rewinding ? dur : -0.0001;\n            this.render(prevTime, true);\n            this.vars.repeatRefresh && !isYoyo && this.invalidate();\n          }\n\n          this._lock = 0;\n\n          if (!this._ts && !prevPaused) {\n            return this;\n          }\n        }\n      }\n\n      if (this._hasPause && !this._forcing && this._lock < 2) {\n        pauseTween = _findNextPauseTween(this, _roundPrecise(prevTime), _roundPrecise(time));\n\n        if (pauseTween) {\n          tTime -= time - (time = pauseTween._start);\n        }\n      }\n\n      this._tTime = tTime;\n      this._time = time;\n      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.\n\n      if (!this._initted) {\n        this._onUpdate = this.vars.onUpdate;\n        this._initted = 1;\n        this._zTime = totalTime;\n        prevTime = 0; // upon init, the playhead should always go forward;
1 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}).\n      }\n\n      if (!prevTime && tTime && dur && !suppressEvents && !prevIteration) {\n        _callback(this, "onStart");\n\n        if (this._tTime !== tTime) {\n          // 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.\n          return this;\n        }\n      }\n\n      if (time >= prevTime && totalTime >= 0) {\n        child = this._first;\n\n        while (child) {\n          next = child._next;\n\n          if ((child._act || time >= child._start) && child._ts && pauseTween !== child) {\n            if (child.parent !== this) {\n              // 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.\n              return this.render(totalTime, suppressEvents, force);\n            }\n\n            child.render(child._ts > 0 ? (time - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (time - child._start) * child._ts, suppressEvents, force);\n\n            if (time !== this._time || !this._ts && !prevPaused) {\n              //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n              pauseTween = 0;\n              next && (tTime += this._zTime = -_tinyNum); // it didn\'t finish rendering, so flag zTime as negative so that the next time render() is called it\'ll be forced (to render any remaining children)\n\n              break;\n            }\n          }\n\n          child = next;\n        }\n      } else {\n        child = this._last;\n        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.\n\n        while (child) {\n          next = child._prev;\n\n          if ((child._act || adjustedTime <= child._end) && child._ts && pauseTween !== child) {\n            if (child.parent !== this) {\n              // 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.\n              return this.render(totalTime, suppressEvents, force);\n            }\n\n            child.render(child._ts > 0 ? (adjustedTime - child._start) * child._ts : (child._dirty ? child.totalDuration() : child._tDur) + (adjustedTime - child._start) * child._ts, suppressEvents, force || _reverting && _isRevertWorthy(child)); // 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.\n\n            if (time !== this._time || !this._ts && !prevPaused) {\n              //in case a tween pauses or seeks the timeline when rendering, like inside of an onUpdate/onComplete\n              pauseTween = 0;\n              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)\n\n              break;\n            }\n          }\n\n          child = next;\n        }\n      }\n\n      if (pauseTween && !suppressEvents) {\n        this.pause();\n        pauseTween.render(time >= prevTime ? 0 : -_tinyNum)._zTime = time >= prevTime ? 1 : -1;\n\n        if (this._ts) {\n          //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).\n          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.\n\n          _setEnd(this);\n\n          return this.render(totalTime, suppressEvents, force);\n        }\n      }
1\n\n      this._onUpdate && !suppressEvents && _callback(this, "onUpdate", true);\n      if (tTime === tDur && this._tTime >= this.totalDuration() || !tTime && prevTime) if (prevStart === this._start || Math.abs(timeScale) !== Math.abs(this._ts)) if (!this._lock) {\n        // remember, a child\'s callback may alter this timeline\'s playhead or timeScale which is why we need to add some of these checks.\n        (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.\n\n        if (!suppressEvents && !(totalTime < 0 && !prevTime) && (tTime || prevTime || !tDur)) {\n          _callback(this, tTime === tDur && totalTime >= 0 ? "onComplete" : "onReverseComplete", true);\n\n          this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n        }\n      }\n    }\n\n    return this;\n  };\n\n  _proto2.add = function add(child, position) {\n    var _this2 = this;\n\n    _isNumber(position) || (position = _parsePosition(this, position, child));\n\n    if (!(child instanceof Animation)) {\n      if (_isArray(child)) {\n        child.forEach(function (obj) {\n          return _this2.add(obj, position);\n        });\n        return this;\n      }\n\n      if (_isString(child)) {\n        return this.addLabel(child, position);\n      }\n\n      if (_isFunction(child)) {\n        child = Tween.delayedCall(0, child);\n      } else {\n        return this;\n      }\n    }\n\n    return this !== child ? _addToTimeline(this, child, position) : this; //don\'t allow a timeline to be added to itself as a child!\n  };\n\n  _proto2.getChildren = function getChildren(nested, tweens, timelines, ignoreBeforeTime) {\n    if (nested === void 0) {\n      nested = true;\n    }\n\n    if (tweens === void 0) {\n      tweens = true;\n    }\n\n    if (timelines === void 0) {\n      timelines = true;\n    }\n\n    if (ignoreBeforeTime === void 0) {\n      ignoreBeforeTime = -_bigNum;\n    }\n\n    var a = [],\n        child = this._first;\n\n    while (child) {\n      if (child._start >= ignoreBeforeTime) {\n        if (child instanceof Tween) {\n          tweens && a.push(child);\n        } else {\n          timelines && a.push(child);\n          nested && a.push.apply(a, child.getChildren(true, tweens, timelines));\n        }\n      }\n\n      child = child._next;\n    }\n\n    return a;\n  };\n\n  _proto2.getById = function getById(id) {\n    var animations = this.getChildren(1, 1, 1),\n        i = animations.length;\n\n    while (i--) {\n      if (animations[i].vars.id === id) {\n        return animations[i];\n      }\n    }\n  };\n\n  _proto2.remove = function remove(child) {\n    if (_isString(child)) {\n      return this.removeLabel(child);\n    }\n\n    if (_isFunction(child)) {\n      return this.killTweensOf(child);\n    }\n\n    child.parent === this && _removeLinkedListItem(this, child);\n\n    if (child === this._recent) {\n      this._recent = this._last;\n    }\n\n    return _uncache(this);\n  };\n\n  _proto2.totalTime = function totalTime(_totalTime2, suppressEvents) {\n    if (!arguments.length) {\n      return this._tTime;\n    }\n\n    this._forcing = 1;\n\n    if (!this._dp && this._ts) {\n      //special case for the global timeline (or any other that has no parent or detached parent).\n      this._start = _roundPrecise(_ticker.time - (this._ts > 0 ? _totalTime2 / this._ts : (this.totalDuration() - _totalTime2) / -this._ts));\n    }\n\n    _Animation.prototype.totalTime.call(this, _totalTime2, suppressEvents);\n\n    this._forcing = 0;\n    return this;\n  };\n\n  _proto2.addLabel = function addLabel(label, position) {\n    this.labels[label] = _parsePosition(this, position);\n    return this;\n  };\n\n  _proto2.removeLabel = function removeLabel(label) {\n    delete this.labels[label];\n    return this;\n  };\n\n  _proto2.addPause = function addPause(position, callback, params) {\n    var t = Tween.delayedCall(0, callback || _emptyFunc, params);
1\n    t.data = "isPause";\n    this._hasPause = 1;\n    return _addToTimeline(this, t, _parsePosition(this, position));\n  };\n\n  _proto2.removePause = function removePause(position) {\n    var child = this._first;\n    position = _parsePosition(this, position);\n\n    while (child) {\n      if (child._start === position && child.data === "isPause") {\n        _removeFromParent(child);\n      }\n\n      child = child._next;\n    }\n  };\n\n  _proto2.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n    var tweens = this.getTweensOf(targets, onlyActive),\n        i = tweens.length;\n\n    while (i--) {\n      _overwritingTween !== tweens[i] && tweens[i].kill(targets, props);\n    }\n\n    return this;\n  };\n\n  _proto2.getTweensOf = function getTweensOf(targets, onlyActive) {\n    var a = [],\n        parsedTargets = toArray(targets),\n        child = this._first,\n        isGlobalTime = _isNumber(onlyActive),\n        // a number is interpreted as a global time. If the animation spans\n    children;\n\n    while (child) {\n      if (child instanceof Tween) {\n        if (_arrayContainsAny(child._targets, parsedTargets) && (isGlobalTime ? (!_overwritingTween || child._initted && child._ts) && child.globalTime(0) <= onlyActive && child.globalTime(child.totalDuration()) > onlyActive : !onlyActive || child.isActive())) {\n          // note: if this is for overwriting, it should only be for tweens that aren\'t paused and are initted.\n          a.push(child);\n        }\n      } else if ((children = child.getTweensOf(parsedTargets, onlyActive)).length) {\n        a.push.apply(a, children);\n      }\n\n      child = child._next;\n    }\n\n    return a;\n  } // potential future feature - targets() on timelines\n  // targets() {\n  // \tlet result = [];\n  // \tthis.getChildren(true, true, false).forEach(t => result.push(...t.targets()));\n  // \treturn result.filter((v, i) => result.indexOf(v) === i);\n  // }\n  ;\n\n  _proto2.tweenTo = function tweenTo(position, vars) {\n    vars = vars || {};\n\n    var tl = this,\n        endTime = _parsePosition(tl, position),\n        _vars = vars,\n        startAt = _vars.startAt,\n        _onStart = _vars.onStart,\n        onStartParams = _vars.onStartParams,\n        immediateRender = _vars.immediateRender,\n        initted,\n        tween = Tween.to(tl, _setDefaults({\n      ease: vars.ease || "none",\n      lazy: false,\n      immediateRender: false,\n      time: endTime,\n      overwrite: "auto",\n      duration: vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale()) || _tinyNum,\n      onStart: function onStart() {\n        tl.pause();\n\n        if (!initted) {\n          var duration = vars.duration || Math.abs((endTime - (startAt && "time" in startAt ? startAt.time : tl._time)) / tl.timeScale());\n          tween._dur !== duration && _setDuration(tween, duration, 0, 1).render(tween._time, true, true);\n          initted = 1;\n        }\n\n        _onStart && _onStart.apply(tween, onStartParams || []); //in case the user had an onStart in the vars - we don\'t want to overwrite it.\n      }\n    }, vars));\n\n    return immediateRender ? tween.render(0) : tween;\n  };\n\n  _proto2.tweenFromTo = function tweenFromTo(fromPosition, toPosition, vars) {\n    return this.tweenTo(toPosition, _setDefaults({\n      startAt: {\n        time: _parsePosition(this, fromPosition)\n      }\n    }, vars));\n  };\n\n  _proto2.recent = function recent() {\n    return this._recent;\n  };\n\n  _proto2.nextLabel = function nextLabel(afterTime) {\n    if (afterTime === void 0) {\n      afterTime = this._time;\n    }\n\n    return _getLabelInDirection(this, _parsePosition(this, afterTime));\n  };\n\n  _proto2.previousLabel = function previousLabel(beforeTime) {\n    if (beforeTime === void 0) {\n      beforeTime = this._time;\n    }\n\n    return _getLabelInDirection(this, _parsePosition(this, beforeTime), 1);\n  };\n\n  _proto2.currentLabel = function currentLabel(value) {\n    return arguments.length ? this.seek(value, true) : this.previousLabel(this._time + _tinyNum);\n  };\n\n  _proto2.shiftChildren = function shiftChildren(amount, adjustLabels, ignoreBeforeTime) {\n    if (ignoreBeforeTime === void 0) {\n      ignoreBeforeTime = 0;\n    }\n\n    var child = this._first,\n        labels = this.labels,\n        p;\n    amount = _roundPrecise(amount);\n\n    while (child) {\n      if (child._start >= ignoreBeforeTime) {\n        child._start += amount;
1\n        child._end += amount;\n      }\n\n      child = child._next;\n    }\n\n    if (adjustLabels) {\n      for (p in labels) {\n        if (labels[p] >= ignoreBeforeTime) {\n          labels[p] += amount;\n        }\n      }\n    }\n\n    return _uncache(this);\n  };\n\n  _proto2.invalidate = function invalidate(soft) {\n    var child = this._first;\n    this._lock = 0;\n\n    while (child) {\n      child.invalidate(soft);\n      child = child._next;\n    }\n\n    return _Animation.prototype.invalidate.call(this, soft);\n  };\n\n  _proto2.clear = function clear(includeLabels) {\n    if (includeLabels === void 0) {\n      includeLabels = true;\n    }\n\n    var child = this._first,\n        next;\n\n    while (child) {\n      next = child._next;\n      this.remove(child);\n      child = next;\n    }\n\n    this._dp && (this._time = this._tTime = this._pTime = 0);\n    includeLabels && (this.labels = {});\n    return _uncache(this);\n  };\n\n  _proto2.totalDuration = function totalDuration(value) {\n    var max = 0,\n        self = this,\n        child = self._last,\n        prevStart = _bigNum,\n        prev,\n        start,\n        parent;\n\n    if (arguments.length) {\n      return self.timeScale((self._repeat < 0 ? self.duration() : self.totalDuration()) / (self.reversed() ? -value : value));\n    }\n\n    if (self._dirty) {\n      parent = self.parent;\n\n      while (child) {\n        prev = child._prev; //record it here in case the tween changes position in the sequence...\n\n        child._dirty && child.totalDuration(); //could change the tween._startTime, so make sure the animation\'s cache is clean before analyzing it.\n\n        start = child._start;\n\n        if (start > prevStart && self._sort && child._ts && !self._lock) {\n          //in case one of the tweens shifted out of order, it needs to be re-inserted into the correct position in the sequence\n          self._lock = 1; //prevent endless recursive calls - there are methods that get triggered that check duration/totalDuration when we add().\n\n          _addToTimeline(self, child, start - child._delay, 1)._lock = 0;\n        } else {\n          prevStart = start;\n        }\n\n        if (start < 0 && child._ts) {\n          //children aren\'t allowed to have negative startTimes unless smoothChildTiming is true, so adjust here if one is found.\n          max -= start;\n\n          if (!parent && !self._dp || parent && parent.smoothChildTiming) {\n            self._start += _roundPrecise(start / self._ts);\n            self._time -= start;\n            self._tTime -= start;\n          }\n\n          self.shiftChildren(-start, false, -1e999);\n          prevStart = 0;\n        }\n\n        child._end > max && child._ts && (max = child._end);\n        child = prev;\n      }\n\n      _setDuration(self, self === _globalTimeline && self._time > max ? self._time : max, 1, 1);\n\n      self._dirty = 0;\n    }\n\n    return self._tDur;\n  };\n\n  Timeline.updateRoot = function updateRoot(time) {\n    if (_globalTimeline._ts) {\n      _lazySafeRender(_globalTimeline, _parentToChildTotalTime(time, _globalTimeline));\n\n      _lastRenderedFrame = _ticker.frame;\n    }\n\n    if (_ticker.frame >= _nextGCFrame) {\n      _nextGCFrame += _config.autoSleep || 120;\n      var child = _globalTimeline._first;\n      if (!child || !child._ts) if (_config.autoSleep && _ticker._listeners.length < 2) {\n        while (child && !child._ts) {\n          child = child._next;\n        }\n\n        child || _ticker.sleep();\n      }\n    }\n  };\n\n  return Timeline;\n}(Animation);\n\n_setDefaults(Timeline.prototype, {\n  _lock: 0,\n  _hasPause: 0,\n  _forcing: 0\n});\n\nvar _addComplexStringPropTween = function _addComplexStringPropTween(target, prop, start, end, setter, stringFilter, funcParam) {\n  //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.\n  var pt = new PropTween(this._pt, target, prop, 0, 1, _renderComplexString, null, setter),\n      index = 0,\n      matchIndex = 0,\n      result,\n      startNums,\n      color,\n      endNum,\n      chunk,\n      startNum,\n      hasRandom,\n      a;\n  pt.b = start;\n  pt.e = end;\n  start += ""; //ensure values are strings\n\n  end += "";
1\n\n  if (hasRandom = ~end.indexOf("random(")) {\n    end = _replaceRandom(end);\n  }\n\n  if (stringFilter) {\n    a = [start, end];\n    stringFilter(a, target, prop); //pass an array with the starting and ending values and let the filter do whatever it needs to the values.\n\n    start = a[0];\n    end = a[1];\n  }\n\n  startNums = start.match(_complexStringNumExp) || [];\n\n  while (result = _complexStringNumExp.exec(end)) {\n    endNum = result[0];\n    chunk = end.substring(index, result.index);\n\n    if (color) {\n      color = (color + 1) % 5;\n    } else if (chunk.substr(-5) === "rgba(") {\n      color = 1;\n    }\n\n    if (endNum !== startNums[matchIndex++]) {\n      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.\n\n      pt._pt = {\n        _next: pt._pt,\n        p: chunk || matchIndex === 1 ? chunk : ",",\n        //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.\n        s: startNum,\n        c: endNum.charAt(1) === "=" ? _parseRelative(startNum, endNum) - startNum : parseFloat(endNum) - startNum,\n        m: color && color < 4 ? Math.round : 0\n      };\n      index = _complexStringNumExp.lastIndex;\n    }\n  }\n\n  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)\n\n  pt.fp = funcParam;\n\n  if (_relExp.test(end) || hasRandom) {\n    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).\n  }\n\n  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.\n\n  return pt;\n},\n    _addPropTween = function _addPropTween(target, prop, start, end, index, targets, modifier, stringFilter, funcParam, optional) {\n  _isFunction(end) && (end = end(index || 0, target, targets));\n  var currentValue = target[prop],\n      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](),\n      setter = !_isFunction(currentValue) ? _setterPlain : funcParam ? _setterFuncWithParam : _setterFunc,\n      pt;\n\n  if (_isString(end)) {\n    if (~end.indexOf("random(")) {\n      end = _replaceRandom(end);\n    }\n\n    if (end.charAt(1) === "=") {\n      pt = _parseRelative(parsedStart, end) + (getUnit(parsedStart) || 0);\n\n      if (pt || pt === 0) {\n        // to avoid isNaN, like if someone passes in a value like "!= whatever"\n        end = pt;\n      }\n    }\n  }\n\n  if (!optional || parsedStart !== end || _forceAllPropTweens) {\n    if (!isNaN(parsedStart * end) && end !== "") {\n      // fun fact: any number multiplied by "" is evaluated as the number 0!\n      pt = new PropTween(this._pt, target, prop, +parsedStart || 0, end - (parsedStart || 0), typeof currentValue === "boolean" ? _renderBoolean : _renderPlain, 0, setter);\n      funcParam && (pt.fp = funcParam);\n      modifier && pt.modifier(modifier, this, target);\n      return this._pt = pt;\n    }\n\n    !currentValue && !(prop in target) && _missingPlugin(prop, end);\n    return _addComplexStringPropTween.call(this, target, prop, parsedStart, end, setter, stringFilter || _config.stringFilter, funcParam);\n  }\n},\n    //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.\
1n_processVars = function _processVars(vars, index, target, targets, tween) {\n  _isFunction(vars) && (vars = _parseFuncOrString(vars, tween, index, target, targets));\n\n  if (!_isObject(vars) || vars.style && vars.nodeType || _isArray(vars) || _isTypedArray(vars)) {\n    return _isString(vars) ? _parseFuncOrString(vars, tween, index, target, targets) : vars;\n  }\n\n  var copy = {},\n      p;\n\n  for (p in vars) {\n    copy[p] = _parseFuncOrString(vars[p], tween, index, target, targets);\n  }\n\n  return copy;\n},\n    _checkPlugin = function _checkPlugin(property, vars, tween, index, target, targets) {\n  var plugin, pt, ptLookup, i;\n\n  if (_plugins[property] && (plugin = new _plugins[property]()).init(target, plugin.rawVars ? vars[property] : _processVars(vars[property], index, target, targets, tween), tween, index, targets) !== false) {\n    tween._pt = pt = new PropTween(tween._pt, target, property, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n    if (tween !== _quickTween) {\n      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.\n\n      i = plugin._props.length;\n\n      while (i--) {\n        ptLookup[plugin._props[i]] = pt;\n      }\n    }\n  }\n\n  return plugin;\n},\n    _overwritingTween,\n    //store a reference temporarily so we can avoid overwriting itself.\n_forceAllPropTweens,\n    _initTween = function _initTween(tween, time, tTime) {\n  var vars = tween.vars,\n      ease = vars.ease,\n      startAt = vars.startAt,\n      immediateRender = vars.immediateRender,\n      lazy = vars.lazy,\n      onUpdate = vars.onUpdate,\n      runBackwards = vars.runBackwards,\n      yoyoEase = vars.yoyoEase,\n      keyframes = vars.keyframes,\n      autoRevert = vars.autoRevert,\n      dur = tween._dur,\n      prevStartAt = tween._startAt,\n      targets = tween._targets,\n      parent = tween.parent,\n      fullTargets = parent && parent.data === "nested" ? parent.vars.targets : targets,\n      autoOverwrite = tween._overwrite === "auto" && !_suppressOverwrites,\n      tl = tween.timeline,\n      reverseEase = vars.easeReverse || yoyoEase,\n      cleanVars,\n      i,\n      p,\n      pt,\n      target,\n      hasPriority,\n      gsData,\n      harness,\n      plugin,\n      ptLookup,\n      index,\n      harnessVars,\n      overwritten;\n  tl && (!keyframes || !ease) && (ease = "none");\n  tween._ease = _parseEase(ease, _defaults.ease);\n  tween._rEase = reverseEase && (_parseEase(reverseEase) || tween._ease);\n  tween._from = !tl && !!vars.runBackwards; //nested timelines should never run backwards - the backwards-ness is in the child tweens.\n\n  if (tween._from) tween.ratio = 1;\n\n  if (!tl || keyframes && !vars.stagger) {\n    //if there\'s an internal timeline, skip all the parsing because we passed that task down the chain.\n    harness = targets[0] ? _getCache(targets[0]).harness : 0;\n    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.\n\n    cleanVars = _copyExcluding(vars, _reservedProps);\n\n    if (prevStartAt) {\n      prevStartAt._zTime < 0 && prevStartAt.progress(1); // in case it\'s a lazy startAt that hasn\'t rendered yet.\n\n      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)\n      // 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.\n\n      prevStartAt._lazy = 0;\n    }\n\n    if (startAt) {\n      _removeFromParent(tween._startAt = Tween.set(targets, _setDefaults({\n        data: "isStart",\n        overwrite: false,\n        parent: parent,\n        immediateRender: true,\n        lazy: !prevStartAt && _isNotFalse(lazy),\n        startAt: null,\n        delay: 0,\n        onUpdate: onUpdate && function () {\n          return _callback(tween, "onUpdate");\n        },\n        stagger: 0\n      }, 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);\n\n\n      tween._startAt._dp = 0; // don\'t allow it to get put back into root timeline! Like when revert() is called and totalTime() gets set.\n\n      tween._startAt._sat = tween; // used in globalTime(). _sat stands for _startAtTween\n\n      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 t
1ween.\n\n      if (immediateRender) {\n        if (dur && time <= 0 && tTime <= 0) {\n          // 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.\n          time && (tween._zTime = time);\n          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.\n        }\n      }\n    } else if (runBackwards && dur) {\n      // 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)\n      if (!prevStartAt) {\n        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\n\n        p = _setDefaults({\n          overwrite: false,\n          data: "isFromStart",\n          //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.\n          lazy: immediateRender && !prevStartAt && _isNotFalse(lazy),\n          immediateRender: immediateRender,\n          //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)\n          stagger: 0,\n          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})\n\n        }, cleanVars);\n        harnessVars && (p[harness.prop] = harnessVars); // in case someone does something like .from(..., {css:{}})\n\n        _removeFromParent(tween._startAt = Tween.set(targets, p));\n\n        tween._startAt._dp = 0; // don\'t allow it to get put back into root timeline!\n\n        tween._startAt._sat = tween; // used in globalTime()\n\n        time < 0 && (_reverting ? tween._startAt.revert(_revertConfigNoKill) : tween._startAt.render(-1, true));\n        tween._zTime = time;\n\n        if (!immediateRender) {\n          _initTween(tween._startAt, _tinyNum, _tinyNum); //ensures that the initial values are recorded\n\n        } else if (!time) {\n          return;\n        }\n      }\n    }\n\n    tween._pt = tween._ptCache = 0;\n    lazy = dur && _isNotFalse(lazy) || lazy && !dur;\n\n    for (i = 0; i < targets.length; i++) {\n      target = targets[i];\n      gsData = target._gsap || _harness(targets)[i]._gsap;\n      tween._ptLookup[i] = ptLookup = {};\n      _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)\n\n      index = fullTargets === targets ? i : fullTargets.indexOf(target);\n\n      if (harness && (plugin = new harness()).init(target, harnessVars || cleanVars, tween, index, fullTargets) !== false) {\n        tween._pt = pt = new PropTween(tween._pt, target, plugin.name, 0, 1, plugin.render, plugin, 0, plugin.priority);\n\n        plugin._props.forEach(function (name) {\n          ptLookup[name] = pt;\n        });\n\n        plugin.priority && (hasPriority = 1);\n      }\n\n      if (!harness || harnessVars) {\n        for (p in cleanVars) {\n          if (_plugins[p] && (plugin = _checkPlugin(p, cleanVars, tween, index, target, fullTargets))) {\n            plugin.priority && (hasPriority = 1);\n          } else {\n            ptLookup[p] = pt = _addPropTween.call(tween, target, p, "get", cleanVars[p], index, fullTargets, 0, vars.stringFilter);\n          }\n        }\n      }\n\n      tween._op && tween._op[i] && tween.kill(target, tween._op[i]);\n\n      if (autoOverwrite && tween._pt) {\n        _overwritingTween = tween;\n\n        _globalTimeline.killTweensOf(target, ptLookup, tween.globalTime(time)); // make sure the overwriting doesn\'t overwrite THIS tween!!!\n\n\n        overwritten = !tween.parent;\n        _overwritingTween = 0;\n      }\n\n      tween._pt && lazy && (_lazyLookup[gsData.id] = 1);\n    }\n\n    hasPriority && _sortPropTweensByPriority(tween);\n    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.\n  }\n\n  tween._onUpdate = onUpdate;\n  tween._initted = (!tween._op || tween._pt) && !overwritten;
1 // if overwrittenProps resulted in the entire tween being killed, do NOT flag it as initted or else it may render for one tick.\n\n  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.\n},\n    _updatePropTweens = function _updatePropTweens(tween, property, value, start, startIsRelative, ratio, time, skipRecursion) {\n  var ptCache = (tween._pt && tween._ptCache || (tween._ptCache = {}))[property],\n      pt,\n      rootPT,\n      lookup,\n      i;\n\n  if (!ptCache) {\n    ptCache = tween._ptCache[property] = [];\n    lookup = tween._ptLookup;\n    i = tween._targets.length;\n\n    while (i--) {\n      pt = lookup[i][property];\n\n      if (pt && pt.d && pt.d._pt) {\n        // it\'s a plugin, so find the nested PropTween\n        pt = pt.d._pt;\n\n        while (pt && pt.p !== property && pt.fp !== property) {\n          // "fp" is functionParam for things like setting CSS variables which require .setProperty("--var-name", value)\n          pt = pt._next;\n        }\n      }\n\n      if (!pt) {\n        // there is no PropTween associated with that property, so we must FORCE one to be created and ditch out of this\n        // 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.\n        _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.\n\n        tween.vars[property] = "+=0";\n\n        _initTween(tween, time);\n\n        _forceAllPropTweens = 0;\n        return skipRecursion ? _warn(property + " not eligible for reset. Try splitting into individual properties") : 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().\n      }\n\n      ptCache.push(pt);\n    }\n  }\n\n  i = ptCache.length;\n\n  while (i--) {\n    rootPT = ptCache[i];\n    pt = rootPT._pt || rootPT; // complex values may have nested PropTweens. We only accommodate the FIRST value.\n\n    pt.s = (start || start === 0) && !startIsRelative ? start : pt.s + (start || 0) + ratio * pt.c;\n    pt.c = value - pt.s;\n    rootPT.e && (rootPT.e = _round(value) + getUnit(rootPT.e)); // mainly for CSSPlugin (end value)\n\n    rootPT.b && (rootPT.b = pt.s + getUnit(rootPT.b)); // (beginning value)\n  }\n},\n    _addAliasesToVars = function _addAliasesToVars(targets, vars) {\n  var harness = targets[0] ? _getCache(targets[0]).harness : 0,\n      propertyAliases = harness && harness.aliases,\n      copy,\n      p,\n      i,\n      aliases;\n\n  if (!propertyAliases) {\n    return vars;\n  }\n\n  copy = _merge({}, vars);\n\n  for (p in propertyAliases) {\n    if (p in copy) {\n      aliases = propertyAliases[p].split(",");\n      i = aliases.length;\n\n      while (i--) {\n        copy[aliases[i]] = copy[p];\n      }\n    }\n  }\n\n  return copy;\n},\n    // 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.\n_parseKeyframe = function _parseKeyframe(prop, obj, allProps, easeEach) {\n  var ease = obj.ease || easeEach || "power1.inOut",\n      p,\n      a;\n\n  if (_isArray(obj)) {\n    a = allProps[prop] || (allProps[prop] = []); // t = time (out of 100), v = value, e = ease\n\n    obj.forEac
1h(function (value, i) {\n      return a.push({\n        t: i / (obj.length - 1) * 100,\n        v: value,\n        e: ease\n      });\n    });\n  } else {\n    for (p in obj) {\n      a = allProps[p] || (allProps[p] = []);\n      p === "ease" || a.push({\n        t: parseFloat(prop),\n        v: obj[p],\n        e: ease\n      });\n    }\n  }\n},\n    _parseFuncOrString = function _parseFuncOrString(value, tween, i, target, targets) {\n  return _isFunction(value) ? value.call(tween, i, target, targets) : _isString(value) && ~value.indexOf("random(") ? _replaceRandom(value) : value;\n},\n    _staggerTweenProps = _callbackNames + "repeat,repeatDelay,yoyo,repeatRefresh,yoyoEase,easeReverse,autoRevert",\n    _staggerPropsToSkip = {};\n\n_forEachName(_staggerTweenProps + ",id,stagger,delay,duration,paused,scrollTrigger", function (name) {\n  return _staggerPropsToSkip[name] = 1;\n});\n/*\n * --------------------------------------------------------------------------------------\n * TWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar Tween = /*#__PURE__*/function (_Animation2) {\n  _inheritsLoose(Tween, _Animation2);\n\n  function Tween(targets, vars, position, skipInherit) {\n    var _this3;\n\n    if (typeof vars === "number") {\n      position.duration = vars;\n      vars = position;\n      position = null;\n    }\n\n    _this3 = _Animation2.call(this, skipInherit ? vars : _inheritDefaults(vars)) || this;\n    var _this3$vars = _this3.vars,\n        duration = _this3$vars.duration,\n        delay = _this3$vars.delay,\n        immediateRender = _this3$vars.immediateRender,\n        stagger = _this3$vars.stagger,\n        overwrite = _this3$vars.overwrite,\n        keyframes = _this3$vars.keyframes,\n        defaults = _this3$vars.defaults,\n        scrollTrigger = _this3$vars.scrollTrigger,\n        parent = vars.parent || _globalTimeline,\n        parsedTargets = (_isArray(targets) || _isTypedArray(targets) ? _isNumber(targets[0]) : "length" in vars) ? [targets] : toArray(targets),\n        tl,\n        i,\n        copy,\n        l,\n        p,\n        curTarget,\n        staggerFunc,\n        staggerVarsToMerge;\n    _this3._targets = parsedTargets.length ? _harness(parsedTargets) : _warn("GSAP target " + targets + " not found. https://gsap.com", !_config.nullTargetWarn) || [];\n    _this3._ptLookup = []; //PropTween lookup. An array containing an object for each target, having keys for each tweening property\n\n    _this3._overwrite = overwrite;\n\n    if (keyframes || stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n      vars = _this3.vars;\n      var easeReverse = vars.easeReverse || vars.yoyoEase;\n      tl = _this3.timeline = new Timeline({\n        data: "nested",\n        defaults: defaults || {},\n        targets: parent && parent.data === "nested" ? parent.vars.targets : parsedTargets\n      }); // 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.\n\n      tl.kill();\n      tl.parent = tl._dp = _assertThisInitialized(_this3);\n      tl._start = 0;\n\n      if (stagger || _isFuncOrString(duration) || _isFuncOrString(delay)) {\n        l = parsedTargets.length;\n        staggerFunc = stagger && distribute(stagger);\n\n        if (_isObject(stagger)) {\n          //users can pass in callbacks like onStart/onComplete in the stagger object. These should fire with each individual tween.\n          for (p in stagger) {\n            if (~_staggerTweenProps.indexOf(p)) {\n              staggerVarsToMerge || (staggerVarsToMerge = {});\n              staggerVarsToMerge[p] = stagger[p];\n            }\n          }\n        }\n\n        for (i = 0; i < l; i++) {\n          copy = _copyExcluding(vars, _staggerPropsToSkip);\n          copy.stagger = 0;\n          easeReverse && (copy.easeReverse = easeReverse);\n          staggerVarsToMerge && _merge(copy, staggerVarsToMerge);\n          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.\n\n          copy.duration = +_parseFuncOrString(duration, _assertThisInitialized(_this3), i, curTarget, parsedTargets);\n          copy.delay = (+_parseFuncOrString(delay, _assertThisInitialized(_this3), i, curTarget, parsedTargets) || 0) - _this3._delay;\n\n          if (!stagger && l === 1 && copy.delay) {\n            // if someone does delay:"random(1, 5)", repeat:-1, for example, the delay 
1shouldn\'t be inside the repeat.\n            _this3._delay = delay = copy.delay;\n            _this3._start += delay;\n            copy.delay = 0;\n          }\n\n          tl.to(curTarget, copy, staggerFunc ? staggerFunc(i, curTarget, parsedTargets) : 0);\n          tl._ease = _easeMap.none;\n        }\n\n        tl.duration() ? duration = delay = 0 : _this3.timeline = 0; // if the timeline\'s duration is 0, we don\'t need a timeline internally!\n      } else if (keyframes) {\n        _inheritDefaults(_setDefaults(tl.vars.defaults, {\n          ease: "none"\n        }));\n\n        tl._ease = _parseEase(keyframes.ease || vars.ease || "none");\n        var time = 0,\n            a,\n            kf,\n            v;\n\n        if (_isArray(keyframes)) {\n          keyframes.forEach(function (frame) {\n            return tl.to(parsedTargets, frame, ">");\n          });\n          tl.duration(); // to ensure tl._dur is cached because we tap into it for performance purposes in the render() method.\n        } else {\n          copy = {};\n\n          for (p in keyframes) {\n            p === "ease" || p === "easeEach" || _parseKeyframe(p, keyframes[p], copy, keyframes.easeEach);\n          }\n\n          for (p in copy) {\n            a = copy[p].sort(function (a, b) {\n              return a.t - b.t;\n            });\n            time = 0;\n\n            for (i = 0; i < a.length; i++) {\n              kf = a[i];\n              v = {\n                ease: kf.e,\n                duration: (kf.t - (i ? a[i - 1].t : 0)) / 100 * duration\n              };\n              v[p] = kf.v;\n              tl.to(parsedTargets, v, time);\n              time += v.duration;\n            }\n          }\n\n          tl.duration() < duration && tl.to({}, {\n            duration: duration - tl.duration()\n          }); // in case keyframes didn\'t go to 100%\n        }\n      }\n\n      duration || _this3.duration(duration = tl.duration());\n    } else {\n      _this3.timeline = 0; //speed optimization, faster lookups (no going up the prototype chain)\n    }\n\n    if (overwrite === true && !_suppressOverwrites) {\n      _overwritingTween = _assertThisInitialized(_this3);\n\n      _globalTimeline.killTweensOf(parsedTargets);\n\n      _overwritingTween = 0;\n    }\n\n    _addToTimeline(parent, _assertThisInitialized(_this3), position);\n\n    vars.reversed && _this3.reverse();\n    vars.paused && _this3.paused(true);\n\n    if (immediateRender || !duration && !keyframes && _this3._start === _roundPrecise(parent._time) && _isNotFalse(immediateRender) && _hasNoPausedAncestors(_assertThisInitialized(_this3)) && parent.data !== "nested") {\n      _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)\n\n      _this3.render(Math.max(0, -delay) || 0); //in case delay is negative\n\n    }\n\n    scrollTrigger && _scrollTrigger(_assertThisInitialized(_this3), scrollTrigger);\n    return _this3;\n  }\n\n  var _proto3 = Tween.prototype;\n\n  _proto3.render = function render(totalTime, suppressEvents, force) {\n    var prevTime = this._time,\n        tDur = this._tDur,\n        dur = this._dur,\n        isNegative = totalTime < 0,\n        tTime = totalTime > tDur - _tinyNum && !isNegative ? tDur : totalTime < _tinyNum ? 0 : totalTime,\n        time,\n        pt,\n        iteration,\n        cycleDuration,\n        prevIteration,\n        isYoyo,\n        ratio,\n        timeline;\n\n    if (!dur) {\n      _renderZeroDurationTween(this, totalTime, suppressEvents, force);\n    } else if (tTime !== this._tTime || !totalTime || force || !this._initted && this._tTime || this._startAt && this._zTime < 0 !== isNegative || this._lazy) {\n      // 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)\n      time = tTime;\n      timeline = this.timeline;\n\n      if (this._repeat) {\n        //adjust the time for repeats and yoyos\n        cycleDuration = dur + this._rDelay;\n\n        if (this._repeat < -1 && isNegative) {\n          return this.totalTime(cycleDuration * 100 + totalTime, suppressEvents, force);\n        }\n\n        time = _roundPrecise(tTime % cycleDuration); //round to avoid floating point errors. (4 % 0.8 should be 0 but some browsers report it as 0.79999999!)\n\n        if (tTime === tDur) {\n          // 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)\n          iteration = this._repeat;\n          time = dur;\n        } else {\n          prevIteration = _roundPrecise(tTime / cycleDuration); // full decimal version of iterations, not the previous iteration (we\'re reusing prevIteration variable for efficiency)\n\n          iteration = ~~prevIteration;\n\n          if (iteration && iteration === prevIteration) {\n            time = dur;\n            iteration--;\n          } else if (time > dur) {\n            time = dur;\n          }\n        }\n\n        isYoyo = this._yoyo && iteration & 1;\n        if (isYoyo) time = dur - time;\n        prevIteration = _animationCycle(this._tTime, cycleDuration);\n\n        if (time === prevTime && !force && this._initted && iteration === prevIteration) {\n          //could be during the repeatDelay part. No need to render and fire callbacks.\n          this._tTime = tTime;\n          return this;\n        }\n\n        if (iteration !== prevIteration) {\n          //repeatRefresh functionality\n          if (this.vars.repeatRefresh && !isYoyo && !this._lock && time !== cycleDuration && this._initted) {\n            // 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).\n            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.\n\n            this.render(_roundPrecise(cycleDuration * iteration), true).invalidate()._lock = 0;\n          }\n        }\n      }\n\n      if (!this._initted) {\n        if (_attemptInitTween(this, isNegative ? totalTime : time, force, suppressEvents, tTime)) {\
1n          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.\n\n          return this;\n        }\n\n        if (prevTime !== this._time && !(force && this.vars.repeatRefresh && iteration !== prevIteration)) {\n          // 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!\n          return this;\n        }\n\n        if (dur !== this._dur) {\n          // while initting, a plugin like InertiaPlugin might alter the duration, so rerun from the start to ensure everything renders as it should.\n          return this.render(totalTime, suppressEvents, force);\n        }\n      }\n\n      if (this._rEase) {\n        var inv = time < prevTime;\n\n        if (inv !== this._inv) {\n          var segDur = inv ? prevTime : dur - prevTime;\n          this._inv = inv;\n          if (this._from) this.ratio = 1 - this.ratio;\n          this._invRatio = this.ratio;\n          this._invTime = prevTime;\n          this._invRecip = segDur ? (inv ? -1 : 1) / segDur : 0;\n          this._invScale = inv ? -this.ratio : 1 - this.ratio;\n          this._invEase = inv ? this._rEase : this._ease;\n        }\n\n        this.ratio = ratio = this._invRatio + this._invScale * this._invEase((time - this._invTime) * this._invRecip);\n      } else {\n        this.ratio = ratio = this._ease(time / dur);\n      }\n\n      if (this._from) this.ratio = ratio = 1 - ratio;\n      this._tTime = tTime;\n      this._time = time;\n\n      if (!this._act && this._ts) {\n        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.\n\n        this._lazy = 0;\n      }\n\n      if (!prevTime && tTime && !suppressEvents && !prevIteration) {\n        _callback(this, "onStart");\n\n        if (this._tTime !== tTime) {\n          // 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.\n          return this;\n        }\n      }\n\n      pt = this._pt;\n\n      while (pt) {\n        pt.r(ratio, pt.d);\n        pt = pt._next;\n      }\n\n      timeline && timeline.render(totalTime < 0 ? totalTime : timeline._dur * timeline._ease(time / this._dur), suppressEvents, force) || this._startAt && (this._zTime = totalTime);\n\n      if (this._onUpdate && !suppressEvents) {\n        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.\n\n        _callback(this, "onUpdate");\n      }\n\n      this._repeat && iteration !== prevIteration && this.vars.onRepeat && !suppressEvents && this.parent && _callback(this, "onRepeat");\n\n      if ((tTime === this._tDur || !tTime) && this._tTime === tTime) {\n        isNegative && !this._onUpdate && _rewindStartAt(this, totalTime, true, true);\n        (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.\n\n        if (!suppressEvents && !(isNegative && !prevTime) && (tTime || prevTime || isYoyo)) {\n          // if prevTime and tTime are zero, we shouldn\'t fire the onReverseComplete. This could happen if you gsap.to(... {paused:true}).play();\n          _callback(this, tTime === tDur ? "onComplete" : "onReverseComplete", true);\n\n          this._prom && !(tTime < tDur && this.timeScale() > 0) && this._prom();\n        }\n      }\n    }\n\n    return this;\n  };\n\n  _proto3.targets = function targets() {\n    return this._targets;\n  };
1\n\n  _proto3.invalidate = function invalidate(soft) {\n    // "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.\n    (!soft || !this.vars.runBackwards) && (this._startAt = 0);\n    this._pt = this._op = this._onUpdate = this._lazy = this.ratio = 0;\n    this._ptLookup = [];\n    this.timeline && this.timeline.invalidate(soft);\n    return _Animation2.prototype.invalidate.call(this, soft);\n  };\n\n  _proto3.resetTo = function resetTo(property, value, start, startIsRelative, skipRecursion) {\n    _tickerActive || _ticker.wake();\n    this._ts || this.play();\n    var time = Math.min(this._dur, (this._dp._time - this._start) * this._ts),\n        ratio;\n    this._initted || _initTween(this, time);\n    ratio = this._ease(time / this._dur); // don\'t just get tween.ratio because it may not have rendered yet.\n    // 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.\n    // if (_isObject(property)) { // performance optimization\n    // \tfor (p in property) {\n    // \t\tif (_updatePropTweens(this, p, property[p], value ? value[p] : null, start, ratio, time)) {\n    // \t\t\treturn 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.\n    // \t\t}\n    // \t}\n    // } else {\n\n    if (_updatePropTweens(this, property, value, start, startIsRelative, ratio, time, skipRecursion)) {\n      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.\n    } //}\n\n\n    _alignPlayhead(this, 0);\n\n    this.parent || _addLinkedListItem(this._dp, this, "_first", "_last", this._dp._sort ? "_start" : 0);\n    return this.render(0);\n  };\n\n  _proto3.kill = function kill(targets, vars) {\n    if (vars === void 0) {\n      vars = "all";\n    }\n\n    if (!targets && (!vars || vars === "all")) {\n      this._lazy = this._pt = 0;\n      this.parent ? _interrupt(this) : this.scrollTrigger && this.scrollTrigger.kill(!!_reverting);\n      return this;\n    }\n\n    if (this.timeline) {\n      var tDur = this.timeline.totalDuration();\n      this.timeline.killTweensOf(targets, vars, _overwritingTween && _overwritingTween.vars.overwrite !== true)._first || _interrupt(this); // if nothing is left tweening, interrupt.\n\n      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.\n\n      return this;\n    }\n\n    var parsedTargets = this._targets,\n        killingTargets = targets ? toArray(targets) : parsedTargets,\n        propTweenLookup = this._ptLookup,\n        firstPT = this._pt,\n        overwrittenProps,\n        curLookup,\n        curOverwriteProps,\n        props,\n        p,\n        pt,\n        i;\n\n    if ((!vars || vars === "all") && _arraysMatch(parsedTargets, killingTargets)) {\n      vars === "all" && (this._pt = 0);\n      return _interrupt(this);\n    }\n\n    overwrittenProps = this._op = this._op || [];\n\n    if (vars !== "all") {\n      //so people can pass in a comma-delimited list of property names\n      if (_isString(vars)) {\n        p = {};
1\n\n        _forEachName(vars, function (name) {\n          return p[name] = 1;\n        });\n\n        vars = p;\n      }\n\n      vars = _addAliasesToVars(parsedTargets, vars);\n    }\n\n    i = parsedTargets.length;\n\n    while (i--) {\n      if (~killingTargets.indexOf(parsedTargets[i])) {\n        curLookup = propTweenLookup[i];\n\n        if (vars === "all") {\n          overwrittenProps[i] = vars;\n          props = curLookup;\n          curOverwriteProps = {};\n        } else {\n          curOverwriteProps = overwrittenProps[i] = overwrittenProps[i] || {};\n          props = vars;\n        }\n\n        for (p in props) {\n          pt = curLookup && curLookup[p];\n\n          if (pt) {\n            if (!("kill" in pt.d) || pt.d.kill(p) === true) {\n              _removeLinkedListItem(this, pt, "_pt");\n            }\n\n            delete curLookup[p];\n          }\n\n          if (curOverwriteProps !== "all") {\n            curOverwriteProps[p] = 1;\n          }\n        }\n      }\n    }\n\n    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.\n\n    return this;\n  };\n\n  Tween.to = function to(targets, vars) {\n    return new Tween(targets, vars, arguments[2]);\n  };\n\n  Tween.from = function from(targets, vars) {\n    return _createTweenType(1, arguments);\n  };\n\n  Tween.delayedCall = function delayedCall(delay, callback, params, scope) {\n    return new Tween(callback, 0, {\n      immediateRender: false,\n      lazy: false,\n      overwrite: false,\n      delay: delay,\n      onComplete: callback,\n      onReverseComplete: callback,\n      onCompleteParams: params,\n      onReverseCompleteParams: params,\n      callbackScope: scope\n    }); // we must use onReverseComplete too for things like timeline.add(() => {...}) which should be triggered in BOTH directions (forward and reverse)\n  };\n\n  Tween.fromTo = function fromTo(targets, fromVars, toVars) {\n    return _createTweenType(2, arguments);\n  };\n\n  Tween.set = function set(targets, vars) {\n    vars.duration = 0;\n    vars.repeatDelay || (vars.repeat = 0);\n    return new Tween(targets, vars);\n  };\n\n  Tween.killTweensOf = function killTweensOf(targets, props, onlyActive) {\n    return _globalTimeline.killTweensOf(targets, props, onlyActive);\n  };\n\n  return Tween;\n}(Animation);\n\n_setDefaults(Tween.prototype, {\n  _targets: [],\n  _lazy: 0,\n  _startAt: 0,\n  _op: 0,\n  _onInit: 0\n}); //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)\n// _forEachName("to,from,fromTo,set,call,add,addLabel,addPause", name => {\n// \tTween.prototype[name] = function() {\n// \t\tlet tl = new Timeline();\n// \t\treturn _addToTimeline(tl, this)[name].apply(tl, toArray(arguments));\n// \t}\n// });\n//for backward compatibility. Leverage the timeline calls.\n\n\n_forEachName("staggerTo,staggerFrom,staggerFromTo", function (name) {\n  Tween[name] = function () {\n    var tl = new Timeline(),\n        params = _slice.call(arguments, 0);\n\n    params.splice(name === "staggerFromTo" ? 5 : 4, 0, 0);\n    return tl[name].apply(tl, params);\n  };\n});\n/*\n * --------------------------------------------------------------------------------------\n * PROPTWEEN\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _setterPlain = function _setterPlain(target, property, value) {\n  return target[property] = value;\n},\n    _setterFunc = function _setterFunc(target, property, value) {\n  return target[property](value);\n},\n    _setterFuncWithParam = function _setterFuncWithParam(target, property, value, data) {\n  return target[property](data.fp, value);\n},\n    _setterAttribute = function _setterAttribute(target, property, value) {\n  return target.setAttribute(property, value);\n},\n    _getSetter = function _getSetter(target, property) {\n  return _isFunction(target[property]) ? _setterFunc : _isUndefined(target[property]) && target.setAttribute ? _setterAttribute : _setterPlain;\n}
1,\n    _renderPlain = function _renderPlain(ratio, data) {\n  return data.set(data.t, data.p, Math.round((data.s + data.c * ratio) * 1000000) / 1000000, data);\n},\n    _renderBoolean = function _renderBoolean(ratio, data) {\n  return data.set(data.t, data.p, !!(data.s + data.c * ratio), data);\n},\n    _renderComplexString = function _renderComplexString(ratio, data) {\n  var pt = data._pt,\n      s = "";\n\n  if (!ratio && data.b) {\n    //b = beginning string\n    s = data.b;\n  } else if (ratio === 1 && data.e) {\n    //e = ending string\n    s = data.e;\n  } else {\n    while (pt) {\n      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.\n\n      pt = pt._next;\n    }\n\n    s += data.c; //we use the "c" of the PropTween to store the final chunk of non-numeric text.\n  }\n\n  data.set(data.t, data.p, s, data);\n},\n    _renderPropTweens = function _renderPropTweens(ratio, data) {\n  var pt = data._pt;\n\n  while (pt) {\n    pt.r(ratio, pt.d);\n    pt = pt._next;\n  }\n},\n    _addPluginModifier = function _addPluginModifier(modifier, tween, target, property) {\n  var pt = this._pt,\n      next;\n\n  while (pt) {\n    next = pt._next;\n    pt.p === property && pt.modifier(modifier, tween, target);\n    pt = next;\n  }\n},\n    _killPropTweensOf = function _killPropTweensOf(property) {\n  var pt = this._pt,\n      hasNonDependentRemaining,\n      next;\n\n  while (pt) {\n    next = pt._next;\n\n    if (pt.p === property && !pt.op || pt.op === property) {\n      _removeLinkedListItem(this, pt, "_pt");\n    } else if (!pt.dep) {\n      hasNonDependentRemaining = 1;\n    }\n\n    pt = next;\n  }\n\n  return !hasNonDependentRemaining;\n},\n    _setterWithModifier = function _setterWithModifier(target, property, value, data) {\n  data.mSet(target, property, data.m.call(data.tween, value, data.mt), data);\n},\n    _sortPropTweensByPriority = function _sortPropTweensByPriority(parent) {\n  var pt = parent._pt,\n      next,\n      pt2,\n      first,\n      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)\n\n  while (pt) {\n    next = pt._next;\n    pt2 = first;\n\n    while (pt2 && pt2.pr > pt.pr) {\n      pt2 = pt2._next;\n    }\n\n    if (pt._prev = pt2 ? pt2._prev : last) {\n      pt._prev._next = pt;\n    } else {\n      first = pt;\n    }\n\n    if (pt._next = pt2) {\n      pt2._prev = pt;\n    } else {\n      last = pt;\n    }\n\n    pt = next;\n  }\n\n  parent._pt = first;\n}; //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)\n\n\nvar PropTween = /*#__PURE__*/function () {\n  function PropTween(next, target, prop, start, change, renderer, data, setter, priority) {\n    this.t = target;\n    this.s = start;\n    this.c = change;\n    this.p = prop;\n    this.r = renderer || _renderPlain;\n    this.d = data || this;\n    this.set = setter || _setterPlain;\n    this.pr = priority || 0;\n    this._next = next;\n\n    if (next) {\n      next._prev = this;\n    }\n  }\n\n  var _proto4 = PropTween.prototype;\n\n  _proto4.modifier = function modifier(func, tween, target) {\n    this.mSet = this.mSet || this.set; //in case it was already set (a PropTween can only have one modifier)\n\n    this.set = _setterWithModifier;\n    this.m = func;\n    this.mt = target; //modifier target\n\n    this.tween = tween;\n  };\n\n  return PropTween;\n}(); //Initialization tasks\n\n_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,easeReverse", function (name) {\n  return _reservedProps[name] = 1;\n});\n\n_globals.TweenMax = _globals.TweenLite = Tween;\n_globals.TimelineLite = _globals.TimelineMax = Timeline;\n_globalTimeline = new Timeline({\n  sortChildren: false,\n  defaults: _defaults,\n  autoRemoveChildren: true,\n  id: "root",\n  smoothChildTiming: true\n});\n_config.stringFilter = _colorStringFilter;\n\nvar _media = [],\n    _listeners = {},\n    _emptyArray = [],\n    _lastMediaTime = 0,\n    _contextID = 0,\n    _dispatch = function _dispatch(type) {\n  return (_listeners[type] || _emptyArray).map(function (f) {\n    return f();\n  });\n},\n    _onMediaChange = function _onMediaChange() {\n  var time = Date.now(),\n      matches = [];\n\n  if (time - _lastMediaTime > 2) {\n    _dispatch("matchMediaInit");
1\n\n    _media.forEach(function (c) {\n      var queries = c.queries,\n          conditions = c.conditions,\n          match,\n          p,\n          anyMatch,\n          toggled;\n\n      for (p in queries) {\n        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.\n\n        match && (anyMatch = 1);\n\n        if (match !== conditions[p]) {\n          conditions[p] = match;\n          toggled = 1;\n        }\n      }\n\n      if (toggled) {\n        c.revert();\n        anyMatch && matches.push(c);\n      }\n    });\n\n    _dispatch("matchMediaRevert");\n\n    matches.forEach(function (c) {\n      return c.onMatch(c, function (func) {\n        return c.add(null, func);\n      });\n    });\n    _lastMediaTime = time;\n\n    _dispatch("matchMedia");\n  }\n};\n\nvar Context = /*#__PURE__*/function () {\n  function Context(func, scope) {\n    this.selector = scope && selector(scope);\n    this.data = [];\n    this._r = []; // returned/cleanup functions\n\n    this.isReverted = false;\n    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\n\n    func && this.add(func);\n  }\n\n  var _proto5 = Context.prototype;\n\n  _proto5.add = function add(name, func, scope) {\n    // 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.\n    // if (name && _isFunction(name.revert)) {\n    // \tthis.data.push(name);\n    // \treturn (name._ctx = this);\n    // }\n    if (_isFunction(name)) {\n      scope = func;\n      func = name;\n      name = _isFunction;\n    }\n\n    var self = this,\n        f = function f() {\n      var prev = _context,\n          prevSelector = self.selector,\n          result;\n      prev && prev !== self && prev.data.push(self);\n      scope && (self.selector = selector(scope));\n      _context = self;\n      result = func.apply(self, arguments);\n      _isFunction(result) && self._r.push(result);\n      _context = prev;\n      self.selector = prevSelector;\n      self.isReverted = false;\n      return result;\n    };\n\n    self.last = f;\n    return name === _isFunction ? f(self, function (func) {\n      return self.add(null, func);\n    }) : name ? self[name] = f : f;\n  };\n\n  _proto5.ignore = function ignore(func) {\n    var prev = _context;\n    _context = null;\n    func(this);\n    _context = prev;\n  };\n\n  _proto5.getTweens = function getTweens() {\n    var a = [];\n    this.data.forEach(function (e) {\n      return e instanceof Context ? a.push.apply(a, e.getTweens()) : e instanceof Tween && !(e.parent && e.parent.data === "nested") && a.push(e);\n    });\n    return a;\n  };\n\n  _proto5.clear = function clear() {\n    this._r.length = this.data.length = 0;\n  };\n\n  _proto5.kill = function kill(revert, matchMedia) {\n    var _this4 = this;\n\n    if (revert) {\n      (function () {\n        var tweens = _this4.getTweens(),\n            i = _this4.data.length,\n            t;\n\n        while (i--) {\n          // 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.\n          t = _this4.data[i];\n\n          if (t.data === "isFlip") {\n            t.revert();\n            t.getChildren(true, true, false).forEach(function (tween) {\n              return tweens.splice(tweens.indexOf(tween), 1);\n            });\n          }\n        } // save as an object so that we can cache the globalTime for each tween to optimize performance during the sort\n\n\n        tweens.map(function (t) {\n          return {\n            g: t._dur || t._delay || t._sat && !t._sat.vars.immediateRender ? t.globalTime(0) : -Infinity,\n            t: t\n          };\n        }).sort(function (a, b) {\n          return b.g - a.g || -Infinity;\n        }
1).forEach(function (o) {\n          return o.t.revert(revert);\n        }); // 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.\n\n        i = _this4.data.length;\n\n        while (i--) {\n          // make sure we loop backwards so that, for example, SplitTexts that were created later on the same element get reverted first\n          t = _this4.data[i];\n\n          if (t instanceof Timeline) {\n            if (t.data !== "nested") {\n              t.scrollTrigger && t.scrollTrigger.revert();\n              t.kill(); // don\'t revert() the timeline because that\'s duplicating efforts since we already reverted all the tweens\n            }\n          } else {\n            !(t instanceof Tween) && t.revert && t.revert(revert);\n          }\n        }\n\n        _this4._r.forEach(function (f) {\n          return f(revert, _this4);\n        });\n\n        _this4.isReverted = true;\n      })();\n    } else {\n      this.data.forEach(function (e) {\n        return e.kill && e.kill();\n      });\n    }\n\n    this.clear();\n\n    if (matchMedia) {\n      var i = _media.length;\n\n      while (i--) {\n        // 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.\n        _media[i].id === this.id && _media.splice(i, 1);\n      }\n    }\n  } // killWithCleanup() {\n  // \tthis.kill();\n  // \tthis._r.forEach(f => f(false, this));\n  // }\n  ;\n\n  _proto5.revert = function revert(config) {\n    this.kill(config || {});\n  };\n\n  return Context;\n}();\n\nvar MatchMedia = /*#__PURE__*/function () {\n  function MatchMedia(scope) {\n    this.contexts = [];\n    this.scope = scope;\n    _context && _context.data.push(this);\n  }\n\n  var _proto6 = MatchMedia.prototype;\n\n  _proto6.add = function add(conditions, func, scope) {\n    _isObject(conditions) || (conditions = {\n      matches: conditions\n    });\n    var context = new Context(0, scope || this.scope),\n        cond = context.conditions = {},\n        mq,\n        p,\n        active;\n    _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()\n\n    this.contexts.push(context);\n    func = context.add("onMatch", func);\n    context.queries = conditions;\n\n    for (p in conditions) {\n      if (p === "all") {\n        active = 1;\n      } else {\n        mq = _win.matchMedia(conditions[p]);\n\n        if (mq) {\n          _media.indexOf(context) < 0 && _media.push(context);\n          (cond[p] = mq.matches) && (active = 1);\n          mq.addListener ? mq.addListener(_onMediaChange) : mq.addEventListener("change", _onMediaChange);\n        }\n      }\n    }\n\n    active && func(context, function (f) {\n      return context.add(null, f);\n    });\n    return this;\n  } // refresh() {\n  // \tlet time = _lastMediaTime,\n  // \t\tmedia = _media;\n  // \t_lastMediaTime = -1;\n  // \t_media = this.contexts;\n  // \t_onMediaChange();\n  // \t_lastMediaTime = time;\n  // \t_media = media;\n  // }\n  ;\n\n  _proto6.revert = function revert(config) {\n    this.kill(config || {});\n  };\n\n  _proto6.kill = function kill(revert) {\n    this.contexts.forEac
1h(function (c) {\n      return c.kill(revert, true);\n    });\n  };\n\n  return MatchMedia;\n}();\n/*\n * --------------------------------------------------------------------------------------\n * GSAP\n * --------------------------------------------------------------------------------------\n */\n\n\nvar _gsap = {\n  registerPlugin: function registerPlugin() {\n    for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {\n      args[_key2] = arguments[_key2];\n    }\n\n    args.forEach(function (config) {\n      return _createPlugin(config);\n    });\n  },\n  timeline: function timeline(vars) {\n    return new Timeline(vars);\n  },\n  getTweensOf: function getTweensOf(targets, onlyActive) {\n    return _globalTimeline.getTweensOf(targets, onlyActive);\n  },\n  getProperty: function getProperty(target, property, unit, uncache) {\n    _isString(target) && (target = toArray(target)[0]); //in case selector text or an array is passed in\n\n    var getter = _getCache(target || {}).get,\n        format = unit ? _passThrough : _numericIfPossible;\n\n    unit === "native" && (unit = "");\n    return !target ? target : !property ? function (property, unit, uncache) {\n      return format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n    } : format((_plugins[property] && _plugins[property].get || getter)(target, property, unit, uncache));\n  },\n  quickSetter: function quickSetter(target, property, unit) {\n    target = toArray(target);\n\n    if (target.length > 1) {\n      var setters = target.map(function (t) {\n        return gsap.quickSetter(t, property, unit);\n      }),\n          l = setters.length;\n      return function (value) {\n        var i = l;\n\n        while (i--) {\n          setters[i](value);\n        }\n      };\n    }\n\n    target = target[0] || {};\n\n    var Plugin = _plugins[property],\n        cache = _getCache(target),\n        p = cache.harness && (cache.harness.aliases || {})[property] || property,\n        // in case it\'s an alias, like "rotate" for "rotation".\n    setter = Plugin ? function (value) {\n      var p = new Plugin();\n      _quickTween._pt = 0;\n      p.init(target, unit ? value + unit : value, _quickTween, 0, [target]);\n      p.render(1, p);\n      _quickTween._pt && _renderPropTweens(1, _quickTween);\n    } : cache.set(target, p);\n\n    return Plugin ? setter : function (value) {\n      return setter(target, p, unit ? value + unit : value, cache, 1);\n    };\n  },\n  quickTo: function quickTo(target, property, vars) {\n    var _setDefaults2;\n\n    var tween = gsap.to(target, _setDefaults((_setDefaults2 = {}, _setDefaults2[property] = "+=0.1", _setDefaults2.paused = true, _setDefaults2.stagger = 0, _setDefaults2), vars || {})),\n        func = function func(value, start, startIsRelative) {\n      return tween.resetTo(property, value, start, startIsRelative);\n    };\n\n    func.tween = tween;\n    return func;\n  },\n  isTweening: function isTweening(targets) {\n    return _globalTimeline.getTweensOf(targets, true).length > 0;\n  },\n  defaults: function defaults(value) {\n    value && value.ease && (value.ease = _parseEase(value.ease, _defaults.ease));\n    return _mergeDeep(_defaults, value || {});\n  },\n  config: function config(value) {\n    return _mergeDeep(_config, value || {});\n  },\n  registerEffect: function registerEffect(_ref3) {\n    var name = _ref3.name,\n        effect = _ref3.effect,\n        plugins = _ref3.plugins,\n        defaults = _ref3.defaults,\n        extendTimeline = _ref3.extendTimeline;\n    (plugins || "").split(",").forEach(function (pluginName) {\n      return pluginName && !_plugins[pluginName] && !_globals[pluginName] && _warn(name + " effect requires " + pluginName + " plugin.");\n    });\n\n    _effects[name] = function (targets, vars, tl) {\n      return effect(toArray(targets), _setDefaults(vars || {}, defaults), tl);\n    };\n\n    if (extendTimeline) {\n      Timeline.prototype[name] = function (targets, vars, position) {\n        return this.add(_effects[name](targets, _isObject(vars) ? vars : (position = vars) && {}, this), position);\n      };\n    }\n  },\n  registerEase: function registerEase(name, ease) {\n    _easeMap[name] = _parseEase(ease);\n  },\n  parseEase: function parseEase(ease, defaultEase) {\n    return arguments.length ? _parseEase(ease, defaultEase) : _easeMap;\n  },\n  getById: function getById(id) {\n    return _globalTimeline.getById(id);\n  },\n  exportRoot: function exportRoot(vars, includeDelayedCalls) {\n    if (vars === void 0) {\n      vars = {};\n    }\n\n    var tl = new Timeline(vars),\n        child,\n        next;\n    tl.smoothChildTiming = _isNotFalse(vars.smoothChildTiming);\n\n    _globalTimeline.remove(tl);\n\n    tl._dp = 0;
1 //otherwise it\'ll get re-activated when adding children and be re-introduced into _globalTimeline\'s linked list (then added to itself).\n\n    tl._time = tl._tTime = _globalTimeline._time;\n    child = _globalTimeline._first;\n\n    while (child) {\n      next = child._next;\n\n      if (includeDelayedCalls || !(!child._dur && child instanceof Tween && child.vars.onComplete === child._targets[0])) {\n        _addToTimeline(tl, child, child._start - child._delay);\n      }\n\n      child = next;\n    }\n\n    _addToTimeline(_globalTimeline, tl, 0);\n\n    return tl;\n  },\n  context: function context(func, scope) {\n    return func ? new Context(func, scope) : _context;\n  },\n  matchMedia: function matchMedia(scope) {\n    return new MatchMedia(scope);\n  },\n  matchMediaRefresh: function matchMediaRefresh() {\n    return _media.forEach(function (c) {\n      var cond = c.conditions,\n          found,\n          p;\n\n      for (p in cond) {\n        if (cond[p]) {\n          cond[p] = false;\n          found = 1;\n        }\n      }\n\n      found && c.revert();\n    }) || _onMediaChange();\n  },\n  addEventListener: function addEventListener(type, callback) {\n    var a = _listeners[type] || (_listeners[type] = []);\n    ~a.indexOf(callback) || a.push(callback);\n  },\n  removeEventListener: function removeEventListener(type, callback) {\n    var a = _listeners[type],\n        i = a && a.indexOf(callback);\n    i >= 0 && a.splice(i, 1);\n  },\n  utils: {\n    wrap: wrap,\n    wrapYoyo: wrapYoyo,\n    distribute: distribute,\n    random: random,\n    snap: snap,\n    normalize: normalize,\n    getUnit: getUnit,\n    clamp: clamp,\n    splitColor: splitColor,\n    toArray: toArray,\n    selector: selector,\n    mapRange: mapRange,\n    pipe: pipe,\n    unitize: unitize,\n    interpolate: interpolate,\n    shuffle: shuffle\n  },\n  install: _install,\n  effects: _effects,\n  ticker: _ticker,\n  updateRoot: Timeline.updateRoot,\n  plugins: _plugins,\n  globalTimeline: _globalTimeline,\n  core: {\n    PropTween: PropTween,\n    globals: _addGlobal,\n    Tween: Tween,\n    Timeline: Timeline,\n    Animation: Animation,\n    getCache: _getCache,\n    _removeLinkedListItem: _removeLinkedListItem,\n    reverting: function reverting() {\n      return _reverting;\n    },\n    context: function context(toAdd) {\n      if (toAdd && _context) {\n        _context.data.push(toAdd);\n\n        toAdd._ctx = _context;\n      }\n\n      return _context;\n    },\n    suppressOverwrites: function suppressOverwrites(value) {\n      return _suppressOverwrites = value;\n    }\n  }\n};\n\n_forEachName("to,from,fromTo,delayedCall,set,killTweensOf", function (name) {\n  return _gsap[name] = Tween[name];\n});\n\n_ticker.add(Timeline.updateRoot);\n\n_quickTween = _gsap.to({}, {\n  duration: 0\n}); // ---- EXTRA PLUGINS --------------------------------------------------------\n\nvar _getPluginPropTween = function _getPluginPropTween(plugin, prop
1) {\n  var pt = plugin._pt;\n\n  while (pt && pt.p !== prop && pt.op !== prop && pt.fp !== prop) {\n    pt = pt._next;\n  }\n\n  return pt;\n},\n    _addModifiers = function _addModifiers(tween, modifiers) {\n  var targets = tween._targets,\n      p,\n      i,\n      pt;\n\n  for (p in modifiers) {\n    i = targets.length;\n\n    while (i--) {\n      pt = tween._ptLookup[i][p];\n\n      if (pt && (pt = pt.d)) {\n        if (pt._pt) {\n          // is a plugin\n          pt = _getPluginPropTween(pt, p);\n        }\n\n        pt && pt.modifier && pt.modifier(modifiers[p], tween, targets[i], p);\n      }\n    }\n  }\n},\n    _buildModifierPlugin = function _buildModifierPlugin(name, modifier) {\n  return {\n    name: name,\n    headless: 1,\n    rawVars: 1,\n    //don\'t pre-process function-based values or "random()" strings.\n    init: function init(target, vars, tween) {\n      tween._onInit = function (tween) {\n        var temp, p;\n\n        if (_isString(vars)) {\n          temp = {};\n\n          _forEachName(vars, function (name) {\n            return temp[name] = 1;\n          }); //if the user passes in a comma-delimited list of property names to roundProps, like "x,y", we round to whole numbers.\n\n\n          vars = temp;\n        }\n\n        if (modifier) {\n          temp = {};\n\n          for (p in vars) {\n            temp[p] = modifier(vars[p]);\n          }\n\n          vars = temp;\n        }\n\n        _addModifiers(tween, vars);\n      };\n    }\n  };\n}; //register core plugins\n\n\nvar gsap = _gsap.registerPlugin({\n  name: "attr",\n  init: function init(target, vars, tween, index, targets) {\n    var p, pt, v;\n    this.tween = tween;\n\n    for (p in vars) {\n      v = target.getAttribute(p) || "";\n      pt = this.add(target, "setAttribute", (v || 0) + "", vars[p], index, targets, 0, 0, p);\n      pt.op = p;\n      pt.b = v; // record the beginning value so we can revert()\n\n      this._props.push(p);\n    }\n  },\n  render: function render(ratio, data) {\n    var pt = data._pt;\n\n    while (pt) {\n      _reverting ? pt.set(pt.t, pt.p, pt.b, pt) : pt.r(ratio, pt.d); // if reverting, go back to the original (pt.b)\n\n      pt = pt._next;\n    }\n  }\n}, {\n  name: "endArray",\n  headless: 1,\n  init: function init(target, value) {\n    var i = value.length;\n\n    while (i--) {\n      this.add(target, i, target[i] || 0, value[i], 0, 0, 0, 0, 0, 1);\n    }\n  }\n}, _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.\n\nTween.version = Timeline.version = gsap.version = "3.15.0";\n_coreReady = 1;\n_windowExists() && _wake();\nvar Power0 = _easeMap.Power0,\n    Power1 = _easeMap.Power1,\n    Power2 = _easeMap.Power2,\n    Power3 = _easeMap.Power3,\n    Power4 = _easeMap.Power4,\n    Linear = _easeMap.Linear,\n    Quad = _easeMap.Quad,\n    Cubic = _easeMap.Cubic,\n    Quart = _easeMap.Quart,\n    Quint = _easeMap.Quint,\n    Strong = _easeMap.Strong,\n    Elastic = _easeMap.Elastic,\n    Back = _easeMap.Back,\n    SteppedEase = _easeMap.SteppedEase,\n    Bounce = _easeMap.Bounce,\n    Sine = _easeMap.Sine,\n    Expo = _easeMap.Expo,\n    Circ = _easeMap.Circ;\n\n //export some internal methods/orojects for use in CSSPlugin so that we can externalize that file and allow custom builds that exclude it.\n\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/gsap-core.js?\n}')},"./node_modules/gsap/index.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Back: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Back),\n/* harmony export */   Bounce: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Bounce),\n/* harmony export */   CSSPlugin: () => (/* reexport safe */ _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__.CSSPlugin),\n/* harmony export */   Circ: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Circ),\n/* harmony export */   Cubic: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Cubic),\n/* harmony export */   Elastic: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Elastic),\n/* harmony export */   Expo: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Expo),\n/* harmony export */   Linear: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Linear),\n/* harmony export */   Power0: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power0),\n
1/* harmony export */   Power1: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power1),\n/* harmony export */   Power2: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power2),\n/* harmony export */   Power3: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power3),\n/* harmony export */   Power4: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Power4),\n/* harmony export */   Quad: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quad),\n/* harmony export */   Quart: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quart),\n/* harmony export */   Quint: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Quint),\n/* harmony export */   Sine: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Sine),\n/* harmony export */   SteppedEase: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.SteppedEase),\n/* harmony export */   Strong: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.Strong),\n/* harmony export */   TimelineLite: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineLite),\n/* harmony export */   TimelineMax: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TimelineMax),\n/* harmony export */   TweenLite: () => (/* reexport safe */ _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__.TweenLite),\n/* harmony export */   TweenMax: () => (/* binding */ TweenMaxWithCSS),\n/* harmony export */   "default": () => (/* binding */ gsapWithCSS),\n/* harmony export */   gsap: () => (/* binding */ gsapWithCSS)\n/* harmony export */ });\n/* harmony import */ var _gsap_core_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./gsap-core.js */ "./node_modules/gsap/gsap-core.js");\n/* harmony import */ var _CSSPlugin_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./CSSPlugin.js */ "./node_modules/gsap/CSSPlugin.js");\n\n\nvar 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,\n    // to protect from tree shaking\nTweenMaxWithCSS = gsapWithCSS.core.Tween;\n\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/index.js?\n}')},"./node_modules/gsap/utils/matrix.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Matrix2D: () => (/* binding */ Matrix2D),\n/* harmony export */   _getCTM: () => (/* binding */ _getCTM),\n/* harmony export */   _getDocScrollLeft: () => (/* binding */ _getDocScrollLeft),\n/* harmony export */   _getDocScrollTop: () => (/* binding */ _getDocScrollTop),\n/* harmony export */   _isFixed: () => (/* binding */ _isFixed),\n/* harmony export */   _setDoc: () => (/* binding */ _setDoc),\n/* harmony export */   getGlobalMatrix: () => (/* binding */ getGlobalMatrix)\n/* harmony export */ });\n/*!\n * matrix 3.15.0\n * https://gsap.com\n *\n * Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar _doc,\n    _win,\n    _docElement,\n    _body,\n    _divContainer,\n    _svgContainer,\n    _identityMatrix,\n    _gEl,\n    _transformProp = "transform",\n    _transformOriginProp = _transformProp + "Origin",\n    _hasOffsetBug,\n    _setDoc = function _setDoc(element) {\n  var doc = element.ownerDocument || element;\n\n  if (!(_transformProp in element.style) && "msTransform" in element.style) {\n    //to improve compatibility with old Microsoft browsers\n    _transformProp = "msTransform";\n    _transformOriginProp = _transformProp + "Origin";\n  }\n\n  while (doc.parentNode && (doc = doc.parentNode)) {}\n\n  _win = window;\n  _identityMatrix = new Matrix2D();\n\n  if (doc) {\n    _doc = doc;\n    _docElement = doc.documentElement;\n    _body = doc.body;\n    _gEl = _doc.createElementNS("http://www.w3.org/2000/svg", "g"); // prevent any existing CSS from transforming it\n\n    _gEl.style.transform = "none"; // now test for the offset reporting bug. Use feature detection instead of browser sniffing to make things more bulletproof and future-proof. Hopefully Safari will fix their bug soon.\n\n    var d1 = doc.createElement("div"),\n        d2 = doc.createElement("div"),\n        root = doc && (doc.body || doc.firstElementChild);\n\n    if (root && root.appendChild) {\n      root.appendChild(d1);\n      d1.appendChild(d2);\n      d1.style.position = "static";
1\n      d1.style.transform = "translate3d(0,0,1px)";\n      _hasOffsetBug = d2.offsetParent !== d1;\n      root.removeChild(d1);\n    }\n  }\n\n  return doc;\n},\n    _forceNonZeroScale = function _forceNonZeroScale(e) {\n  // walks up the element\'s ancestors and finds any that had their scale set to 0 via GSAP, and changes them to 0.0001 to ensure that measurements work. Firefox has a bug that causes it to incorrectly report getBoundingClientRect() when scale is 0.\n  var a, cache;\n\n  while (e && e !== _body) {\n    cache = e._gsap;\n    cache && cache.uncache && cache.get(e, "x"); // force re-parsing of transforms if necessary\n\n    if (cache && !cache.scaleX && !cache.scaleY && cache.renderTransform) {\n      cache.scaleX = cache.scaleY = 1e-4;\n      cache.renderTransform(1, cache);\n      a ? a.push(cache) : a = [cache];\n    }\n\n    e = e.parentNode;\n  }\n\n  return a;\n},\n    // possible future addition: pass an element to _forceDisplay() and it\'ll walk up all its ancestors and make sure anything with display: none is set to display: block, and if there\'s no parentNode, it\'ll add it to the body. It returns an Array that you can then feed to _revertDisplay() to have it revert all the changes it made.\n// _forceDisplay = e => {\n// \tlet a = [],\n// \t\tparent;\n// \twhile (e && e !== _body) {\n// \t\tparent = e.parentNode;\n// \t\t(_win.getComputedStyle(e).display === "none" || !parent) && a.push(e, e.style.display, parent) && (e.style.display = "block");\n// \t\tparent || _body.appendChild(e);\n// \t\te = parent;\n// \t}\n// \treturn a;\n// },\n// _revertDisplay = a => {\n// \tfor (let i = 0; i < a.length; i+=3) {\n// \t\ta[i+1] ? (a[i].style.display = a[i+1]) : a[i].style.removeProperty("display");\n// \t\ta[i+2] || a[i].parentNode.removeChild(a[i]);\n// \t}\n// },\n_svgTemps = [],\n    //we create 3 elements for SVG, and 3 for other DOM elements and cache them for performance reasons. They get nested in _divContainer and _svgContainer so that just one element is added to the DOM on each successive attempt. Again, performance is key.\n_divTemps = [],\n    _getDocScrollTop = function _getDocScrollTop() {\n  return _win.pageYOffset || _doc.scrollTop || _docElement.scrollTop || _body.scrollTop || 0;\n},\n    _getDocScrollLeft = function _getDocScrollLeft() {\n  return _win.pageXOffset || _doc.scrollLeft || _docElement.scrollLeft || _body.scrollLeft || 0;\n},\n    _svgOwner = function _svgOwner(element) {\n  return element.ownerSVGElement || ((element.tagName + "").toLowerCase() === "svg" ? element : null);\n},\n    _isFixed = function _isFixed(element) {\n  if (_win.getComputedStyle(element).position === "fixed") {\n    return true;\n  }\n\n  element = element.parentNode;\n\n  if (element && element.nodeType === 1) {\n    // avoid document fragments which will throw an error.\n    return _isFixed(element);\n  }\n},\n    _createSibling = function _createSibling(element, i) {\n  if (element.parentNode && (_doc || _setDoc(element))) {\n    var svg = _svgOwner(element),\n        ns = svg ? svg.getAttribute("xmlns") || "http://www.w3.org/2000/svg" : "http://www.w3.org/1999/xhtml",\n        type = svg ? i ? "rect" : "g" : "div",\n        x = i !== 2 ? 0 : 100,\n        y = i === 3 ? 100 : 0,\n        css = {\n      position: "absolute",\n      display: "block",\n      pointerEvents: "none",\n      margin: "0",\n      padding: "0"\n    },\n        e = _doc.createElementNS ? _doc.createElementNS(ns.replace(/^https/, "http"), type) : _doc.createElement(type);\n\n    if (i) {\n      if (!svg) {\n        if (!_divContainer) {\n          _divContainer = _createSibling(element);\n          Object.assign(_divContainer.style, css);\n        }\n\n        Object.assign(e.style, css, {\n          width: "0.1px",\n          height: "0.1px",\n          top: y + "px",\n          left: x + "px"\n        });\n\n        _divContainer.appendChild(e);\n      } else {\n        _svgContainer || (_svgContainer = _createSibling(element));\n        e.setAttribute("width", 0.01);\n        e.setAttribute("height", 0.01);\n        e.setAttribute("transform", "translate(" + x + "," + y + ")");\n        e.setAttribute("fill", "transparent");\n\n        _svgContainer.appendChild(e);\n      }\n    }\n\n    return e;\n  }\n\n  throw "Need document and parent.";\n},\n    _consolidate = function _consolidate(m) {\n  // replaces SVGTransformList.consolidate() because a bug in Firefox causes it to break pointer events. See https://gsap.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800\n  var c = new Matrix2D(),\n      i = 0;\n\n  for (; i < m.numberOfItems;
1 i++) {\n    c.multiply(m.getItem(i).matrix);\n  }\n\n  return c;\n},\n    _getCTM = function _getCTM(svg) {\n  var m = svg.getCTM(),\n      transform;\n\n  if (!m) {\n    // Firefox returns null for getCTM() on root <svg> elements, so this is a workaround using a <g> that we temporarily append.\n    transform = svg.style[_transformProp];\n    svg.style[_transformProp] = "none"; // a bug in Firefox causes css transforms to contaminate the getCTM()\n\n    svg.appendChild(_gEl);\n    m = _gEl.getCTM();\n    svg.removeChild(_gEl);\n    transform ? svg.style[_transformProp] = transform : svg.style.removeProperty(_transformProp.replace(/([A-Z])/g, "-$1").toLowerCase());\n  }\n\n  return m || _identityMatrix.clone(); // Firefox will still return null if the <svg> has a width/height of 0 in the browser.\n},\n    _placeSiblings = function _placeSiblings(element, adjustGOffset) {\n  var svg = _svgOwner(element),\n      isRootSVG = element === svg,\n      siblings = svg ? _svgTemps : _divTemps,\n      parent = element.parentNode,\n      appendToEl = parent && !svg && parent.shadowRoot && parent.shadowRoot.appendChild ? parent.shadowRoot : parent,\n      container,\n      m,\n      b,\n      x,\n      y,\n      cs;\n\n  if (element === _win) {\n    return element;\n  }\n\n  siblings.length || siblings.push(_createSibling(element, 1), _createSibling(element, 2), _createSibling(element, 3));\n  container = svg ? _svgContainer : _divContainer;\n\n  if (svg) {\n    if (isRootSVG) {\n      b = _getCTM(element);\n      x = -b.e / b.a;\n      y = -b.f / b.d;\n      m = _identityMatrix;\n    } else if (element.getBBox) {\n      b = element.getBBox();\n      m = element.transform ? element.transform.baseVal : {}; // IE11 doesn\'t follow the spec.\n\n      m = !m.numberOfItems ? _identityMatrix : m.numberOfItems > 1 ? _consolidate(m) : m.getItem(0).matrix; // don\'t call m.consolidate().matrix because a bug in Firefox makes pointer events not work when consolidate() is called on the same tick as getBoundingClientRect()! See https://gsap.com/forums/topic/23248-touch-is-not-working-on-draggable-in-firefox-windows-v324/?tab=comments#comment-109800\n\n      x = m.a * b.x + m.c * b.y;\n      y = m.b * b.x + m.d * b.y;\n    } else {\n      // may be a <mask> which has no getBBox() so just use defaults instead of throwing errors.\n      m = new Matrix2D();\n      x = y = 0;\n    }\n\n    if (adjustGOffset && element.tagName.toLowerCase() === "g") {\n      x = y = 0;\n    }\n\n    (isRootSVG || !element.getBoundingClientRect().width ? svg : parent).appendChild(container); // check getBoundingClientRect().width because things inside a <mask>, for example, may return 0 in which case we need to move the element to the root SVG to properly measure things. An alternative would be to walk up the DOM and see if any ancestor is a nodeName of "mask" and if so, set parent to svg.\n\n    container.setAttribute("transform", "matrix(" 
1+ m.a + "," + m.b + "," + m.c + "," + m.d + "," + (m.e + x) + "," + (m.f + y) + ")");\n  } else {\n    x = y = 0;\n\n    if (_hasOffsetBug) {\n      // some browsers (like Safari) have a bug that causes them to misreport offset values. When an ancestor element has a transform applied, it\'s supposed to treat it as if it\'s position: relative (new context). Safari botches this, so we need to find the closest ancestor (between the element and its offsetParent) that has a transform applied and if one is found, grab its offsetTop/Left and subtract them to compensate.\n      m = element.offsetParent;\n      b = element;\n\n      while (b && (b = b.parentNode) && b !== m && b.parentNode) {\n        if ((_win.getComputedStyle(b)[_transformProp] + "").length > 4) {\n          x = b.offsetLeft;\n          y = b.offsetTop;\n          b = 0;\n        }\n      }\n    }\n\n    cs = _win.getComputedStyle(element);\n\n    if (cs.position !== "absolute" && cs.position !== "fixed") {\n      m = element.offsetParent;\n\n      while (parent && parent !== m) {\n        // if there\'s an ancestor element between the element and its offsetParent that\'s scrolled, we must factor that in.\n        x += parent.scrollLeft || 0;\n        y += parent.scrollTop || 0;\n        parent = parent.parentNode;\n      }\n    }\n\n    b = container.style;\n    b.top = element.offsetTop - y + "px";\n    b.left = element.offsetLeft - x + "px";\n    b[_transformProp] = cs[_transformProp];\n    b[_transformOriginProp] = cs[_transformOriginProp]; // b.border = m.border;\n    // b.borderLeftStyle = m.borderLeftStyle;\n    // b.borderTopStyle = m.borderTopStyle;\n    // b.borderLeftWidth = m.borderLeftWidth;\n    // b.borderTopWidth = m.borderTopWidth;\n\n    b.position = cs.position === "fixed" ? "fixed" : "absolute";\n    appendToEl.appendChild(container);\n  }\n\n  return container;\n},\n    _setMatrix = function _setMatrix(m, a, b, c, d, e, f) {\n  m.a = a;\n  m.b = b;\n  m.c = c;\n  m.d = d;\n  m.e = e;\n  m.f = f;\n  return m;\n};\n\nvar Matrix2D = /*#__PURE__*/function () {\n  function Matrix2D(a, b, c, d, e, f) {\n    if (a === void 0) {\n      a = 1;\n    }\n\n    if (b === void 0) {\n      b = 0;\n    }\n\n    if (c === void 0) {\n      c = 0;\n    }\n\n    if (d === void 0) {\n      d = 1;\n    }\n\n    if (e === void 0) {\n      e = 0;\n    }\n\n    if (f === void 0) {\n      f = 0;\n    }\n\n    _setMatrix(this, a, b, c, d, e, f);\n  }\n\n  var _proto = Matrix2D.prototype;\n\n  _proto.inverse = function inverse() {\n    var a = this.a,\n        b = this.b,\n        c = this.c,\n        d = this.d,\n        e = this.e,\n        f = this.f,\n        determinant = a * d - b * c || 1e-10;\n    return _setMatrix(this, d / determinant, -b / determinant, -c / determinant, a / determinant, (c * f - d * e) / determinant, -(a * f - b * e) / determinant);\n  };\n\n  _proto.multiply = function multiply(matrix) {\n    var a = this.a,\n        b = this.b,\n        c = this.c,\n        d = this.d,\n        e = this.e,\n        f = this.f,\n        a2 = matrix.a,\n        b2 = matrix.c,\n        c2 = matrix.b,\n        d2 = matrix.d,\n        e2 = matrix.e,\n        f2 = matrix.f;\n    return _setMatrix(this, a2 * a + c2 * c, a2 * b + c2 * d, b2 * a + d2 * c, b2 * b + d2 * d, e + e2 * a + f2 * c, f + e2 * b + f2 * d);\n  };\n\n  _proto.clone = function clone() {\n    return new Matrix2D(this.a, this.b, this.c, this.d, this.e, this.f);\n  };\n\n  _proto.equals = function equals(matrix) {\n    var a = this.a,\n        b = this.b,\n        c = this.c,\n        d = this.d,\n        e = this.e,\n        f = this.f;\n    return a === matrix.a && b === matrix.b && c === matrix.c && d === matrix.d && e === matrix.e && f === matrix.f;\n  };\n\n  _proto.apply = function apply(point, decoratee) {\n    if (decoratee === void 0) {\n      decoratee = {};\n    }\n\n    var x = point.x,\n        y = point.y,\n        a = this.a,\n        b = this.b,\n        c = this.c,\n        d = this.d,\n        e = this.e,\n        f = this.f;\n    decoratee.x = x * a + y * c + e || 0;\n    decoratee.y = x * b + y * d + f || 0;\n    return decoratee;\n  };\n\n  return Matrix2D;\n}(); // Feed in an element and it\'ll return a 2D matrix (optionally inverted) so that you can translate between coordinate space
1s.\n// Inverting lets you translate a global point into a local coordinate space. No inverting lets you go the other way.\n// We needed this to work around various browser bugs, like Firefox doesn\'t accurately report getScreenCTM() when there\n// are transforms applied to ancestor elements.\n// The matrix math to convert any x/y coordinate is as follows, which is wrapped in a convenient apply() method of Matrix2D above:\n//     tx = m.a * x + m.c * y + m.e\n//     ty = m.b * x + m.d * y + m.f\n\nfunction getGlobalMatrix(element, inverse, adjustGOffset, includeScrollInFixed) {\n  // adjustGOffset is typically used only when grabbing an element\'s PARENT\'s global matrix, and it ignores the x/y offset of any SVG <g> elements because they behave in a special way.\n  if (!element || !element.parentNode || (_doc || _setDoc(element)).documentElement === element) {\n    return new Matrix2D();\n  }\n\n  var zeroScales = _forceNonZeroScale(element),\n      svg = _svgOwner(element),\n      temps = svg ? _svgTemps : _divTemps,\n      container = _placeSiblings(element, adjustGOffset),\n      b1 = temps[0].getBoundingClientRect(),\n      b2 = temps[1].getBoundingClientRect(),\n      b3 = temps[2].getBoundingClientRect(),\n      parent = container.parentNode,\n      isFixed = !includeScrollInFixed && _isFixed(element),\n      m = new Matrix2D((b2.left - b1.left) / 100, (b2.top - b1.top) / 100, (b3.left - b1.left) / 100, (b3.top - b1.top) / 100, b1.left + (isFixed ? 0 : _getDocScrollLeft()), b1.top + (isFixed ? 0 : _getDocScrollTop()));\n\n  parent.removeChild(container);\n\n  if (zeroScales) {\n    b1 = zeroScales.length;\n\n    while (b1--) {\n      b2 = zeroScales[b1];\n      b2.scaleX = b2.scaleY = 0;\n      b2.renderTransform(1, b2);\n    }\n  }\n\n  return inverse ? m.inverse() : m;\n}\n // export function getMatrix(element) {\n// \t_doc || _setDoc(element);\n// \tlet m = (_win.getComputedStyle(element)[_transformProp] + "").substr(7).match(/[-.]*\\d+[.e\\-+]*\\d*[e\\-\\+]*\\d*/g),\n// \t\tis2D = m && m.length === 6;\n// \treturn !m || m.length < 6 ? new Matrix2D() : new Matrix2D(+m[0], +m[1], +m[is2D ? 2 : 4], +m[is2D ? 3 : 5], +m[is2D ? 4 : 12], +m[is2D ? 5 : 13]);\n// }\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/utils/matrix.js?\n}')},"./node_modules/gsap/utils/paths.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   bezierToPoints: () => (/* binding */ bezierToPoints),\n/* harmony export */   cacheRawPathMeasurements: () => (/* binding */ cacheRawPathMeasurements),\n/* harmony export */   convertToPath: () => (/* binding */ convertToPath),\n/* harmony export */   copyRawPath: () => (/* binding */ copyRawPath),\n/* harmony export */   flatPointsToSegment: () => (/* binding */ flatPointsToSegment),\n/* harmony export */   getClosestData: () => (/* binding */ getClosestData),\n/* harmony export */   getPositionOnPath: () => (/* binding */ getPositionOnPath),\n/* harmony export */   getRawPath: () => (/* binding */ getRawPath),\n/* harmony export */   getRotationAtProgress: () => (/* binding */ getRotationAtProgress),\n/* harmony export */   pointsToSegment: () => (/* binding */ pointsToSegment),\n/* harmony export */   rawPathToString: () => (/* binding */ rawPathToString),\n/* harmony export */   reverseSegment: () => (/* binding */ reverseSegment),\n/* harmony export */   segmentToDistributedPoints: () => (/* binding */ segmentToDistributedPoints),\n/* harmony export */   simplifyPoints: () => (/* binding */ simplifyPoints),\n/* harmony export */   sliceRawPath: () => (/* binding */ sliceRawPath),\n/* harmony export */   stringToRawPath: () => (/* binding */ stringToRawPath),\n/* harmony export */   subdivideSegment: () => (/* binding */ subdivideSegment),\n/* harmony export */   subdivideSegmentNear: () => (/* binding */ subdivideSegmentNear),\n/* harmony export */   transformRawPath: () => (/* binding */ transformRawPath)\n/* harmony export */ });\n/*!\n * paths 3.15.0\n * https://gsap.com\n *\n * Copyright 2008-2026, GreenSock. All rights reserved.\n * Subject to the terms at https://gsap.com/standard-license\n * @author: Jack Doyle, [email protected]\n*/\n\n/* eslint-disable */\nvar _svgPathExp = /[achlmqstvz]|(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[0-9]/ig,\n    _numbersExp = /(?:(-)?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[0-9]/ig,\n    _scientific = /[\\+\\-]?\\d*\\.?\\d+e[\\+\\-]?\\d+/ig,\n    _selectorExp = /(^[#\\.][a-z]|[a-y][a-z])/i,\n    _DEG2RAD = Math.PI / 180,\n    _RAD2DEG = 180 / Math.PI,\n    _sin = Math.sin,\n    _cos = Math.cos,\n    _abs = Math.abs,\n    _sqrt = Math.sqrt,\n    _atan2 = Math.atan2,\n    _largeNum = 1e8,\n    _isString = function _isString(value) {\n  return typeof value === "string";\n},\n    _isNumber = function _isNumber(value) {\n  return typeof value === "number";\n},\n    _isUndefined = function _isUndefined(value) {\n  return typeof value === "undefined";\n},\n    _temp = {},\n    _temp2 = {},\n    _roundingNum = 1e5,\n    _wrapProgress = function _wrapProgress(progress) {\n  return Math.round((progress + _largeNum) % 1 * _roundingNum) / _roundingNum || (progress < 0 ? 0 : 1);\n},\n    //if progress lands on 1, the % will make it 0 which is why we || 1, but not if it\'s negative because it makes more sense for motion to end at 0 in that case.\n_round = function _round(value) {\n  return Math.round(value * _roundingNum) / _roundingNum || 0;\n},\n    _roundPrecise = function _roundPrecise(value) {\n  return Math.round(value * 1e10) / 1e10 || 0;\n},\n    _segmentIsClosed = function _segmentIsClosed(segment) {\n  return segment.closed = Math.abs(segment[0] - segment[segment.length - 2]) < 0.001 && Math.abs(segment[1] - segment[segment.length - 1]) < 0.001;\n},\n    _splitSegment = function _splitSegment(rawPath, segIndex, i, t) {\n  var segment = rawPath[segIndex],\n      shift = t === 1 ? 6 : subdivideSegment(segment, i, t);\n\n  if ((shift || !t) && shift + i + 2 < segment.length) {\n    rawPath.splice(segIndex, 0, segment.slice(0, i + shift + 2));\n    segment.splice(0, i + shift);\n    return 1;\n  }\n},\n    _getSampleIndex = function _getSampleIndex(samples, length, progress) {\n  // slightly slower way than doing this (when there\'s no lookup): segment.lookup[progress < 1 ? ~~(length / 
1segment.minLength) : segment.lookup.length - 1] || 0;\n  var l = samples.length,\n      i = ~~(progress * l);\n\n  if (samples[i] > length) {\n    while (--i && samples[i] > length) {}\n\n    i < 0 && (i = 0);\n  } else {\n    while (samples[++i] < length && i < l) {}\n  }\n\n  return i < l ? i : l - 1;\n},\n    _reverseRawPath = function _reverseRawPath(rawPath, skipOuter) {\n  var i = rawPath.length;\n  skipOuter || rawPath.reverse();\n\n  while (i--) {\n    rawPath[i].reversed || reverseSegment(rawPath[i]);\n  }\n},\n    _copyMetaData = function _copyMetaData(source, copy) {\n  copy.totalLength = source.totalLength;\n\n  if (source.samples) {\n    //segment\n    copy.samples = source.samples.slice(0);\n    copy.lookup = source.lookup.slice(0);\n    copy.minLength = source.minLength;\n    copy.resolution = source.resolution;\n  } else if (source.totalPoints) {\n    //rawPath\n    copy.totalPoints = source.totalPoints;\n  }\n\n  return copy;\n},\n    //pushes a new segment into a rawPath, but if its starting values match the ending values of the last segment, it\'ll merge it into that same segment (to reduce the number of segments)\n_appendOrMerge = function _appendOrMerge(rawPath, segment) {\n  var index = rawPath.length,\n      prevSeg = rawPath[index - 1] || [],\n      l = prevSeg.length;\n\n  if (index && segment[0] === prevSeg[l - 2] && segment[1] === prevSeg[l - 1]) {\n    segment = prevSeg.concat(segment.slice(2));\n    index--;\n  }\n\n  rawPath[index] = segment;\n},\n    _bestDistance;\n/* TERMINOLOGY\n - RawPath - an array of arrays, one for each Segment. A single RawPath could have multiple "M" commands, defining Segments (paths aren\'t always connected).\n - Segment - an array containing a sequence of Cubic Bezier coordinates in alternating x, y, x, y format. Starting anchor, then control point 1, control point 2, and ending anchor, then the next control point 1, control point 2, anchor, etc. Uses less memory than an array with a bunch of {x, y} points.\n - Bezier - a single cubic Bezier with a starting anchor, two control points, and an ending anchor.\n - the variable "t" is typically the position along an individual Bezier path (time) and it\'s NOT linear, meaning it could accelerate/decelerate based on the control points whereas the "p" or "progress" value is linearly mapped to the whole path, so it shouldn\'t really accelerate/decelerate based on control points. So a progress of 0.2 would be almost exactly 20% along the path. "t" is ONLY in an individual Bezier piece.\n */\n//accepts basic selector text, a path instance, a RawPath instance, or a Segment and returns a RawPath (makes it easy to homogenize things). If an element or selector text is passed in, it\'ll also cache the value so that if it\'s queried again, it\'ll just take the path data from there instead of parsing it all over again (as long as the path data itself hasn\'t changed - it\'ll check).\n\n\nfunction getRawPath(value) {\n  value = _isString(value) && _selectorExp.test(value) ? document.querySelector(value) || value : value;\n  var e = value.getAttribute ? value : 0,\n      rawPath;\n\n  if (e && (value = value.getAttribute("d"))) {\n    //implements caching\n    if (!e._gsPath) {\n      e._gsPath = {};\n    }\n\n    rawPath = e._gsPath[value];\n    return rawPath && !rawPath._dirty ? rawPath : e._gsPath[value] = stringToRawPath(value);\n  }\n\n  return !value ? console.warn("Expecting a <path> element or an SVG path data string") : _isString(value) ? stringToRawPath(value) : _isNumber(value[0]) ? [value] : value;\n} //copies a RawPath WITHOUT the length meta data (for speed)\n\nfunction copyRawPath(rawPath) {\n  var a = [],\n      i = 0;\n\n  for (; i < rawPath.length; i++) {\n    a[i] = _copyMetaData(rawPath[i], rawPath[i].slice(0));\n  }\n\n  return _copyMetaData(rawPath, a);\n}\nfunction reverseSegment(segment) {\n  var i = 0,\n      y;\n  segment.reverse(); //this will invert the order y, x, y, x so we must flip it back.\n\n  for (; i < segment.length; i += 2) {\n    y = segment[i];\n    segment[i] = segment[i + 1];\n    segment[i + 1] = y;\n  }\n\n  segment.reversed = !segment.reversed;\n}\n\nvar _createPath = function _createPath(e, ignore) {\n  var path = document.createElementNS("http://www.w3.org/2000/svg", "path"),\n      attr = [].slice.call(e.attributes),\n      i = attr.length,\n      name;\n  ignore = "," + ignore + ",";\n\n  while (--i > -1) {\n    name = attr[i].nodeName.toLowerCase(); //in Microsoft Edge, if you don\'t set the attribute with a lowercase name, it doesn\'t render correctly! Super weird.\n\n    if (ignore.indexOf("," + name + ",") < 0) {\n      path.setAttributeNS(null, name, attr[i].nodeValue);\n    }\n  }\n\n  return path;\n},\n    _typeAttrs = {\n  rect: "rx,ry,x,y,width,height",\n  circle: "r,cx,cy",\n  ellipse: "rx,ry,cx,cy",\n  line: "x1,x2,y1,y2"\n},\n    _attrToObj = function _attrToObj(e, attrs) {\n  var props = attrs ? attrs.split(",") : [],\n      obj = {},\n      i = props.length;\n\n  while (--i > -1) {\n    obj[props[i]] = +e.getAttribute(props[i]) || 0;\n  }\n\n  return obj;\n}; //converts an SVG shape like <circle>, <rect>, <polygon>, <polyline>, <ellipse>, etc. to a <path>, swapping it in and copying the attributes to match.\n\n\nfunction convertToPath(element, swap) {\n  var type = element.tagName.toLowerCase(),\n      circ = 0.552284749831,\n      data,\n      x,\n      y,\n      r,\n      ry,\n      path,\n      rcirc,\n      rycirc,\n      points,\n      w,\n      h,\n      x2,\n      x3,\n      x4,\n      x5,\n      x6,\n      y2,\n      y3,\n      y4,\n      y5,\n      y6,\n      attr;\n\n  if (type === "path" || !element.getBBox) {\n    return element;\n  }\n\n  path = _createPath(element, "x,y,width,height,cx,cy,rx,ry,r,x1,x2,y1,y2,points");\n  attr = _attrToObj(element, _typeAttrs[type]);\n\n  if (type === "rect") {\n    r = attr.rx;\n    ry = attr.ry || r;\n    x = attr.x;\n    y = attr.y;\n    w = attr.width - r * 2;\n    h = attr.height - ry * 2;\n\n    if (r || ry) {\n      //if there are rounded corners, render cubic beziers\n      x2 = x + r * (1 - circ);\n      x3 = x + r;\n      x4 = x3 + w;\n      x5 = x4 + r * circ;\n      x6 = x4 + r;\n      y2 = y + ry * (1 - circ);\n      y3 = y + ry;\n      y4 = y3 + h;\n      y5 = y4 + ry * circ;\n      y6 = y4 + ry;\n      data = "M" + x6 + "," + y3 + " V" + y4 + " C" + [x6, y5, x5, y6, x4, y6, x4 - (x4 - x3) / 3, y6, x3 + (x4 - x3) / 3, y6, x3, y6, x2, y6, x, y5, x, y4, x, y4 - (y4 - y3) / 3, x, y3 + (y4 - y3) / 3, x, y3, x, y2, x2, y, x3, y, x3 + (x4 - x3) / 3, y, x4 - (x4 - x3) / 3, y, x4, y, x5, y, x6, y2, x6, y3].join(",") + "z";\n    } else {\n      data = "M" + (x + w) + "," + y + " v" + h + " h" + -w + " v" + 
1-h + " h" + w + "z";\n    }\n  } else if (type === "circle" || type === "ellipse") {\n    if (type === "circle") {\n      r = ry = attr.r;\n      rycirc = r * circ;\n    } else {\n      r = attr.rx;\n      ry = attr.ry;\n      rycirc = ry * circ;\n    }\n\n    x = attr.cx;\n    y = attr.cy;\n    rcirc = r * circ;\n    data = "M" + (x + r) + "," + y + " C" + [x + r, y + rycirc, x + rcirc, y + ry, x, y + ry, x - rcirc, y + ry, x - r, y + rycirc, x - r, y, x - r, y - rycirc, x - rcirc, y - ry, x, y - ry, x + rcirc, y - ry, x + r, y - rycirc, x + r, y].join(",") + "z";\n  } else if (type === "line") {\n    data = "M" + attr.x1 + "," + attr.y1 + " L" + attr.x2 + "," + attr.y2; //previously, we just converted to "Mx,y Lx,y" but Safari has bugs that cause that not to render properly when using a stroke-dasharray that\'s not fully visible! Using a cubic bezier fixes that issue.\n  } else if (type === "polyline" || type === "polygon") {\n    points = (element.getAttribute("points") + "").match(_numbersExp) || [];\n    x = points.shift();\n    y = points.shift();\n    data = "M" + x + "," + y + " L" + points.join(",");\n\n    if (type === "polygon") {\n      data += "," + x + "," + y + "z";\n    }\n  }\n\n  path.setAttribute("d", rawPathToString(path._gsRawPath = stringToRawPath(data)));\n\n  if (swap && element.parentNode) {\n    element.parentNode.insertBefore(path, element);\n    element.parentNode.removeChild(element);\n  }\n\n  return path;\n} //returns the rotation (in degrees) at a particular progress on a rawPath (the slope of the tangent)\n\nfunction getRotationAtProgress(rawPath, progress) {\n  var d = getProgressData(rawPath, progress >= 1 ? 1 - 1e-9 : progress ? progress : 1e-9);\n  return getRotationAtBezierT(d.segment, d.i, d.t);\n}\n\nfunction getRotationAtBezierT(segment, i, t) {\n  var a = segment[i],\n      b = segment[i + 2],\n      c = segment[i + 4],\n      x;\n  a += (b - a) * t;\n  b += (c - b) * t;\n  a += (b - a) * t;\n  x = b + (c + (segment[i + 6] - c) * t - b) * t - a;\n  a = segment[i + 1];\n  b = segment[i + 3];\n  c = segment[i + 5];\n  a += (b - a) * t;\n  b += (c - b) * t;\n  a += (b - a) * t;\n  return _round(_atan2(b + (c + (segment[i + 7] - c) * t - b) * t - a, x) * _RAD2DEG);\n}\n\nfunction sliceRawPath(rawPath, start, end) {\n  end = _isUndefined(end) ? 1 : _roundPrecise(end) || 0;
1 // we must round to avoid issues like 4.15 / 8 = 0.8300000000000001 instead of 0.83 or 2.8 / 5 = 0.5599999999999999 instead of 0.56 and if someone is doing a loop like start: 2.8 / 0.5, end: 2.8 / 0.5 + 1.\n\n  start = _roundPrecise(start) || 0;\n  var loops = Math.max(0, ~~(_abs(end - start) - 1e-8)),\n      path = copyRawPath(rawPath);\n\n  if (start > end) {\n    start = 1 - start;\n    end = 1 - end;\n\n    _reverseRawPath(path);\n\n    path.totalLength = 0;\n  }\n\n  if (start < 0 || end < 0) {\n    var offset = Math.abs(~~Math.min(start, end)) + 1;\n    start += offset;\n    end += offset;\n  }\n\n  path.totalLength || cacheRawPathMeasurements(path);\n  var wrap = end > 1,\n      s = getProgressData(path, start, _temp, true),\n      e = getProgressData(path, end, _temp2),\n      eSeg = e.segment,\n      sSeg = s.segment,\n      eSegIndex = e.segIndex,\n      sSegIndex = s.segIndex,\n      ei = e.i,\n      si = s.i,\n      sameSegment = sSegIndex === eSegIndex,\n      sameBezier = ei === si && sameSegment,\n      wrapsBehind,\n      sShift,\n      eShift,\n      i,\n      copy,\n      totalSegments,\n      l,\n      j;\n\n  if (wrap || loops) {\n    wrapsBehind = eSegIndex < sSegIndex || sameSegment && ei < si || sameBezier && e.t < s.t;\n\n    if (_splitSegment(path, sSegIndex, si, s.t)) {\n      sSegIndex++;\n\n      if (!wrapsBehind) {\n        eSegIndex++;\n\n        if (sameBezier) {\n          e.t = (e.t - s.t) / (1 - s.t);\n          ei = 0;\n        } else if (sameSegment) {\n          ei -= si;\n        }\n      }\n    }\n\n    if (Math.abs(1 - (end - start)) < 1e-5) {\n      eSegIndex = sSegIndex - 1;\n    } else if (!e.t && eSegIndex) {\n      eSegIndex--;\n    } else if (_splitSegment(path, eSegIndex, ei, e.t) && wrapsBehind) {\n      sSegIndex++;\n    }\n\n    if (s.t === 1) {\n      sSegIndex = (sSegIndex + 1) % path.length;\n    }\n\n    copy = [];\n    totalSegments = path.length;\n    l = 1 + totalSegments * loops;\n    j = sSegIndex;\n    l += (totalSegments - sSegIndex + eSegIndex) % totalSegments;\n\n    for (i = 0; i < l; i++) {\n      _appendOrMerge(copy, path[j++ % totalSegments]);\n    }\n\n    path = copy;\n  } else {\n    eShift = e.t === 1 ? 6 : subdivideSegment(eSeg, ei, e.t);\n\n    if (start !== end) {\n      sShift = subdivideSegment(sSeg, si, sameBezier ? s.t / e.t : s.t);\n      sameSegment && (eShift += sShift);\n      eSeg.splice(ei + eShift + 2);\n      (sShift || si) && sSeg.splice(0, si + sShift);\n      i = path.length;\n\n      while (i--) {\n        //chop off any extra segments\n        (i < sSegIndex || i > eSegIndex) && path.splice(i, 1);\n      }\n    } else {\n      eSeg.angle = getRotationAtBezierT(eSeg, ei + eShift, 0); //record the value before we chop because it\'ll be impossible to determine the angle after its length is 0!\n\n      ei += eShift;\n      s = eSeg[ei];\n      e = eSeg[ei + 1];\n      eSeg.length = eSeg.totalLength = 0;\n      eSeg.totalPoints = path.totalPoints = 8;\n      eSeg.push(s, e, s, e, s, e, s, e);\n    }\n  }\n\n  path.totalLength = 0;\n  return path;\n} //measures a Segment according to its resolution (so if segment.resolution is 6, for example, it\'ll take 6 samples equally across each Bezier) and create/populate a "samples" Array that has the length up to each of those sample points (always increasing from the start) as well as a "lookup" array that\'s broken up according to the smallest distance between 2 samples. This gives us a very fast way of looking up a progress position rather than looping through all the points/Beziers. You can optionally have it only measure a subset, starting at startIndex and going for a specific number of beziers (remember, there are 3 x/y pairs each, for a total of 6 elements for each Bezier). It will also populate a "totalLength" property, but that\'s not generally super accurate because by default it\'ll only take 6 samples per Bezier. But for performance reasons, it\'s perfectly adequate for measuring progress values along the path. If you need a more accurate totalLength, either increase the resolution or use the more advanced bezierToPoints() method which keeps adding points until they don\'t deviate b
1y more than a certain precision value.\n\nfunction measureSegment(segment, startIndex, bezierQty) {\n  startIndex = startIndex || 0;\n\n  if (!segment.samples) {\n    segment.samples = [];\n    segment.lookup = [];\n  }\n\n  var resolution = ~~segment.resolution || 12,\n      inc = 1 / resolution,\n      endIndex = bezierQty ? startIndex + bezierQty * 6 + 1 : segment.length,\n      x1 = segment[startIndex],\n      y1 = segment[startIndex + 1],\n      samplesIndex = startIndex ? startIndex / 6 * resolution : 0,\n      samples = segment.samples,\n      lookup = segment.lookup,\n      min = (startIndex ? segment.minLength : _largeNum) || _largeNum,\n      prevLength = samples[samplesIndex + bezierQty * resolution - 1],\n      length = startIndex ? samples[samplesIndex - 1] : 0,\n      i,\n      j,\n      x4,\n      x3,\n      x2,\n      xd,\n      xd1,\n      y4,\n      y3,\n      y2,\n      yd,\n      yd1,\n      inv,\n      t,\n      lengthIndex,\n      l,\n      segLength;\n  samples.length = lookup.length = 0;\n\n  for (j = startIndex + 2; j < endIndex; j += 6) {\n    x4 = segment[j + 4] - x1;\n    x3 = segment[j + 2] - x1;\n    x2 = segment[j] - x1;\n    y4 = segment[j + 5] - y1;\n    y3 = segment[j + 3] - y1;\n    y2 = segment[j + 1] - y1;\n    xd = xd1 = yd = yd1 = 0;\n\n    if (_abs(x4) < .01 && _abs(y4) < .01 && _abs(x2) + _abs(y2) < .01) {\n      // dump points that are close enough (basically right on top of each other, making a bezier super tiny or 0 length)\n      if (segment.length > 8) {\n        segment.splice(j, 6);\n        j -= 6;\n        endIndex -= 6;\n      }\n    } else {\n      for (i = 1; i <= resolution; i++) {\n        t = inc * i;\n        inv = 1 - t;\n        xd = xd1 - (xd1 = (t * t * x4 + 3 * inv * (t * x3 + inv * x2)) * t);\n        yd = yd1 - (yd1 = (t * t * y4 + 3 * inv * (t * y3 + inv * y2)) * t);\n        l = _sqrt(yd * yd + xd * xd);\n\n        if (l < min) {\n          min = l;\n        }\n\n        length += l;\n        samples[samplesIndex++] = length;\n      }\n    }\n\n    x1 += x4;\n    y1 += y4;\n  }\n\n  if (prevLength) {\n    prevLength -= length;\n\n    for (; samplesIndex < samples.length; samplesIndex++) {\n      samples[samplesIndex] += prevLength;\n    }\n  }\n\n  if (samples.length && min) {\n    segment.totalLength = segLength = samples[samples.length - 1] || 0;\n    segment.minLength = min;\n\n    if (segLength / min < 9999) {\n      // if the lookup would require too many values (memory problem), we skip this and instead we use a loop to lookup values directly in the samples Array\n      l = lengthIndex = 0;\n\n      for (i = 0; i < segLength; i += min) {\n        lookup[l++] = samples[lengthIndex] < i ? ++lengthIndex : lengthIndex;\n      }\n    }\n  } else {\n    segment.totalLength = samples[0] = 0;\n  }\n\n  return startIndex ? length - samples[startIndex / 2 - 1] : length;\n}\n\nfunction cacheRawPathMeasurements(rawPath, resolution) {\n  var pathLength, points, i;\n\n  for (i = pathLength = points = 0; i < rawPath.length; i++) {\n    rawPath[i].resolution = ~~resolution || 12; //steps per Bezier curve (anchor, 2 control points, to anchor)\n\n    pathLength += measureSegment(rawPath[i]); // note: measureSegment() also removes points that are basically on top of each other, so the segment.length may change!\n\n    points += rawPath[i].length;\n  }\n\n  rawPath.totalPoints = points;\n  rawPath.totalLength = pathLength;\n  return rawPath;\n} //divide segment[i] at position t (value between 0 and 1, progress along that particular cubic bezier segment that starts at segment[i]). Returns how many elements were spliced into the segment array (either 0 or 6)\n\nfunction subdivideSegment(segment, i, t) {\n  if (t <= 0 || t >= 1) {\n    return 0;\n  }\n\n  var ax = segment[i],\n      ay = segment[i + 1],\n      cp1x = segment[i + 2],\n      cp1y = segment[i + 3],\n      cp2x = segment[i + 4],\n      cp2y = segment[i + 5],\n      bx = segment[i + 6],\n      by = segment[i + 7],\n      x1a = ax + (cp1x - ax) * t,\n      x2 = cp1x + (cp2x - cp1x) * t,\n      y1a = ay + (cp1y - ay) * t,\n      y2 = cp1y + (cp2y - cp1y) * t,\n      x1 = x1a + (x2 - x1a) * t,\n      y1 = y1a + (y2 - y1a) * t,\n      x2a = cp2x + (bx - cp2x) * t,\n      y2a = cp2y + (by - cp2y) * t;\n  x2 += (x2a - x2) * t;\n  y2 += (y2a - y2) * t;\n  segment.splice(i + 2, 4, _round(x1a), //first control point\n  _round(y1a), _round(x1), //second control point\n  _round(y1), _round(x1 + (x2 - x1) * t), //new fabricated anchor on line\n  _round(y1 + (y2 - y1) * t), _round(x2), //third control point\n  _round(y2), _round(x2a), //fourth control point\n  _round(y2a));\n  segment.samples && segment.samples.splice(i / 6 * segment.resolution | 0, 0, 0, 0, 0, 0, 0, 0);\n  return 6;\n} // returns an object {path, segment, segIndex, i, t}\n\nfunction getProgressData(rawPath, progress, decoratee, pushToNextIfAtEnd) {\n  decoratee = decoratee || {};\n  rawPath.totalLength || cacheRawPathMeasurements(rawPath);\n\n  if (progress < 0 || progress > 1) {\n    progress = _wrapProgress(progress);\n  }\n\n  var segIndex = 0,\n      segment = rawPath[0],\n      samples,\n      resolution,\n      length,\n      min,\n      max,\n      i,\n      t;\n\n  if (!progress) {\n    t = i = segIndex = 0;\n    segment = rawPath[0];\n  } else if (progress === 1) {\n    t = 1;\n    segIndex = rawPath.length - 1;\n    segment = rawPath[segIndex];\n    i = segment.length - 8;\n  } else {\n    if (rawPath.length > 1) {\n      //speed optimization: most of the time, there\'s only one segment so skip the recursion.\n      length = rawPath.totalLength * progress;\n      max = i = 0;\n\n      while ((max += rawPath[i++].totalLength) < length) {\n        segIndex = i;\n      }\n\n      segment = rawPath[segIndex];\n      min = max - segment.totalLength;\n      progress = (length - min) / (max - min) || 0;\n    }\n\n    samples = segment.samples;\n    resolution = segment.resolution; //how many samples per cubic bezier chunk\n\n    length = segment.totalLength * progress;
1\n    i = segment.lookup.length ? segment.lookup[~~(length / segment.minLength)] || 0 : _getSampleIndex(samples, length, progress);\n    min = i ? samples[i - 1] : 0;\n    max = samples[i];\n\n    if (max < length) {\n      min = max;\n      max = samples[++i];\n    }\n\n    t = 1 / resolution * ((length - min) / (max - min) + i % resolution);\n    i = ~~(i / resolution) * 6;\n\n    if (pushToNextIfAtEnd && t === 1) {\n      if (i + 6 < segment.length) {\n        i += 6;\n        t = 0;\n      } else if (segIndex + 1 < rawPath.length) {\n        i = t = 0;\n        segment = rawPath[++segIndex];\n      }\n    }\n  }\n\n  decoratee.t = t;\n  decoratee.i = i;\n  decoratee.path = rawPath;\n  decoratee.segment = segment;\n  decoratee.segIndex = segIndex;\n  return decoratee;\n}\n\nfunction getPositionOnPath(rawPath, progress, includeAngle, point) {\n  var segment = rawPath[0],\n      result = point || {},\n      samples,\n      resolution,\n      length,\n      min,\n      max,\n      i,\n      t,\n      a,\n      inv;\n\n  if (progress < 0 || progress > 1) {\n    progress = _wrapProgress(progress);\n  }\n\n  segment.lookup || cacheRawPathMeasurements(rawPath);\n\n  if (rawPath.length > 1) {\n    //speed optimization: most of the time, there\'s only one segment so skip the recursion.\n    length = rawPath.totalLength * progress;\n    max = i = 0;\n\n    while ((max += rawPath[i++].totalLength) < length) {\n      segment = rawPath[i];\n    }\n\n    min = max - segment.totalLength;\n    progress = (length - min) / (max - min) || 0;\n  }\n\n  samples = segment.samples;\n  resolution = segment.resolution;\n  length = segment.totalLength * progress;\n  i = segment.lookup.length ? segment.lookup[progress < 1 ? ~~(length / segment.minLength) : segment.lookup.length - 1] || 0 : _getSampleIndex(samples, length, progress);\n  min = i ? samples[i - 1] : 0;\n  max = samples[i];\n\n  if (max < length) {\n    min = max;\n    max = samples[++i];\n  }\n\n  t = 1 / resolution * ((length - min) / (max - min) + i % resolution) || 0;\n  inv = 1 - t;\n  i = ~~(i / resolution) * 6;\n  a = segment[i];\n  result.x = _round((t * t * (segment[i + 6] - a) + 3 * inv * (t * (segment[i + 4] - a) + inv * (segment[i + 2] - a))) * t + a);\n  result.y = _round((t * t * (segment[i + 7] - (a = segment[i + 1])) + 3 * inv * (t * (segment[i + 5] - a) + inv * (segment[i + 3] - a))) * t + a);\n\n  if (includeAngle) {\n    result.angle = segment.totalLength ? getRotationAtBezierT(segment, i, t >= 1 ? 1 - 1e-9 : t ? t : 1e-9) : segment.angle || 0;\n  }\n\n  return result;\n} //applies a matrix transform to RawPath (or a segment in a RawPath) and returns whatever was passed in (it transforms the values in the array(s), not a copy).\n\nfunction transformRawPath(rawPath, a, b, c, d, tx, ty) {\n  var j = rawPath.length,\n      segment,\n      l,\n      i,\n      x,\n      y;\n\n  while (--j > -1) {\n    segment = rawPath[j];\n    l = segment.length;\n\n    for (i = 0; i < l; i += 2) {\n      x = segment[i];\n      y = segment[i + 1];\n      segment[i] = x * a + y * c + tx;\n      segment[i + 1] = x * b + y * d + ty;\n    }\n  }\n\n  rawPath._dirty = 1;\n  return rawPath;\n} // translates SVG arc data into a segment (cubic beziers). Angle is in degrees.\n\nfunction arcToSegment(lastX, lastY, rx, ry, angle, largeArcFlag, sweepFlag, x, y) {\n  if (lastX === x && lastY === y) {\n    return;\n  }\n\n  rx = _abs(rx);\n  ry = _abs(ry);\n\n  var angleRad = angle % 360 * _DEG2RAD,\n      cosAngle = _cos(angleRad),\n      sinAngle = _sin(angleRad),\n      PI = Math.PI,\n      TWOPI = PI * 2,\n      dx2 = (lastX - x) / 2,\n      dy2 = (lastY - y) / 2,\n      x1 = cosAngle * dx2 + sinAngle * dy2,\n      y1 = -sinAngle * dx2 + cosAngle * dy2,\n      x1_sq = x1 * x1,\n      y1_sq = y1 * y1,\n      radiiCheck = x1_sq / (rx * rx) + y1_sq / (ry * ry);\n\n  if (radiiCheck > 1) {\n    rx = _sqrt(radiiCheck) * rx;\n    ry = _sqrt(radiiCheck) * ry;\n  }\n\n  var rx_sq = rx * rx,\n      ry_sq = ry * ry,\n      sq = (rx_sq * ry_sq - rx_sq * y1_sq - ry_sq * x1_sq) / (rx_sq * y1_sq + ry_sq * x1_sq);\n\n  if (sq < 0) {\n    sq = 0;\n  }\n\n  var coef = (largeArcFlag === sweepFlag ? -1 : 1) * _sqrt(sq),\n      cx1 = coef * (rx * y1 / ry),\n      cy1 = coef * -(ry * x1 / rx),\n      sx2 = (lastX + x) / 2,\n      sy2 = (lastY + y) / 2,\n      cx = sx2 + (cosAngle * cx1 - sinAngle * cy1),\n      cy = sy2 + (sinAngle * cx1 + cosAngle * cy1),\n      ux = (x1 - cx1) / rx,\n      uy = (y1 - cy1) / ry,\n      vx = (-x1 - cx1) / rx,\n      vy = (-y1 - cy1) / ry,\n      temp = ux * ux + uy * uy,\n      angleStart = (uy < 0 ? -1 : 1) * Math.acos(ux / _sqrt(temp)),\n      angleExtent = (ux * vy - uy * vx < 0 ? -1 : 1) * Math.acos((ux * vx + uy * vy) / _sqrt(temp * (vx * vx + vy * vy)));\n\n  isNaN(angleExtent) && (angleExtent = PI); //rare edge case. Math.cos(-1) is NaN.\n\n  if (!sweepFlag && angleExtent > 0) {\n    angleExtent -= TWOPI;\n  } else if (sweepFlag && angleExtent < 0) {\n    angleExtent += TWOPI;\n  }\n\n  angleStart %= TWOPI;\n  angleExtent %= TWOPI;\n\n  var segments = Math.ceil(_abs(angleExtent) / (TWOPI / 4)),\n      rawPath = [],\n      angleIncrement = angleExtent / segments,\n      control
1Length = 4 / 3 * _sin(angleIncrement / 2) / (1 + _cos(angleIncrement / 2)),\n      ma = cosAngle * rx,\n      mb = sinAngle * rx,\n      mc = sinAngle * -ry,\n      md = cosAngle * ry,\n      i;\n\n  for (i = 0; i < segments; i++) {\n    angle = angleStart + i * angleIncrement;\n    x1 = _cos(angle);\n    y1 = _sin(angle);\n    ux = _cos(angle += angleIncrement);\n    uy = _sin(angle);\n    rawPath.push(x1 - controlLength * y1, y1 + controlLength * x1, ux + controlLength * uy, uy - controlLength * ux, ux, uy);\n  } //now transform according to the actual size of the ellipse/arc (the beziers were noramlized, between 0 and 1 on a circle).\n\n\n  for (i = 0; i < rawPath.length; i += 2) {\n    x1 = rawPath[i];\n    y1 = rawPath[i + 1];\n    rawPath[i] = x1 * ma + y1 * mc + cx;\n    rawPath[i + 1] = x1 * mb + y1 * md + cy;\n  }\n\n  rawPath[i - 2] = x; //always set the end to exactly where it\'s supposed to be\n\n  rawPath[i - 1] = y;\n  return rawPath;\n} //Spits back a RawPath with absolute coordinates. Each segment starts with a "moveTo" command (x coordinate, then y) and then 2 control points (x, y, x, y), then anchor. The goal is to minimize memory and maximize speed.\n\n\nfunction stringToRawPath(d) {\n  var a = (d + "").replace(_scientific, function (m) {\n    var n = +m;\n    return n < 0.0001 && n > -0.0001 ? 0 : n;\n  }).match(_svgPathExp) || [],\n      //some authoring programs spit out very small numbers in scientific notation like "1e-5", so make sure we round that down to 0 first.\n  path = [],\n      relativeX = 0,\n      relativeY = 0,\n      twoThirds = 2 / 3,\n      elements = a.length,\n      points = 0,\n      errorMessage = "ERROR: malformed path: " + d,\n      i,\n      j,\n      x,\n      y,\n      command,\n      isRelative,\n      segment,\n      startX,\n      startY,\n      difX,\n      difY,\n      beziers,\n      prevCommand,\n      flag1,\n      flag2,\n      line = function line(sx, sy, ex, ey) {\n    difX = (ex - sx) / 3;\n    difY = (ey - sy) / 3;\n    segment.push(sx + difX, sy + difY, ex - difX, ey - difY, ex, ey);\n  };\n\n  if (!d || !isNaN(a[0]) || isNaN(a[1])) {\n    console.log(errorMessage);\n    return path;\n  }\n\n  for (i = 0; i < elements; i++) {\n    prevCommand = command;\n\n    if (isNaN(a[i])) {\n      command = a[i].toUpperCase();\n      isRelative = command !== a[i]; //lower case means relative\n    } else {\n      //commands like "C" can be strung together without any new command characters between.\n      i--;\n    }\n\n    x = +a[i + 1];\n    y = +a[i + 2];\n\n    if (isRelative) {\n      x += relativeX;\n      y += relativeY;\n    }\n\n    if (!i) {\n      startX = x;\n      startY = y;\n    } // "M" (move)\n\n\n    if (command === "M") {\n      if (segment) {\n        if (segment.length < 8) {\n          //if the path data was funky and just had a M with no actual drawing anywhere, skip it.\n          path.length -= 1;\n        } else {\n          points += segment.length;\n        }\n\n        _segmentIsClosed(segment);\n      }\n\n      relativeX = startX = x;\n      relativeY = startY = y;\n      segment = [x, y];\n      path.push(segment);\n      i += 2;\n      command = "L"; //an "M" with more than 2 values gets interpreted as "lineTo" commands ("L").\n      // "C" (cubic bezier)\n    } else if (command === "C") {\n      if (!segment) {\n        segment = [0, 0];\n      }\n\n      if (!isRelative) {\n        relativeX = relativeY = 0;\n      } //note: "*1" is just a fast/short way to cast the value as a Number. WAAAY faster in Chrome, slightly slower in Firefox.\n\n\n      segment.push(x, y, relativeX + a[i + 3] * 1, relativeY + a[i + 4] * 1, relativeX += a[i + 5] * 1, relativeY += a[i + 6] * 1);\n      i += 6; // "S" (continuation of cubic bezier)\n    } else if (command === "S") {\n      difX = relativeX;\n      difY = relativeY;\n\n      if (prevCommand === "C" || prevCommand === "S") {\n        difX += relativeX - segment[segment.length - 4];\n        difY += relativeY - segment[segment.length - 3];\n      }\n\n      if (!isRelative) {\n        relativeX = relativeY = 0;\n      }\n\n      segment.push(difX, difY, x, y, relativeX += a[i + 3] * 1, relativeY += a[i + 4] * 1);\n      i += 4; // "Q" (quadratic bezier)\n    } else if (command === "Q") {\n      difX = relativeX + (x - relativeX) * twoThirds;\n      difY = relativeY + (y - relativeY) * twoThirds;\n\n      if (!isRelative) {\n        relativeX = relativeY = 0;\n      }\n\n      relativeX += a[i + 3] * 1;\n      relativeY += a[i + 4] * 1;\n      segment.push(difX, difY, relativeX + (x - relativeX) * twoThirds, relativeY + (y - relativeY) * twoThirds, relativeX, relativeY);\n      i += 4; // "T" (continuation of quadratic bezier)\n    } else if (command === "T") {\n      difX = relativeX - segment[segment.length - 4];\n      difY = relativeY - segment[segment.length - 3];\n      segment.push(relativeX + difX, relativeY + difY, x + (relativeX + difX * 1.5 - x) * twoThirds, y + (relativeY + difY * 1.5 - y) * twoThirds, relativeX = x, relativeY = y);\n      i += 2; // "H" (horizontal line)\n    } else if (command === "H") {\n      line(relativeX, relativeY, relativeX = x, relativeY);\n      i += 1; // "V" (vertical line)\n    } else if (command === "V") {\n      //adjust values because the first (and only one) isn\'t x in this case, it\'s y.\n      line(relativeX, relativeY, relativeX, relativeY = x + (isRelative ? relativeY - relativeX : 0));\n      i += 1; // "L" (line) or "Z" (close)\n    } else if (command === "L" || command === "Z") {\n      if (command === "Z") {\n        x = startX;\n        y = startY;\n        segment.closed = true;\n      }\n\n      if (command === "L" || _abs(relativeX - x) > 0.5 || _abs(relativeY - y) > 0.5) {\n        line(relativeX, relativeY, x, y);\n\n        if (command === "L") {\n          i += 2;\n        }\n      }\n\n      relativeX = x;\n      relativeY = y; // "A" (arc)\n    } else if (command === "A") {\n      flag1 = a[i + 4];\n      flag2 = a[i + 5];\n      difX = a[i + 6];\n      difY = a[i + 7];\n      j = 7;\n\n      if (flag1.length > 1) {\n        // for cases when the flags are merged, like "a8 8 0 018 8" (the 0 and 1 flags are WITH the x value of 8, but it could also be "a8 8 0 01-8 8" so it may include x or not)\n        if (flag1.length < 3) {\n          difY = difX;\n          difX = flag2;\n          j--;\n        } else {\n          difY = flag2;\n          difX = flag1.substr(2);\n          j -= 2;\n        }\n\n        flag2 = flag1.charAt(1);\n        flag1 = flag1.charAt(0);\n      }\n\n      beziers = arcToSegment(relativeX, relativeY, +a[i + 1], +a[i + 2], +a[i + 3], +flag1, +flag2, (isRelative ? relativeX : 0) + difX * 1, (isRelative ? relativeY : 0) + difY * 1);\n      i += j;\n\n      if (beziers) {\n        for (j = 0; j < beziers.length;
1 j++) {\n          segment.push(beziers[j]);\n        }\n      }\n\n      relativeX = segment[segment.length - 2];\n      relativeY = segment[segment.length - 1];\n    } else {\n      console.log(errorMessage);\n    }\n  }\n\n  i = segment.length;\n\n  if (i < 6) {\n    //in case there\'s odd SVG like a M0,0 command at the very end.\n    path.pop();\n    i = 0;\n  } else {\n    _segmentIsClosed(segment);\n  }\n\n  path.totalPoints = points + i;\n  return path;\n} //populates the points array in alternating x/y values (like [x, y, x, y...] instead of individual point objects [{x, y}, {x, y}...] to conserve memory and stay in line with how we\'re handling segment arrays\n\nfunction bezierToPoints(x1, y1, x2, y2, x3, y3, x4, y4, threshold, points, index) {\n  var x12 = (x1 + x2) / 2,\n      y12 = (y1 + y2) / 2,\n      x23 = (x2 + x3) / 2,\n      y23 = (y2 + y3) / 2,\n      x34 = (x3 + x4) / 2,\n      y34 = (y3 + y4) / 2,\n      x123 = (x12 + x23) / 2,\n      y123 = (y12 + y23) / 2,\n      x234 = (x23 + x34) / 2,\n      y234 = (y23 + y34) / 2,\n      x1234 = (x123 + x234) / 2,\n      y1234 = (y123 + y234) / 2,\n      dx = x4 - x1,\n      dy = y4 - y1,\n      d2 = _abs((x2 - x4) * dy - (y2 - y4) * dx),\n      d3 = _abs((x3 - x4) * dy - (y3 - y4) * dx),\n      length;\n\n  if (!points) {\n    points = [x1, y1, x4, y4];\n    index = 2;\n  }\n\n  points.splice(index || points.length - 2, 0, x1234, y1234);\n\n  if ((d2 + d3) * (d2 + d3) > threshold * (dx * dx + dy * dy)) {\n    length = points.length;\n    bezierToPoints(x1, y1, x12, y12, x123, y123, x1234, y1234, threshold, points, index);\n    bezierToPoints(x1234, y1234, x234, y234, x34, y34, x4, y4, threshold, points, index + 2 + (points.length - length));\n  }\n\n  return points;\n}\n/*\nfunction getAngleBetweenPoints(x0, y0, x1, y1, x2, y2) { //angle between 3 points in radians\n\tvar dx1 = x1 - x0,\n\t\tdy1 = y1 - y0,\n\t\tdx2 = x2 - x1,\n\t\tdy2 = y2 - y1,\n\t\tdx3 = x2 - x0,\n\t\tdy3 = y2 - y0,\n\t\ta = dx1 * dx1 + dy1 * dy1,\n\t\tb = dx2 * dx2 + dy2 * dy2,\n\t\tc = dx3 * dx3 + dy3 * dy3;\n\treturn Math.acos( (a + b - c) / _sqrt(4 * a * b) );\n},\n*/\n//pointsToSegment() doesn\'t handle flat coordinates (where y is always 0) the way we need (the resulting control points are always right on top of the anchors), so this function basically makes the control points go directly up and down, varying in length based on the curviness (more curvy, further control points)\n\nfunction flatPointsToSegment(points, curviness) {\n  if (curviness === void 0) {\n    curviness = 1;\n  }\n\n  var x = points[0],\n      y = 0,\n      segment = [x, y],\n      i = 2;\n\n  for (; i < points.length; i += 2) {\n    segment.push(x, y, points[i], y = (points[i] - x) * curviness / 2, x = points[i], -y);\n  }\n\n  return segment;\n} // plots a number of points along the segment as evenly as possible while retaining non-smooth (angled) anchors.\n\nfunction segmentToDistributedPoints(segment, totalPoints) {\n  segment.samples || measureSegment(segment);\n  var samples = segment.samples,\n      lookup = segment.lookup,\n      resolution = segment.resolution,\n      totalLength = segment.totalLength,\n      points = segment.slice(0, 2),\n      curveStoppingPoints = [],\n      l = segment.length - 4,\n      i = 6,\n      limit = 0.2,\n      startLength = 0,\n      curvePointsCumulative = 0,\n      t,\n      curvePoints,\n      min,\n      max,\n      ci,\n      ratioInc,\n      j,\n      inv,\n      curveLength,\n      length,\n      a,\n      nonSmooth,\n      curveStoppingPointIndex,\n      sampleIndex; // first, loop through each anchor and find out if it\'s smooth (curve) or not by comparing the angle to each control point (if they\'re within a certain range, it\'s smooth). We want to keep pivot points (non-smooth) anchors but allow curved/smooth ones to be subject to simplification.\n\n  for (; i < l; i += 6) {\n    if (Math.abs(_atan2(segment[i + 1] - segment[i - 1], segment[i] - segment[i - 2]) - _atan2(segment[i + 3] - segment[i + 1], segment[i + 2] - segment[i])) > limit) {\n      curveStoppingPoints.push(i);\n    }\n  }\n\n  curveStoppingPoints.push(segment.length - 2); // the last anchor is always a curve stopping point.\n\n  l = curveStoppingPoints.length;\n  points.nonSmooth = nonSmooth = [1]; // keep track of which points are non-smooth so that when we call pointsToSegment() we can maintain their angle.\n\n  if (totalPoints > l) {\n    totalPoints -= l;\n\n    for (ci = 0; ci < l; ci++) {\n      curveStoppingPointIndex = curveStoppingPoints[ci];\n      sampleIndex = Math.round(curveStoppingPointIndex / 6 * resolution);\n      curveLength = samples[sampleIndex - 1] - startLength;\n      curvePoints = Math.round(samples[sampleIndex - 1] / totalLength * totalPoints) - curvePointsCumulative;\n      curvePointsCumulative += curvePoints;\n      ratioInc = 1 / (curvePoints + 1);\n\n      for (j = 1; j <= curvePoints;
1 j++) {\n        length = startLength + curveLength * j * ratioInc;\n        i = lookup.length ? lookup[length < totalLength ? ~~(length / segment.minLength) : lookup.length - 1] || 0 : _getSampleIndex(samples, length, length / totalLength);\n        min = i ? samples[i - 1] : 0;\n        max = samples[i];\n\n        if (max < length) {\n          min = max;\n          max = samples[++i];\n        }\n\n        t = 1 / resolution * ((length - min) / (max - min) + i % resolution) || 0;\n        inv = 1 - t;\n        i = ~~(i / resolution) * 6;\n        a = segment[i];\n        points.push(_round((t * t * (segment[i + 6] - a) + 3 * inv * (t * (segment[i + 4] - a) + inv * (segment[i + 2] - a))) * t + a), // x\n        _round((t * t * (segment[i + 7] - (a = segment[i + 1])) + 3 * inv * (t * (segment[i + 5] - a) + inv * (segment[i + 3] - a))) * t + a) // y\n        );\n      }\n\n      nonSmooth[points.length] = 1;\n      points.push(segment[curveStoppingPointIndex], segment[curveStoppingPointIndex + 1]);\n      startLength += curveLength;\n    }\n  } // if the path is closed (the last anchor is the same as the first), check to see if it\'s a smooth joint. If so, update the nonSmooth Array accordingly.\n\n\n  i = segment.length - 2;\n\n  if (segment.closed && Math.abs(_atan2(segment[i + 1] - segment[i - 1], segment[i] - segment[i - 2]) - _atan2(segment[3] - segment[1], segment[2] - segment[0])) <= limit) {\n    nonSmooth[0] = nonSmooth[nonSmooth.length - 1] = 0;\n  }\n\n  return points;\n} //points is an array of x/y points, like [x, y, x, y, x, y]\n\nfunction pointsToSegment(points, curviness) {\n  //points = simplifyPoints(points, tolerance);\n  _abs(points[0] - points[2]) < 1e-4 && _abs(points[1] - points[3]) < 1e-4 && (points = points.slice(2)); // if the first two points are super close, dump the first one.\n\n  var l = points.length - 2,\n      x = +points[0],\n      y = +points[1],\n      nextX = +points[2],\n      nextY = +points[3],\n      segment = [x, y, x, y],\n      dx2 = nextX - x,\n      dy2 = nextY - y,\n      nonSmooth = points.nonSmooth || [],\n      // populated by segmentToDistributedPoints(). The x slot will have 1 if it\'s a non-smooth point, in which case we should skip the smoothing here, obviously.\n  closed = Math.abs(points[l] - x) < 0.001 && Math.abs(points[l + 1] - y) < 0.001,\n      prevX,\n      prevY,\n      i,\n      dx1,\n      dy1,\n      r1,\n      r2,\n      r3,\n      tl,\n      mx1,\n      mx2,\n      mxm,\n      my1,\n      my2,\n      mym;\n\n  if (!l) {\n    return [x, y, x, y, x, y, x, y];\n  }\n\n  if (closed) {\n    // if the start and end points are basically on top of each other, close the segment by adding the 2nd point to the end, and the 2nd-to-last point to the beginning (we\'ll remove them at the end, but this allows the curvature to look perfect)\n    points.push(nextX, nextY);\n    nextX = x;\n    nextY = y;\n    x = points[l - 2];\n    y = points[l - 1];\n    points.unshift(x, y);\n    l += 4;\n    nonSmooth = [0, 0].concat(nonSmooth);\n  }\n\n  curviness = curviness || curviness === 0 ? +curviness : 1;\n\n  for (i = 2; i < l; i += 2) {\n    prevX = x;\n    prevY = y;\n    x = nextX;\n    y = nextY;\n    nextX = +points[i + 2];\n    nextY = +points[i + 3];\n\n    if (x === nextX && y === nextY) {\n      continue;\n    }\n\n    dx1 = dx2;\n    dy1 = dy2;\n    dx2 = nextX - x;\n    dy2 = nextY - y;\n\n    if (nonSmooth[i]) {\n      segment.push(x - (x - prevX) / 4, y - (y - prevY) / 4, x, y, x + (nextX - x) / 4, y + (nextY - y) / 4);\n      continue;\n    }\n\n    r1 = _sqrt(dx1 * dx1 + dy1 * dy1); // r1, r2, and r3 correlate x and y (and z in the future). Basically 2D or 3D hypotenuse\n\n    r2 = _sqrt(dx2 * dx2 + dy2 * dy2);\n    r3 = _sqrt(Math.pow(dx2 / r2 + dx1 / r1, 2) + Math.pow(dy2 / r2 + dy1 / r1, 2));\n    tl = (r1 + r2) * curviness * 0.25 / r3;\n    mx1 = x - (x - prevX) * (r1 ? tl / r1 : 0);\n    mx2 = x + (nextX - x) * (r2 ? tl / r2 : 0);\n    mxm = x - (mx1 + ((mx2 - mx1) * (r1 * 3 / (r1 + r2) + 0.5) / 4 || 0));\n    my1 = y - (y - prevY) * (r1 ? tl / r1 : 0);
1\n    my2 = y + (nextY - y) * (r2 ? tl / r2 : 0);\n    mym = y - (my1 + ((my2 - my1) * (r1 * 3 / (r1 + r2) + 0.5) / 4 || 0));\n    segment.push(_round(mx1 + mxm), // first control point\n    _round(my1 + mym), _round(x), // anchor\n    _round(y), _round(mx2 + mxm), // second control point\n    _round(my2 + mym));\n  }\n\n  x !== nextX || y !== nextY || segment.length < 4 ? segment.push(_round(nextX), _round(nextY), _round(nextX), _round(nextY)) : segment.length -= 2;\n\n  if (segment.length === 2) {\n    // only one point!\n    segment.push(x, y, x, y, x, y);\n  } else if (closed) {\n    segment.splice(0, 6);\n    segment.length -= 6;\n  }\n\n  segment.closed = closed;\n  return segment;\n} //returns the squared distance between an x/y coordinate and a segment between x1/y1 and x2/y2\n\nfunction pointToSegDist(x, y, x1, y1, x2, y2) {\n  var dx = x2 - x1,\n      dy = y2 - y1,\n      t;\n\n  if (dx || dy) {\n    t = ((x - x1) * dx + (y - y1) * dy) / (dx * dx + dy * dy);\n\n    if (t > 1) {\n      x1 = x2;\n      y1 = y2;\n    } else if (t > 0) {\n      x1 += dx * t;\n      y1 += dy * t;\n    }\n  }\n\n  return Math.pow(x - x1, 2) + Math.pow(y - y1, 2);\n}\n\nfunction simplifyStep(points, first, last, tolerance, simplified) {\n  var maxSqDist = tolerance,\n      firstX = points[first],\n      firstY = points[first + 1],\n      lastX = points[last],\n      lastY = points[last + 1],\n      index,\n      i,\n      d;\n\n  for (i = first + 2; i < last; i += 2) {\n    d = pointToSegDist(points[i], points[i + 1], firstX, firstY, lastX, lastY);\n\n    if (d > maxSqDist) {\n      index = i;\n      maxSqDist = d;\n    }\n  }\n\n  if (maxSqDist > tolerance) {\n    index - first > 2 && simplifyStep(points, first, index, tolerance, simplified);\n    simplified.push(points[index], points[index + 1]);\n    last - index > 2 && simplifyStep(points, index, last, tolerance, simplified);\n  }\n} //points is an array of x/y values like [x, y, x, y, x, y]\n\n\nfunction simplifyPoints(points, tolerance) {\n  var prevX = parseFloat(points[0]),\n      prevY = parseFloat(points[1]),\n      temp = [prevX, prevY],\n      l = points.length - 2,\n      i,\n      x,\n      y,\n      dx,\n      dy,\n      result,\n      last;\n  tolerance = Math.pow(tolerance || 1, 2);\n\n  for (i = 2; i < l; i += 2) {\n    x = parseFloat(points[i]);\n    y = parseFloat(points[i + 1]);\n    dx = prevX - x;\n    dy = prevY - y;\n\n    if (dx * dx + dy * dy > tolerance) {\n      temp.push(x, y);\n      prevX = x;\n      prevY = y;\n    }\n  }\n\n  temp.push(parseFloat(points[l]), parseFloat(points[l + 1]));\n  last = temp.length - 2;\n  result = [temp[0], temp[1]];\n  simplifyStep(temp, 0, last, tolerance, result);\n  result.push(temp[last], temp[last + 1]);\n  return result;\n}\n\nfunction getClosestProgressOnBezier(iterations, px, py, start, end, slices, x0, y0, x1, y1, x2, y2, x3, y3) {\n  var inc = (end - start) / slices,\n      best = 0,\n      t = start,\n      x,\n      y,\n      d,\n      dx,\n      dy,\n      inv;\n  _bestDistance = _largeNum;\n\n  while (t <= end) {\n    inv = 1 - t;\n    x = inv * inv * inv * x0 + 3 * inv * inv * t * x1 + 3 * inv * t * t * x2 + t * t * t * x3;\n    y = inv * inv * inv * y0 + 3 * inv * inv * t * y1 + 3 * inv * t * t * y2 + t * t * t * y3;\n    dx = x - px;\n    dy = y - py;\n    d = dx * dx + dy * dy;\n\n    if (d < _bestDistance) {\n      _bestDistance = d;\n      best = t;\n    }\n\n    t += inc;\n  }\n\n  return iterations > 1 ? getClosestProgressOnBezier(iterations - 1, px, py, Math.max(best - inc, 0), Math.min(best + inc, 1), slices, x0, y0, x1, y1, x2, y2, x3, y3) : best;\n}\n\nfunction getClosestData(rawPath, x, y, slices) {\n  //returns an object with the closest j, i, and t (j is the segment index, i is the index of the point in that segment, and t is the time/progress along that bezier)\n  var closest = {\n    j: 0,\n    i: 0,\n    t: 0\n  },\n      bestDistance = _largeNum,\n      i,\n      j,\n      t,\n      segment;\n\n  for (j = 0; j < rawPath.length; j++) {\n    segment = rawPath[j];\n\n    for (i = 0; i < segment.length; i += 6) {\n      t = getClosestProgressOnBezier(1, x, y, 0, 1, slices || 20, segment[i], segment[i + 1], segment[i + 2], segment[i + 3], segment[i + 4], segment[i + 5], segment[i + 6], segment[i + 7]);\n\n      if (bestDistance > _bestDistance) {\n        bestDistance = _bestDistance;\n        closest.j = j;\n        closest.i = i;\n        closest.t = t;\n      }\n    }\n  }\n\n  return closest;\n} //subdivide a Segment closest to a specific x,y coordinate\n\nfunction subdivideSegmentNear(x, y, segment, slices, iterations) {\n  var l = segment.length,\n      bestDistance = _largeNum,\n      bestT = 0,\n      bestSegmentIndex = 0,\n      t,\n      i;
1\n  slices = slices || 20;\n  iterations = iterations || 3;\n\n  for (i = 0; i < l; i += 6) {\n    t = getClosestProgressOnBezier(1, x, y, 0, 1, slices, segment[i], segment[i + 1], segment[i + 2], segment[i + 3], segment[i + 4], segment[i + 5], segment[i + 6], segment[i + 7]);\n\n    if (bestDistance > _bestDistance) {\n      bestDistance = _bestDistance;\n      bestT = t;\n      bestSegmentIndex = i;\n    }\n  }\n\n  t = getClosestProgressOnBezier(iterations, x, y, bestT - 0.05, bestT + 0.05, slices, segment[bestSegmentIndex], segment[bestSegmentIndex + 1], segment[bestSegmentIndex + 2], segment[bestSegmentIndex + 3], segment[bestSegmentIndex + 4], segment[bestSegmentIndex + 5], segment[bestSegmentIndex + 6], segment[bestSegmentIndex + 7]);\n  subdivideSegment(segment, bestSegmentIndex, t);\n  return bestSegmentIndex + 6;\n}\n/*\nTakes any of the following and converts it to an all Cubic Bezier SVG data string:\n- A <path> data string like "M0,0 L2,4 v20,15 H100"\n- A RawPath, like [[x, y, x, y, x, y, x, y][[x, y, x, y, x, y, x, y]]\n- A Segment, like [x, y, x, y, x, y, x, y]\n\nNote: all numbers are rounded down to the closest 0.001 to minimize memory, maximize speed, and avoid odd numbers like 1e-13\n*/\n\nfunction rawPathToString(rawPath) {\n  if (_isNumber(rawPath[0])) {\n    //in case a segment is passed in instead\n    rawPath = [rawPath];\n  }\n\n  var result = "",\n      l = rawPath.length,\n      sl,\n      s,\n      i,\n      segment;\n\n  for (s = 0; s < l; s++) {\n    segment = rawPath[s];\n    result += "M" + _round(segment[0]) + "," + _round(segment[1]) + " C";\n    sl = segment.length;\n\n    for (i = 2; i < sl; i++) {\n      result += _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i++]) + " " + _round(segment[i++]) + "," + _round(segment[i]) + " ";\n    }\n\n    if (segment.closed) {\n      result += "z";\n    }\n  }\n\n  return result;\n}\n/*\n// takes a segment with coordinates [x, y, x, y, ...] and converts the control points into angles and lengths [x, y, angle, length, angle, length, x, y, angle, length, ...] so that it animates more cleanly and avoids odd breaks/kinks. For example, if you animate from 1 o\'clock to 6 o\'clock, it\'d just go directly/linearly rather than around. So the length would be very short in the middle of the tween.\nexport function cpCoordsToAngles(segment, copy) {\n\tvar result = copy ? segment.slice(0) : segment,\n\t\tx, y, i;\n\tfor (i = 0; i < segment.length; i+=6) {\n\t\tx = segment[i+2] - segment[i];\n\t\ty = segment[i+3] - segment[i+1];\n\t\tresult[i+2] = Math.atan2(y, x);\n\t\tresult[i+3] = Math.sqrt(x * x + y * y);\n\t\tx = segment[i+6] - segment[i+4];\n\t\ty = segment[i+7] - segment[i+5];\n\t\tresult[i+4] = Math.atan2(y, x);\n\t\tresult[i+5] = Math.sqrt(x * x + y * y);\n\t}\n\treturn result;\n}\n\n// takes a segment that was converted with cpCoordsToAngles() to have angles and lengths instead of coordinates for the control points, and converts it BACK into coordinates.\nexport function cpAnglesToCoords(segment, copy) {\n\tvar result = copy ? segment.slice(0) : segment,\n\t\tlength = segment.length,\n\t\trnd = 1000,\n\t\tangle, l, i, j;\n\tfor (i = 0; i < length; i+=6) {\n\t\tangle = segment[i+2];\n\t\tl = segment[i+3]; //length\n\t\tresult[i+2] = (((segment[i] + Math.cos(angle) * l) * rnd) | 0) / rnd;\n\t\tresult[i+3] = (((segment[i+1] + Math.sin(angle) * l) * rnd) | 0) / rnd;\n\t\tangle = segment[i+4];\n\t\tl = segment[i+5]; //length\n\t\tresult[i+4] = (((segment[i+6] - Math.cos(angle) * l) * rnd) | 0) / rnd;\n\t\tresult[i+5] = (((segment[i+7] - Math.sin(angle) * l) * rnd) | 0) / rnd;\n\t}\n\treturn result;\n}\n\n//adds an "isSmooth" array to each segment and populates it with a boolean value indicating whether or not it\'s smooth (the control points have basically the same slope). For any smooth control points, it converts the coordinates into angle (x, in radians) and length (y) and puts them into the same index value in a smoothData array.\nexport function populateSmoothData(rawPath) {\n\tlet j = rawPath.length,\n\t\tsmooth, segment, x, y, x2, y2, i, l, a, a2, isSmooth, smoothData;\n\twhile (--j > -1) {\n\t\tsegment = rawPath[j];\n\t\tisSmooth = segment.isSmooth = segment.isSmooth || [0, 0, 0, 0];\n\t\tsmoothData = segment.smoothData = segment.smoothData || [0, 0, 0, 0];\n\t\tisSmooth.length = 4;\n\t\tl = segment.length - 2;\n\t\tfor (i = 6; i < l; i += 6) {\n\t\t\tx = segment[i] - segment[i - 2];\n\t\t\ty = segment[i + 1] - segment[i - 1];\n\t\t\tx2 = segment[i + 2] - segment[i];\n\t\t\ty2 = segment[i + 3] - segment[i + 1];\n\t\t\ta = _atan2(y, x);\n\t\t\ta2 = _atan2(y2, x2);\n\t\t\tsmooth = (Math.abs(a - a2) < 0.09);\n\t\t\tif (smooth) {\n\t\t\t\tsmoothData[i - 2] = a;\n\t\t\t\tsmoothData[i + 2] = a2;\n\t\t\t\tsmoothData[i - 1] = _sqrt(x * x + y * y);\n\t\t\t\tsmoothData[i + 3] = _sqrt(x2 * x2 + y2 * y2);\n\t\t\t}\n\t\t\tisSmooth.push(smooth, smooth, 0, 0, smooth, smooth);\n\t\t}\n\t\t//if the first and last points are identical, check to see if there\'s a smooth transition. We must handle this a bit differently due to their positions in the array.\n\t\tif (segment[l] === segment[0] && segment[l+1] === segment[1]) {\n\t\t\tx = segment[0] - segment[l-2];\n\t\t\ty = segment[1] - segment[l-1];\n\t\t\tx2 = segment[2] - segment[0];\n\t\t\ty2 = segment[3] - segment[1];\n\t\t\ta = _atan2(y, x);\n\t\t\ta2 = _atan2(y2, x2);\n\t\t\tif (Math.abs(a - a2) < 0.09) {\n\t\t\t\tsmoothData[l-2] = a;\n\t\t\t\tsmoothData[2] = a2;\n\t\t\t\tsmoothData[l-1] = _sqrt(x * x + y * y);\n\t\t\t\tsmoothData[3] = _sqrt(x2 * x2 + y2 * y2);\n\t\t\t\tisSmooth[l-2] = isSmooth[l-1] = true; //don\'t change indexes 2 and 3 because we\'ll trigger everything from the END, and this will optimize file size a bit.\n\t\t\t}\n\t\t}\n\t}\n\treturn rawPath;\n}\nexport function pointToScreen(svgElement, point) {\n\tif (arguments.length < 2) { //by default, take the first set of coordinates in the path as the point\n\t\tlet rawPath = getRawPath(svgElement);\n\t\tpoint = svgElement.ownerSVGElement.createSVGPoint();\n\t\tpoint.x = rawPath[0][0];\n\t\tpoint.y = rawPath[0][1];\n\t}\n\treturn point.matrixTransform(svgElement.getScreenCTM());\n}\n// takes a <path> and normalizes all of its coordinates to values between 0 and 1\nexport function normalizePath(path) {\n  path = gsap.utils.toArray(path);\n  if (!path[0].hasAttribute("d")) {\n    path = gsap.utils.toArray(path[0].children);\n  }\n  if (path.length > 1) {\n    path.forEach(normalizePath);\n    return path;\n  }\n  let _svgPathExp = /[achlmqstvz]|(-?\\d*\\.?\\d*(?:e[\\-+]?\\d+)?)[0-9]/ig,\n      _scientific = /[\\+\\-]?\\d*\\.?\\d+e[\\+\\-]?\\d+/ig,\n      d = path[0].getAttribute("d"),\n      a = d.replace(_scientific, m => { let n = +m; return (n < 0.0001 && n > -0.0001) ? 0 : n; }).match(_svgPathExp),\n      nums = a.filter(n => !isNaN(n)).map(n => +n),\n      normalize = gsap.utils.normalize(Math.min(...nums), Math.max(...nums)),\n      finals = a.map(val => isNaN(val) ? val : normalize(+val)),\n      s = "",\n      prevWasCommand;
1\n  finals.forEach((value, i) => {\n    let isCommand = isNaN(value)\n    s += (isCommand && i ? " " : prevWasCommand || !i ? "" : ",") + value;\n    prevWasCommand = isCommand;\n  });\n  path[0].setAttribute("d", s);\n}\n*/\n\n//# sourceURL=webpack://real-insight/./node_modules/gsap/utils/paths.js?\n}')},"./node_modules/imagesloaded/imagesloaded.js"(module,__unused_webpack_exports,__webpack_require__){eval("{/*!\n * imagesLoaded v5.0.0\n * JavaScript is all like \"You images are done yet or what?\"\n * MIT License\n */\n\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory( window, __webpack_require__(/*! ev-emitter */ \"./node_modules/ev-emitter/ev-emitter.js\") );\n  } else {\n    // browser global\n    window.imagesLoaded = factory( window, window.EvEmitter );\n  }\n\n} )( typeof window !== 'undefined' ? window : this,\n    function factory( window, EvEmitter ) {\n\nlet $ = window.jQuery;\nlet console = window.console;\n\n// -------------------------- helpers -------------------------- //\n\n// turn element or nodeList into an array\nfunction makeArray( obj ) {\n  // use object if already an array\n  if ( Array.isArray( obj ) ) return obj;\n\n  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';\n  // convert nodeList to array\n  if ( isArrayLike ) return [ ...obj ];\n\n  // array of single index\n  return [ obj ];\n}\n\n// -------------------------- imagesLoaded -------------------------- //\n\n/**\n * @param {[Array, Element, NodeList, String]} elem\n * @param {[Object, Function]} options - if function, use as callback\n * @param {Function} onAlways - callback function\n * @returns {ImagesLoaded}\n */\nfunction ImagesLoaded( elem, options, onAlways ) {\n  // coerce ImagesLoaded() without new, to be new ImagesLoaded()\n  if ( !( this instanceof ImagesLoaded ) ) {\n    return new ImagesLoaded( elem, options, onAlways );\n  }\n  // use elem as selector string\n  let queryElem = elem;\n  if ( typeof elem == 'string' ) {\n    queryElem = document.querySelectorAll( elem );\n  }\n  // bail if bad element\n  if ( !queryElem ) {\n    console.error(`Bad element for imagesLoaded ${queryElem || elem}`);\n    return;\n  }\n\n  this.elements = makeArray( queryElem );\n  this.options = {};\n  // shift arguments if no options set\n  if ( typeof options == 'function' ) {\n    onAlways = options;\n  } else {\n    Object.assign( this.options, options );\n  }\n\n  if ( onAlways ) this.on( 'always', onAlways );\n\n  this.getImages();\n  // add jQuery Deferred object\n  if ( $ ) this.jqDeferred = new $.Deferred();\n\n  // HACK check async to allow time to bind listeners\n  setTimeout( this.check.bind( this ) );\n}\n\nImagesLoaded.prototype = Object.create( EvEmitter.prototype );\n\nImagesLoaded.prototype.getImages = function() {\n  this.images = [];\n\n  // filter & find items if we have an item selector\n  this.elements.forEach( this.addElementImages, this );\n};\n\nconst elementNodeTypes = [ 1, 9, 11 ];\n\n/**\n * @param {Node} elem\n */\nImagesLoaded.prototype.addElementImages = function( elem ) {\n  // filter siblings\n  if ( elem.nodeName === 'IMG' ) {\n    this.addImage( elem );\n  }\n  // get background image on element\n  if ( this.options.background === true ) {\n    this.addElementBackgroundImages( elem );\n  }\n\n  // find children\n  // no non-element nodes, #143\n  let { nodeType } = elem;\n  if ( !nodeType || !elementNodeTypes.includes( nodeType ) ) return;\n\n  let childImgs = elem.querySelectorAll('img');\n  // concat childElems to filterFound array\n  for ( let img of childImgs ) {\n    this.addImage( img );\n  }\n\n  // get child background images\n  if ( typeof this.options.background == 'string' ) {\n    let children = elem.querySelectorAll( this.options.background );\n    for ( let child of children ) {\n      this.addElementBackgroundImages( child );\n    }\n  }\n};\n\nconst reURL = /url\\((['\"])?(.*?)\\1\\)/gi;\n\nImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {\n  let style = getComputedStyle( elem );\n  // Firefox returns null if in a hidden iframe https://bugzil.la/548397\n  if ( !style ) return;\n\n  // get url inside url(\"...\")\n  let matches = reURL.exec( style.backgroundImage );\n  while ( matches !== null ) {\n    let url = matches && matches[2];
1\n    if ( url ) {\n      this.addBackground( url, elem );\n    }\n    matches = reURL.exec( style.backgroundImage );\n  }\n};\n\n/**\n * @param {Image} img\n */\nImagesLoaded.prototype.addImage = function( img ) {\n  let loadingImage = new LoadingImage( img );\n  this.images.push( loadingImage );\n};\n\nImagesLoaded.prototype.addBackground = function( url, elem ) {\n  let background = new Background( url, elem );\n  this.images.push( background );\n};\n\nImagesLoaded.prototype.check = function() {\n  this.progressedCount = 0;\n  this.hasAnyBroken = false;\n  // complete if no images\n  if ( !this.images.length ) {\n    this.complete();\n    return;\n  }\n\n  /* eslint-disable-next-line func-style */\n  let onProgress = ( image, elem, message ) => {\n    // HACK - Chrome triggers event before object properties have changed. #83\n    setTimeout( () => {\n      this.progress( image, elem, message );\n    } );\n  };\n\n  this.images.forEach( function( loadingImage ) {\n    loadingImage.once( 'progress', onProgress );\n    loadingImage.check();\n  } );\n};\n\nImagesLoaded.prototype.progress = function( image, elem, message ) {\n  this.progressedCount++;\n  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;\n  // progress event\n  this.emitEvent( 'progress', [ this, image, elem ] );\n  if ( this.jqDeferred && this.jqDeferred.notify ) {\n    this.jqDeferred.notify( this, image );\n  }\n  // check if completed\n  if ( this.progressedCount === this.images.length ) {\n    this.complete();\n  }\n\n  if ( this.options.debug && console ) {\n    console.log( `progress: ${message}`, image, elem );\n  }\n};\n\nImagesLoaded.prototype.complete = function() {\n  let eventName = this.hasAnyBroken ? 'fail' : 'done';\n  this.isComplete = true;\n  this.emitEvent( eventName, [ this ] );\n  this.emitEvent( 'always', [ this ] );\n  if ( this.jqDeferred ) {\n    let jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';\n    this.jqDeferred[ jqMethod ]( this );\n  }\n};\n\n// --------------------------  -------------------------- //\n\nfunction LoadingImage( img ) {\n  this.img = img;\n}\n\nLoadingImage.prototype = Object.create( EvEmitter.prototype );\n\nLoadingImage.prototype.check = function() {\n  // If complete is true and browser supports natural sizes,\n  // try to check for image status manually.\n  let isComplete = this.getIsImageComplete();\n  if ( isComplete ) {\n    // report based on naturalWidth\n    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n    return;\n  }\n\n  // If none of the checks above matched, simulate loading on detached element.\n  this.proxyImage = new Image();\n  // add crossOrigin attribute. #204\n  if ( this.img.crossOrigin ) {\n    this.proxyImage.crossOrigin = this.img.crossOrigin;\n  }\n  this.proxyImage.addEventListener( 'load', this );\n  this.proxyImage.addEventListener( 'error', this );\n  // bind to image as well for Firefox. #191\n  this.img.addEventListener( 'load', this );\n  this.img.addEventListener( 'error', this );\n  this.proxyImage.src = this.img.currentSrc || this.img.src;\n};\n\nLoadingImage.prototype.getIsImageComplete = function() {\n  // check for non-zero, non-undefined naturalWidth\n  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671\n  return this.img.complete && this.img.naturalWidth;\n};\n\nLoadingImage.prototype.confirm = function( isLoaded, message ) {\n  this.isLoaded = isLoaded;\n  let { parentNode } = this.img;\n  // emit progress with parent <picture> or self <img>\n  let elem = parentNode.nodeName === 'PICTURE' ? parentNode : this.img;\n  this.emitEvent( 'progress', [ this, elem, message ] );\n};\n\n// ----- events ----- //\n\n// trigger specified handler for event type\nLoadingImage.prototype.handleEvent = function( event ) {\n  let method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\nLoadingImage.prototype.onload = function() {\n  this.confirm( true, 'onload' );\n  this.unbindEvents();\n};\n\nLoadingImage.prototype.onerror = function() {\n  this.confirm( false, 'onerror' );\n  this.unbindEvents();\n};
1\n\nLoadingImage.prototype.unbindEvents = function() {\n  this.proxyImage.removeEventListener( 'load', this );\n  this.proxyImage.removeEventListener( 'error', this );\n  this.img.removeEventListener( 'load', this );\n  this.img.removeEventListener( 'error', this );\n};\n\n// -------------------------- Background -------------------------- //\n\nfunction Background( url, element ) {\n  this.url = url;\n  this.element = element;\n  this.img = new Image();\n}\n\n// inherit LoadingImage prototype\nBackground.prototype = Object.create( LoadingImage.prototype );\n\nBackground.prototype.check = function() {\n  this.img.addEventListener( 'load', this );\n  this.img.addEventListener( 'error', this );\n  this.img.src = this.url;\n  // check if image is already complete\n  let isComplete = this.getIsImageComplete();\n  if ( isComplete ) {\n    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );\n    this.unbindEvents();\n  }\n};\n\nBackground.prototype.unbindEvents = function() {\n  this.img.removeEventListener( 'load', this );\n  this.img.removeEventListener( 'error', this );\n};\n\nBackground.prototype.confirm = function( isLoaded, message ) {\n  this.isLoaded = isLoaded;\n  this.emitEvent( 'progress', [ this, this.element, message ] );\n};\n\n// -------------------------- jQuery -------------------------- //\n\nImagesLoaded.makeJQueryPlugin = function( jQuery ) {\n  jQuery = jQuery || window.jQuery;\n  if ( !jQuery ) return;\n\n  // set local variable\n  $ = jQuery;\n  // $().imagesLoaded()\n  $.fn.imagesLoaded = function( options, onAlways ) {\n    let instance = new ImagesLoaded( this, options, onAlways );\n    return instance.jqDeferred.promise( $( this ) );\n  };\n};\n// try making plugin\nImagesLoaded.makeJQueryPlugin();\n\n// --------------------------  -------------------------- //\n\nreturn ImagesLoaded;\n\n} );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/imagesloaded/imagesloaded.js?\n}")},"./node_modules/lightgallery/lightgallery.es5.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/*!\n * lightgallery | 2.9.0 | October 1st 2025\n * http://www.lightgalleryjs.com/\n * Copyright (c) 2020 Sachin Neravath;\n * @license GPLv3\n */\n\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    };\r\n    return __assign.apply(this, arguments);\r\n};\r\n\r\nfunction __spreadArrays() {\r\n    for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;\r\n    for (var r = Array(s), k = 0, i = 0; i < il; i++)\r\n        for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)\r\n            r[k] = a[j];\r\n    return r;\r\n}\n\n/**\r\n * List of lightGallery events\r\n * All events should be documented here\r\n * Below interfaces are used to build the website documentations\r\n * */\r\nvar lGEvents = {\r\n    afterAppendSlide: 'lgAfterAppendSlide',\r\n    init: 'lgInit',\r\n    hasVideo: 'lgHasVideo',\r\n    containerResize: 'lgContainerResize',\r\n    updateSlides: 'lgUpdateSlides',\r\n    afterAppendSubHtml: 'lgAfterAppendSubHtml',\r\n    beforeOpen: 'lgBeforeOpen',\r\n    afterOpen: 'lgAfterOpen',\r\n    slideItemLoad: 'lgSlideItemLoad',\r\n    beforeSlide: 'lgBeforeSlide',\r\n    afterSlide: 'lgAfterSlide',\r\n    posterClick: 'lgPosterClick',\r\n    dragStart: 'lgDragStart',\r\n    dragMove: 'lgDragMove',\r\n    dragEnd: 'lgDragEnd',\r\n    beforeNextSlide: 'lgBeforeNextSlide',\r\n    beforePrevSlide: 'lgBeforePrevSlide',\r\n    beforeClose: 'lgBeforeClose',\r\n    afterClose: 'lgAfterClose',\r\n    rotateLeft: 'lgRotateLeft',\r\n    rotateRight: 'lgRotateRight',\r\n    flipHorizontal: 'lgFlipHorizontal',\r\n    flipVertical: 'lgFlipVertical',\r\n    autoplay: 'lgAutoplay',\r\n    autoplayStart: 'lgAutoplayStart',\r\n    autoplayStop: 'lgAutoplayStop',\r\n};\n\nvar lightGalleryCoreSettings = {\r\n    mode: 'lg-slide',\r\n    easing: 'ease',\r\n    speed: 400,\r\n    licenseKey: '0000-0000-000-0000',\r\n    height: '100%',\r\n    width: '100%',\r\n    addClass: '',\r\n    startClass: 'lg-start-zoom',\r\n    backdropDuration: 300,\r\n    container: '',\r\n    startAnimationDuration: 400,\r\n    zoomFromOrigin: true,\r\n    hideBarsDelay: 0,\r\n    showBarsAfter: 10000,\r\n    slideDelay: 0,\r\n    supportLegacyBrowser: true,\r\n    allowMediaOverlap: false,\r\n    videoMaxSize: '1280-720',\r\n    loadYouTubePoster: true,\r\n    defaultCaptionHeight: 0,\r\n    ariaLabelledby: '',\r\n    ariaDescribedby: '',\r\n    resetScrollPosition: true,\r\n    hideScrollbar: false,\r\n    closable: true,\r\n    swipeToClose: true,\r\n    closeOnTap: true,\r\n    showCloseIcon: true,\r\n    showMaximizeIcon: false,\r\n    loop: true,\r\n    escKey: true,\r\n    keyPress: true,\r\n    trapFocus: true,\r\n    controls: true,\r\n    slideEndAnimation: true,\r\n    hideControlOnEnd: false,\r\n    mousewheel: false,\r\n    getCaptionFromTitleOrAlt: true,\r\n    appendSubHtmlTo: '.lg-sub-html',\r\n    subHtmlSelectorRelative: false,\r\n    preload: 2,\r\n    numberOfSlideItemsInDom: 10,\r\n    selector: '',\r\n    selectWithin: '',\r\n    nextHtml: '',\r\n    prevHtml: '',\r\n    index: 0,\r\n    iframeWidth: '100%',\r\n    iframeHeight: '100%',\r\n    iframeMaxWidth: '100%',\r\n    iframeMaxHeight: '100%',\r\n    download: true,\r\n    counter: true,\r\n    appendCounterTo: '.lg-toolbar',\r\n    swipeThreshold: 50,\r\n    enableSwipe: true,\r\n    enableDrag: true,\r\n    dynamic: fal
1se,\r\n    dynamicEl: [],\r\n    extraProps: [],\r\n    exThumbImage: '',\r\n    isMobile: undefined,\r\n    mobileSettings: {\r\n        controls: false,\r\n        showCloseIcon: false,\r\n        download: false,\r\n    },\r\n    plugins: [],\r\n    strings: {\r\n        closeGallery: 'Close gallery',\r\n        toggleMaximize: 'Toggle maximize',\r\n        previousSlide: 'Previous slide',\r\n        nextSlide: 'Next slide',\r\n        download: 'Download',\r\n        playVideo: 'Play video',\r\n        mediaLoadingFailed: 'Oops... Failed to load content...',\r\n    },\r\n};\n\nfunction initLgPolyfills() {\r\n    (function () {\r\n        if (typeof window.CustomEvent === 'function')\r\n            return false;\r\n        function CustomEvent(event, params) {\r\n            params = params || {\r\n                bubbles: false,\r\n                cancelable: false,\r\n                detail: null,\r\n            };\r\n            var evt = document.createEvent('CustomEvent');\r\n            evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);\r\n            return evt;\r\n        }\r\n        window.CustomEvent = CustomEvent;\r\n    })();\r\n    (function () {\r\n        if (!Element.prototype.matches) {\r\n            Element.prototype.matches =\r\n                Element.prototype.msMatchesSelector ||\r\n                    Element.prototype.webkitMatchesSelector;\r\n        }\r\n    })();\r\n}\r\nvar lgQuery = /** @class */ (function () {\r\n    function lgQuery(selector) {\r\n        this.cssVenderPrefixes = [\r\n            'TransitionDuration',\r\n            'TransitionTimingFunction',\r\n            'Transform',\r\n            'Transition',\r\n        ];\r\n        this.selector = this._getSelector(selector);\r\n        this.firstElement = this._getFirstEl();\r\n        return this;\r\n    }\r\n    lgQuery.generateUUID = function () {\r\n        return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\r\n            var r = (Math.random() * 16) | 0, v = c == 'x' ? r : (r & 0x3) | 0x8;\r\n            return v.toString(16);\r\n        });\r\n    };\r\n    lgQuery.prototype._getSelector = function (selector, context) {\r\n        if (context === void 0) { context = document; }\r\n        if (typeof selector !== 'string') {\r\n            return selector;\r\n        }\r\n        context = context || document;\r\n        var fl = selector.substring(0, 1);\r\n        if (fl === '#') {\r\n            return context.querySelector(selector);\r\n        }\r\n        else {\r\n            return context.querySelectorAll(selector);\r\n        }\r\n    };\r\n    lgQuery.prototype._each = function (func) {\r\n        if (!this.selector) {\r\n            return this;\r\n        }\r\n        if (this.selector.length !== undefined) {\r\n            [].forEach.call(this.selector, func);\r\n        }\r\n        else {\r\n            func(this.selector, 0);\r\n        }\r\n        return this;\r\n    };\r\n    lgQuery.prototype._setCssVendorPrefix = function (el, cssProperty, value) {\r\n        // prettier-ignore\r\n        var property = cssProperty.replace(/-([a-z])/gi, function (s, group1) {\r\n            return group1.toUpperCase();\r\n        });\r\n        if (this.cssVenderPrefixes.indexOf(property) !== -1) {\r\n            el.style[property.charAt(0).toLowerCase() + property.slice(1)] = value;\r\n            el.style['webkit' + property] = value;\r\n            el.style['moz' + property] = value;\r\n            el.style['ms' + property] = value;\r\n            el.style['o' + property] = value;\r\n        }\r\n        else {\r\n            el.style[property] = value;\r\n        }\r\n    };\r\n    lgQuery.prototype._getFirstEl = function () {\r\n        if (this.selector && this.selector.length !== undefined) {\r\n            return this.selector[0];\r\n        }\r\n        else {\r\n            return this.selector;\r\n        }\r\n    };\r\n    lgQuery.prototype.isEventMatched = function (event, eventName) {\r\n        var eventNamespace = eventName.split('.');\r\n        return event\r\n            .split('.')\r\n            .filter(function (e) { return e; })\r\n            .every(function (e) {\r\n            return eventNamespace.indexOf(e) !== -1;\r\n        });\r\n    };\r\n    lgQuery.prototype.attr = function (attr, value) {\r\n        if (value === undefined) {\r\n            if (!this.firstElement) {\r\n                return '';\r\n            }\r\n            return this.firstElement.getAttribute(attr);\r\n        }\r\n        this._each(function (el) {\r\n            el.setAttribute(attr, value);\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.find = function (selector) {\r\n        return $LG(this._getSelector(selector, this.selector));\r\n    };\r\n    lgQuery.prototype.first = function () {\r\n        if (this.selector && this.selector.length !== undefined) {\r\n            return $LG(this.selector[0]);\r\n        }\r\n        else {\r\n            return $LG(this.selector);\r\n        }\r\n    };\r\n    lgQuery.prototype.eq = function (index) {\r\n        return $LG(this.selector[index]);\r\n    };\r\n    lgQuery.prototype.parent = function () {\r\n        return $LG(this.selector.parentElement);\r\n    };\r\n    lgQuery.prototype.get = function () {\r\n        return this._getFirstEl();\r\n    };\r\n    lgQuery.prototype.removeAttr = function (attributes) {\r\n        var attrs = attributes.split(' ');\r\n        this._each(function (el) {\r\n            attrs.forEac
1h(function (attr) { return el.removeAttribute(attr); });\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.wrap = function (className) {\r\n        if (!this.firstElement) {\r\n            return this;\r\n        }\r\n        var wrapper = document.createElement('div');\r\n        wrapper.className = className;\r\n        this.firstElement.parentNode.insertBefore(wrapper, this.firstElement);\r\n        this.firstElement.parentNode.removeChild(this.firstElement);\r\n        wrapper.appendChild(this.firstElement);\r\n        return this;\r\n    };\r\n    lgQuery.prototype.addClass = function (classNames) {\r\n        if (classNames === void 0) { classNames = ''; }\r\n        this._each(function (el) {\r\n            // IE doesn't support multiple arguments\r\n            classNames.split(' ').forEach(function (className) {\r\n                if (className) {\r\n                    el.classList.add(className);\r\n                }\r\n            });\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.removeClass = function (classNames) {\r\n        this._each(function (el) {\r\n            // IE doesn't support multiple arguments\r\n            classNames.split(' ').forEach(function (className) {\r\n                if (className) {\r\n                    el.classList.remove(className);\r\n                }\r\n            });\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.hasClass = function (className) {\r\n        if (!this.firstElement) {\r\n            return false;\r\n        }\r\n        return this.firstElement.classList.contains(className);\r\n    };\r\n    lgQuery.prototype.hasAttribute = function (attribute) {\r\n        if (!this.firstElement) {\r\n            return false;\r\n        }\r\n        return this.firstElement.hasAttribute(attribute);\r\n    };\r\n    lgQuery.prototype.toggleClass = function (className) {\r\n        if (!this.firstElement) {\r\n            return this;\r\n        }\r\n        if (this.hasClass(className)) {\r\n            this.removeClass(className);\r\n        }\r\n        else {\r\n            this.addClass(className);\r\n        }\r\n        return this;\r\n    };\r\n    lgQuery.prototype.css = function (property, value) {\r\n        var _this = this;\r\n        this._each(function (el) {\r\n            _this._setCssVendorPrefix(el, property, value);\r\n        });\r\n        return this;\r\n    };\r\n    // Need to pass separate namespaces for separate elements\r\n    lgQuery.prototype.on = function (events, listener) {\r\n        var _this = this;\r\n        if (!this.selector) {\r\n            return this;\r\n        }\r\n        events.split(' ').forEach(function (event) {\r\n            if (!Array.isArray(lgQuery.eventListeners[event])) {\r\n                lgQuery.eventListeners[event] = [];\r\n            }\r\n            lgQuery.eventListeners[event].push(listener);\r\n            _this.selector.addEventListener(event.split('.')[0], listener);\r\n        });\r\n        return this;\r\n    };\r\n    // @todo - test this\r\n    lgQuery.prototype.once = function (event, listener) {\r\n        var _this = this;\r\n        this.on(event, function () {\r\n            _this.off(event);\r\n            listener(event);\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.off = function (event) {\r\n        var _this = this;\r\n        if (!this.selector) {\r\n            return this;\r\n        }\r\n        Object.keys(lgQuery.eventListeners).forEach(function (eventName) {\r\n            if (_this.isEventMatched(event, eventName)) {\r\n                lgQuery.eventListeners[eventName].forEach(function (listener) {\r\n                    _this.selector.removeEventListener(eventName.split('.')[0], listener);\r\n                });\r\n                lgQuery.eventListeners[eventName] = [];\r\n            }\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.trigger = function (event, detail) {\r\n        if (!this.firstElement) {\r\n            return this;\r\n        }\r\n        var customEvent = new CustomEvent(event.split('.')[0], {\r\n            detail: detail || null,\r\n        });\r\n        this.firstElement.dispatchEvent(customEvent);\r\n        return this;\r\n    };\r\n    // Does not support IE\r\n    lgQuery.prototype.load = function (url) {\r\n        var _this = this;\r\n        fetch(url)\r\n            .then(function (res) { return res.text(); })\r\n            .then(function (html) {\r\n            _this.selector.innerHTML = html;\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.html = function (html) {\r\n        if (html === undefined) {\r\n            if (!this.firstElement) {\r\n                return '';\r\n            }\r\n            return this.firstElement.innerHTML;\r\n        }\r\n        this._each(function (el) {\r\n            el.innerHTML = html;\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.append = function (html) {\r\n        this._each(function (el) {\r\n            if (typeof html === 'string') {\r\n                el.insertAdjacentHTML('beforeend', html);\r\n            }\r\n            else {\r\n                el.appendChild(html);\r\n            }\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.prepend = function (html) {\r\n        this._each(function (el) {\r\n            if (typeof html === 'string') {\r\n                el.insertAdjacentHTML('afterbegin', html);\r\n            }\r\n            else if (html instanceof HTMLElement) {\r\n                el.insertBefore(html.cloneNode(true), el.firstChild);\r\n            }\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.remove = function () {\r\n        this._each(function (el) {\r\n            el.parentNode.removeChild(el);\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.empty = function () {\r\n        this._each(function (el) {\r\n            el.innerHTML = '';\r\n        });\r\n        return this;\r\n    };\r\n    lgQuery.prototype.scrollTop = function (scrollTop) {\r\n        if (scrollTop !== undefined) {\r\n            document.body.scrollTop = scrollTop;\r\n            document.documentElement.scrollTop = scrollTop;\r\n            return this;\r\n        }\r\n        else {\r\n            return (window.pageYOffset ||\r\n                document.documentElement.scrollTop ||\r\n                document.body.scrollTop ||\r\n                0);\r\n        }\r\n    };\r\n    lgQuery.prototype.scrollLeft = function (scrollLeft) {\r\n        if (scrollLeft !== undefined) {\r\n            document.body.scrollLeft = scrollLeft;\r\n            document.documentElement.scrollLeft = scrollLeft;\r\n            return this;\r\n        }\r\n        else {\r\n            return (window.pageXOffset ||\r\n                document.documentElement.scrollLeft ||\r\n                document.body.scrollLeft ||\r\n                0);\r\n        }\r\n    };\r\n    lgQuery.prototype.offset = function () {\r\n        if (!this.firstElement) {\r\n            return {\r\n                left: 0,\r\n                top: 0,\r\n            };\r\n        }\r\n        var rect = this.firstElement.getBoundingClientRect();\r\n        var bodyMarginLeft = $LG('body').style().marginLeft;\r\n        // Minus body margin - https://stackoverflow.com/questions/30711548/is-getboundingclientrect-left-returning-a-wrong-value\r\n        return {\r\n            left: rect.left - parseFloat(bodyMarginLeft) + this.scrollLeft(),\r\n            top: rect.top + this.scrollTop(),\r\n        };\r\n    };\r\n    lgQuery.prototype.style = function () {\r\n        if (!this.firstElement) {\r\n            return {};\r\n        }\r\n        return (this.firstElement.currentStyle ||\r\n            window.getComputedStyle(this.firstElement));\r\n    };\r\n    // Width without padding and border even if box-sizing is used.\r\n    lgQuery.prototype.width = function () {\r\n        var style = this.style();\r\n        return (this.firstElement.clientWidth -\r\n            parseFloat(style.paddingLeft) -\r\n            parseFloat(style.paddingRight));\r\n    };\r\n    // Height without padding and border even if box-sizing is used.\r\n    lgQuery.prototype.height = function () {\r\n        var style = this.style();\r\n        return (this.firstElement.clientHeight -\r\n            parseFloat(style.paddingTop) -\r\n            parseFloat(style.paddingBottom));\r\n    };\r\n    lgQuery.eventListeners = {};\r\n    return lgQuery;\r\n}());\r\nfunction $LG(selector) {\r\n    initLgPolyfills();\r\n    return new lgQuery(selector);\r\n}\n\nvar defaultDynamicOptions = [\r\n    'src',\r\n    'sources',\r\n    'subHtml',\r\n    'subHtmlUrl',\r\n    'html',\r\n    'video',\r\n    'poster',\r\n    'slideName',\r\n    'responsive',\r\n    'srcset',\r\n    'sizes',\r\n    'iframe',\r\n    'downloadUrl',\r\n    'download',\r\n    'width',\r\n    'facebookShareUrl',\r\n    'tweetText',\r\n    'iframeTitle',\r\n    'twitterShareUrl',\r\n    'pinterestShareUrl',\r\n    'pinterestText',\r\n    'fbHtml',\r\n    'disqusIdentifier',\r\n    'disqusUrl',\r\n];\r\n// Convert html data-attribute to camalcase\r\nfunction convertToData(attr) {\r\n    // FInd a way for lgsize\r\n    if (attr === 'href') {\r\n        return 'src';\r\n    }\r\n    attr = attr.replace('data-', '');\r\n    attr = attr.charAt(0).toLowerCase() + attr.slice(1);\r\n    attr = attr.replace(/-([a-z])/g, function (g) { return g[1].toUpperCase(); });\r\n    return attr;\r\n}\r\nvar utils = {\r\n    /**\r\n     * Fetches HTML content from a given URL and inserts it into a specified element.\r\n     *\r\n     * @param url - The URL to fetch the HTML content from.\r\n     * @param element - The DOM element (jQuery object) to insert the HTML content into.\r\n     * @param insertMethod - The method to insert the HTML ('append' or 'replace').\r\n     */\r\n    fetchCaptionFromUrl: function (url, element, insertMethod) {\r\n        // Fetch content from the URL\r\n        fetch(url)\r\n            .then(function (response) { return response.text(); })\r\n            .then(function (htmlContent) {\r\n            if (insertMethod === 'append') {\r\n                var contentDiv = \"<div class=\\\"lg-sub-html\\\">\" + htmlContent + \"</div>\";\r\n                element.append(contentDiv);\r\n            }\r\n            else {\r\n                element.html(htmlContent);\r\n            }\r\n        });\r\n    },\r\n    /**\r\n     * get possible width and height from the lgSize attribute. Used for ZoomFromOrigin option\r\n     */\r\n    getSize: function (el, container, spacing, defaultLgSize) {\r\n        if (spacing === void 0) { spacing = 0; }\r\n        var LGel = $LG(el);\r\n        var lgSize = LGel.attr('data-lg-size') || defaultLgSize;\r\n        if (!lgSize) {\r\n            return;\r\n        }\r\n        var isResponsiveSizes = lgSize.split(',');\r\n        // if at-least two viewport sizes are available\r\n        if (isResponsiveSizes[1]) {\r\n            var wWidth = window.innerWidth;\r\n            for (var i = 0; i < isResponsiveSizes.length; i++) {\r\n                var size_1 = isResponsiveSizes[i];\r\n                var responsiveWidth = parseInt(size_1.split('-')[2], 10);\r\n                if (responsiveWidth > wWidth) {\r\n                    lgSize = size_1;\r\n                    break;\r\n                }\r\n                // take last item as last option\r\n                if (i === isResponsiveSizes.length - 1) {\r\n                    lgSize = size_1;\r\n                }\r\n            }\r\n        }\r\n        var size = lgSize.split('-');\r\n        var width = parseInt(size[0], 10);\r\n        var height = parseInt(size[1], 10);\r\n        var cWidth = container.width();\r\n        var cHeight = container.height() - spacing;\r\n        var maxWidth = Math.min(cWidth, width);\r\n        var maxHeight = Math.min(cHeight, height);\r\n        var ratio = Math.min(maxWidth / width, maxHeight / height);\r\n        return { width: width * ratio, height: height * ratio };\r\n    }
1,\r\n    /**\r\n     * @desc Get transform value based on the imageSize. Used for ZoomFromOrigin option\r\n     * @param {jQuery Element}\r\n     * @returns {String} Transform CSS string\r\n     */\r\n    getTransform: function (el, container, top, bottom, imageSize) {\r\n        if (!imageSize) {\r\n            return;\r\n        }\r\n        var LGel = $LG(el).find('img').first();\r\n        if (!LGel.get()) {\r\n            return;\r\n        }\r\n        var containerRect = container.get().getBoundingClientRect();\r\n        var wWidth = containerRect.width;\r\n        // using innerWidth to include mobile safari bottom bar\r\n        var wHeight = container.height() - (top + bottom);\r\n        var elWidth = LGel.width();\r\n        var elHeight = LGel.height();\r\n        var elStyle = LGel.style();\r\n        var x = (wWidth - elWidth) / 2 -\r\n            LGel.offset().left +\r\n            (parseFloat(elStyle.paddingLeft) || 0) +\r\n            (parseFloat(elStyle.borderLeft) || 0) +\r\n            $LG(window).scrollLeft() +\r\n            containerRect.left;\r\n        var y = (wHeight - elHeight) / 2 -\r\n            LGel.offset().top +\r\n            (parseFloat(elStyle.paddingTop) || 0) +\r\n            (parseFloat(elStyle.borderTop) || 0) +\r\n            $LG(window).scrollTop() +\r\n            top;\r\n        var scX = elWidth / imageSize.width;\r\n        var scY = elHeight / imageSize.height;\r\n        var transform = 'translate3d(' +\r\n            (x *= -1) +\r\n            'px, ' +\r\n            (y *= -1) +\r\n            'px, 0) scale3d(' +\r\n            scX +\r\n            ', ' +\r\n            scY +\r\n            ', 1)';\r\n        return transform;\r\n    },\r\n    getIframeMarkup: function (iframeWidth, iframeHeight, iframeMaxWidth, iframeMaxHeight, src, iframeTitle) {\r\n        var title = iframeTitle ? 'title=\"' + iframeTitle + '\"' : '';\r\n        return \"<div class=\\\"lg-media-cont lg-has-iframe\\\" style=\\\"width:\" + iframeWidth + \"; max-width:\" + iframeMaxWidth + \"; height: \" + iframeHeight + \"; max-height:\" + iframeMaxHeight + \"\\\">\\n                    <iframe class=\\\"lg-object\\\" frameborder=\\\"0\\\" \" + title + \" src=\\\"\" + src + \"\\\"  allowfullscreen=\\\"true\\\"></iframe>\\n                </div>\";\r\n    },\r\n    getImgMarkup: function (index, src, altAttr, srcset, sizes, sources) {\r\n        var srcsetAttr = srcset ? \"srcset=\\\"\" + srcset + \"\\\"\" : '';\r\n        var sizesAttr = sizes ? \"sizes=\\\"\" + sizes + \"\\\"\" : '';\r\n        var imgMarkup = \"<img \" + altAttr + \" \" + srcsetAttr + \"  \" + sizesAttr + \" class=\\\"lg-object lg-image\\\" data-index=\\\"\" + index + \"\\\" src=\\\"\" + src + \"\\\" />\";\r\n        var sourceTag = '';\r\n        if (sources) {\r\n            var sourceObj = typeof sources === 'string' ? JSON.parse(sources) : sources;\r\n            sourceTag = sourceObj.map(function (source) {\r\n                var attrs = '';\r\n                Object.keys(source).forEach(function (key) {\r\n                    // Do not remove the first space as it is required to separate the attributes\r\n                    attrs += \" \" + key + \"=\\\"\" + source[key] + \"\\\"\";\r\n                });\r\n                return \"<source \" + attrs + \"></source>\";\r\n            });\r\n        }\r\n        return \"\" + sourceTag + imgMarkup;\r\n    },\r\n    // Get src from responsive src\r\n    getResponsiveSrc: function (srcItms) {\r\n        var rsWidth = [];\r\n        var rsSrc = [];\r\n        var src = '';\r\n        for (var i = 0; i < srcItms.length; i++) {\r\n            var _src = srcItms[i].split(' ');\r\n            // Manage empty space\r\n            if (_src[0] === '') {\r\n                _src.splice(0, 1);\r\n            }\r\n            rsSrc.push(_src[0]);\r\n            rsWidth.push(_src[1]);\r\n        }\r\n        var wWidth = window.innerWidth;\r\n        for (var j = 0; j < rsWidth.length; j++) {\r\n            if (parseInt(rsWidth[j], 10) > wWidth) {\r\n                src = rsSrc[j];\r\n                break;\r\n            }\r\n        }\r\n        return src;\r\n    },\r\n    isImageLoaded: function (img) {\r\n        if (!img)\r\n            return false;\r\n        // During the onload event, IE correctly identifies any images that\r\n        // weren’t downloaded as 
1not complete. Others should too. Gecko-based\r\n        // browsers act like NS4 in that they report this incorrectly.\r\n        if (!img.complete) {\r\n            return false;\r\n        }\r\n        // However, they do have two very useful properties: naturalWidth and\r\n        // naturalHeight. These give the true size of the image. If it failed\r\n        // to load, either of these should be zero.\r\n        if (img.naturalWidth === 0) {\r\n            return false;\r\n        }\r\n        // No other way of checking: assume it’s ok.\r\n        return true;\r\n    },\r\n    getVideoPosterMarkup: function (_poster, dummyImg, videoContStyle, playVideoString, _isVideo) {\r\n        var videoClass = '';\r\n        if (_isVideo && _isVideo.youtube) {\r\n            videoClass = 'lg-has-youtube';\r\n        }\r\n        else if (_isVideo && _isVideo.vimeo) {\r\n            videoClass = 'lg-has-vimeo';\r\n        }\r\n        else {\r\n            videoClass = 'lg-has-html5';\r\n        }\r\n        var _dummy = dummyImg;\r\n        if (typeof dummyImg !== 'string') {\r\n            _dummy = dummyImg.outerHTML;\r\n        }\r\n        return \"<div class=\\\"lg-video-cont \" + videoClass + \"\\\" style=\\\"\" + videoContStyle + \"\\\">\\n                <div class=\\\"lg-video-play-button\\\">
1\\n                <svg\\n                    viewBox=\\\"0 0 20 20\\\"\\n                    preserveAspectRatio=\\\"xMidYMid\\\"\\n                    focusable=\\\"false\\\"\\n                    aria-labelledby=\\\"\" + playVideoString + \"\\\"\\n                    role=\\\"img\\\"\\n                    class=\\\"lg-video-play-icon\\\"\\n                >\\n                    <title>\" + playVideoString + \"</title>\\n                    <polygon class=\\\"lg-video-play-icon-inner\\\" points=\\\"1,0 20,10 1,20\\\"></polygon>\\n                </svg>\\n                <svg class=\\\"lg-video-play-icon-bg\\\" viewBox=\\\"0 0 50 50\\\" focusable=\\\"false\\\">\\n                    <circle cx=\\\"50%\\\" cy=\\\"50%\\\" r=\\\"20\\\"></circle></svg>\\n                <svg class=\\\"lg-video-play-icon-circle\\\" viewBox=\\\"0 0 50 50\\\" focusable=\\\"false\\\">\\n                    <circle cx=\\\"50%\\\" cy=\\\"50%\\\" r=\\\"20\\\"></circle>\\n                </svg>\\n            </div>\\n            \" + _dummy + \"\\n            <img class=\\\"lg-object lg-video-poster\\\" src=\\\"\" + _poster + \"\\\" />\\n        </div>\";\r\n    },\r\n    getFocusableElements: function (container) {\r\n        var elements = container.querySelectorAll('a[href]:not([disabled]), button:not([disabled]), textarea:not([disabled]), input[type=\"text\"]:not([disabled]), input[type=\"radio\"]:not([disabled]), input[type=\"checkbox\"]:not([disabled]), select:not([disabled])');\r\n        var visibleElements = [].filter.call(elements, function (element) {\r\n            var style = window.getComputedStyle(element);\r\n            return style.display !== 'none' && style.visibility !== 'hidden';\r\n        });\r\n        return visibleElements;\r\n    },\r\n    /**\r\n     * @desc Create dynamic elements array from gallery items when dynamic option is false\r\n     * It helps to avoid frequent DOM interaction\r\n     * and avoid multiple checks for dynamic elments\r\n     *\r\n     * @returns {Array} dynamicEl\r\n     */\r\n    getDynamicOptions: function (items, extraProps, getCaptionFromTitleOrAlt, exThumbImage) {\r\n        var dynamicElements = [];\r\n        var availableDynamicOptions = __spreadArrays(defaultDynamicOptions, extraProps);\r\n        [].forEach.call(items, function (item) {\r\n            var dynamicEl = {};\r\n            for (var i = 0; i < item.attributes.length; i++) {\r\n                var attr = item.attributes[i];\r\n                if (attr.specified) {\r\n                    var dynamicAttr = convertToData(attr.name);\r\n                    var label = '';\r\n                    if (availableDynamicOptions.indexOf(dynamicAttr) > -1) {\r\n                        label = dynamicAttr;\r\n                    }\r\n                    if (label) {\r\n                        dynamicEl[label] = attr.value;\r\n                    }\r\n                }\r\n            }\r\n            var currentItem = $LG(item);\r\n            var alt = currentItem.find('img').first().attr('alt');\r\n            var title = currentItem.attr('title');\r\n            var thumb = exThumbImage\r\n                ? currentItem.attr(exThumbImage)\r\n                : currentItem.find('img').first().attr('src');\r\n            dynamicEl.thumb = thumb;\r\n            if (getCaptionFromTitleOrAlt && !dynamicEl.subHtml) {\r\n                dynamicEl.subHtml = title || alt || '';\r\n            }\r\n            dynamicEl.alt = alt || title || '';\r\n            dynamicElements.push(dynamicEl);\r\n        });\r\n        return dynamicElements;\r\n    },\r\n    isMobile: function () {\r\n        return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);\r\n    },\r\n    /**\r\n     * @desc Check the given src is video\r\n     * @param {String} src\r\n     * @return {Object} video type\r\n     * Ex:{ youtube  :  [\"//www.youtube.com/watch?v=c0asJgSyxcY\", \"c0asJgSyxcY\"] }\r\n     *\r\n     * @todo - this information can be moved to dynamicEl to avoid frequent calls\r\n     */\r\n    isVideo: function (src, isHTML5VIdeo, index) {\r\n        if (!src) {\r\n            if (isHTML5VIdeo) {\r\n                return {\r\n                    html5: true,\r\n                };\r\n            }\r\n            else {\r\n                console.error('lightGallery :- data-src is not provided on slide item ' +\r\n                    (index + 1) +\r\n                    '. Please make sure the selector property is properly configured. More info - https://www.lightgalleryjs.com/demos/html-markup/');\r\n                return;\r\n            }\r\n        }\r\n        var youtube = src.match(/\\/\\/(?:www\\.)?youtu(?:\\.be|be\\.com|be-nocookie\\.com)\\/(?:watch\\?v=|embed\\/)?([a-z0-9\\-\\_\\%]+)([\\&|?][\\S]
1*)*/i);\r\n        var vimeo = src.match(/\\/\\/(?:www\\.)?(?:player\\.)?vimeo.com\\/(?:video\\/)?([0-9a-z\\-_]+)(.*)?/i);\r\n        var wistia = src.match(/https?:\\/\\/(.+)?(wistia\\.com|wi\\.st)\\/(medias|embed)\\/([0-9a-z\\-_]+)(.*)/);\r\n        if (youtube) {\r\n            return {\r\n                youtube: youtube,\r\n            };\r\n        }\r\n        else if (vimeo) {\r\n            return {\r\n                vimeo: vimeo,\r\n            };\r\n        }\r\n        else if (wistia) {\r\n            return {\r\n                wistia: wistia,\r\n            };\r\n        }\r\n    },\r\n};\n\n// @ref - https://stackoverflow.com/questions/3971841/how-to-resize-images-proportionally-keeping-the-aspect-ratio\r\n// @ref - https://2ality.com/2017/04/setting-up-multi-platform-packages.html\r\n// Unique id for each gallery\r\nvar lgId = 0;\r\nvar LightGallery = /** @class */ (function () {\r\n    function LightGallery(element, options) {\r\n        this.lgOpened = false;\r\n        this.index = 0;\r\n        // lightGallery modules\r\n        this.plugins = [];\r\n        // false when lightGallery load first slide content;\r\n        this.lGalleryOn = false;\r\n        // True when a slide animation is in progress\r\n        this.lgBusy = false;\r\n        this.currentItemsInDom = [];\r\n        // Scroll top value before lightGallery is opened\r\n        this.prevScrollTop = 0;\r\n        this.bodyPaddingRight = 0;\r\n        this.isDummyImageRemoved = false;\r\n        this.dragOrSwipeEnabled = false;\r\n        this.mediaContainerPosition = {\r\n            top: 0,\r\n            bottom: 0,\r\n        };\r\n        if (!element) {\r\n            return this;\r\n        }\r\n        lgId++;\r\n        this.lgId = lgId;\r\n        this.el = element;\r\n        this.LGel = $LG(element);\r\n        this.generateSettings(options);\r\n        this.buildModules();\r\n        // When using dynamic mode, ensure dynamicEl is an array\r\n        if (this.settings.dynamic &&\r\n            this.settings.dynamicEl !== undefined &&\r\n            !Array.isArray(this.settings.dynamicEl)) {\r\n            throw 'When using dynamic mode, you must also define dynamicEl as an Array.';\r\n        }\r\n        this.galleryItems = this.getItems();\r\n        this.normalizeSettings();\r\n        // Gallery items\r\n        this.init();\r\n        this.validateLicense();\r\n        return this;\r\n    }\r\n    LightGallery.prototype.generateSettings = function (options) {\r\n        // lightGallery settings\r\n        this.settings = __assign(__assign({}, lightGalleryCoreSettings), options);\r\n        if (this.settings.isMobile &&\r\n            typeof this.settings.isMobile === 'function'\r\n            ? this.settings.isMobile()\r\n            : utils.isMobile()) {\r\n            var mobileSettings = __assign(__assign({}, this.settings.mobileSettings), this.settings.mobileSettings);\r\n            this.settings = __assign(__assign({}, this.settings), mobileSettings);\r\n        }\r\n    };\r\n    LightGallery.prototype.normalizeSettings = function () {\r\n        if (this.settings.slideEndAnimation) {\r\n            this.settings.hideControlOnEnd = false;\r\n        }\r\n        if (!this.settings.closable) {\r\n            this.settings.swipeToClose = false;\r\n        }\r\n        // And reset it on close to get the correct value next time\r\n        this.zoomFromOrigin = this.settings.zoomFromOrigin;\r\n        // At the moment, Zoom from image doesn't support dynamic options\r\n        // @todo add zoomFromOrigin support for dynamic images\r\n        if (this.settings.dynamic) {\r\n            this.zoomFromOrigin = false;\r\n        }\r\n        if (this.settings.container) {\r\n            var container = this.settings.container;\r\n            if (typeof container === 'function') {\r\n                this.settings.container = container();\r\n            }\r\n            else if (typeof container === 'string') {\r\n                var el = document.querySelector(container);\r\n                this.settings.container = el !== null && el !== void 0 ? el : document.body;\r\n            }\r\n        }\r\n        else {\r\n            this.settings.container = document.body;\r\n        }\r\n        // settings.preload should not be grater than $item.length\r\n        this.settings.preload = Math.min(this.settings.preload, this.galleryItems.length);\r\n    };\r\n    LightGallery.prototype.init = function () {\r\n        var _this = this;\r\n        this.addSlideVideoInfo(this.galleryItems);\r\n        this.buildStructure();\r\n        this.LGel.trigger(lGEvents.init, {\r\n            instance: this,\r\n        });\r\n        if (this.settings.keyPress) {\r\n            this.keyPress();\r\n        }\r\n        setTimeout(function () {\r\n            _this.enableDrag();\r\n            _this.enableSwipe();\r\n            _this.triggerPosterClick();\r\n        }, 50);\r\n        this.arrow();\r\n        if (this.settings.mousewheel) {\r\n            this.mousewheel();\r\n        }\r\n        if (!this.settings.dynamic) {\r\n            this.openGalleryOnItemClick();\r\n        }\r\n    };\r\n    LightGallery.prototype.openGalleryOnItemClick = function () {\r\n        var _this = this;\r\n        var _loop_1 = function (index) {\r\n            var element = this_1.items[index];\r\n            var $element = $LG(element);\r\n            // Using different namespace for click because click event should not unbind if selector is same object('this')\r\n            // @todo manage all event listners - should have namespace that represent element\r\n            var uuid = lgQuery.generateUUID();\r\n            $element\r\n                .attr('data-lg-id', uuid)\r\n                .on(\"click.lgcustom-item-\" + uuid, function (e) {\r\n                e.preventDefault();\r\n                var currentItemIndex = _this.settings.index || index;\r\n                _this.openGallery(currentItemIndex, element);\r\n            });\r\n        };\r\n        var this_1 = this;\r\n        // Using for loop instead of using bubbling as the items can be any html element.\r\n        for (var index = 0; index < this.items.length; index++) {\r\n            _loop_1(index);\r\n        }\r\n    };\r\n    /**\r\n     * Module constructor\r\n     * Modules are build incrementally.\r\n     * Gallery should be opened only once all the modules are initialized.\r\n     * use moduleBuildTimeout to make sure this\r\n     */\r\n    LightGallery.prototype.buildModules = function () {\r\n        var _this = this;\r\n        this.settings.plugins.forEach(function (plugin) {\r\n            _this.plugins.push(new plugin(_this, $LG));\r\n        });\r\n    };\r\n    LightGallery.prototype.validateLicense = function () {\r\n        if (!this.settings.licenseKey) {\r\n            console.error('Please provide a valid license key');\r\n        }\r\n        else if (this.settings.licenseKey === '0000-0000-000-0000') {\r\n            console.warn(\"lightGallery: \" + this.settings.licenseKey + \" license key is not val
1id for production use\");\r\n        }\r\n    };\r\n    LightGallery.prototype.getSlideItem = function (index) {\r\n        return $LG(this.getSlideItemId(index));\r\n    };\r\n    LightGallery.prototype.getSlideItemId = function (index) {\r\n        return \"#lg-item-\" + this.lgId + \"-\" + index;\r\n    };\r\n    LightGallery.prototype.getIdName = function (id) {\r\n        return id + \"-\" + this.lgId;\r\n    };\r\n    LightGallery.prototype.getElementById = function (id) {\r\n        return $LG(\"#\" + this.getIdName(id));\r\n    };\r\n    LightGallery.prototype.manageSingleSlideClassName = function () {\r\n        if (this.galleryItems.length < 2) {\r\n            this.outer.addClass('lg-single-item');\r\n        }\r\n        else {\r\n            this.outer.removeClass('lg-single-item');\r\n        }\r\n    };\r\n    LightGallery.prototype.buildStructure = function () {\r\n        var _this = this;\r\n        var container = this.$container && this.$container.get();\r\n        if (container) {\r\n            return;\r\n        }\r\n        var controls = '';\r\n        var subHtmlCont = '';\r\n        // Create controls\r\n        if (this.settings.controls) {\r\n            controls = \"<button type=\\\"button\\\" id=\\\"\" + this.getIdName('lg-prev') + \"\\\" aria-label=\\\"\" + this.settings.strings['previousSlide'] + \"\\\" class=\\\"lg-prev lg-icon\\\"> \" + this.settings.prevHtml + \" </button>\\n                <button type=\\\"button\\\" id=\\\"\" + this.getIdName('lg-next') + \"\\\" aria-label=\\\"\" + this.settings.strings['nextSlide'] + \"\\\" class=\\\"lg-next lg-icon\\\"> \" + this.settings.nextHtml + \" </button>\";\r\n        }\r\n        if (this.settings.appendSubHtmlTo !== '.lg-item') {\r\n            subHtmlCont =\r\n                '<div class=\"lg-sub-html\" role=\"status\" aria-live=\"polite\"></div>';\r\n        }\r\n        var addClasses = '';\r\n        if (this.settings.allowMediaOverlap) {\r\n            // Do not remove space before last single quote\r\n            addClasses += 'lg-media-overlap ';\r\n        }\r\n        var ariaLabelledby = this.settings.ariaLabelledby\r\n            ? 'aria-labelledby=\"' + this.settings.ariaLabelledby + '\"'\r\n            : '';\r\n        var ariaDescribedby = this.settings.ariaDescribedby\r\n            ? 'aria-describedby=\"' + this.settings.ariaDescribedby + '\"'\r\n            : '';\r\n        var containerClassName = \"lg-container \" + this.settings.addClass + \" \" + (document.body !== this.settings.container ? 'lg-inline' : '');\r\n        var closeIcon = this.settings.closable && this.settings.showCloseIcon\r\n            ? \"<button type=\\\"button\\\" aria-label=\\\"\" + this.settings.strings['closeGallery'] + \"\\\" id=\\\"\" + this.getIdName('lg-close') + \"\\\" class=\\\"lg-close lg-icon\\\"></button>\"\r\n            : '';\r\n        var maximizeIcon = this.settings.showMaximizeIcon\r\n            ? \"<button type=\\\"button\\\" aria-label=\\\"\" + this.settings.strings['toggleMaximize'] + \"\\\" id=\\\"\" + this.getIdName('lg-maximize') + \"\\\" class=\\\"lg-maximize lg-icon\\\"></button>\"\r\n            : '';\r\n        var template = \"\\n        <div class=\\\"\" + containerClassName + \"\\\" id=\\\"\" + this.getIdName('lg-container') + \"\\\" tabindex=\\\"-1\\\" aria-modal=\\\"true\\\" \" + ariaLabelledby + \" \" + ariaDescribedby + \" role=\\\"dialog\\\"\\n        >\\n            <div id=\\\"\" + this.getIdName('lg-backdrop') + \"\\\" class=\\\"lg-backdrop\\\"></div>\\n\\n            <div id=\\\"\" + this.getIdName('lg-outer') + \"\\\" class=\\\"lg-outer lg-use-css3 lg-css3 lg-hide-items \" + addClasses + \" \\\">\\n\\n              <div id=\\\"\" + this.getIdName('lg-content') + \"\\\" class=\\\"lg-content\\\">\\n                <div id=\\\"\" + this.getIdName('lg-inner') + \"\\\" class=\\\"lg-inner\\\">\\n                </div>\\n                \" + controls + \"\\n              </div>\\n                <div id=\\\"\" + this.getIdName('lg-toolbar') + \"\\\" class=\\\"lg-toolbar lg-group\\\">\\n                    \" + maximizeIcon + \"\\n                    \" + closeIcon + \"\\n                    </div>\\n                    \" + (this.settings.appendSubHtmlTo === '.lg-outer'\r\n            ? subHtmlCont\r\n            : '') + \"\\n                <div id=\\\"\" + this.getIdName('lg-components') + \"\\\" class=\\\"lg-components\\\">\\n                    \" + (this.settings.appendSubHtmlTo === '.lg-sub-html'\r\n            ? subHtmlCont\r\n            : '') + \"\\n                </div>\\n            </div>\\n        </div>\\n        \";\r\n        $LG(this.settings.container).append(template);\r\n        if (document.body !== this.settings.container) {\r\n            $LG(this.settings.container).css('position', 'relative');\r\n        }\r\n        this.outer = this.getElementById('lg-outer');\r\n        this.$lgComponents = this.getElementById('lg-components');\r\n        this.$backdrop = this.getElementById('lg-backdrop');\r\n        this.$container = this.getElementById('lg-container');\r\n        this.$inner = this.getElementById('lg-inner');\r\n        this.$content = this.getElementById('lg-content');\r\n        this.$toolbar = this.getElementById('lg-toolbar');\r\n        this.$backdrop.css('transition-duration', this.settings.backdropDuration + 'ms');\r\n        var outerClassNames = this.settings.mode + \" \";\r\n        this.manageSingleSlideClassName();\r\n        if (this.settings.enableDrag) {\r\n            outerClassNames += 'lg-grab ';\r\n        }\r\n        this.outer.addClass(outerClassNames);\r\n        this.$inner.css('transition-timing-function', this.settings.easing);\r\n        this.$inner.css('transition-duration', this.settings.speed + 'ms');\r\n        if (this.settings.download) {\r\n            this.$toolbar.append(\"<a id=\\\"\" + this.getIdName('lg-download') + \"\\\" target=\\\"_blank\\\" rel=\\\"noopener\\\" aria-label=\\\"\" + this.settings.strings['download'] + \"\\\" download class=\\\"lg-download lg-icon\\\"></a>\");\r\n        }\r\n        this.counter();\r\n        $LG(window).on(\"resize.lg.global\" + this.lgId + \" orientationchange.lg.global\" + this.lgId, function () {\r\n            _this.refreshOnResize();\r\n        });\r\n        this.hideBars();\r\n        this.manageCloseGallery();\r\n        this.toggleMaximize();\r\n        this.initModules();\r\n    };\r\n    LightGallery.prototype.refreshOnResize = function () {\r\n        if (this.lgOpened) {\r\n            var currentGalleryItem = this.galleryItems[this.index];\r\n            var __slideVideoInfo = currentGalleryItem.__slideVideoInfo;\r\n            this.mediaContainerPosition = this.getMediaContainerPosition();\r\n            var _a = this.mediaContainerPosition, top_1 = _a.top, bottom = _a.bottom;\r\n            this.currentImageSize = utils.getSize(this.items[this.index], this.outer, top_1 + bottom, __slideVideoInfo && this.settings.videoMaxSize);\r\n            if (__slideVideoInfo) {\r\n                this.resizeVideoSlide(this.index, this.currentImageSize);\r\n            }\r\n            if (this.zoomFromOrigin && !this.isDummyImageRemoved) {\r\n                var imgStyle = this.getDummyImgStyles(this.currentImageSize);\r\n                this.outer\r\n                    .find('.lg-current .lg-dummy-img')\r\n                    .first()\r\n                    .attr('style', imgStyle);\r\n            }\r\n            this.LGel.trigger(lGEvents.containerResize);\r\n        }\r\n    };\r\n    LightGallery.prototype.resizeVideoSlide = function (index, imageSize) {\r\n        var lgVideoStyle = this.getVideoContStyle(imageSize);
1\r\n        var currentSlide = this.getSlideItem(index);\r\n        currentSlide.find('.lg-video-cont').attr('style', lgVideoStyle);\r\n    };\r\n    /**\r\n     * Update slides dynamically.\r\n     * Add, edit or delete slides dynamically when lightGallery is opened.\r\n     * Modify the current gallery items and pass it via updateSlides method\r\n     * @note\r\n     * - Do not mutate existing lightGallery items directly.\r\n     * - Always pass new list of gallery items\r\n     * - You need to take care of thumbnails outside the gallery if any\r\n     * - user this method only if you want to update slides when the gallery is opened. Otherwise, use `refresh()` method.\r\n     * @param items Gallery items\r\n     * @param index After the update operation, which slide gallery should navigate to\r\n     * @category lGPublicMethods\r\n     * @example\r\n     * const plugin = lightGallery();\r\n     *\r\n     * // Adding slides dynamically\r\n     * let galleryItems = [\r\n     * // Access existing lightGallery items\r\n     * // galleryItems are automatically generated internally from the gallery HTML markup\r\n     * // or directly from galleryItems when dynamic gallery is used\r\n     *   ...plugin.galleryItems,\r\n     *     ...[\r\n     *       {\r\n     *         src: 'img/img-1.png',\r\n     *           thumb: 'img/thumb1.png',\r\n     *         },\r\n     *     ],\r\n     *   ];\r\n     *   plugin.updateSlides(\r\n     *     galleryItems,\r\n     *     plugin.index,\r\n     *   );\r\n     *\r\n     *\r\n     * // Remove slides dynamically\r\n     * galleryItems = JSON.parse(\r\n     *   JSON.stringify(updateSlideInstance.galleryItems),\r\n     * );\r\n     * galleryItems.shift();\r\n     * updateSlideInstance.updateSlides(galleryItems, 1);\r\n     * @see <a href=\"/demos/update-slides/\">Demo</a>\r\n     */\r\n    LightGallery.prototype.updateSlides = function (items, index) {\r\n        if (this.index > items.length - 1) {\r\n            this.index = items.length - 1;\r\n        }\r\n        if (items.length === 1) {\r\n            this.index = 0;\r\n        }\r\n        if (!items.length) {\r\n            this.closeGallery();\r\n            return;\r\n        }\r\n        var currentSrc = this.galleryItems[index].src;\r\n        this.galleryItems = items;\r\n        this.updateControls();\r\n        this.$inner.empty();\r\n        this.currentItemsInDom = [];\r\n        var _index = 0;\r\n        // Find the current index based on source value of the slide\r\n        this.galleryItems.some(function (galleryItem, itemIndex) {\r\n            if (galleryItem.src === currentSrc) {\r\n                _index = itemIndex;\r\n                return true;\r\n            }\r\n            return false;\r\n        });\r\n        this.currentItemsInDom = this.organizeSlideItems(_index, -1);\r\n        this.loadContent(_index, true);
1\r\n        this.getSlideItem(_index).addClass('lg-current');\r\n        this.index = _index;\r\n        this.updateCurrentCounter(_index);\r\n        this.LGel.trigger(lGEvents.updateSlides);\r\n    };\r\n    // Get gallery items based on multiple conditions\r\n    LightGallery.prototype.getItems = function () {\r\n        // Gallery items\r\n        this.items = [];\r\n        if (!this.settings.dynamic) {\r\n            if (this.settings.selector === 'this') {\r\n                this.items.push(this.el);\r\n            }\r\n            else if (this.settings.selector) {\r\n                if (typeof this.settings.selector === 'string') {\r\n                    if (this.settings.selectWithin) {\r\n                        var selectWithin = $LG(this.settings.selectWithin);\r\n                        this.items = selectWithin\r\n                            .find(this.settings.selector)\r\n                            .get();\r\n                    }\r\n                    else {\r\n                        this.items = this.el.querySelectorAll(this.settings.selector);\r\n                    }\r\n                }\r\n                else {\r\n                    this.items = this.settings.selector;\r\n                }\r\n            }\r\n            else {\r\n                this.items = this.el.children;\r\n            }\r\n            return utils.getDynamicOptions(this.items, this.settings.extraProps, this.settings.getCaptionFromTitleOrAlt, this.settings.exThumbImage);\r\n        }\r\n        else {\r\n            return this.settings.dynamicEl || [];\r\n        }\r\n    };\r\n    LightGallery.prototype.shouldHideScrollbar = function () {\r\n        return (this.settings.hideScrollbar &&\r\n            document.body === this.settings.container);\r\n    };\r\n    LightGallery.prototype.hideScrollbar = function () {\r\n        if (!this.shouldHideScrollbar()) {\r\n            return;\r\n        }\r\n        this.bodyPaddingRight = parseFloat($LG('body').style().paddingRight);\r\n        var bodyRect = document.documentElement.getBoundingClientRect();\r\n        var scrollbarWidth = window.innerWidth - bodyRect.width;\r\n        $LG(document.body).css('padding-right', scrollbarWidth + this.bodyPaddingRight + 'px');\r\n        $LG(document.body).addClass('lg-overlay-open');\r\n    };\r\n    LightGallery.prototype.resetScrollBar = function () {\r\n        if (!this.shouldHideScrollbar()) {\r\n            return;\r\n        }\r\n        $LG(document.body).css('padding-right', this.bodyPaddingRight + 'px');\r\n        $LG(document.body).removeClass('lg-overlay-open');\r\n    };\r\n    /**\r\n     * Open lightGallery.\r\n     * Open gallery with specific slide by passing index of the slide as parameter.\r\n     * @category lGPublicMethods\r\n     * @param {Number} index  - index of the slide\r\n     * @param {HTMLElement} element - Which image lightGallery should zoom from\r\n     *\r\n     * @example\r\n     * const $dynamicGallery = document.getElementById('dynamic-gallery-demo');\r\n     * const dynamicGallery = lightGallery($dynamicGallery, {\r\n     *     dynamic: true,\r\n     *     dynamicEl: [\r\n     *         {\r\n     *              src: 'img/1.jpg',\r\n     *              thumb: 'img/thumb-1.jpg',\r\n     *              subHtml: '<h4>Image 1 title</h4><p>Image 1 descriptions.</p>',\r\n     *         },\r\n     *         ...\r\n     *     ],\r\n     * });\r\n     * $dynamicGallery.addEventListener('click', function () {\r\n     *     // Starts with third item.(Optional).\r\n     *     // This is useful if you want use dynamic mode with\r\n     *     // custom thumbnails (thumbnails outside gallery),\r\n     *     dynamicGallery.openGallery(2);\r\n     * });\r\n     *\r\n     */\r\n    LightGallery.prototype.openGallery = function (index, element) {\r\n        var _this = this;\r\n        if (index === void 0) { index = this.settings.index; }\r\n        // prevent accidental double execution\r\n        if (this.lgOpened)\r\n            return;\r\n        this.lgOpened = true;\r\n        this.outer.removeClass('lg-hide-items');\r\n        this.hideScrollbar();\r\n        // Add display block, but still has opacity 0\r\n        this.$container.addClass('lg-show');\r\n        var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, index);\r\n        this.currentItemsInDom = itemsToBeInsertedToDom;\r\n        var items = '';\r\n        itemsToBeInsertedToDom.forEach(function (item) {\r\n            items = items + (\"<div id=\\\"\" + item + \"\\\" class=\\\"lg-item\\\"></div>\");\r\n        });\r\n        this.$inner.append(items);\r\n        this.addHtml(index);\r\n        var transform = '';\r\n        this.mediaContainerPosition = this.getMediaContainerPosition();\r\n        var _a = this.mediaContainerPosition, top = _a.top, bottom = _a.bottom;
1\r\n        if (!this.settings.allowMediaOverlap) {\r\n            this.setMediaContainerPosition(top, bottom);\r\n        }\r\n        var __slideVideoInfo = this.galleryItems[index].__slideVideoInfo;\r\n        if (this.zoomFromOrigin && element) {\r\n            this.currentImageSize = utils.getSize(element, this.outer, top + bottom, __slideVideoInfo && this.settings.videoMaxSize);\r\n            transform = utils.getTransform(element, this.outer, top, bottom, this.currentImageSize);\r\n        }\r\n        if (!this.zoomFromOrigin || !transform) {\r\n            this.outer.addClass(this.settings.startClass);\r\n            this.getSlideItem(index).removeClass('lg-complete');\r\n        }\r\n        var timeout = this.settings.zoomFromOrigin\r\n            ? 100\r\n            : this.settings.backdropDuration;\r\n        setTimeout(function () {\r\n            _this.outer.addClass('lg-components-open');\r\n        }, timeout);\r\n        this.index = index;\r\n        this.LGel.trigger(lGEvents.beforeOpen);\r\n        // add class lg-current to remove initial transition\r\n        this.get
1SlideItem(index).addClass('lg-current');\r\n        this.lGalleryOn = false;\r\n        // Store the current scroll top value to scroll back after closing the gallery..\r\n        this.prevScrollTop = $LG(window).scrollTop();\r\n        setTimeout(function () {\r\n            // Need to check both zoomFromOrigin and transform values as we need to set set the\r\n            // default opening animation if user missed to add the lg-size attribute\r\n            if (_this.zoomFromOrigin && transform) {\r\n                var currentSlide_1 = _this.getSlideItem(index);\r\n                currentSlide_1.css('transform', transform);\r\n                setTimeout(function () {\r\n                    currentSlide_1\r\n                        .addClass('lg-start-progress lg-start-end-progress')\r\n                        .css('transition-duration', _this.settings.startAnimationDuration + 'ms');\r\n                    _this.outer.addClass('lg-zoom-from-image');\r\n                });\r\n                setTimeout(function () {\r\n                    currentSlide_1.css('transform', 'translate3d(0, 0, 0)');\r\n                }, 100);\r\n            }\r\n            setTimeout(function () {\r\n                _this.$backdrop.addClass('in');\r\n                _this.$container.addClass('lg-show-in');\r\n            }, 10);\r\n            setTimeout(function () {\r\n                if (_this.settings.trapFocus &&\r\n                    document.body === _this.settings.container) {\r\n                    _this.trapFocus();\r\n                }\r\n            }, _this.settings.backdropDuration + 50);\r\n            // lg-visible class resets gallery opacity to 1\r\n            if (!_this.zoomFromOrigin || !transform) {\r\n                setTimeout(function () {\r\n                    _this.outer.addClass('lg-visible');\r\n                }, _this.settings.backdropDuration);\r\n            }\r\n            // initiate slide function\r\n            _this.slide(index, false, false, false);\r\n            _this.LGel.trigger(lGEvents.afterOpen);\r\n        });\r\n        if (document.body === this.settings.container) {\r\n            $LG('html').addClass('lg-on');\r\n        }\r\n    };\r\n    /**\r\n     * Note - Changing the position of the media on every slide transition creates a flickering effect.\r\n     * Therefore, The height of the caption is calculated dynamically, only once based on the first slide caption.\r\n     * if you have dynamic captions for each media,\r\n     * you can provide an appropriate height for the captions via allowMediaOverlap option\r\n     */\r\n    LightGallery.prototype.getMediaContainerPosition = function () {\r\n        if (this.settings.allowMediaOverlap) {\r\n            return {\r\n                top: 0,\r\n                bottom: 0,\r\n            };\r\n        }\r\n        var top = this.$toolbar.get().clientHeight || 0;\r\n        var subHtml = this.outer.find('.lg-components .lg-sub-html').get();\r\n        var captionHeight = this.settings.defaultCaptionHeight ||\r\n            (subHtml && subHtml.clientHeight) ||\r\n            0;\r\n        var thumbContainer = this.outer.find('.lg-thumb-outer').get();\r\n        var thumbHeight = thumbContainer ? thumbContainer.clientHeight : 0;\r\n        var bottom = thumbHeight + captionHeight;\r\n        return {\r\n            top: top,\r\n            bottom: bottom,\r\n        };\r\n    };\r\n    LightGallery.prototype.setMediaContainerPosition = function (top, bottom) {\r\n        if (top === void 0) { top = 0; }\r\n        if (bottom === void 0) { bottom = 0; }\r\n        this.$content.css('top', top + 'px').css('bottom', bottom + 'px');\r\n    };\r\n    LightGallery.prototype.hideBars = function () {\r\n        var _this = this;\r\n        // Hide controllers if mouse doesn't move for some period\r\n        setTimeout(function () {\r\n            _this.outer.removeClass('lg-hide-items');\r\n            if (_this.settings.hideBarsDelay > 0) {\r\n                _this.outer.on('mousemove.lg click.lg touchstart.lg', function () {\r\n                    _this.outer.removeClass('lg-hide-items');\r\n                    clearTimeout(_this.hideBarTimeout);\r\n                    // Timeout will be cleared on each slide movement also\r\n                    _this.hideBarTimeout = setTimeout(function () {\r\n                        _this.outer.addClass('lg-hide-items');\r\n                    }, _this.settings.hideBarsDelay);\r\n                });\r\n                _this.outer.trigger('mousemove.lg');\r\n            }\r\n        }, this.settings.showBarsAfter);\r\n    };\r\n    LightGallery.prototype.initPictureFill = function ($img) {\r\n        if (this.settings.supportLegacyBrowser) {\r\n            try {\r\n                picturefill({\r\n                    elements: [$img.get()],\r\n                });\r\n            }\r\n            catch (e) {\r\n                console.warn('lightGallery :- If you want srcset or picture tag to be supported for older browser please include picturefil javascript library in your document.');\r\n            }\r\n        }\r\n    };\r\n    /**\r\n     *  @desc Create image counter\r\n     *  Ex: 1/10\r\n     */\r\n    LightGallery.prototype.counter = function () {\r\n        if (this.settings.counter) {\r\n            var counterHtml = \"<div class=\\\"lg-counter\\\" role=\\\"status\\\" aria-live=\\\"polite\\\">
1\\n                <span id=\\\"\" + this.getIdName('lg-counter-current') + \"\\\" class=\\\"lg-counter-current\\\">\" + (this.index + 1) + \" </span> /\\n                <span id=\\\"\" + this.getIdName('lg-counter-all') + \"\\\" class=\\\"lg-counter-all\\\">\" + this.galleryItems.length + \" </span></div>\";\r\n            this.outer.find(this.settings.appendCounterTo).append(counterHtml);\r\n        }\r\n    };\r\n    /**\r\n     *  @desc add sub-html into the slide\r\n     *  @param {Number} index - index of the slide\r\n     */\r\n    LightGallery.prototype.addHtml = function (index) {\r\n        var subHtml;\r\n        var subHtmlUrl;\r\n        if (this.galleryItems[index].subHtmlUrl) {\r\n            subHtmlUrl = this.galleryItems[index].subHtmlUrl;\r\n        }\r\n        else {\r\n            subHtml = this.galleryItems[index].subHtml;\r\n        }\r\n        if (!subHtmlUrl) {\r\n            if (subHtml) {\r\n                // get first letter of sub-html\r\n                // if first letter starts with . or # get the html form the jQuery object\r\n                var fL = subHtml.substring(0, 1);\r\n                if (fL === '.' || fL === '#') {\r\n                    try {\r\n                        if (this.settings.subHtmlSelectorRelative &&\r\n                            !this.settings.dynamic) {\r\n                            subHtml = $LG(this.items)\r\n                                .eq(index)\r\n                                .find(subHtml)\r\n                                .first()\r\n                                .html();\r\n                        }\r\n                        else {\r\n                            subHtml = $LG(subHtml).first().html();\r\n                        }\r\n                    }\r\n                    catch (error) {\r\n                        console.warn(\"Error processing subHtml selector \\\"\" + subHtml + \"\\\"\");\r\n                        subHtml = '';\r\n                    }\r\n                }\r\n            }\r\n            else {\r\n                subHtml = '';\r\n            }\r\n        }\r\n        if (this.settings.appendSubHtmlTo !== '.lg-item') {\r\n            if (subHtmlUrl) {\r\n                utils.fetchCaptionFromUrl(subHtmlUrl, this.outer.find('.lg-sub-html'), 'replace');\r\n            }\r\n            else {\r\n                this.outer.find('.lg-sub-html').html(subHtml);\r\n            }\r\n        }\r\n        else {\r\n            var currentSlide = $LG(this.getSlideItemId(index));\r\n            if (subHtmlUrl) {\r\n                utils.fetchCaptionFromUrl(subHtmlUrl, currentSlide, 'append');\r\n            }\r\n            else {\r\n                currentSlide.append(\"<div class=\\\"lg-sub-html\\\">\" + subHtml + \"</div>\");\r\n            }\r\n        }\r\n        // Add lg-empty-html class if title doesn't exist\r\n        if (typeof subHtml !== 'undefined' && subHtml !== null) {\r\n            if (subHtml === '') {\r\n                this.outer\r\n                    .find(this.settings.appendSubHtmlTo)\r\n                    .addClass('lg-empty-html');\r\n            }\r\n            else {\r\n                this.outer\r\n                    .find(this.settings.appendSubHtmlTo)\r\n                    .removeClass('lg-empty-html');\r\n            }\r\n        }\r\n        this.LGel.trigger(lGEvents.afterAppendSubHtml, {\r\n            index: index,\r\n        });\r\n    };\r\n    /**\r\n     *  @desc Preload slides\r\n     *  @param {Number} index - index of the slide\r\n     * @todo preload not working for the first slide, Also, should work for the first and last slide as well\r\n     */\r\n    LightGallery.prototype.preload = function (index) {\r\n        for (var i = 1; i <= this.settings.preload; i++) {\r\n            if (i >= this.galleryItems.length - index) {\r\n                break;\r\n            }\r\n            this.loadContent(index + i, false);\r\n        }\r\n        for (var j = 1; j <= this.settings.preload; j++) {\r\n            if (index - j < 0) {\r\n                break;\r\n            }\r\n            this.loadContent(index - j, false);\r\n        }\r\n    };\r\n    LightGallery.prototype.getDummyImgStyles = function (imageSize) {\r\n        if (!imageSize)\r\n            return '';\r\n        return \"width:\" + imageSize.width + \"px;\\n                margin-left: -\" + imageSize.width / 2 + \"px;\\n                margin-top: -\" + imageSize.height / 2 + \"px;\\n                height:\" + imageSize.height + \"px\";\r\n    };\r\n    LightGallery.prototype.getVideoContStyle = function (imageSize) {\r\n        if (!imageSize)\r\n            return '';\r\n        return \"width:\" + imageSize.width + \"px;\\n                height:\" + imageSize.height + \"px\";\r\n    };\r\n    LightGallery.prototype.getDummyImageContent = function ($currentSlide, index, alt) {\r\n        var $currentItem;\r\n        if (!this.settings.dynamic) {\r\n            $currentItem = $LG(this.items).eq(index);\r\n        }\r\n        if ($currentItem) {\r\n            var _dummyImgSrc = void 0;\r\n            if (!this.settings.exThumbImage) {\r\n                _dummyImgSrc = $currentItem.find('img').first().attr('src');\r\n            }\r\n            else {\r\n                _dummyImgSrc = $currentItem.attr(this.settings.exThumbImage);\r\n            }\r\n            if (!_dummyImgSrc)\r\n                return '';\r\n            var imgStyle = this.getDummyImgStyles(this.currentImageSize);\r\n            var dummyImgContentImg = document.createElement('img');\r\n            dummyImgContentImg.alt = alt || '';\r\n            dummyImgContentImg.src = _dummyImgSrc;\r\n            dummyImgContentImg.className = \"lg-dummy-img\";\r\n            dummyImgContentImg.style.cssText = imgStyle;\r\n            $currentSlide.addClass('lg-first-slide');\r\n            this.outer.addClass('lg-first-slide-loading');\r\n            return dummyImgContentImg;\r\n        }\r\n        return '';\r\n    };\r\n    LightGallery.prototype.setImgMarkup = function (src, $currentSlide, index) {\r\n        var currentGalleryItem = this.galleryItems[index];\r\n        var alt = currentGalleryItem.alt, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;\r\n        // Use the thumbnail as dummy image which will be resized to actual image size and\r\n        // displayed on top of actual image\r\n        var imgContent = '';\r\n        var altAttr = alt ? 'alt=\"' + alt + '\"' : '';\r\n        if (this.isFirstSlideWithZoomAnimation()) {\r\n            imgContent = this.getDummyImageContent($currentSlide, index, altAttr);\r\n        }\r\n        else {\r\n            imgContent = utils.getImgMarkup(index, src, altAttr, srcset, sizes, sources);\r\n        }\r\n        var picture = document.createElement('picture');\r\n        picture.className = 'lg-img-wrap';\r\n        $LG(picture).append(imgContent);\r\n        $currentSlide.prepend(picture);\r\n    };\r\n    LightGallery.prototype.onSlideObjectLoad = function ($slide, isHTML5VideoWithoutPoster, onLoad, onError) {\r\n        var mediaObject = $
1slide.find('.lg-object').first();\r\n        if (utils.isImageLoaded(mediaObject.get()) ||\r\n            isHTML5VideoWithoutPoster) {\r\n            onLoad();\r\n        }\r\n        else {\r\n            mediaObject.on('load.lg error.lg', function () {\r\n                onLoad && onLoad();\r\n            });\r\n            mediaObject.on('error.lg', function () {\r\n                onError && onError();\r\n            });\r\n        }\r\n    };\r\n    /**\r\n     *\r\n     * @param $el Current slide item\r\n     * @param index\r\n     * @param delay Delay is 0 except first time\r\n     * @param speed Speed is same as delay, except it is 0 if gallery is opened via hash plugin\r\n     * @param isFirstSlide\r\n     */\r\n    LightGallery.prototype.onLgObjectLoad = function (currentSlide, index, delay, speed, isFirstSlide, isHTML5VideoWithoutPoster) {\r\n        var _this = this;\r\n        this.onSlideObjectLoad(currentSlide, isHTML5VideoWithoutPoster, function () {\r\n            _this.triggerSlideItemLoad(currentSlide, index, delay, speed, isFirstSlide);\r\n        }, function () {\r\n            currentSlide.addClass('lg-complete lg-complete_');\r\n            currentSlide.html('<span class=\"lg-error-msg\">' +\r\n                _this.settings.strings['mediaLoadingFailed'] +\r\n                '</span>');\r\n        });\r\n    };\r\n    LightGallery.prototype.triggerSlideItemLoad = function ($currentSlide, index, delay, speed, isFirstSlide) {\r\n        var _this = this;\r\n        var currentGalleryItem = this.galleryItems[index];\r\n        // Adding delay for video slides without poster for better performance and user experience\r\n        // Videos should start playing once once the gallery is completely loaded\r\n        var _speed = isFirstSlide &&\r\n            this.get
1SlideType(currentGalleryItem) === 'video' &&\r\n            !currentGalleryItem.poster\r\n            ? speed\r\n            : 0;\r\n        setTimeout(function () {\r\n            $currentSlide.addClass('lg-complete lg-complete_');\r\n            _this.LGel.trigger(lGEvents.slideItemLoad, {\r\n                index: index,\r\n                delay: delay || 0,\r\n                isFirstSlide: isFirstSlide,\r\n            });\r\n        }, _speed);\r\n    };\r\n    LightGallery.prototype.isFirstSlideWithZoomAnimation = function () {\r\n        return !!(!this.lGalleryOn &&\r\n            this.zoomFromOrigin &&\r\n            this.currentImageSize);\r\n    };\r\n    // Add video slideInfo\r\n    LightGallery.prototype.addSlideVideoInfo = function (items) {\r\n        var _this = this;\r\n        items.forEach(function (element, index) {\r\n            element.__slideVideoInfo = utils.isVideo(element.src, !!element.video, index);\r\n            if (element.__slideVideoInfo &&\r\n                _this.settings.loadYouTubePoster &&\r\n                !element.poster &&\r\n                element.__slideVideoInfo.youtube) {\r\n                element.poster = \"//img.youtube.com/vi/\" + element.__slideVideoInfo.youtube[1] + \"/maxresdefault.jpg\";\r\n            }\r\n        });\r\n    };\r\n    /**\r\n     *  Load slide content into slide.\r\n     *  This is used to load content into slides that is not visible too\r\n     *  @param {Number} index - index of the slide.\r\n     *  @param {Boolean} rec - if true call loadcontent() function again.\r\n     */\r\n    LightGallery.prototype.loadContent = function (index, rec) {\r\n        var _this = this;\r\n        var currentGalleryItem = this.galleryItems[index];\r\n        var $currentSlide = $LG(this.getSlideItemId(index));\r\n        var poster = currentGalleryItem.poster, srcset = currentGalleryItem.srcset, sizes = currentGalleryItem.sizes, sources = currentGalleryItem.sources;\r\n        var src = currentGalleryItem.src;\r\n        var video = currentGalleryItem.video;\r\n        var _html5Video = video && typeof video === 'string' ? JSON.parse(video) : video;\r\n        if (currentGalleryItem.responsive) {\r\n            var srcDyItms = currentGalleryItem.responsive.split(',');\r\n            src = utils.getResponsiveSrc(srcDyItms) || src;\r\n        }\r\n        var videoInfo = currentGalleryItem.__slideVideoInfo;\r\n        var lgVideoStyle = '';\r\n        var iframe = !!currentGalleryItem.iframe;\r\n        var isFirstSlide = !this.lGalleryOn;\r\n        // delay for adding complete class. it is 0 except first time.\r\n        var delay = 0;\r\n        if (isFirstSlide) {\r\n            if (this.zoomFromOrigin && this.currentImageSize) {\r\n                delay = this.settings.startAnimationDuration + 10;\r\n            }\r\n            else {\r\n                delay = this.settings.backdropDuration + 10;\r\n            }\r\n        }\r\n        if (!$currentSlide.hasClass('lg-loaded')) {\r\n            if (videoInfo) {\r\n                var _a = this.mediaContainerPosition, top_2 = _a.top, bottom = _a.bottom;\r\n                var videoSize = utils.getSize(this.items[index], this.outer, top_2 + bottom, videoInfo && this.settings.videoMaxSize);\r\n                lgVideoStyle = this.getVideoContStyle(videoSize);\r\n            }\r\n            if (iframe) {\r\n                var markup = utils.getIframeMarkup(this.settings.iframeWidth, this.settings.iframeHeight, this.settings.iframeMaxWidth, this.settings.iframeMaxHeight, src, currentGalleryItem.iframeTitle);\r\n                $currentSlide.prepend(markup);\r\n            }\r\n            else if (poster) {\r\n                var dummyImg = '';\r\n                var hasStartAnimation = isFirstSlide &&\r\n                    this.zoomFromOrigin &&\r\n                    this.currentImageSize;\r\n                if (hasStartAnimation) {\r\n                    dummyImg = this.getDummyImageContent($currentSlide, index, '');\r\n                }\r\n                var markup = utils.getVideoPosterMarkup(poster, dummyImg || '', lgVideoStyle, this.settings.strings['playVideo'], videoInfo);\r\n                $currentSlide.prepend(markup);\r\n            }\r\n            else if (videoInfo) {\r\n                var markup = \"<div class=\\\"lg-video-cont \\\" style=\\\"\" + lgVideoStyle + \"\\\"></div>\";\r\n                $currentSlide.prepend(markup);\r\n            }\r\n            else {\r\n                this.setImgMarkup(src, $currentSlide, index);\r\n                if (srcset || sources) {\r\n                    var $img = $currentSlide.find('.lg-object');\r\n                    this.initPictureFill($img);\r\n                }\r\n            }\r\n            if (poster || videoInfo) {\r\n                this.LGel.trigger(lGEvents.hasVideo, {\r\n                    index: index,\r\n                    src: src,\r\n                    html5Video: _html5Video,\r\n                    hasPoster: !!poster,\r\n                });\r\n            }\r\n            this.LGel.trigger(lGEvents.afterAppendSlide, { index: index });\r\n            if (this.lGalleryOn &&\r\n                this.settings.appendSubHtmlTo === '.lg-item') {\r\n                this.addHtml(index);\r\n            }\r\n        }\r\n        // For first time add some delay for displaying the start animation.\r\n        var _speed = 0;
1\r\n        // Do not change the delay value because it is required for zoom plugin.\r\n        // If gallery opened from direct url (hash) speed value should be 0\r\n        if (delay && !$LG(document.body).hasClass('lg-from-hash')) {\r\n            _speed = delay;\r\n        }\r\n        // Only for first slide and zoomFromOrigin is enabled\r\n        if (this.isFirstSlideWithZoomAnimation()) {\r\n            setTimeout(function () {\r\n                $currentSlide\r\n                    .removeClass('lg-start-end-progress lg-start-progress')\r\n                    .removeAttr('style');\r\n            }, this.settings.startAnimationDuration + 100);\r\n            if (!$currentSlide.hasClass('lg-loaded')) {\r\n                setTimeout(function () {\r\n                    if (_this.getSlideType(currentGalleryItem) === 'image') {\r\n                        var alt = currentGalleryItem.alt;\r\n                        var altAttr = alt ? 'alt=\"' + alt + '\"' : '';\r\n                        $currentSlide\r\n                            .find('.lg-img-wrap')\r\n                            .append(utils.getImgMarkup(index, src, altAttr, srcset, sizes, currentGalleryItem.sources));\r\n                        if (srcset || sources) {\r\n                            var $img = $currentSlide.find('.lg-object');\r\n                            _this.initPictureFill($img);\r\n                        }\r\n                    }\r\n                    if (_this.getSlideType(currentGalleryItem) === 'image' ||\r\n                        (_this.getSlideType(currentGalleryItem) === 'video' &&\r\n                            poster)) {\r\n                        _this.onLgObjectLoad($currentSlide, index, delay, _speed, true, false);\r\n                        // load remaining slides once the slide is completely loaded\r\n                        _this.onSlideObjectLoad($currentSlide, !!(videoInfo && videoInfo.html5 && !poster), function () {\r\n                            _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);\r\n                        }, function () {\r\n                            _this.loadContentOnFirstSlideLoad(index, $currentSlide, _speed);\r\n                        });\r\n                    }\r\n                }, this.settings.startAnimationDuration + 100);\r\n            }\r\n        }\r\n        // SLide content has been added to dom\r\n        $currentSlide.addClass('lg-loaded');\r\n        if (!this.isFirstSlideWithZoomAnimation() ||\r\n            (this.getSlideType(currentGalleryItem) === 'video' && !poster)) {\r\n            this.onLgObjectLoad($currentSlide, index, delay, _speed, isFirstSlide, !!(videoInfo && videoInfo.html5 && !poster));\r\n        }\r\n        // When gallery is opened once content is loaded (second time) need to add lg-complete class for css styling\r\n        if ((!this.zoomFromOrigin || !this.currentImageSize) &&\r\n            $currentSlide.hasClass('lg-complete_') &&\r\n            !this.lGalleryOn) {\r\n            setTimeout(function () {\r\n                $currentSlide.addClass('lg-complete');\r\n            }, this.settings.backdropDuration);\r\n        }\r\n        // Content loaded\r\n        // Need to set lGalleryOn before calling preload function\r\n        this.lGalleryOn = true;\r\n        if (rec === true) {\r\n            if (!$currentSlide.hasClass('lg-complete_')) {\r\n                $currentSlide\r\n                    .find('.lg-object')\r\n                    .first()\r\n                    .on('load.lg error.lg', function () {\r\n                    _this.preload(index);\r\n                });\r\n            }\r\n            else {\r\n                this.preload(index);\r\n            }\r\n        }\r\n    };\r\n    /**\r\n     * @desc Remove dummy image content and load next slides\r\n     * Called only for the first time if zoomFromOrigin animation is enabled\r\n     * @param index\r\n     * @param $currentSlide\r\n     * @param speed\r\n     */\r\n    LightGallery.prototype.loadContentOnFirstSlideLoad = function (index, $currentSlide, speed) {\r\n        var _this = this;\r\n        setTimeout(function () {\r\n            $currentSlide.find('.lg-dummy-img').remove();\r\n            $currentSlide.removeClass('lg-first-slide');\r\n            _this.outer.removeClass('lg-first-slide-loading');\r\n            _this.isDummyImageRemoved = true;\r\n            _this.preload(index);\r\n        }, speed + 300);\r\n    };\r\n    LightGallery.prototype.getItemsToBeInsertedToDom = function (index, prevIndex, numberOfItems) {\r\n        var _this = this;\r\n        if (numberOfItems === void 0) { numberOfItems = 0; }\r\n        var itemsToBeInsertedToDom = [];\r\n        // Minimum 2 items should be there\r\n        var possibleNumberOfItems = Math.max(numberOfItems, 3);\r\n        possibleNumberOfItems = Math.min(possibleNumberOfItems, this.galleryItems.length);\r\n        var prevIndexItem = \"lg-item-\" + this.lgId + \"-\" + prevIndex;\r\n        if (this.galleryItems.length <= 3) {\r\n            this.galleryItems.forEac
1h(function (_element, index) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + _this.lgId + \"-\" + index);\r\n            });\r\n            return itemsToBeInsertedToDom;\r\n        }\r\n        if (index < (this.galleryItems.length - 1) / 2) {\r\n            for (var idx = index; idx > index - possibleNumberOfItems / 2 && idx >= 0; idx--) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + idx);\r\n            }\r\n            var numberOfExistingItems = itemsToBeInsertedToDom.length;\r\n            for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (index + idx + 1));\r\n            }\r\n        }\r\n        else {\r\n            for (var idx = index; idx <= this.galleryItems.length - 1 &&\r\n                idx < index + possibleNumberOfItems / 2; idx++) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + idx);\r\n            }\r\n            var numberOfExistingItems = itemsToBeInsertedToDom.length;\r\n            for (var idx = 0; idx < possibleNumberOfItems - numberOfExistingItems; idx++) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (index - idx - 1));\r\n            }\r\n        }\r\n        if (this.settings.loop) {\r\n            if (index === this.galleryItems.length - 1) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + 0);\r\n            }\r\n            else if (index === 0) {\r\n                itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + (this.galleryItems.length - 1));\r\n            }\r\n        }\r\n        if (itemsToBeInsertedToDom.indexOf(prevIndexItem) === -1) {\r\n            itemsToBeInsertedToDom.push(\"lg-item-\" + this.lgId + \"-\" + prevIndex);\r\n        }\r\n        return itemsToBeInsertedToDom;\r\n    };\r\n    LightGallery.prototype.organizeSlideItems = function (index, prevIndex) {\r\n        var _this = this;\r\n        var itemsToBeInsertedToDom = this.getItemsToBeInsertedToDom(index, prevIndex, this.settings.numberOfSlideItemsInDom);\r\n        itemsToBeInsertedToDom.forEach(function (item) {\r\n            if (_this.currentItemsInDom.indexOf(item) === -1) {\r\n                _this.$inner.append(\"<div id=\\\"\" + item + \"\\\" class=\\\"lg-item\\\"></div>\");\r\n            }\r\n        });\r\n        this.currentItemsInDom.forEach(function (item) {\r\n            if (itemsToBeInsertedToDom.indexOf(item) === -1) {\r\n                $LG(\"#\" + item).remove();\r\n            }\r\n        });\r\n        return itemsToBeInsertedToDom;\r\n    };\r\n    /**\r\n     * Get previous index of the slide\r\n     */\r\n    LightGallery.prototype.getPreviousSlideIndex = function () {\r\n        var prevIndex = 0;\r\n        try {\r\n            var currentItemId = this.outer\r\n                .find('.lg-current')\r\n                .first()\r\n                .attr('id');\r\n            prevIndex = parseInt(currentItemId.split('-')[3]) || 0;\r\n        }\r\n        catch (error) {\r\n            prevIndex = 0;\r\n        }\r\n        return prevIndex;\r\n    };\r\n    LightGallery.prototype.setDownloadValue = function (index) {\r\n        if (this.settings.download) {\r\n            var currentGalleryItem = this.galleryItems[index];\r\n            var hideDownloadBtn = currentGalleryItem.downloadUrl === false ||\r\n                currentGalleryItem.downloadUrl === 'false';\r\n            if (hideDownloadBtn) {\r\n                this.outer.addClass('lg-hide-download');\r\n            }\r\n            else {\r\n                var $download = this.getElementById('lg-download');\r\n                this.outer.removeClass('lg-hide-download');\r\n                $download.attr('href', currentGalleryItem.downloadUrl ||\r\n                    currentGalleryItem.src);\r\n                if (currentGalleryItem.download) {\r\n                    $download.attr('download', currentGalleryItem.download);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    LightGallery.prototype.makeSlideAnimation = function (direction, currentSlideItem, previousSlideItem) {\r\n        var _this = this;\r\n        if (this.lGalleryOn) {\r\n            previousSlideItem.addClass('lg-slide-progress');\r\n        }\r\n        setTimeout(function () {\r\n            // remove all transitions\r\n            _this.outer.addClass('lg-no-trans');\r\n            _this.outer\r\n                .find('.lg-item')\r\n                .removeClass('lg-prev-slide lg-next-slide');\r\n            if (direction === 'prev') {\r\n                //prevslide\r\n                currentSlideItem.addClass('lg-prev-slide');\r\n                previousSlideItem.addClass('lg-next-slide');\r\n            }\r\n            else {\r\n                // next slide\r\n                currentSlideItem.addClass('lg-next-slide');\r\n                previousSlideItem.addClass('lg-prev-slide');\r\n            }\r\n            // give 50 ms for browser to add/remove class\r\n            setTimeout(function () {\r\n                _this.outer.find('.lg-item').removeClass('lg-current');\r\n                currentSlideItem.addClass('lg-current');\r\n                // reset all transitions\r\n                _this.outer.removeClass('lg-no-trans');\r\n            }, 50);\r\n        }, this.lGalleryOn ? this.settings.slideDelay : 0);\r\n    };\r\n    /**\r\n     * Goto a specific slide.\r\n     * @param {Number} index - index of the slide\r\n     * @param {Boolean} fromTouch - true if slide function called via touch event or mouse drag\r\n     * @param {Boolean} fromThumb - true if slide function called via thumbnail click\r\n     * @param {String} direction - Direction of the slide(next/prev)\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery();\r\n     *  // to go to 3rd slide\r\n     *  plugin.slide(2);\r\n     *\r\n     */\r\n    LightGallery.prototype.slide = function (index, fromTouch, fromThumb, direction) {\r\n        var _this = this;\r\n        var prevIndex = this.getPreviousSlideIndex();\r\n        this.currentItemsInDom = this.organizeSlideItems(index, prevIndex);\r\n        // Prevent multiple call, Required for hsh plugin\r\n        if (this.lGalleryOn && prevIndex === index) {\r\n            return;\r\n        }\r\n        var numberOfGalleryItems = this.galleryItems.length;\r\n        if (!this.lgBusy) {\r\n            if (this.settings.counter) {\r\n                this.updateCurrentCounter(index);\r\n            }
1\r\n            var currentSlideItem = this.getSlideItem(index);\r\n            var previousSlideItem_1 = this.getSlideItem(prevIndex);\r\n            var currentGalleryItem = this.galleryItems[index];\r\n            var videoInfo = currentGalleryItem.__slideVideoInfo;\r\n            this.outer.attr('data-lg-slide-type', this.getSlideType(currentGalleryItem));\r\n            this.setDownloadValue(index);\r\n            if (videoInfo) {\r\n                var _a = this.mediaContainerPosition, top_3 = _a.top, bottom = _a.bottom;\r\n                var videoSize = utils.getSize(this.items[index], this.outer, top_3 + bottom, videoInfo && this.settings.videoMaxSize);\r\n                this.resizeVideoSlide(index, videoSize);\r\n            }\r\n            this.LGel.trigger(lGEvents.beforeSlide, {\r\n                prevIndex: prevIndex,\r\n                index: index,\r\n                fromTouch: !!fromTouch,\r\n                fromThumb: !!fromThumb,\r\n            });\r\n            this.lgBusy = true;\r\n            clearTimeout(this.hideBarTimeout);\r\n            this.arrowDisable(index);\r\n            if (!direction) {\r\n                if (index < prevIndex) {\r\n                    direction = 'prev';\r\n                }\r\n                else if (index > prevIndex) {\r\n                    direction = 'next';\r\n                }\r\n            }\r\n            if (!fromTouch) {\r\n                this.makeSlideAnimation(direction, currentSlideItem, previousSlideItem_1);\r\n            }\r\n            else {\r\n                this.outer\r\n                    .find('.lg-item')\r\n                    .removeClass('lg-prev-slide lg-current lg-next-slide');\r\n                var touchPrev = void 0;\r\n                var touchNext = void 0;\r\n                if (numberOfGalleryItems > 2) {\r\n                    touchPrev = index - 1;\r\n                    touchNext = index + 1;\r\n                    if (index === 0 && prevIndex === numberOfGalleryItems - 1) {\r\n                        // next slide\r\n                        touchNext = 0;\r\n                        touchPrev = numberOfGalleryItems - 1;\r\n                    }\r\n                    else if (index === numberOfGalleryItems - 1 &&\r\n                        prevIndex === 0) {\r\n                        // prev slide\r\n                        touchNext = 0;\r\n                        touchPrev = numberOfGalleryItems - 1;\r\n                    }\r\n                }\r\n                else {\r\n                    touchPrev = 0;\r\n                    touchNext = 1;\r\n                }\r\n                if (direction === 'prev') {\r\n                    this.get
1SlideItem(touchNext).addClass('lg-next-slide');\r\n                }\r\n                else {\r\n                    this.getSlideItem(touchPrev).addClass('lg-prev-slide');\r\n                }\r\n                currentSlideItem.addClass('lg-current');\r\n            }\r\n            // Do not put load content in set timeout as it needs to load immediately when the gallery is opened\r\n            if (!this.lGalleryOn) {\r\n                this.loadContent(index, true);\r\n            }\r\n            else {\r\n                setTimeout(function () {\r\n                    _this.loadContent(index, true);\r\n                    // Add title if this.settings.appendSubHtmlTo === lg-sub-html\r\n                    if (_this.settings.appendSubHtmlTo !== '.lg-item') {\r\n                        _this.addHtml(index);\r\n                    }\r\n                }, this.settings.speed + 50 + (fromTouch ? 0 : this.settings.slideDelay));\r\n            }\r\n            setTimeout(function () {\r\n                _this.lgBusy = false;\r\n                previousSlideItem_1.removeClass('lg-slide-progress');\r\n                _this.LGel.trigger(lGEvents.afterSlide, {\r\n                    prevIndex: prevIndex,\r\n                    index: index,\r\n                    fromTouch: fromTouch,\r\n                    fromThumb: fromThumb,\r\n                });\r\n            }, (this.lGalleryOn ? this.settings.speed + 100 : 100) + (fromTouch ? 0 : this.settings.slideDelay));\r\n        }\r\n        this.index = index;\r\n    };\r\n    LightGallery.prototype.updateCurrentCounter = function (index) {\r\n        this.getElementById('lg-counter-current').html(index + 1 + '');\r\n    };\r\n    LightGallery.prototype.updateCounterTotal = function () {\r\n        this.getElementById('lg-counter-all').html(this.galleryItems.length + '');\r\n    };\r\n    LightGallery.prototype.getSlideType = function (item) {\r\n        if (item.__slideVideoInfo) {\r\n            return 'video';\r\n        }\r\n        else if (item.iframe) {\r\n            return 'iframe';\r\n        }\r\n        else {\r\n            return 'image';\r\n        }\r\n    };\r\n    LightGallery.prototype.touchMove = function (startCoords, endCoords, e) {\r\n        var distanceX = endCoords.pageX 
1- startCoords.pageX;\r\n        var distanceY = endCoords.pageY - startCoords.pageY;\r\n        var allowSwipe = false;\r\n        if (this.swipeDirection) {\r\n            allowSwipe = true;\r\n        }\r\n        else {\r\n            if (Math.abs(distanceX) > 15) {\r\n                this.swipeDirection = 'horizontal';\r\n                allowSwipe = true;\r\n            }\r\n            else if (Math.abs(distanceY) > 15) {\r\n                this.swipeDirection = 'vertical';\r\n                allowSwipe = true;\r\n            }\r\n        }\r\n        if (!allowSwipe) {\r\n            return;\r\n        }\r\n        var $currentSlide = this.getSlideItem(this.index);\r\n        if (this.swipeDirection === 'horizontal') {\r\n            e === null || e === void 0 ? void 0 : e.preventDefault();\r\n            // reset opacity and transition duration\r\n            this.outer.addClass('lg-dragging');\r\n            // move current slide\r\n            this.setTranslate($currentSlide, distanceX, 0);\r\n            // move next and prev slide with current slide\r\n            var width = $currentSlide.get().offsetWidth;\r\n            var slideWidthAmount = (width * 15) / 100;\r\n            var gutter = slideWidthAmount - Math.abs((distanceX * 10) / 100);\r\n            this.setTranslate(this.outer.find('.lg-prev-slide').first(), -width + distanceX - gutter, 0);\r\n            this.setTranslate(this.outer.find('.lg-next-slide').first(), width + distanceX + gutter, 0);\r\n        }\r\n        else if (this.swipeDirection === 'vertical') {\r\n            if (this.settings.swipeToClose) {\r\n                e === null || e === void 0 ? void 0 : e.preventDefault();\r\n                this.$container.addClass('lg-dragging-vertical');\r\n                var opacity = 1 - Math.abs(distanceY) / window.innerHeight;\r\n                this.$backdrop.css('opacity', opacity);\r\n                var scale = 1 - Math.abs(distanceY) / (window.innerWidth * 2);\r\n                this.setTranslate($currentSlide, 0, distanceY, scale, scale);\r\n                if (Math.abs(distanceY) > 100) {\r\n                    this.outer\r\n                        .addClass('lg-hide-items')\r\n                        .removeClass('lg-components-open');\r\n                }\r\n            }\r\n        }\r\n    };\r\n    LightGallery.prototype.touchEnd = function (endCoords, startCoords, event) {\r\n        var _this = this;\r\n        var distance;\r\n        // keep slide animation for any mode while dragg/swipe\r\n        if (this.settings.mode !== 'lg-slide') {\r\n            this.outer.addClass('lg-slide');\r\n        }\r\n        // set transition duration\r\n        setTimeout(function () {\r\n            _this.$container.removeClass('lg-dragging-vertical');\r\n            _this.outer\r\n                .removeClass('lg-dragging lg-hide-items')\r\n                .addClass('lg-components-open');\r\n            var triggerClick = true;\r\n            if (_this.swipeDirection === 'horizontal') {\r\n                distance = endCoords.pageX 
1- startCoords.pageX;\r\n                var distanceAbs = Math.abs(endCoords.pageX - startCoords.pageX);\r\n                if (distance < 0 &&\r\n                    distanceAbs > _this.settings.swipeThreshold) {\r\n                    _this.goToNextSlide(true);\r\n                    triggerClick = false;\r\n                }\r\n                else if (distance > 0 &&\r\n                    distanceAbs > _this.settings.swipeThreshold) {\r\n                    _this.goToPrevSlide(true);\r\n                    triggerClick = false;\r\n                }\r\n            }\r\n            else if (_this.swipeDirection === 'vertical') {\r\n                distance = Math.abs(endCoords.pageY - startCoords.pageY);\r\n                if (_this.settings.closable &&\r\n                    _this.settings.swipeToClose &&\r\n                    distance > 100) {\r\n                    _this.closeGallery();\r\n                    return;\r\n                }\r\n                else {\r\n                    _this.$backdrop.css('opacity', 1);\r\n                }\r\n            }\r\n            _this.outer.find('.lg-item').removeAttr('style');\r\n            if (triggerClick &&\r\n                Math.abs(endCoords.pageX 
1- startCoords.pageX) < 5) {\r\n                // Trigger click if distance is less than 5 pix\r\n                var target = $LG(event.target);\r\n                if (_this.isPosterElement(target)) {\r\n                    _this.LGel.trigger(lGEvents.posterClick);\r\n                }\r\n            }\r\n            _this.swipeDirection = undefined;\r\n        });\r\n        // remove slide class once drag/swipe is completed if mode is not slide\r\n        setTimeout(function () {\r\n            if (!_this.outer.hasClass('lg-dragging') &&\r\n                _this.settings.mode !== 'lg-slide') {\r\n                _this.outer.removeClass('lg-slide');\r\n            }\r\n        }, this.settings.speed + 100);\r\n    };\r\n    LightGallery.prototype.enableSwipe = function () {\r\n        var _this = this;\r\n        var startCoords = {};\r\n        var endCoords = {};\r\n        var isMoved = false;\r\n        var isSwiping = false;\r\n        if (this.settings.enableSwipe) {\r\n            this.$inner.on('touchstart.lg', function (e) {\r\n                _this.dragOrSwipeEnabled = true;\r\n                var $item = _this.getSlideItem(_this.index);\r\n                if (($LG(e.target).hasClass('lg-item') ||\r\n                    $item.get().contains(e.target)) &&\r\n                    !_this.outer.hasClass('lg-zoomed') &&\r\n                    !_this.lgBusy &&\r\n                    e.touches.length === 1) {\r\n                    isSwiping = true;\r\n                    _this.touchAction = 'swipe';\r\n                    _this.manageSwipeClass();\r\n                    startCoords = {\r\n                        pageX: e.touches[0].pageX,\r\n                        pageY: e.touches[0].pageY,\r\n                    };\r\n                }\r\n            });\r\n            this.$inner.on('touchmove.lg', function (e) {\r\n                if (isSwiping &&\r\n                    _this.touchAction === 'swipe' &&\r\n                    e.touches.length === 1) {\r\n                    endCoords = {\r\n                        pageX: e.touches[0].pageX,\r\n                        pageY: e.touches[0].pageY,\r\n                    };\r\n                    _this.touchMove(startCoords, endCoords, e);\r\n                    isMoved = true;\r\n                }\r\n            });\r\n            this.$inner.on('touchend.lg', function (event) {\r\n                if (_this.touchAction === 'swipe') {\r\n                    if (isMoved) {\r\n                        isMoved = false;\r\n                        _this.touchEnd(endCoords, startCoords, event);\r\n                    }\r\n                    else if (isSwiping) {\r\n                        var target = $LG(event.target);\r\n                        if (_this.isPosterElement(target)) {\r\n                            _this.LGel.trigger(lGEvents.posterClick);\r\n                        }\r\n                    }\r\n                    _this.touchAction = undefined;\r\n                    isSwiping = false;\r\n                }\r\n            });\r\n        }\r\n    };\r\n    LightGallery.prototype.enableDrag = function () {\r\n        var _this = this;\r\n        var startCoords = {};\r\n        var endCoords = {};\r\n        var isDraging = false;\r\n        var isMoved = false;\r\n        if (this.settings.enableDrag) {\r\n            this.outer.on('mousedown.lg', function (e) {\r\n                _this.dragOrSwipeEnabled = true;\r\n                var $item = _this.getSlideItem(_this.index);\r\n                if ($LG(e.target).hasClass('lg-item') ||\r\n                    $item.get().contains(e.target)) {\r\n                    if (!_this.outer.hasClass('lg-zoomed') && !_this.lgBusy) {\r\n                        e.preventDefault();\r\n                        if (!_this.lgBusy) {\r\n                            _this.manageSwipeClass();\r\n                            startCoords = {\r\n                                pageX: e.pageX,\r\n                                pageY: e.pageY,\r\n                            };\r\n                            isDraging = true;\r\n                            // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723\r\n                            _this.outer.get().scrollLeft += 1;\r\n                            _this.outer.get().scrollLeft -= 1;\r\n                            // *\r\n                            _this.outer\r\n                                .removeClass('lg-grab')\r\n                                .addClass('lg-grabbing');\r\n                            _this.LGel.trigger(lGEvents.dragStart);\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n            $LG(window).on(\"mousemove.lg.global\" + this.lgId, function (e) {\r\n                if (isDraging && _this.lgOpened) {\r\n                    isMoved = true;\r\n                    endCoords = {\r\n                        pageX: e.pageX,\r\n                        pageY: e.pageY,\r\n                    };\r\n                    _this.touchMove(startCoords, endCoords);\r\n                    _this.LGel.trigger(lGEvents.dragMove);\r\n                }\r\n            });\r\n            $LG(window).on(\"mouseup.lg.global\" + this.lgId, function (event) {\r\n                if (!_this.lgOpened) {\r\n                    return;\r\n                }\r\n                var target = $LG(event.target);\r\n                if (isMoved) {\r\n                    isMoved = false;\r\n                    _this.touchEnd(endCoords, startCoords, event);\r\n                    _this.LGel.trigger(lGEvents.dragEnd);\r\n                }\r\n                else if (_this.isPosterElement(target)) {\r\n                    _this.LGel.trigger(lGEvents.posterClick);\r\n                }\r\n                // Prevent execution on click\r\n                if (isDraging) {\r\n                    isDraging = false;\r\n                    _this.outer.removeClass('lg-grabbing').addClass('lg-grab');\r\n                }\r\n            });\r\n        }\r\n    };\r\n    LightGallery.prototype.triggerPosterClick = function () {\r\n        var _this = this;\r\n        this.$inner.on('click.lg', function (event) {\r\n            if (!_this.dragOrSwipeEnabled &&\r\n                _this.isPosterElement($LG(event.target))) {\r\n                _this.LGel.trigger(lGEvents.posterClick);\r\n            }\r\n        });\r\n    };\r\n    LightGallery.prototype.manageSwipeClass = function () {\r\n        var _touchNext = this.index + 1;\r\n        var _touchPrev = this.index - 1;\r\n        if (this.settings.loop && this.galleryItems.length > 2) {\r\n            if (this.index === 0) {\r\n                _touchPrev = this.galleryItems.length - 1;\r\n            }\r\n            else if (this.index === this.galleryItems.length - 1) {\r\n                _touchNext = 0;\r\n            }\r\n        }\r\n        this.outer.find('.lg-item').removeClass('lg-next-slide lg-prev-slide');\r\n        if (_touchPrev >
1 -1) {\r\n            this.getSlideItem(_touchPrev).addClass('lg-prev-slide');\r\n        }\r\n        this.getSlideItem(_touchNext).addClass('lg-next-slide');\r\n    };\r\n    /**\r\n     * Go to next slide\r\n     * @param {Boolean} fromTouch - true if slide function called via touch event\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery();\r\n     *  plugin.goToNextSlide();\r\n     * @see <a href=\"/demos/methods/\">Demo</a>\r\n     */\r\n    LightGallery.prototype.goToNextSlide = function (fromTouch) {\r\n        var _this = this;\r\n        var _loop = this.settings.loop;\r\n        if (fromTouch && this.galleryItems.length < 3) {\r\n            _loop = false;\r\n        }\r\n        if (!this.lgBusy) {\r\n            if (this.index + 1 < this.galleryItems.length) {\r\n                this.index++;\r\n                this.LGel.trigger(lGEvents.beforeNextSlide, {\r\n                    index: this.index,\r\n                });\r\n                this.slide(this.index, !!fromTouch, false, 'next');\r\n            }\r\n            else {\r\n                if (_loop) {\r\n                    this.index = 0;\r\n                    this.LGel.trigger(lGEvents.beforeNextSlide, {\r\n                        index: this.index,\r\n                    });\r\n                    this.slide(this.index, !!fromTouch, false, 'next');\r\n                }\r\n                else if (this.settings.slideEndAnimation && !fromTouch) {\r\n                    this.outer.addClass('lg-right-end');\r\n                    setTimeout(function () {\r\n                        _this.outer.removeClass('lg-right-end');\r\n                    }, 400);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    /**\r\n     * Go to previous slides\r\n     * @param {Boolean} fromTouch - true if slide function called via touch event\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery({});\r\n     *  plugin.goToPrevSlide();\r\n     * @see <a href=\"/demos/methods/\">Demo</a>\r\n     *\r\n     */\r\n    LightGallery.prototype.goToPrevSlide = function (fromTouch) {\r\n        var _this = this;\r\n        var _loop = this.settings.loop;\r\n        if (fromTouch && this.galleryItems.length < 3) {\r\n            _loop = false;\r\n        }\r\n        if (!this.lgBusy) {\r\n            if (this.index > 0) {\r\n                this.index--;\r\n                this.LGel.trigger(lGEvents.beforePrevSlide, {\r\n                    index: this.index,\r\n                    fromTouch: fromTouch,\r\n                });\r\n                this.slide(this.index, !!fromTouch, false, 'prev');\r\n            }\r\n            else {\r\n                if (_loop) {\r\n                    this.index = this.galleryItems.length - 1;\r\n                    this.LGel.trigger(lGEvents.beforePrevSlide, {\r\n                        index: this.index,\r\n                        fromTouch: fromTouch,\r\n                    });\r\n                    this.slide(this.index, !!fromTouch, false, 'prev');\r\n                }\r\n                else if (this.settings.slideEndAnimation && !fromTouch) {\r\n                    this.outer.addClass('lg-left-end');\r\n                    setTimeout(function () {\r\n                        _this.outer.removeClass('lg-left-end');\r\n                    }, 400);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    LightGallery.prototype.keyPress = function () {\r\n        var _this = this;\r\n        $LG(window).on(\"keydown.lg.global\" + this.lgId, function (e) {\r\n            if (_this.lgOpened &&\r\n                _this.settings.escKey === true &&\r\n                e.keyCode === 27) {\r\n                e.preventDefault();\r\n                if (_this.settings.allowMediaOverlap &&\r\n                    _this.outer.hasClass('lg-can-toggle') &&\r\n                    _this.outer.hasClass('lg-components-open')) {\r\n                    _this.outer.removeClass('lg-components-open');\r\n                }\r\n                else {\r\n                    _this.closeGallery();\r\n                }\r\n            }\r\n            if (_this.lgOpened && _this.galleryItems.length > 1) {\r\n                if (e.keyCode === 37) {\r\n                    e.preventDefault();\r\n                    _this.goToPrevSlide();\r\n                }\r\n                if (e.keyCode === 39) {\r\n                    e.preventDefault();\r\n                    _this.goToNextSlide();\r\n                }\r\n            }\r\n        });\r\n    };\r\n    LightGallery.prototype.arrow = function () {\r\n        var _this = this;\r\n        this.getElementById('lg-prev').on('click.lg', function () {\r\n            _this.goToPrevSlide();\r\n        });\r\n        this.getElementById('lg-next').on('click.lg', function () {\r\n            _this.goToNextSlide();\r\n        });\r\n    };\r\n    LightGallery.prototype.arrowDisable = function (index) {\r\n        // Disable arrows if settings.hideControlOnEnd is true\r\n        if (!this.settings.loop && this.settings.hideControlOnEnd) {\r\n            var $prev = this.getElementById('lg-prev');\r\n            var $next = this.getElementById('lg-next');\r\n            if (index + 1 === this.galleryItems.length) {\r\n                $next.attr('disabled', 'disabled').addClass('disabled');\r\n            }\r\n            else {\r\n                $next.removeAttr('disabled').removeClass('disabled');\r\n            }\r\n            if (index === 0) {\r\n                $prev.attr('disabled', 'disabled').addClass('disabled');\r\n            }\r\n            else {\r\n                $prev.removeAttr('disabled').removeClass('disabled');\r\n            }\r\n        }\r\n    };\r\n    LightGallery.prototype.setTranslate = function ($el, xValue, yValue, scaleX, scaleY) {\r\n        if (scaleX === void 0) { scaleX = 1; }\r\n        if (scaleY === void 0) { scaleY = 1; }\r\n        $el.css('transform', 'translate3d(' +\r\n            xValue +\r\n            'px, ' +\r\n            yValue +\r\n            'px, 0px) scale3d(' +\r\n            scaleX +\r\n            ', ' +\r\n            scaleY +\r\n            ', 1)');\r\n    };\r\n    LightGallery.prototype.mousewheel = function () {\r\n        var _this = this;\r\n        var lastCall = 0;\r\n        this.outer.on('wheel.lg', function (e) {\r\n            if (!e.deltaY || _this.galleryItems.length < 2) {\r\n                return;\r\n            }\r\n            e.preventDefault();\r\n            var now = new Date().getTime();\r\n            if (now - lastCall < 1000) {\r\n                return;\r\n            }
1\r\n            lastCall = now;\r\n            if (e.deltaY > 0) {\r\n                _this.goToNextSlide();\r\n            }\r\n            else if (e.deltaY < 0) {\r\n                _this.goToPrevSlide();\r\n            }\r\n        });\r\n    };\r\n    LightGallery.prototype.isSlideElement = function (target) {\r\n        return (target.hasClass('lg-outer') ||\r\n            target.hasClass('lg-item') ||\r\n            target.hasClass('lg-img-wrap') ||\r\n            target.hasClass('lg-img-rotate'));\r\n    };\r\n    LightGallery.prototype.isPosterElement = function (target) {\r\n        var playButton = this.getSlideItem(this.index)\r\n            .find('.lg-video-play-button')\r\n            .get();\r\n        return (target.hasClass('lg-video-poster') ||\r\n            target.hasClass('lg-video-play-button') ||\r\n            (playButton && playButton.contains(target.get())));\r\n    };\r\n    /**\r\n     * Maximize minimize inline gallery.\r\n     * @category lGPublicMethods\r\n     */\r\n    LightGallery.prototype.toggleMaximize = function () {\r\n        var _this = this;\r\n        this.getElementById('lg-maximize').on('click.lg', function () {\r\n            _this.$container.toggleClass('lg-inline');\r\n            _this.refreshOnResize();\r\n        });\r\n    };\r\n    LightGallery.prototype.invalidateItems = function () {\r\n        for (var index = 0; index < this.items.length; index++) {\r\n            var element = this.items[index];\r\n            var $element = $LG(element);\r\n            $element.off(\"click.lgcustom-item-\" + $element.attr('data-lg-id'));\r\n        }\r\n    };\r\n    LightGallery.prototype.trapFocus = function () {\r\n        var _this = this;\r\n        this.$container.get().focus({\r\n            preventScroll: true,\r\n        });\r\n        $LG(window).on(\"keydown.lg.global\" + this.lgId, function (e) {\r\n            if (!_this.lgOpened) {\r\n                return;\r\n            }\r\n            var isTabPressed = e.key === 'Tab' || e.keyCode === 9;\r\n            if (!isTabPressed) {\r\n                return;\r\n            }\r\n            var focusableEls = utils.getFocusableElements(_this.$container.get());\r\n            var firstFocusableEl = focusableEls[0];\r\n            var lastFocusableEl = focusableEls[focusableEls.length - 1];\r\n            if (e.shiftKey) {\r\n                if (document.activeElement === firstFocusableEl) {\r\n                    lastFocusableEl.focu
1s();\r\n                    e.preventDefault();\r\n                }\r\n            }\r\n            else {\r\n                if (document.activeElement === lastFocusableEl) {\r\n                    firstFocusableEl.focus();\r\n                    e.preventDefault();\r\n                }\r\n            }\r\n        });\r\n    };\r\n    LightGallery.prototype.manageCloseGallery = function () {\r\n        var _this = this;\r\n        if (!this.settings.closable)\r\n            return;\r\n        var mousedown = false;\r\n        this.getElementById('lg-close').on('click.lg', function () {\r\n            _this.closeGallery();\r\n        });\r\n        if (this.settings.closeOnTap) {\r\n            // If you drag the slide and release outside gallery gets close on chrome\r\n            // for preventing this check mousedown and mouseup happened on .lg-item or lg-outer\r\n            this.outer.on('mousedown.lg', function (e) {\r\n                var target = $LG(e.target);\r\n                if (_this.isSlideElement(target)) {\r\n                    mousedown = true;\r\n                }\r\n                else {\r\n                    mousedown = false;\r\n                }\r\n            });\r\n            this.outer.on('mousemove.lg', function () {\r\n                mousedown = false;\r\n            });\r\n            this.outer.on('mouseup.lg', function (e) {\r\n                var target = $LG(e.target);\r\n                if (_this.isSlideElement(target) && mousedown) {\r\n                    if (!_this.outer.hasClass('lg-dragging')) {\r\n                        _this.closeGallery();\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    };\r\n    /**\r\n     * Close lightGallery if it is opened.\r\n     *\r\n     * @description If closable is false in the settings, you need to pass true via closeGallery method to force close gallery\r\n     * @return returns the estimated time to close gallery completely including the close animation duration\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery();\r\n     *  plugin.closeGallery();\r\n     *\r\n     */\r\n    LightGallery.prototype.closeGallery = function (force) {\r\n        var _this = this;\r\n        if (!this.lgOpened || (!this.settings.closable && !force)) {\r\n            return 0;\r\n        }\r\n        this.LGel.trigger(lGEvents.beforeClose);\r\n        if (this.settings.resetScrollPosition && !this.settings.hideScrollbar) {\r\n            $LG(window).scrollTop(this.prevScrollTop);\r\n        }\r\n        var currentItem = this.items[this.index];\r\n        var transform;\r\n        if (this.zoomFromOrigin && currentItem) {\r\n            var _a = this.mediaContainerPosition, top_4 = _a.top, bottom = _a.bottom;\r\n            var _b = this.galleryItems[this.index], __slideVideoInfo = _b.__slideVideoInfo, poster = _b.poster;\r\n            var imageSize = utils.getSize(currentItem, this.outer, top_4 + bottom, __slideVideoInfo && poster && this.settings.videoMaxSize);\r\n            transform = utils.getTransform(currentItem, this.outer, top_4, bottom, imageSize);\r\n        }\r\n        if (this.zoomFromOrigin && transform) {\r\n            this.outer.addClass('lg-closing lg-zoom-from-image');
1\r\n            this.getSlideItem(this.index)\r\n                .addClass('lg-start-end-progress')\r\n                .css('transition-duration', this.settings.startAnimationDuration + 'ms')\r\n                .css('transform', transform);\r\n        }\r\n        else {\r\n            this.outer.addClass('lg-hide-items');\r\n            // lg-zoom-from-image is used for setting the opacity to 1 if zoomFromOrigin is true\r\n            // If the closing item doesn't have the lg-size attribute, remove this class to avoid the closing css conflicts\r\n            this.outer.removeClass('lg-zoom-from-image');\r\n        }\r\n        // Unbind all events added by lightGallery\r\n        // @todo\r\n        //this.$el.off('.lg.tm');\r\n        this.destroyModules();\r\n        this.lGalleryOn = false;\r\n        this.isDummyImageRemoved = false;\r\n        this.zoomFromOrigin = this.settings.zoomFromOrigin;\r\n        clearTimeout(this.hideBarTimeout);\r\n        this.hideBarTimeout = false;\r\n        $LG('html').removeClass('lg-on');\r\n        this.outer.removeClass('lg-visible lg-components-open');\r\n        // Resetting opacity to 0 isd required as  vertical swipe to close function adds inline opacity.\r\n        this.$backdrop.removeClass('in').css('opacity', 0);\r\n        var removeTimeout = this.zoomFromOrigin && transform\r\n            ? Math.max(this.settings.startAnimationDuration, this.settings.backdropDuration)\r\n            : this.settings.backdropDuration;\r\n        this.$container.removeClass('lg-show-in');\r\n        // Once the closign animation is completed and gallery is invisible\r\n        setTimeout(function () {\r\n            if (_this.zoomFromOrigin && transform) {\r\n                _this.outer.removeClass('lg-zoom-from-image');\r\n            }\r\n            _this.$container.removeClass('lg-show');\r\n            // Reset scrollbar\r\n            _this.resetScrollBar();\r\n            // Need to remove inline opacity as it is used in the stylesheet as well\r\n            _this.$backdrop\r\n                .removeAttr('style')\r\n                .css('transition-duration', _this.settings.backdropDuration + 'ms');\r\n            _this.outer.removeClass(\"lg-closing \" + _this.settings.startClass);
1\r\n            _this.getSlideItem(_this.index).removeClass('lg-start-end-progress');\r\n            _this.$inner.empty();\r\n            if (_this.lgOpened) {\r\n                _this.LGel.trigger(lGEvents.afterClose, {\r\n                    instance: _this,\r\n                });\r\n            }\r\n            if (_this.$container.get()) {\r\n                _this.$container.get().blur();\r\n            }\r\n            _this.lgOpened = false;\r\n        }, removeTimeout + 100);\r\n        return removeTimeout + 100;\r\n    };\r\n    LightGallery.prototype.initModules = function () {\r\n        this.plugins.forEach(function (module) {\r\n            try {\r\n                module.init();\r\n            }\r\n            catch (err) {\r\n                console.warn(\"lightGallery:- make sure lightGallery module is properly initiated\");\r\n            }\r\n        });\r\n    };\r\n    LightGallery.prototype.destroyModules = function (destroy) {\r\n        this.plugins.forEach(function (module) {\r\n            try {\r\n                if (destroy) {\r\n                    module.destroy();\r\n                }\r\n                else {\r\n                    module.closeGallery && module.closeGallery();\r\n                }\r\n            }\r\n            catch (err) {\r\n                console.warn(\"lightGallery:- make sure lightGallery module is properly destroyed\");\r\n            }\r\n        });\r\n    };\r\n    /**\r\n     * Refresh lightGallery with new set of children.\r\n     *\r\n     * @description This is useful to update the gallery when the child elements are changed without calling destroy method.\r\n     *\r\n     * If you are using dynamic mode, you can pass the modified array of dynamicEl as the first parameter to refresh the dynamic gallery\r\n     * @see <a href=\"/demos/dynamic-mode/\">Demo</a>\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery();\r\n     *  // Delete or add children, then call\r\n     *  plugin.refresh();\r\n     *\r\n     */\r\n    LightGallery.prototype.refresh = function (galleryItems) {\r\n        if (!this.settings.dynamic) {\r\n            this.invalidateItems();\r\n        }\r\n        if (galleryItems) {\r\n            this.galleryItems = galleryItems;\r\n        }\r\n        else {\r\n            this.galleryItems = this.getItems();\r\n        }\r\n        this.updateControls();\r\n        this.openGalleryOnItemClick();\r\n        this.LGel.trigger(lGEvents.updateSlides);\r\n    };\r\n    LightGallery.prototype.updateControls = function () {\r\n        this.addSlideVideoInfo(this.galleryItems);\r\n        this.updateCounterTotal();\r\n        this.manageSingleSlideClassName();\r\n    };\r\n    LightGallery.prototype.destroyGallery = function () {\r\n        this.destroyModules(true);\r\n        if (!this.settings.dynamic) {\r\n            this.invalidateItems();\r\n        }\r\n        $LG(window).off(\".lg.global\" + this.lgId);\r\n        this.LGel.off('.lg');\r\n        this.$container.remove();\r\n    };\r\n    /**\r\n     * Destroy lightGallery.\r\n     * Destroy lightGallery and its plugin instances completely\r\n     *\r\n     * @description This method also calls CloseGallery function internally. Returns the time takes to completely close and destroy the instance.\r\n     * In case if you want to re-initialize lightGallery right after destroying it, initialize it only once the destroy process is completed.\r\n     * You can use refresh method most of the times.\r\n     * @category lGPublicMethods\r\n     * @example\r\n     *  const plugin = lightGallery();\r\n     *  plugin.destroy();\r\n     *\r\n     */\r\n    LightGallery.prototype.destroy = function () {\r\n        var closeTimeout = this.closeGallery(true);\r\n        if (closeTimeout) {\r\n            setTimeout(this.destroyGallery.bind(this), closeTimeout);\r\n        }\r\n        else {\r\n            this.destroyGallery();\r\n        }\r\n        return closeTimeout;\r\n    };\r\n    return LightGallery;\r\n}());\n\nfunction lightGallery(el, options) {\r\n    return new LightGallery(el, options);\r\n}\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (lightGallery);\n//# sourceMappingURL=lightgallery.es5.js.map\n\n\n//# sourceURL=webpack://real-insight/./node_modules/lightgallery/lightgallery.es5.js?\n}")},"./node_modules/lightgallery/plugins/thumbnail/lg-thumbnail.es5.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/*!\n * lightgallery | 2.9.0 | October 1st 2025\n * http://www.lightgalleryjs.com/\n * Copyright (c) 2020 Sachin Neravath;\n * @license GPLv3\n */\n\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AN
1D THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    };\r\n    return __assign.apply(this, arguments);\r\n};\n\nvar thumbnailsSettings = {\r\n    thumbnail: true,\r\n    animateThumb: true,\r\n    currentPagerPosition: 'middle',\r\n    alignThumbnails: 'middle',\r\n    thumbWidth: 100,\r\n    thumbHeight: '80px',\r\n    thumbMargin: 5,\r\n    appendThumbnailsTo: '.lg-components',\r\n    toggleThumb: false,\r\n    enableThumbDrag: true,\r\n    enableThumbSwipe: true,\r\n    thumbnailSwipeThreshold: 10,\r\n    loadYouTubeThumbnail: true,\r\n    youTubeThumbSize: 1,\r\n    thumbnailPluginStrings: {\r\n        toggleThumbnails: 'Toggle thumbnails',\r\n    },\r\n};\n\n/**\r\n * List of lightGallery events\r\n * All events should be documented here\r\n * Below interfaces are used to build the website documentations\r\n * */\r\nvar lGEvents = {\r\n    afterAppendSlide: 'lgAfterAppendSlide',\r\n    init: 'lgInit',\r\n    hasVideo: 'lgHasVideo',\r\n    containerResize: 'lgContainerResize',\r\n    updateSlides: 'lgUpdateSlides',\r\n    afterAppendSubHtml: 'lgAfterAppendSubHtml',\r\n    beforeOpen: 'lgBeforeOpen',\r\n    afterOpen: 'lgAfterOpen',\r\n    slideItemLoad: 'lgSlideItemLoad',\r\n    beforeSlide: 'lgBeforeSlide',\r\n    afterSlide: 'lgAfterSlide',\r\n    posterClick: 'lgPosterClick',\r\n    dragStart: 'lgDragStart',\r\n    dragMove: 'lgDragMove',\r\n    dragEnd: 'lgDragEnd',\r\n    beforeNextSlide: 'lgBeforeNextSlide',\r\n    beforePrevSlide: 'lgBeforePrevSlide',\r\n    beforeClose: 'lgBeforeClose',\r\n    afterClose: 'lgAfterClose',\r\n    rotateLeft: 'lgRotateLeft',\r\n    rotateRight: 'lgRotateRight',\r\n    flipHorizontal: 'lgFlipHorizontal',\r\n    flipVertical: 'lgFlipVertical',\r\n    autoplay: 'lgAutoplay',\r\n    autoplayStart: 'lgAutoplayStart',\r\n    autoplayStop: 'lgAutoplayStop',\r\n};\n\nvar Thumbnail = /** @class */ (function () {\r\n    function Thumbnail(instance, $LG) {\r\n        this.thumbOuterWidth = 0;\r\n        this.thumbTotalWidth = 0;\r\n        this.translateX = 0;\r\n        this.thumbClickable = false;\r\n        // get lightGallery core plugin instance\r\n        this.core = instance;\r\n        this.$LG = $LG;\r\n        return this;\r\n    }\r\n    Thumbnail.prototype.init = function () {\r\n        // extend module default settings with lightGallery core settings\r\n        this.settings = __assign(__assign({}, thumbnailsSettings), this.core.settings);\r\n        this.thumbOuterWidth = 0;\r\n        this.thumbTotalWidth =\r\n            this.core.galleryItems.length *\r\n                (this.settings.thumbWidth + this.settings.thumbMargin);\r\n        // Thumbnail animation value\r\n        this.translateX = 0;\r\n        this.setAnimateThumbStyles();\r\n        if (!this.core.settings.allowMediaOverlap) {\r\n            this.settings.toggleThumb = false;\r\n        }\r\n        if (this.settings.thumbnail) {\r\n            this.build();\r\n            if (this.settings.animateThumb) {\r\n                if (this.settings.enableThumbDrag) {\r\n                    this.enableThumbDrag();\r\n                }\r\n                if (this.settings.enableThumbSwipe) {\r\n                    this.enableThumbSwipe();\r\n                }\r\n                this.thumbClickable = false;\r\n            }\r\n            else {\r\n                this.thumbClickable = true;\r\n            }\r\n            this.toggleThumbBar();\r\n            this.thumbKeyPress();\r\n        }\r\n    };\r\n    Thumbnail.prototype.build = function () {\r\n        var _this = this;\r\n        this.setThumbMarkup();\r\n        this.manageActiveClassOnSlideChange();\r\n        this.$lgThumb.first().on('click.lg touchend.lg', function (e) {\r\n            var $target = _this.$LG(e.target);\r\n            if (!$target.hasAttribute('data-lg-item-id')) {\r\n                return;\r\n            }\r\n            setTimeout(function () {\r\n                // In IE9 and bellow touch does not support\r\n                // Go to slide if browser does not support css transitions\r\n                if (_this.thumbClickable && !_this.core.lgBusy) {\r\n                    var index = parseInt($target.attr('data-lg-item-id'));\r\n                    _this.core.slide(index, false, true, false);\r\n                }\r\n            }, 50);\r\n        });\r\n        this.core.LGel.on(lGEvents.beforeSlide + \".thumb\", function (event) {\r\n            var index = event.detail.index;\r\n            _this.animateThumb(index);\r\n        });\r\n        this.core.LGel.on(lGEvents.beforeOpen + \".thumb\", function () {\r\n            _this.thumbOuterWidth = _this.core.outer.get().offsetWidth;\r\n        });\r\n        this.core.LGel.on(lGEvents.updateSlides + \".thumb\", function () {\r\n            _this.rebuildThumbnails();\r\n        });\r\n        this.core.LGel.on(lGEvents.containerResize + \".thumb\", function () {\r\n            if (!_this.core.lgOpened)\r\n                return;\r\n            setTimeout(function () {\r\n                _this.thumbOuterWidth = _this.core.outer.get().offsetWidth;\r\n                _this.animateThumb(_this.core.index);\r\n                _this.thumbOuterWidth = _this.core.outer.get().offsetWidth;\r\n            }, 50);\r\n        });\r\n    };\r\n    Thumbnail.prototype.setThumbMarkup = function () {\r\n        var thumbOuterClassNames = 'lg-thumb-outer ';\r\n        if (this.settings.alignThumbnails) {\r\n            thumbOuterClassNames += \"lg-thumb-align-\" + this.settings.alignThumbnails;\r\n        }\r\n        var html = \"<div class=\\\"\" + thumbOuterClassNames + \"\\\">\\n        <div class=\\\"lg-thumb lg-group\\\">\\n        </div>\\n        </div>\";\r\n        this.core.outer.addClass('lg-has-thumb');\r\n        if (this.settings.appendThumbnailsTo === '.lg-components') {\r\n            this.core.$lgComponents.append(html);\r\n        }\r\n        else {\r\n            this.core.outer.append(html);\r\n        }\r\n        this.$thumbOuter = this.core.outer.find('.lg-thumb-outer').first();\r\n        this.$lgThumb = this.core.outer.find('.lg-thumb').first();\r\n        if (this.settings.animateThumb) {\r\n            this.core.outer\r\n                .find('.lg-thumb')\r\n                .css('transition-duration', this.core.settings.speed + 'ms')\r\n                .css('width', this.thumbTotalWidth + 'px')\r\n                .css('position', 'relative');\r\n        }\r\n        this.setThumbItemHtml(this.core.galleryItems);\r\n    };\r\n    Thumbnail.prototype.enableThumbDrag = function () {\r\n        var _this = this;\r\n        var thumbDragUtils = {\r\n            cords: {\r\n                startX: 0,\r\n                endX: 0,\r\n            },\r\n            isMoved: false,\r\n            newTranslateX: 0,\r\n            startTime: new Date(),\r\n            endTime: new Date(),\r\n            touchMoveTime: 0,\r\n        };\r\n        var isDragging = false;\r\n        this.$thumbOuter.addClass('lg-grab');\r\n        this.core.outer\r\n            .find('.lg-thumb')\r\n            .first()\r\n            .on('mousedown.lg.thumb', function (e) {\r\n            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {\r\n                // execute only on .lg-object\r\n                e.preventDefault();\r\n                thumbDragUtils.cords.startX = e.pageX;\r\n                thumbDragUtils.startTime = new Date();\r\n                _this.thumbClickable = false;\r\n                isDragging = true;\r\n                // ** Fix for webkit cursor issue https://code.google.com/p/chromium/issues/detail?id=26723\r\n                _this.core.outer.get().scrollLeft += 1;\r\n                _this.core.outer.get().scrollLeft -= 1;\r\n                // *\r\n                _this.$thumbOuter\r\n                    .removeClass('lg-grab')\r\n                    .addClass('lg-grabbing');\r\n            }\r\n        });\r\n        this.$LG(window).on(\"mousemove.lg.thumb.global\" + this.core.lgId, function (e) {\r\n            if (!_this.core.lgOpened)\r\n                return;\r\n            if (isDragging) {\r\n                thumbDragUtils.cords.endX = e.pageX;\r\n                thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);\r\n            }\r\n        });\r\n        this.$LG(window).on(\"mouseup.lg.thumb.global\" + this.core.lgId, function () {\r\n            if (!_this.core.lgOpened)\r\n                return;\r\n            if (thumbDragUtils.isMoved) {\r\n                thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);\r\n            }\r\n            else {\r\n                _this.thumbClickable = true;\r\n            }\r\n            if (isDragging) {\r\n                isDragging = false;\r\n                _this.$thumbOuter.removeClass('lg-grabbing').addClass('lg-grab');\r\n            }\r\n        });\r\n    };\r\n    Thumbnail.prototype.enableThumbSwipe = function () {\r\n        var _this = this;\r\n        var thumbDragUtils = {\r\n            cords: {\r\n                startX: 0,\r\n                endX: 0,\r\n            },\r\n            isMoved: false,\r\n            newTranslateX: 0,\r\n            startTime: new Date(),\r\n            endTime: new Date(),\r\n            touchMoveTime: 0,\r\n        };\r\n        this.$lgThumb.on('touchstart.lg', function (e) {\r\n            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {\r\n                e.preventDefault();\r\n                thumbDragUtils.cords.startX = e.targetTouches[0].pageX;\r\n                _this.thumbClickable = false;\r\n                thumbDragUtils.startTime = new Date();\r\n            }\r\n        });\r\n        this.$lgThumb.on('touchmove.lg', function (e) {\r\n            if (_this.thumbTotalWidth > _this.thumbOuterWidth) {\r\n                e.preventDefault();\r\n                thumbDragUtils.cords.endX = e.targetTouches[0].pageX;\r\n                thumbDragUtils = _this.onThumbTouchMove(thumbDragUtils);\r\n            }\r\n        });\r\n        this.$lgThumb.on('touchend.lg', function () {\r\n            if (thumbDragUtils.isMoved) {\r\n                thumbDragUtils = _this.onThumbTouchEnd(thumbDragUtils);\r\n            }\r\n            else {\r\n                _this.thumbClickable = true;\r\n            }\r\n        });\r\n    };\r\n    // Rebuild thumbnails\r\n    Thumbnail.prototype.rebuildThumbnails = function () {\r\n        var _this = this;\r\n        // Remove transitions\r\n        this.$thumbOuter.addClass('lg-rebuilding-thumbnails');\r\n        setTimeout(function () {\r\n            _this.thumbTotalWidth =\r\n                _this.core.galleryItems.length *\r\n                    (_this.settings.thumbWidth + _this.settings.thumbMargin);\r\n            _this.$lgThumb.css('width', _this.thumbTotalWidth + 'px');\r\n            _this.$lgThumb.empty();\r\n            _this.setThumbItemHtml(_this.core.galleryItems);\r\n            _this.animateThumb(_this.core.index);\r\n        }, 50);\r\n        setTimeout(function () {\r\n            _this.$thumbOuter.removeClass('lg-rebuilding-thumbnails');\r\n        }, 200);\r\n    };\r\n    // @ts-check\r\n    Thumbnail.prototype.setTranslate = function (value) {\r\n        this.$lgThumb.css('transform', 'translate3d(-' + value + 'px, 0px, 0px)');\r\n    };\r\n    Thumbnail.prototype.getPossibleTransformX = function (left) {\r\n        if (left > this.thumbTotalWidth - this.thumbOuterWidth) {\r\n            left = this.thumbTotalWidth - this.thumbOuterWidth;\r\n        }\r\n        if (left < 0) {\r\n            left = 0;\r\n        }\r\n        return left;\r\n    };\r\n    Thumbnail.prototype.animateThumb = function (index) {\r\n        this.$lgThumb.css('transition-duration', this.core.settings.speed + 'ms');\r\n        if (this.settings.animateThumb) {\r\n            var position = 0;\r\n            switch (this.settings.currentPagerPosition) {\r\n                case 'left':\r\n                    position = 0;\r\n                    break;\r\n                case 'middle':\r\n                    position =\r\n                        this.thumbOuterWidth / 2 - this.settings.thumbWidth / 2;\r\n                    break;\r\n                case 'right':\r\n                    position = this.thumbOuterWidth - this.settings.thumbWidth;\r\n            }\r\n            this.translateX =\r\n                (this.settings.thumbWidth + this.settings.thumbMargin) * index -\r\n                    1 -\r\n                    position;\r\n            if (this.translateX > this.thumbTotalWidth - this.thumbOuterWidth) {\r\n                this.translateX = this.thumbTotalWidth - this.thumbOuterWidth;\r\n            }\r\n            if (this.translateX < 0) {\r\n                this.translateX = 0;\r\n            }\r\n            this.setTranslate(this.translateX);\r\n        }\r\n    };\r\n    Thumbnail.prototype.onThumbTouchMove = function (thumbDragUtils) {\r\n        thumbDragUtils.newTranslateX = this.translateX;\r\n        thumbDragUtils.isMoved = true;\r\n        thumbDragUtils.touchMoveTime = new Date().valueOf();\r\n        thumbDragUtils.newTranslateX -=\r\n            thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;\r\n        thumbDragUtils.newTranslateX = this.getPossibleTransformX(thumbDragUtils.newTranslateX);\r\n        // move current slide\r\n        this.setTranslate(thumbDragUtils.newTranslateX);\r\n        this.$thumbOuter.addClass('lg-dragging');\r\n        return thumbDragUtils;\r\n    };\r\n    Thumbnail.prototype.onThumbTouchEnd = function (thumbDragUtils) {\r\n        thumbDragUtils.isMoved = false;\r\n        thumbDragUtils.endTime = new Date();\r\n        this.$thumbOuter.removeClass('lg-dragging');\r\n        var touchDuration = thumbDragUtils.endTime.valueOf() -\r\n            thumbDragUtils.startTime.valueOf();\r\n        var distanceXnew = thumbDragUtils.cords.endX - thumbDragUtils.cords.startX;\r\n        var speedX = Math.abs(distanceXnew) / touchDuration;\r\n        // Some magical numbers\r\n        // Can be improved\r\n        if (speedX > 0.15 &&\r\n            thumbDragUtils.endTime.valueOf() - thumbDragUtils.touchMoveTime < 30) {\r\n            speedX += 1;\r\n            if (speedX > 2) {\r\n                speedX += 1;\r\n            }\r\n            speedX =\r\n                speedX +\r\n                    speedX * (Math.abs(distanceXnew) / this.thumbOuterWidth);\r\n            this.$lgThumb.css('transition-duration', Math.min(speedX - 1, 2) + 'settings');\r\n            distanceXnew = distanceXnew * speedX;\r\n            this.translateX = this.getPossibleTransformX(this.translateX - distanceXnew);\r\n            this.setTranslate(this.translateX);\r\n        }\r\n        else {\r\n            this.translateX = thumbDragUtils.newTranslateX;\r\n        }\r\n        if (Math.abs(thumbDragUtils.cords.endX - thumbDragUtils.cords.startX) <\r\n            this.settings.thumbnailSwipeThreshold) {\r\n            this.thumbClickable = true;\r\n        }\r\n        return thumbDragUtils;\r\n    };\r\n    Thumbnail.prototype.getThumbHtml = function (thumb, index, alt) {\r\n        var slideVideoInfo = this.core.galleryItems[index].__slideVideoInfo || {};\r\n        var thumbImg;\r\n        if (slideVideoInfo.youtube) {\r\n            if (this.settings.loadYouTubeThumbn
1ail) {\r\n                thumbImg =\r\n                    '//img.youtube.com/vi/' +\r\n                        slideVideoInfo.youtube[1] +\r\n                        '/' +\r\n                        this.settings.youTubeThumbSize +\r\n                        '.jpg';\r\n            }\r\n            else {\r\n                thumbImg = thumb;\r\n            }\r\n        }\r\n        else {\r\n            thumbImg = thumb;\r\n        }\r\n        var div = document.createElement('div');\r\n        div.setAttribute('data-lg-item-id', index + '');\r\n        div.className = \"lg-thumb-item \" + (index === this.core.index ? 'active' : '');\r\n        div.style.cssText = \"width: \" + this.settings.thumbWidth + \"px; height: \" + this.settings.thumbHeight + \"; margin-right: \" + this.settings.thumbMargin + \"px;\";\r\n        var img = document.createElement('img');\r\n        img.alt = alt || '';\r\n        img.setAttribute('data-lg-item-id', index + '');\r\n        img.src = thumbImg;\r\n        div.appendChild(img);\r\n        return div;\r\n    };\r\n    Thumbnail.prototype.setThumbItemHtml = function (items) {\r\n        for (var i = 0; i < items.length; i++) {\r\n            var thumb = this.getThumbHtml(items[i].thumb, i, items[i].alt);\r\n            this.$lgThumb.append(thumb);\r\n        }\r\n    };\r\n    Thumbnail.prototype.setAnimateThumbStyles = function () {\r\n        if (this.settings.animateThumb) {\r\n            this.core.outer.addClass('lg-animate-thumb');\r\n        }\r\n    };\r\n    // Manage thumbnail active calss\r\n    Thumbnail.prototype.manageActiveClassOnSlideChange = function () {\r\n        var _this = this;\r\n        // manage active class for thumbnail\r\n        this.core.LGel.on(lGEvents.beforeSlide + \".thumb\", function (event) {\r\n            var $thumb = _this.core.outer.find('.lg-thumb-item');\r\n            var index = event.detail.index;\r\n            $thumb.removeClass('active');\r\n            $thumb.eq(index).addClass('active');\r\n        });\r\n    };\r\n    // Toggle thumbnail bar\r\n    Thumbnail.prototype.toggleThumbBar = function () {\r\n        var _this = this;\r\n        if (this.settings.toggleThumb) {\r\n            this.core.outer.addClass('lg-can-toggle');\r\n            this.core.$toolbar.append('<button type=\"button\" aria-label=\"' +\r\n                this.settings.thumbnailPluginStrings['toggleThumbnails'] +\r\n                '\" class=\"lg-toggle-thumb lg-icon\"></button>');\r\n            this.core.outer\r\n                .find('.lg-toggle-thumb')\r\n                .first()\r\n                .on('click.lg', function () {\r\n                _this.core.outer.toggleClass('lg-components-open');\r\n            });\r\n        }\r\n    };\r\n    Thumbnail.prototype.thumbKeyPress = function () {\r\n        var _this = this;\r\n        this.$LG(window).on(\"keydown.lg.thumb.global\" + this.core.lgId, function (e) {\r\n            if (!_this.core.lgOpened || !_this.settings.toggleThumb)\r\n                return;\r\n            if (e.keyCode === 38) {\r\n                e.preventDefault();\r\n                _this.core.outer.addClass('lg-components-open');\r\n            }\r\n            else if (e.keyCode === 40) {\r\n                e.preventDefault();\r\n                _this.core.outer.removeClass('lg-components-open');\r\n            }\r\n        });\r\n    };\r\n    Thumbnail.prototype.destroy = function () {\r\n        if (this.settings.thumbnail) {\r\n            this.$LG(window).off(\".lg.thumb.global\" + this.core.lgId);\r\n            this.core.LGel.off('.lg.thumb');\r\n            this.core.LGel.off('.thumb');\r\n            this.$thumbOuter.remove();\r\n            this.core.outer.removeClass('lg-has-thumb');\r\n        }\r\n    };\r\n    return Thumbnail;\r\n}());\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Thumbnail);\n//# sourceMappingURL=lg-thumbnail.es5.js.map\n\n\n//# sourceURL=webpack://real-insight/./node_modules/lightgallery/plugins/thumbnail/lg-thumbnail.es5.js?\n}")},"./node_modules/lightgallery/plugins/video/lg-video.es5.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (__WEBPACK_DEFAULT_EXPORT__)\n/* harmony export */ });\n/*!\n * lightgallery | 2.9.0 | October 1st 2025\n * http://www.lightgalleryjs.com/\n * Copyright (c) 2020 Sachin Neravath;\n * @license GPLv3\n */\n\n/*! *****************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AN
1D THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n    __assign = Object.assign || function __assign(t) {\r\n        for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n            s = arguments[i];\r\n            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n        }\r\n        return t;\r\n    };\r\n    return __assign.apply(this, arguments);\r\n};\n\nvar videoSettings = {\r\n    autoplayFirstVideo: true,\r\n    youTubePlayerParams: false,\r\n    vimeoPlayerParams: false,\r\n    wistiaPlayerParams: false,\r\n    gotoNextSlideOnVideoEnd: true,\r\n    autoplayVideoOnSlide: false,\r\n    videojs: false,\r\n    videojsTheme: '',\r\n    videojsOptions: {},\r\n};\n\n/**\r\n * List of lightGallery events\r\n * All events should be documented here\r\n * Below interfaces are used to build the website documentations\r\n * */\r\nvar lGEvents = {\r\n    afterAppendSlide: 'lgAfterAppendSlide',\r\n    init: 'lgInit',\r\n    hasVideo: 'lgHasVideo',\r\n    containerResize: 'lgContainerResize',\r\n    updateSlides: 'lgUpdateSlides',\r\n    afterAppendSubHtml: 'lgAfterAppendSubHtml',\r\n    beforeOpen: 'lgBeforeOpen',\r\n    afterOpen: 'lgAfterOpen',\r\n    slideItemLoad: 'lgSlideItemLoad',\r\n    beforeSlide: 'lgBeforeSlide',\r\n    afterSlide: 'lgAfterSlide',\r\n    posterClick: 'lgPosterClick',\r\n    dragStart: 'lgDragStart',\r\n    dragMove: 'lgDragMove',\r\n    dragEnd: 'lgDragEnd',\r\n    beforeNextSlide: 'lgBeforeNextSlide',\r\n    beforePrevSlide: 'lgBeforePrevSlide',\r\n    beforeClose: 'lgBeforeClose',\r\n    afterClose: 'lgAfterClose',\r\n    rotateLeft: 'lgRotateLeft',\r\n    rotateRight: 'lgRotateRight',\r\n    flipHorizontal: 'lgFlipHorizontal',\r\n    flipVertical: 'lgFlipVertical',\r\n    autoplay: 'lgAutoplay',\r\n    autoplayStart: 'lgAutoplayStart',\r\n    autoplayStop: 'lgAutoplayStop',\r\n};\n\nvar param = function (obj) {\r\n    return Object.keys(obj)\r\n        .map(function (k) {\r\n        return encodeURIComponent(k) + '=' + encodeURIComponent(obj[k]);\r\n    })\r\n        .join('&');\r\n};\r\nvar paramsToObject = function (url) {\r\n    var paramas = url\r\n        .slice(1)\r\n        .split('&')\r\n        .map(function (p) { return p.split('='); })\r\n        .reduce(function (obj, pair) {\r\n        var _a = pair.map(decodeURIComponent), key = _a[0], value = _a[1];\r\n        obj[key] = value;\r\n        return obj;\r\n    }, {});\r\n    return paramas;\r\n};\r\nvar getYouTubeParams = function (videoInfo, youTubePlayerParamsSettings) {\r\n    if (!videoInfo.youtube)\r\n        return '';\r\n    var slideUrlParams = videoInfo.youtube[2]\r\n        ? paramsToObject(videoInfo.youtube[2])\r\n        : '';\r\n    // For youtube first params gets priority if duplicates found\r\n    var defaultYouTubePlayerParams = {\r\n        wmode: 'opaque',\r\n        autoplay: 0,\r\n        mute: 1,\r\n        enablejsapi: 1,\r\n    };\r\n    var playerParamsSettings = youTubePlayerParamsSettings || {};\r\n    var youTubePlayerParams = __assign(__assign(__assign({}, defaultYouTubePlayerParams), playerParamsSettings), slideUrlParams);\r\n    var youTubeParams = \"?\" + param(youTubePlayerParams);\r\n    return youTubeParams;\r\n};\r\nvar isYouTubeNoCookie = function (url) {\r\n    return url.includes('youtube-nocookie.com');\r\n};\r\nvar getVimeoURLParams = function (defaultParams, videoInfo) {\r\n    if (!videoInfo || !videoInfo.vimeo)\r\n        return '';\r\n    var urlParams = videoInfo.vimeo[2] || '';\r\n    var defaultVimeoPlayerParams = Object.assign({}, {\r\n        autoplay: 0,\r\n        muted: 1,\r\n    }, defaultParams);\r\n    var defaultPlayerParams = defaultVimeoPlayerParams &&\r\n        Object.keys(defaultVimeoPlayerParams).length !== 0\r\n        ? param(defaultVimeoPlayerParams)\r\n        : '';
1\r\n    // Support private video\r\n    var urlWithHash = videoInfo.vimeo[0].split('/').pop() || '';\r\n    var urlWithHashWithParams = urlWithHash.split('?')[0] || '';\r\n    var hash = urlWithHashWithParams.split('#')[0];\r\n    var isPrivate = videoInfo.vimeo[1] !== hash;\r\n    if (isPrivate) {\r\n        urlParams = urlParams.replace(\"/\" + hash, '');\r\n    }\r\n    urlParams =\r\n        urlParams[0] == '?' ? '&' + urlParams.slice(1) : urlParams || '';\r\n    var privateUrlParams = isPrivate ? \"h=\" + hash : '';\r\n    defaultPlayerParams = privateUrlParams\r\n        ? \"&\" + defaultPlayerParams\r\n        : defaultPlayerParams;\r\n    var vimeoPlayerParams = \"?\" + privateUrlParams + defaultPlayerParams + urlParams;\r\n    return vimeoPlayerParams;\r\n};\n\n/**\r\n * Video module for lightGallery\r\n * Supports HTML5, YouTube, Vimeo, wistia videos\r\n *\r\n *\r\n * @ref Wistia\r\n * https://wistia.com/support/integrations/wordpress(How to get url)\r\n * https://wistia.com/support/developers/embed-options#using-embed-options\r\n * https://wistia.com/support/developers/player-api\r\n * https://wistia.com/support/developers/construct-an-embed-code\r\n * http://jsfiddle.net/xvnm7xLm/\r\n * https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video\r\n * https://wistia.com/support/embed-and-share/sharing-videos\r\n * https://private-sharing.wistia.com/medias/mwhrulrucj\r\n *\r\n * @ref Youtube\r\n * https://developers.google.com/youtube/player_parameters#enablejsapi\r\n * https://developers.google.com/youtube/iframe_api_reference\r\n * https://developer.chrome.com/blog/autoplay/#iframe-delegation\r\n *\r\n * @ref Vimeo\r\n * https://stackoverflow.com/questions/10488943/easy-way-to-get-vimeo-id-from-a-vimeo-url\r\n * https://vimeo.zendesk.com/hc/en-us/articles/360000121668-Starting-playback-at-a-specific-timecode\r\n * https://vimeo.zendesk.com/hc/en-us/articles/360001494447-Using-Player-Parameters\r\n */\r\nvar Video = /** @class */ (function () {\r\n    function Video(instance) {\r\n        // get lightGallery core plugin instance\r\n        this.core = instance;\r\n        this.settings = __assign(__assign({}, videoSettings), this.core.settings);\r\n        return this;\r\n    }\r\n    Video.prototype.init = function () {\r\n        var _this = this;\r\n        /**\r\n         * Event triggered when video url found without poster\r\n         * Append video HTML\r\n         * Play if autoplayFirstVideo is true\r\n         */\r\n        this.core.LGel.on(lGEvents.hasVideo + \".video\", this.onHasVideo.bind(this));\r\n        this.core.LGel.on(lGEvents.posterClick + \".video\", function () {\r\n            var $el = _this.core.getSlideItem(_this.core.index);\r\n            _this.loadVideoOnPosterClick($el);\r\n        });\r\n        this.core.LGel.on(lGEvents.slideItemLoad + \".video\", this.onSlideItemLoad.bind(this));\r\n        // @desc fired immediately before each slide transition.\r\n        this.core.LGel.on(lGEvents.beforeSlide + \".video\", this.onBeforeSlide.bind(this));\r\n        // @desc fired immediately after each slide transition.\r\n        this.core.LGel.on(lGEvents.afterSlide + \".video\", this.onAfterSlide.bind(this));\r\n    };\r\n    /**\r\n     * @desc Event triggered when a slide is completely loaded\r\n     *\r\n     * @param {Event} event - lightGalley custom event\r\n     */\r\n    Video.prototype.onSlideItemLoad = function (event) {\r\n        var _this = this;\r\n        var _a = event.detail, isFirstSlide = _a.isFirstSlide, index = _a.index;\r\n        // Should check the active slide as well as user may have moved to different slide before the first slide is loaded\r\n        if (this.settings.autoplayFirstVideo &&\r\n            isFirstSlide &&\r\n            index === this.core.index) {\r\n            // Delay is just for the transition effect on video load\r\n            setTimeout(function () {\r\n                _this.loadAndPlayVideo(index);\r\n            }, 200);\r\n        }\r\n        // Should not call on first slide. should check only if the slide is active\r\n        if (!isFirstSlide &&\r\n            this.settings.autoplayVideoOnSlide &&\r\n            index === this.core.index) {\r\n            this.loadAndPlayVideo(index);\r\n        }\r\n    };
1\r\n    /**\r\n     * @desc Event triggered when video url or poster found\r\n     * Append video HTML is poster is not given\r\n     * Play if autoplayFirstVideo is true\r\n     *\r\n     * @param {Event} event - Javascript Event object.\r\n     */\r\n    Video.prototype.onHasVideo = function (event) {\r\n        var _a = event.detail, index = _a.index, src = _a.src, html5Video = _a.html5Video, hasPoster = _a.hasPoster;\r\n        if (!hasPoster) {\r\n            // All functions are called separately if poster exist in loadVideoOnPosterClick function\r\n            this.appendVideos(this.core.getSlideItem(index), {\r\n                src: src,\r\n                addClass: 'lg-object',\r\n                index: index,\r\n                html5Video: html5Video,\r\n            });\r\n            // Automatically navigate to next slide once video reaches the end.\r\n            this.gotoNextSlideOnVideoEnd(src, index);\r\n        }\r\n    };\r\n    /**\r\n     * @desc fired immediately before each slide transition.\r\n     * Pause the previous video\r\n     * Hide the download button if the slide contains YouTube, Vimeo, or Wistia videos.\r\n     *\r\n     * @param {Event} event - Javascript Event object.\r\n     * @param {number} prevIndex - Previous index of the slide.\r\n     * @param {number} index - Current index of the slide\r\n     */\r\n    Video.prototype.onBeforeSlide = function (event) {\r\n        if (this.core.lGalleryOn) {\r\n            var prevIndex = event.detail.prevIndex;\r\n            this.pauseVideo(prevIndex);\r\n        }\r\n    };\r\n    /**\r\n     * @desc fired immediately after each slide transition.\r\n     * Play video if autoplayVideoOnSlide option is enabled.\r\n     *\r\n     * @param {Event} event - Javascript Event object.\r\n     * @param {number} prevIndex - Previous index of the slide.\r\n     * @param {number} index - Current index of the slide\r\n     * @todo should check on onSlideLoad as well if video is not loaded on after slide\r\n     */\r\n    Video.prototype.onAfterSlide = function (event) {\r\n        var _this = this;\r\n        var _a = event.detail, index = _a.index, prevIndex = _a.prevIndex;\r\n        // Do not call on first slide\r\n        var $slide = this.core.getSlideItem(index);\r\n        if (this.settings.autoplayVideoOnSlide && index !== prevIndex) {\r\n            if ($slide.hasClass('lg-complete')) {\r\n                setTimeout(function () {\r\n                    _this.loadAndPlayVideo(index);\r\n                }, 100);\r\n            }\r\n        }\r\n    };\r\n    Video.prototype.loadAndPlayVideo = function (index) {\r\n        var $slide = this.core.getSlideItem(index);\r\n        var currentGalleryItem = this.core.galleryItems[index];\r\n        if (currentGalleryItem.poster) {\r\n            this.loadVideoOnPosterClick($slide, true);\r\n        }\r\n        else {\r\n            this.playVideo(index);\r\n        }\r\n    };\r\n    /**\r\n     * Play HTML5, Youtube, Vimeo or Wistia videos in a particular slide.\r\n     * @param {number} index - Index of the slide\r\n     */\r\n    Video.prototype.playVideo = function (index) {\r\n        this.controlVideo(index, 'play');\r\n    };\r\n    /**\r\n     * Pause HTML5, Youtube, Vimeo or Wistia videos in a particular slide.\r\n     * @param {number} index - Index of the slide\r\n     */\r\n    Video.prototype.pauseVideo = function (index) {\r\n        this.controlVideo(index, 'pause');\r\n    };\r\n    Video.prototype.getVideoHtml = function (src, addClass, index, html5Video) {\r\n        var video = '';\r\n        var videoInfo = this.core.galleryItems[index]\r\n            .__slideVideoInfo || {};\r\n        var currentGalleryItem = this.core.galleryItems[index];\r\n        var videoTitle = currentGalleryItem.title || currentGalleryItem.alt;\r\n        videoTitle = videoTitle ? 'title=\"' + videoTitle + '\"' : '';\r\n        var commonIframeProps = \"allowtransparency=\\\"true\\\"\\n            frameborder=\\\"0\\\"\\n            scrolling=\\\"no\\\"\\n            allowfullscreen\\n            mozallowfullscreen\\n            webkitallowfullscreen\\n            oallowfullscreen\\n            msallowfullscreen\";\r\n        if (videoInfo.youtube) {\r\n            var videoId = 'lg-youtube' + index;\r\n            var youTubeParams = getYouTubeParams(videoInfo, this.settings.youTubePlayerParams);
1\r\n            var isYouTubeNoCookieURL = isYouTubeNoCookie(src);\r\n            var youtubeURL = isYouTubeNoCookieURL\r\n                ? '//www.youtube-nocookie.com/'\r\n                : '//www.youtube.com/';\r\n            video = \"<iframe allow=\\\"autoplay\\\" id=\" + videoId + \" class=\\\"lg-video-object lg-youtube \" + addClass + \"\\\" \" + videoTitle + \" src=\\\"\" + youtubeURL + \"embed/\" + (videoInfo.youtube[1] + youTubeParams) + \"\\\" \" + commonIframeProps + \"></iframe>\";\r\n        }\r\n        else if (videoInfo.vimeo) {\r\n            var videoId = 'lg-vimeo' + index;\r\n            var playerParams = getVimeoURLParams(this.settings.vimeoPlayerParams, videoInfo);\r\n            video = \"<iframe allow=\\\"autoplay\\\" id=\" + videoId + \" class=\\\"lg-video-object lg-vimeo \" + addClass + \"\\\" \" + videoTitle + \" src=\\\"//player.vimeo.com/video/\" + (videoInfo.vimeo[1] + playerParams) + \"\\\" \" + commonIframeProps + \"></iframe>\";\r\n        }\r\n        else if (videoInfo.wistia) {\r\n            var wistiaId = 'lg-wistia' + index;\r\n            var playerParams = param(this.settings.wistiaPlayerParams);\r\n            playerParams = playerParams ? '?' + playerParams : '';\r\n            video = \"<iframe allow=\\\"autoplay\\\" id=\\\"\" + wistiaId + \"\\\" src=\\\"//fast.wistia.net/embed/iframe/\" + (videoInfo.wistia[4] + playerParams) + \"\\\" \" + videoTitle + \" class=\\\"wistia_embed lg-video-object lg-wistia \" + addClass + \"\\\" name=\\\"wistia_embed\\\" \" + commonIframeProps + \"></iframe>\";\r\n        }\r\n        else if (videoInfo.html5) {\r\n            var html5VideoMarkup = '';\r\n            for (var i = 0; i < html5Video.source.length; i++) {\r\n                var type = html5Video.source[i].type;\r\n                var typeAttr = type ? \"type=\\\"\" + type + \"\\\"\" : '';\r\n                html5VideoMarkup += \"<source src=\\\"\" + html5Video.source[i].src + \"\\\" \" + typeAttr + \">\";\r\n            }\r\n            if (html5Video.tracks) {\r\n                var _loop_1 = function (i) {\r\n                    var trackAttributes = '';\r\n                    var track = html5Video.tracks[i];\r\n                    Object.keys(track || {}).forEach(function (key) {\r\n                        trackAttributes += key + \"=\\\"\" + track[key] + \"\\\" \";\r\n                    });\r\n                    html5VideoMarkup += \"<track \" + trackAttributes + \">\";\r\n                };\r\n                for (var i = 0; i < html5Video.tracks.length; i++) {\r\n                    _loop_1(i);\r\n                }\r\n            }\r\n            var html5VideoAttrs_1 = '';\r\n            var videoAttributes_1 = html5Video.attributes || {};\r\n            Object.keys(videoAttributes_1 || {}).forEach(function (key) {\r\n                html5VideoAttrs_1 += key + \"=\\\"\" + videoAttributes_1[key] + \"\\\" \";\r\n            });\r\n            video = \"<video class=\\\"lg-video-object lg-html5 \" + (this.settings.videojs && this.settings.videojsTheme\r\n                ? this.settings.videojsTheme + ' '\r\n                : '') + \" \" + (this.settings.videojs ? ' video-js' : '') + \"\\\" \" + html5VideoAttrs_1 + \">\\n                \" + html5VideoMarkup + \"\\n                Your browser does not support HTML5 video.\\n            </video>\";\r\n        }\r\n        return video;\r\n    };\r\n    /**\r\n     * @desc - Append videos to the slide\r\n     *\r\n     * @param {HTMLElement} el - slide element\r\n     * @param {Object} videoParams - Video parameters, Contains src, class, index, htmlVideo\r\n     */\r\n    Video.prototype.appendVideos = function (el, videoParams) {\r\n        var _a;\r\n        var videoHtml = this.getVideoHtml(videoParams.src, videoParams.addClass, videoParams.index, videoParams.html5Video);\r\n        el.find('.lg-video-cont').append(videoHtml);\r\n        var $videoElement = el.find('.lg-video-object').first();\r\n        if (videoParams.html5Video) {\r\n            $videoElement.on('mousedown.lg.video', function (e) {\r\n                e.stopPropagation();\r\n            });\r\n        }\r\n        if (this.settings.videojs && ((_a = this.core.galleryItems[videoParams.index].__slideVideoInfo) === null || _a === void 0 ? void 0 : _a.html5)) {\r\n            try {\r\n                return videojs($videoElement.get(), this.settings.videojsOptions);\r\n            }\r\n            catch (e) {\r\n                console.error('lightGallery:- Make sure you have included videojs');\r\n            }\r\n        }\r\n    };\r\n    Video.prototype.gotoNextSlideOnVideoEnd = function (src, index) {\r\n        var _this = this;\r\n        var $videoElement = this.core\r\n            .getSlideItem(index)\r\n            .find('.lg-video-object')\r\n            .first();\r\n        var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};\r\n        if (this.settings.gotoNextSlideOnVideoEnd) {\r\n            if (videoInfo.html5) {\r\n                $videoElement.on('ended', function () {\r\n                    _this.core.goToNextSlide();\r\n                });\r\n            }\r\n            else if (videoInfo.vimeo) {\r\n                try {\r\n                    // https://github.com/vimeo/player.js/#ended\r\n                    new Vimeo.Player($videoElement.get()).on('ended', function () {\r\n                        _this.core.goToNextSlide();\r\n                    });\r\n                }\r\n                catch (e) {\r\n                    console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');\r\n                }\r\n            }\r\n            else if (videoInfo.wistia) {\r\n                try {\r\n                    window._wq = window._wq || [];\r\n                    // @todo Event is gettign triggered multiple times\r\n                    window._wq.push({\r\n                        id: $videoElement.attr('id'),\r\n                        onReady: function (video) {\r\n                            video.bind('end', function () {\r\n                                _this.core.goToNextSlide();\r\n                            });\r\n                        },\r\n                    });\r\n                }\r\n                catch (e) {\r\n                    console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');\r\n                }\r\n            }\r\n        }\r\n    };\r\n    Video.prototype.controlVideo = function (index, action) {\r\n        var $videoElement = this.core\r\n            .getSlideItem(index)\r\n            .find('.lg-video-object')\r\n            .first();\r\n        var videoInfo = this.core.galleryItems[index].__slideVideoInfo || {};\r\n        if (!$videoElement.get())\r\n            return;\r\n        if (videoInfo.youtube) {\r\n            try {\r\n                $videoElement.get().contentWindow.postMessage(\"{\\\"event\\\":\\\"command\\\",\\\"func\\\":\\\"\" + action + \"Video\\\",\\\"args\\\":\\\"\\\"}\", '*');\r\n            }\r\n            catch (e) {\r\n                console.error(\"lightGallery:- \" + e);\r\n            }\r\n        }\r\n        else if (videoInfo.vimeo) {\r\n            try {\r\n                new Vimeo.Player($videoElement.get())[action]();\r\n            }\r\n            catch (e) {\r\n                console.error('lightGallery:- Make sure you have included //github.com/vimeo/player.js');\r\n            }\r\n        }\r\n        else if (videoInfo.html5) {\r\n            if (this.settings.videojs) {\r\n                try {\r\n                    videojs($videoElement.get())[action]();\r\n                }\r\n                catch (e) {\r\n                    console.error('lightGallery:- Make sure you have included videojs');\r\n                }\r\n            }\r\n            else {\r\n                $videoElement.get()[action]();\r\n            }\r\n        }\r\n        else if (videoInfo.wistia) {\r\n            try {\r\n                window._wq = window._wq || [];\r\n                // @todo Find a way to destroy wistia player instance\r\n                window._wq.push({\r\n                    id: $videoElement.attr('id'),\r\n                    onReady: function (video) {\r\n                        video[action]();\r\n                    },\r\n                });\r\n            }\r\n            catch (e) {\r\n                console.error('lightGallery:- Make sure you have included //fast.wistia.com/assets/external/E-v1.js');\r\n            }\r\n        }\r\n    };\r\n    Video.prototype.loadVideoOnPosterClick = function ($el, forcePlay) {\r\n        var _this = this;\r\n        // check slide has poster\r\n        if (!$el.hasClass('lg-video-loaded')) {\r\n            // check already video element present\r\n            if (!$el.hasClass('lg-has-vi
1deo')) {\r\n                $el.addClass('lg-has-video');\r\n                var _html = void 0;\r\n                var _src = this.core.galleryItems[this.core.index].src;\r\n                var video = this.core.galleryItems[this.core.index].video;\r\n                if (video) {\r\n                    _html =\r\n                        typeof video === 'string' ? JSON.parse(video) : video;\r\n                }\r\n                var videoJsPlayer_1 = this.appendVideos($el, {\r\n                    src: _src,\r\n                    addClass: '',\r\n                    index: this.core.index,\r\n                    html5Video: _html,\r\n                });\r\n                this.gotoNextSlideOnVideoEnd(_src, this.core.index);\r\n                var $tempImg = $el.find('.lg-object').first().get();\r\n                // @todo make sure it is working\r\n                $el.find('.lg-video-cont').first().append($tempImg);\r\n                $el.addClass('lg-video-loading');\r\n                videoJsPlayer_1 &&\r\n                    videoJsPlayer_1.ready(function () {\r\n                        videoJsPlayer_1.on('loadedmetadata', function () {\r\n                            _this.onVideoLoadAfterPosterClick($el, _this.core.index);\r\n                        });\r\n                    });\r\n                $el.find('.lg-video-object')\r\n                    .first()\r\n                    .on('load.lg error.lg loadedmetadata.lg', function () {\r\n                    setTimeout(function () {\r\n                        _this.onVideoLoadAfterPosterClick($el, _this.core.index);\r\n                    }, 50);\r\n                });\r\n            }\r\n            else {\r\n                this.playVideo(this.core.index);\r\n            }\r\n        }\r\n        else if (forcePlay) {\r\n            this.playVideo(this.core.index);\r\n        }\r\n    };\r\n    Video.prototype.onVideoLoadAfterPosterClick = function ($el, index) {\r\n        $el.addClass('lg-video-loaded');\r\n        this.playVideo(index);\r\n    };\r\n    Video.prototype.destroy = function () {\r\n        this.core.LGel.off('.lg.video');\r\n        this.core.LGel.off('.video');\r\n    };\r\n    return Video;\r\n}());\n\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Video);\n//# sourceMappingURL=lg-video.es5.js.map\n\n\n//# sourceURL=webpack://real-insight/./node_modules/lightgallery/plugins/video/lg-video.es5.js?\n}")},"./node_modules/rellax/rellax.js"(module,exports,__webpack_require__){eval("{var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;\n// ------------------------------------------\n// Rellax.js\n// Buttery smooth parallax library\n// Copyright (c) 2016 Moe Amaya (@moeamaya)\n// MIT license\n//\n// Thanks to Paraxify.js and Jaime Cabllero\n// for parallax concepts\n// ------------------------------------------\n\n(function (root, factory) {\n  if (true) {\n    // AMD. Register as an anonymous module.\n    !(__WEBPACK_AMD_DEFINE_ARRAY__ = [], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ?\n\t\t(__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__),\n\t\t__WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n  } else // removed by dead control flow\n{}\n}(typeof window !== \"undefined\" ? window : __webpack_require__.g, function () {\n  var Rellax = function(el, options){\n    \"use strict\";\n\n    var self = Object.create(Rellax.prototype);\n\n    var posY = 0;\n    var screenY = 0;\n    var posX = 0;\n    var screenX = 0;\n    var blocks = [];\n    var pause = true;\n\n    // check what requestAnimationFrame to use, and if\n    // it's not supported, use the onscroll event\n    var loop = window.requestAnimationFrame ||\n      window.webkitRequestAnimationFrame ||\n      window.mozRequestAnimationFrame ||\n      window.msRequestAnimationFrame ||\n      window.oRequestAnimationFrame ||\n      function(callback){ return setTimeout(callback, 1000 / 60); };\n\n    // store the id for later use\n    var loopId = null;\n\n    // Test via a getter in the options object to see if the passive property is accessed\n    var supportsPassive = false;\n    try {\n      var opts = Object.defineProperty({}
1, 'passive', {\n        get: function() {\n          supportsPassive = true;\n        }\n      });\n      window.addEventListener(\"testPassive\", null, opts);\n      window.removeEventListener(\"testPassive\", null, opts);\n    } catch (e) {}\n\n    // check what cancelAnimation method to use\n    var clearLoop = window.cancelAnimationFrame || window.mozCancelAnimationFrame || clearTimeout;\n\n    // check which transform property to use\n    var transformProp = window.transformProp || (function(){\n        var testEl = document.createElement('div');\n        if (testEl.style.transform === null) {\n          var vendors = ['Webkit', 'Moz', 'ms'];\n          for (var vendor in vendors) {\n            if (testEl.style[ vendors[vendor] + 'Transform' ] !== undefined) {\n              return vendors[vendor] + 'Transform';\n            }\n          }\n        }\n        return 'transform';\n      })();\n\n    // Default Settings\n    self.options = {\n      speed: -2,\n\t    verticalSpeed: null,\n\t    horizontalSpeed: null,\n      breakpoints: [576, 768, 1201],\n      center: false,\n      wrapper: null,\n      relativeToWrapper: false,\n      round: true,\n      vertical: true,\n      horizontal: false,\n      verticalScrollAxis: \"y\",\n      horizontalScrollAxis: \"x\",\n      callback: function() {},\n    };\n\n    // User defined options (might have more in the future)\n    if (options){\n      Object.keys(options).forEach(function(key){\n        self.options[key] = options[key];\n      });\n    }\n\n    function validateCustomBreakpoints () {\n      if (self.options.breakpoints.length === 3 && Array.isArray(self.options.breakpoints)) {\n        var isAscending = true;\n        var isNumerical = true;\n        var lastVal;\n        self.options.breakpoints.forEach(function (i) {\n          if (typeof i !== 'number') isNumerical = false;\n          if (lastVal !== null) {\n            if (i < lastVal) isAscending = false;\n          }\n          lastVal = i;\n        });\n        if (isAscending && isNumerical) return;\n      }\n      // revert defaults if set incorrectly\n      self.options.breakpoints = [576, 768, 1201];\n      console.warn(\"Rellax: You must pass an array of 3 numbers in ascending order to the breakpoints option. Defaults reverted\");\n    }\n\n    if (options && options.breakpoints) {\n      validateCustomBreakpoints();\n    }\n\n    // By default, rellax class\n    if (!el) {\n      el = '.rellax';\n    }\n\n    // check if el is a className or a node\n    var elements = typeof el === 'string' ? document.querySelectorAll(el) : [el];\n\n    // Now query selector\n    if (elements.length > 0) {\n      self.elems = elements;\n    }\n\n    // The elements don't exist\n    else {\n      console.warn(\"Rellax: The elements you're trying to select don't exist.\");\n      return;\n    }\n\n    // Has a wrapper and it exists\n    if (self.options.wrapper) {\n      if (!self.options.wrapper.nodeType) {\n        var wrapper = document.querySelector(self.options.wrapper);\n\n        if (wrapper) {\n          self.options.wrapper = wrapper;\n        } else {\n          console.warn(\"Rellax: The wrapper you're trying to use doesn't exist.\");\n          return;\n        }\n      }\n    }\n\n    // set a placeholder for the current breakpoint\n    var currentBreakpoint;\n\n    // helper to determine current breakpoint\n    var getCurrentBreakpoint = function (w) {\n      var bp = self.options.breakpoints;\n      if (w < bp[0]) return 'xs';\n      if (w >= bp[0] && w < bp[1]) return 'sm';\n      if (w >= bp[1] && w < bp[2]) return 'md';\n      return 'lg';\n    };\n\n    // Get and cache initial position of all elements\n    var cacheBlocks = function() {\n      for (var i = 0; i < self.elems.length; i++){\n        var block = createBlock(self.elems[i]);\n        blocks.push(block);\n      }\n    };\n\n\n    // Let's kick this script off\n    // Build array for cached element values\n    var init = function() {\n      for (var i = 0; i < blocks.length; i++){\n        self.elems[i].style.cssText = blocks[i].style;\n      }\n\n      blocks = [];\n\n      screenY = window.innerHeight;\n      screenX = window.innerWidth;\n      currentBreakpoint = getCurrentBreakpoint(screenX);\n\n      setPosition();\n\n      cacheBlocks();\n\n      animate();\n\n      // If paused, unpause and set listener for window resizing events\n      if (pause) {\n        window.addEventListener('resize', init);\n        pause = false;\n        // Start the loop\n        update();\n      }\n    };\n\n    // We want to cache the parallax blocks'\n    // values: base, top, height, speed\n    // el: is dom object, return: el cache values\n    var createBlock = function(el) {\n      var dataPercentage = el.getAttribute( 'data-rellax-percentage' );\n      var dataSpeed = el.getAttribute( 'data-rellax-speed' );\n      var dataXsSpeed = el.getAttribute( 'data-rellax-xs-speed' );\n      var dataMobileSpeed = el.getAttribute( 'data-rellax-mobile-speed' );\n      var dataTabletSpeed = el.getAttribute( 'data-rellax-tablet-speed' );\n      var dataDesktopSpeed = el.getAttribute( 'data-rellax-desktop-speed' );\n      var dataVerticalSpeed = el.getAttribute('data-rellax-vert
1ical-speed');\n      var dataHorizontalSpeed = el.getAttribute('data-rellax-horizontal-speed');\n      var dataVericalScrollAxis = el.getAttribute('data-rellax-vertical-scroll-axis');\n      var dataHorizontalScrollAxis = el.getAttribute('data-rellax-horizontal-scroll-axis');\n      var dataZindex = el.getAttribute( 'data-rellax-zindex' ) || 0;\n      var dataMin = el.getAttribute( 'data-rellax-min' );\n      var dataMax = el.getAttribute( 'data-rellax-max' );\n      var dataMinX = el.getAttribute('data-rellax-min-x');\n      var dataMaxX = el.getAttribute('data-rellax-max-x');\n      var dataMinY = el.getAttribute('data-rellax-min-y');\n      var dataMaxY = el.getAttribute('data-rellax-max-y');\n      var mapBreakpoints;\n      var breakpoints = true;\n\n      if (!dataXsSpeed && !dataMobileSpeed && !dataTabletSpeed && !dataDesktopSpeed) {\n        breakpoints = false;\n      } else {\n        mapBreakpoints = {\n          'xs': dataXsSpeed,\n          'sm': dataMobileSpeed,\n          'md': dataTabletSpeed,\n          'lg': dataDesktopSpeed\n        };\n      }\n\n      // initializing at scrollY = 0 (top of browser), scrollX = 0 (left of browser)\n      // ensures elements are positioned based on HTML layout.\n      //\n      // If the element has the percentage attribute, the posY and posX needs to be\n      // the current scroll position's value, so that the elements are still positioned based on HTML layout\n      var wrapperPosY = self.options.wrapper ? self.options.wrapper.scrollTop : (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);\n      // If the option relativeToWrapper is true, use the wrappers offset to top, subtracted from the current page scroll.\n      if (self.options.relativeToWrapper) {\n        var scrollPosY = (window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);\n        wrapperPosY = scrollPosY - self.options.wrapper.offsetTop;\n      }\n      var posY = self.options.vertical ? ( dataPercentage || self.options.center ? wrapperPosY : 0 ) : 0;\n      var posX = self.options.horizontal ? ( dataPercentage || self.options.center ? self.options.wrapper ? self.options.wrapper.scrollLeft : (window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft) : 0 ) : 0;\n\n      var blockTop = posY + el.getBoundingClientRect().top;\n      var blockHeight = el.clientHeight || el.offsetHeight || el.scrollHeight;\n\n      var blockLeft = posX + el.getBoundingClientRect().left;\n      var blockWidth = el.clientWidth || el.offsetWidth || el.scrollWidth;\n\n      // apparently parallax equation everyone uses\n      var percentageY = dataPercentage ? dataPercentage : (posY - blockTop + screenY) / (blockHeight + screenY);\n      var percentageX = dataPercentage ? dataPercentage : (posX - blockLeft + screenX) / (blockWidth + screenX);\n      if(self.options.center){ percentageX = 0.5; percentageY = 0.5; }\n\n      // Optional individual block speed as data attr, otherwise global speed\n      var speed = (breakpoints && mapBreakpoints[currentBreakpoint] !== null) ? Number(mapBreakpoints[currentBreakpoint]) : (dataSpeed ? dataSpeed : self.options.speed);\n      var verticalSpeed = dataVerticalSpeed ? dataVerticalSpeed : self.options.verticalSpeed;\n      var horizontalSpeed = dataHorizontalSpeed ? dataHorizontalSpeed : self.options.horizontalSpeed;\n\n      // Optional individual block movement axis direction as data attr, otherwise gobal movement direction\n      var verticalScrollAxis = dataVericalScrollAxis ? dataVericalScrollAxis : self.options.verticalScrollAxis;\n      var horizontalScrollAxis = dataHorizontalScrollAxis ? dataHorizontalScrollAxis : self.options.horizontalScrollAxis;\n\n      var bases = updatePosition(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed);\n\n      // ~~Store non-translate3d transforms~~\n      // Store inline styles and extract transforms\n      var style = el.style.cssText;\n      var transform = '';\n\n      // Check if there's an inline styled transform\n      var searchResult = /transform\\s*:/i.exec(style);\n      if (searchResult) {\n        // Get the index of the transform\n        var index = searchResult.index;\n\n        // Trim the style to the transform point and get the following semi-colon index\n        var trimmedStyle = style.slice(index);\n        var delimiter = trimmedStyle.indexOf(';');\n\n        // Remove \"transform\" string and save the attribute\n        if (delimiter) {\n          transform = \" \" + trimmedStyle.slice(11, delimiter).replace(/\\s/g,'');\n        } else {\n          transform = \" \" + trimmedStyle.slice(11).replace(/\\s/g,'');\n        }\n      }\n\n      return {\n        baseX: bases.x,\n        baseY: bases.y,\n        top: blockTop,\n        left: blockLeft,\n        height: blockHeight,\n        width: blockWidth,\n        speed: speed,\n        verticalSpeed: verticalSpeed,\n        horizontalSpeed: horizontalSpeed,\n        verticalScrollAxis: verticalScrollAxis,\n        horizontalScrollAxis: horizontalScrollAxis,\n        style: style,\n        transform: transform,\n        zindex: dataZindex,\n        min: dataMin,\n        max: dataMax,\n        minX: dataMinX,\n        maxX: dataMaxX,\n        minY: dataMinY,\n        maxY: dataMaxY\n      };\n    };\n\n    // set scroll position (posY, posX)\n    // side effect method is not ideal, but okay for now\n    // returns true if the scroll changed, false if nothing happened\n    var setPosition = function() {\
1n      var oldY = posY;\n      var oldX = posX;\n\n      posY = self.options.wrapper ? self.options.wrapper.scrollTop : (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;\n      posX = self.options.wrapper ? self.options.wrapper.scrollLeft : (document.documentElement || document.body.parentNode || document.body).scrollLeft || window.pageXOffset;\n      // If option relativeToWrapper is true, use relative wrapper value instead.\n      if (self.options.relativeToWrapper) {\n        var scrollPosY = (document.documentElement || document.body.parentNode || document.body).scrollTop || window.pageYOffset;\n        posY = scrollPosY - self.options.wrapper.offsetTop;\n      }\n\n\n      if (oldY != posY && self.options.vertical) {\n        // scroll changed, return true\n        return true;\n      }\n\n      if (oldX != posX && self.options.horizontal) {\n        // scroll changed, return true\n        return true;\n      }\n\n      // scroll did not change\n      return false;\n    };\n\n    // Ahh a pure function, gets new transform value\n    // based on scrollPosition and speed\n    // Allow for decimal pixel values\n    var updatePosition = function(percentageX, percentageY, speed, verticalSpeed, horizontalSpeed) {\n      var result = {};\n      var valueX = ((horizontalSpeed ? horizontalSpeed : speed) * (100 * (1 - percentageX)));\n      var valueY = ((verticalSpeed ? verticalSpeed : speed) * (100 * (1 - percentageY)));\n\n      result.x = self.options.round ? Math.round(valueX) : Math.round(valueX * 100) / 100;\n      result.y = self.options.round ? Math.round(valueY) : Math.round(valueY * 100) / 100;\n\n      return result;\n    };\n\n    // Remove event listeners and loop again\n    var deferredUpdate = function() {\n      window.removeEventListener('resize', deferredUpdate);\n      window.removeEventListener('orientationchange', deferredUpdate);\n      (self.options.wrapper ? self.options.wrapper : window).removeEventListener('scroll', deferredUpdate);\n      (self.options.wrapper ? self.options.wrapper : document).removeEventListener('touchmove', deferredUpdate);\n\n      // loop again\n      loopId = loop(update);\n    };\n\n    // Loop\n    var update = function() {\n      if (setPosition() && pause === false) {\n        animate();\n\n        // loop again\n        loopId = loop(update);\n      } else {\n        loopId = null;\n\n        // Don't animate until we get a position updating event\n        window.addEventListener('resize', deferredUpdate);\n        window.addEventListener('orientationchange', deferredUpdate);\n        (self.options.wrapper ? self.options.wrapper : window).addEventListener('scroll', deferredUpdate, supportsPassive ? { passive: true } : false);\n        (self.options.wrapper ? self.options.wrapper : document).addEventListener('touchmove', deferredUpdate, supportsPassive ? { passive: true } : false);\n      }\n    };\n\n    // Transform3d on parallax element\n    var animate = function() {\n      var positions;\n      for (var i = 0; i < self.elems.length; i++){\n        // Determine relevant movement directions\n        var verticalScrollAxis = blocks[i].verticalScrollAxis.toLowerCase();\n        var horizontalScrollAxis = blocks[i].horizontalScrollAxis.toLowerCase();\n        var verticalScrollX = verticalScrollAxis.indexOf(\"x\") != -1 ? posY : 0;\n        var verticalScrollY = verticalScrollAxis.indexOf(\"y\") != -1 ? posY : 0;\n        var horizontalScrollX = horizontalScrollAxis.indexOf(\"x\") != -1 ? posX : 0;\n        var horizontalScrollY = horizontalScrollAxis.indexOf(\"y\") != -1 ? posX : 0;\n\n        var percentageY = ((verticalScrollY + horizontalScrollY - blocks[i].top + screenY) / (blocks[i].height + screenY));\n        var percentageX = ((verticalScrollX + horizontalScrollX - blocks[i].left + screenX) / (blocks[i].width + screenX));\n\n        // Subtracting initialize value, so element stays in same spot as HTML\n        positions = updatePosition(percentageX, percentageY, blocks[i].speed, blocks[i].verticalSpeed, blocks[i].horizontalSpeed);\n        var positionY = positions.y - blocks[i].baseY;\n        var positionX = positions.x - blocks[i].baseX;\n\n        // The next two \"if\" blocks go like this:\n        // Check if a limit is defined (first \"min\", then \"max\");\n        // Check if we need to change the Y or the X\n        // (Currently working only if just one of the axes is enabled)\n        // Then, check if the new position is inside the allowed limit\n        // If so, use new position. If not, set position to limit.\n\n        // Check if a min limit is defined\n        if (blocks[i].min !== null) {\n          if (self.options.vertical && !self.options.horizontal) {\n            positionY = positionY <= blocks[i].min ? blocks[i].min : positionY;\n          }\n          if (self.options.horizontal && !self.options.vertical) {\n            positionX = positionX <= blocks[i].min ? blocks[i].min : positionX;\n          }\n        }\n\n        // Check if directional min limits are defined\n        if (blocks[i].minY != null) {\n            positionY = positionY <= blocks[i].minY ? blocks[i].minY : positionY;\n        }\n        if (blocks[i].minX != null) {\n            positionX = positionX <= blocks[i].minX ? blocks[i].minX : positionX;\n        }\n\n        // Check if a max limit is defined\n        if (blocks[i].max !== null) {\n          if (self.options.vertical && !self.options.horizontal) {\n            positionY = positionY >= blocks[i].max ? blocks[i].max : positionY;\n          }\n          if (self.options.horizontal && !self.options.vertical) {\n            positionX = positionX >= blocks[i].max ? blocks[i].max : positionX;\n          }\n        }\n\n        // Check if directional max limits are defined\n        if (blocks[i].maxY != null) {\n            positionY = positionY >= blocks[i].maxY ? blocks[i].maxY : positionY;\n        }\n        if (blocks[i].maxX != null) {\n            positionX = positionX >= blocks[i].maxX ? blocks[i].maxX : positionX;\n        }\n\n        var zindex = blocks[i].zindex;\n\n        // Move that element\n        // (Set the new translation and append initial inline transforms.)\n        var translate = 'translate3d(' + (self.options.horizontal ? positionX : '0') + 'px,' + (self.options.vertical ? positionY : '0') + 'px,' + zindex + 'px) ' + blocks[i].transform;\n        self.elems[i].style[transformProp] = translate;\n      }\n      self.options.callback(positions);\n    };
1\n\n    self.destroy = function() {\n      for (var i = 0; i < self.elems.length; i++){\n        self.elems[i].style.cssText = blocks[i].style;\n      }\n\n      // Remove resize event listener if not pause, and pause\n      if (!pause) {\n        window.removeEventListener('resize', init);\n        pause = true;\n      }\n\n      // Clear the animation loop to prevent possible memory leak\n      clearLoop(loopId);\n      loopId = null;\n    };\n\n    // Init\n    init();\n\n    // Allow to recalculate the initial values whenever we want\n    self.refresh = init;\n\n    return self;\n  };\n  return Rellax;\n}));\n\n\n//# sourceURL=webpack://real-insight/./node_modules/rellax/rellax.js?\n}")},"./node_modules/unidragger/unidragger.js"(module,__unused_webpack_exports,__webpack_require__){eval("{/*!\n * Unidragger v3.0.1\n * Draggable base class\n * MIT license\n */\n\n( function( window, factory ) {\n  // universal module definition\n  if (  true && module.exports ) {\n    // CommonJS\n    module.exports = factory(\n        window,\n        __webpack_require__(/*! ev-emitter */ \"./node_modules/ev-emitter/ev-emitter.js\"),\n    );\n  } else {\n    // browser global\n    window.Unidragger = factory(\n        window,\n        window.EvEmitter,\n    );\n  }\n\n}( typeof window != 'undefined' ? window : this, function factory( window, EvEmitter ) {\n\nfunction Unidragger() {}\n\n// inherit EvEmitter\nlet proto = Unidragger.prototype = Object.create( EvEmitter.prototype );\n\n// ----- bind start ----- //\n\n// trigger handler methods for events\nproto.handleEvent = function( event ) {\n  let method = 'on' + event.type;\n  if ( this[ method ] ) {\n    this[ method ]( event );\n  }\n};\n\nlet startEvent, activeEvents;\nif ( 'ontouchstart' in window ) {\n  // HACK prefer Touch Events as you can preventDefault on touchstart to\n  // disable scroll in iOS & mobile Chrome metafizzy/flickity#1177\n  startEvent = 'touchstart';\n  activeEvents = [ 'touchmove', 'touchend', 'touchcancel' ];\n} else if ( window.PointerEvent ) {\n  // Pointer Events\n  startEvent = 'pointerdown';\n  activeEvents = [ 'pointermove', 'pointerup', 'pointercancel' ];\n} else {\n  // mouse events\n  startEvent = 'mousedown';\n  activeEvents = [ 'mousemove', 'mouseup' ];\n}\n\n// prototype so it can be overwriteable by Flickity\nproto.touchActionValue = 'none';\n\nproto.bindHandles = function() {\n  this._bindHandles( 'addEventListener', this.touchActionValue );\n};\n\nproto.unbindHandles = function() {\n  this._bindHandles( 'removeEventListener', '' );\n};\n\n/**\n * Add or remove start event\n * @param {String} bindMethod - addEventListener or removeEventListener\n * @param {String} touchAction - value for touch-action CSS property\n */\nproto._bindHandles = function( bindMethod, touchAction ) {\n  this.handles.forEach( ( handle ) => {\n    handle[ bindMethod ]( startEvent, this );\n    handle[ bindMethod ]( 'click', this );\n    // touch-action: none to override browser touch gestures. metafizzy/flickity#540\n    if ( window.PointerEvent ) handle.style.touchAction = touchAction;\n  } );\n};\n\nproto.bindActivePointerEvents = function() {\n  activeEvents.forEach( ( eventName ) => {\n    window.addEventListener( eventName, this );\n  } );\n};\n\nproto.unbindActivePointerEvents = function() {\n  activeEvents.forEach( ( eventName ) => {\n    window.removeEventListener( eventName, this );\n  } );\n};\n\n// ----- event handler helpers ----- //\n\n// trigger method with matching pointer\nproto.withPointer = function( methodName, event ) {\n  if ( event.pointerId === this.pointerIdentifier ) {\n    this[ methodName ]( event, event );\n  }\n};\n\n// trigger method with matching touch\nproto.withTouch = function( methodName, event ) {\n  let touch;\n  for ( let changedTouch of event.changedTouches ) {\n    if ( changedTouch.identifier === this.pointerIdentifier ) {\n      touch = changedTouch;\n    }\n  }\n  if ( touch ) this[ methodName ]( event, touch );\n};\n\n// ----- start event ----- //\n\nproto.onmousedown = function( event ) {\n  this.pointerDown( event, event );\n};\n\nproto.ontouchstart = function( event ) {\n  this.pointerDown( event, event.changedTouches[0] );\n};\n\nproto.onpointerdown = function( event ) {\n  this.pointerDown( event, event );\n};\n\n// nodes that have text fields\nconst cursorNodes = [ 'TEXTAREA', 'INPUT', 'SELECT', 'OPTION' ];\n// input types that do not have text fields\nconst clickTypes = [ 'radio', 'checkbox', 'button', 'submit', 'image', 'file' ];\n\n/**\n * any time you set `event, pointer` it refers to:\n * @param {Event} event\n * @param {Event | Touch} pointer\n */\nproto.pointerDown = function( event, pointer ) {\n  // dismiss multi-touch taps, right clicks, and clicks on text fields\n  let isCursorNode = cursorNodes.includes( event.target.nodeName );\n  let isClickType = clickTypes.includes( event.target.type );\n  let isOkayElement = !isCursorNode || isClickType;\n  let isOkay = !this.isPointerDown && !event.button && isOkayElement;\n  if ( !isOkay ) return;\n\n  this.isPointerDown = true;\n  // save pointer identifier to match up touch events\n  this.pointerIdentifier = pointer.pointerId !== undefined ?\n    // pointerId for pointer events, touch.indentifier for touch events\n    pointer.pointerId : pointer.identifier;\n  // track position for move\n  this.pointerDownPointer = {\n    pageX: pointer.pageX,\n    pageY: pointer.pageY,\n  };\n\n  this.bindActivePointerEvents();\n  this.emitEvent( 'pointerDown', [ event, pointer ] );\n};\n\n// ----- move ----- //\n\nproto.onmousemove = function( event ) {\n  this.pointerMove( event, event );\n};\n\nproto.onpointermove = function( event ) {\n  this.withPointer( 'pointerMove', event );\n};\n\nproto.ontouchmove = function( event ) {\n  this.withTouch( 'pointerMove', event );\n};\n\nproto.pointerMove = function( event, pointer ) {\n  let moveVector = {\n    x: pointer.pageX - this.pointerDownPointer.pageX,\n    y: pointer.pageY - this.pointerDownPointer.pageY,\n  };\n  this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );\n  // start drag if pointer has moved far enough to start drag\n  let isDragStarting = !this.isDragging && this.hasDragStarted( moveVector );\n  if ( isDragStarting ) this.dragStart( event, pointer );\n  if ( this.isDragging ) this.dragMove( event, pointer, moveVector );\n};\n\n// condition if pointer has moved far enough to start drag\nproto.hasDragStarted = function( moveVector ) {\n  return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;\n};\n\n// ----- drag ----- //\n\nproto.dragStart = function( event, pointer ) {\n  this.isDragging = true;
1\n  this.isPreventingClicks = true; // set flag to prevent clicks\n  this.emitEvent( 'dragStart', [ event, pointer ] );\n};\n\nproto.dragMove = function( event, pointer, moveVector ) {\n  this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );\n};\n\n// ----- end ----- //\n\nproto.onmouseup = function( event ) {\n  this.pointerUp( event, event );\n};\n\nproto.onpointerup = function( event ) {\n  this.withPointer( 'pointerUp', event );\n};\n\nproto.ontouchend = function( event ) {\n  this.withTouch( 'pointerUp', event );\n};\n\nproto.pointerUp = function( event, pointer ) {\n  this.pointerDone();\n  this.emitEvent( 'pointerUp', [ event, pointer ] );\n\n  if ( this.isDragging ) {\n    this.dragEnd( event, pointer );\n  } else {\n    // pointer didn't move enough for drag to start\n    this.staticClick( event, pointer );\n  }\n};\n\nproto.dragEnd = function( event, pointer ) {\n  this.isDragging = false; // reset flag\n  // re-enable clicking async\n  setTimeout( () => delete this.isPreventingClicks );\n\n  this.emitEvent( 'dragEnd', [ event, pointer ] );\n};\n\n// triggered on pointer up & pointer cancel\nproto.pointerDone = function() {\n  this.isPointerDown = false;\n  delete this.pointerIdentifier;\n  this.unbindActivePointerEvents();\n  this.emitEvent('pointerDone');\n};\n\n// ----- cancel ----- //\n\nproto.onpointercancel = function( event ) {\n  this.withPointer( 'pointerCancel', event );\n};\n\nproto.ontouchcancel = function( event ) {\n  this.withTouch( 'pointerCancel', event );\n};\n\nproto.pointerCancel = function( event, pointer ) {\n  this.pointerDone();\n  this.emitEvent( 'pointerCancel', [ event, pointer ] );\n};\n\n// ----- click ----- //\n\n// handle all clicks and prevent clicks when dragging\nproto.onclick = function( event ) {\n  if ( this.isPreventing
1Clicks ) event.preventDefault();\n};\n\n// triggered after pointer down & up with no/tiny movement\nproto.staticClick = function( event, pointer ) {\n  // ignore emulated mouse up clicks\n  let isMouseup = event.type === 'mouseup';\n  if ( isMouseup && this.isIgnoringMouseUp ) return;\n\n  this.emitEvent( 'staticClick', [ event, pointer ] );\n\n  // set flag for emulated clicks 300ms after touchend\n  if ( isMouseup ) {\n    this.isIgnoringMouseUp = true;\n    // reset flag after 400ms\n    setTimeout( () => {\n      delete this.isIgnoringMouseUp;\n    }, 400 );\n  }\n};\n\n// -----  ----- //\n\nreturn Unidragger;\n\n} ) );\n\n\n//# sourceURL=webpack://real-insight/./node_modules/unidragger/unidragger.js?\n}")},"./src/js/components/action.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   accordion: () => (/* binding */ accordion),\n/* harmony export */   copyToClipboard: () => (/* binding */ copyToClipboard),\n/* harmony export */   customOverlapAccordion: () => (/* binding */ customOverlapAccordion),\n/* harmony export */   heroObject: () => (/* binding */ heroObject),\n/* harmony export */   menu: () => (/* binding */ menu),\n/* harmony export */   overlapAccordionToggle: () => (/* binding */ overlapAccordionToggle),\n/* harmony export */   share: () => (/* binding */ share),\n/* harmony export */   statCards: () => (/* binding */ statCards),\n/* harmony export */   storylane: () => (/* binding */ storylane),\n/* harmony export */   testimonials: () => (/* binding */ testimonials)\n/* harmony export */ });\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var flickity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! flickity */ \"./node_modules/flickity/js/index.js\");\n/* harmony import */ var flickity__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(flickity__WEBPACK_IMPORTED_MODULE_1__);\n\n\n\nfunction storylane() {\n\tconst triggers = [...document.querySelectorAll('[data-storylane]')]\n\tif (!triggers.length) return\n\n\ttriggers.forEach((trigger) => {\n\t\ttrigger.addEventListener('click', function (e) {\n\t\t\te.preventDefault()\n\t\t\tconst script = trigger.dataset.storylane\n\t\t\tif (script) {\n\t\t\t\teval(script)\n\t\t\t}\n\t\t})\n\t})\n}\n\nfunction overlapAccordionToggle() {\n\tconst modules = [\n\t\t...document.querySelectorAll('.custom-overlap-accordion-toggle'),\n\t]\n\tif (!modules.length) return\n\n\tfunction setTriggerWidth(module, triggers) {\n\t\tconst max = Math.max(...triggers.map((t) => t.offsetWidth))\n\t\tmodule.style.setProperty('--trigger-width', max + 'px')\n\t}\n\n\tmodules.forEach((module) => {\n\t\tconst triggers = [...module.querySelectorAll('.toggle-trigger')]\n\t\tconst contents = [...module.querySelectorAll('.toggle-content')]\n\t\tif (!triggers.length || !contents.length) return\n\n\t\tfunction activate(index) {\n\t\t\ttriggers.forEach((t, i) => {\n\t\t\t\tt.classList.toggle('is-active', i === index)\n\t\t\t\tt.setAttribute('aria-pressed', i === index ? 'true' : 'false')\n\t\t\t})\n\t\t\tcontents.forEach((c, i) => c.classList.toggle('is-active', i === index))\n\t\t}\n\n\t\tactivate(0)\n\t\tsetTriggerWidth(module, triggers)\n\n\t\t// Plain <div>s with a click handler -- not focusable and not announced\n\t\t// as controls to screen reader users. role=\"button\" + tabindex make it\n\t\t// reachable and identifiable; the keydown handler covers Enter/Space,\n\t\t// which a real <button> gets for free but a div does not.\n\t\ttriggers.forEach((trigger, index) => {\n\t\t\ttrigger.setAttribute('role', 'button')\n\t\t\ttrigger.setAttribute('tabindex', '0')\n\n\t\t\ttrigger.addEventListener('click', () => activate(index))\n\t\t\ttrigger.addEventListener('keydown', (e) => {\n\t\t\t\tif (e.key !== 'Enter' && e.key !== ' ') return\n\t\t\t\te.preventDefault()\n\t\t\t\tactivate(index)\n\t\t\t})\n\t\t})\n\t})\n\n\twindow.addEventListener('resize', () =>
1 {\n\t\tmodules.forEach((module) => {\n\t\t\tconst triggers = [...module.querySelectorAll('.toggle-trigger')]\n\t\t\tsetTriggerWidth(module, triggers)\n\t\t})\n\t})\n}\n\nfunction customOverlapAccordion() {\n\tconst wrappers = [\n\t\t...document.querySelectorAll('.custom-overlap-accordion-toggle-content'),\n\t]\n\tif (!wrappers.length > 0) return\n\n\tfunction run() {\n\t\twrappers.forEach((wrapper) => {\n\t\t\tlet parent = wrapper.parentElement\n\t\t\twhile (parent && parent.tagName.toLowerCase() !== 'section') {\n\t\t\t\tparent = parent.parentElement\n\t\t\t}\n\t\t\tif (!parent) return\n\n\t\t\tparent.style.setProperty('--content-height', wrapper.clientHeight + 'px')\n\t\t})\n\t}\n\n\trun()\n\twindow.addEventListener('resize', run)\n}\n\nfunction heroObject() {\n\tconst heroObject = document.getElementById('hero-object-cover')\n\n\tif (!heroObject) return\n\n\tfunction run() {\n\t\tconst height = heroObject.clientHeight\n\t\t// Don't overwrite a good value with a transient 0. The cover is sized\n\t\t// h-[60%] of #hero-object, so before the hero's object content (image /\n\t\t// SVG animation / video — a sibling) has loaded and given the parent\n\t\t// its height, this measures ~0. Writing that would zero out the layout.\n\t\tif (height > 0) {\n\t\t\tdocument.documentElement.style.setProperty(\n\t\t\t\t'--spacing-hero-object',\n\t\t\t\theight + 'px',\n\t\t\t)\n\t\t}\n\t}\n\n\t// A ResizeObserver re-measures on the initial layout, on content load, and\n\t// on resize, so the var can't get stuck at the 0px it had at init time.\n\t// (The previous img/video listener queried inside the cover, which holds no\n\t// media, so the post-load re-measure never fired.)\n\tif ('ResizeObserver' in window) {\n\t\tnew ResizeObserver(run).observe(heroObject)\n\t} else {\n\t\trun()\n\t\twindow.addEventListener('resize', run)\n\t\twindow.addEventListener('load', run)\n\t}\n}\n\nfunction menu() {\n\tconst header = document.querySelector('#main-header')\n\tconst trigger = document.querySelector('.menu-trigger')\n\n\tif (header && trigger) {\n\t\ttrigger.addEventListener('click', () => {\n\t\t\theader.classList.toggle('is-active-mobile')\n\t\t})\n\t}\n\n\tconst items = [...document.querySelectorAll('.mobile-nav .has-children')]\n\n\tif (items.length > 0) {\n\t\titems.forEach((item) => {\n\t\t\titem.addEventListener('click', function () {\n\t\t\t\titem.classList.toggle('is-active')\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunction accordion() {\n\tconst items = [...document.querySelectorAll('.accordion-item')]\n\tconst accordionStates = []\n\n\tif (items.length > 0) {\n\t\titems.forEach((item) => {\n\t\t\tlet state = false\n\t\t\tif (item.classList.contains('is-active')) {\n\t\t\t\tstate = true\n\t\t\t}\n\t\t\taccordionStates.push(state)\n\t\t})\n\n\t\titems.forEach((item, index) => {\n\t\t\tconst trigger = item.querySelector('.accordion-trigger')\n\t\t\tconst type = trigger.dataset.type ?? null\n\n\t\t\ttrigger.addEventListener('click', function () {\n\t\t\t\tconst isCurrentlyActive = accordionStates[index]\n\t\t\t\taccordionStates.forEach((state, i) => {\n\t\t\t\t\tif (i !== index && state) {\n\t\t\t\t\t\titems[i].classList.remove('is-active')\n\t\t\t\t\t\taccordionStates[i] = false\n\t\t\t\t\t}\n\t\t\t\t})\n\n\t\t\t\tif (isCurrentlyActive) {\n\t\t\t\t\taccordionStates[index] = false\n\t\t\t\t\titem.classList.remove('is-active')\n\t\t\t\t} else {\n\t\t\t\t\titem.classList.add('is-active')\n\t\t\t\t\taccordionStates[index] = true\n\t\t\t\t}\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunction share() {\n\tconst trigger = document.getElementById('share-button')\n\tif (!trigger) return\n\n\ttrigger.addEventListener('click', function () {\n\t\tthis.classList.toggle('is-active')\n\t})\n\tcopyToClipboard()\n}\n\nfunction copyToClipboard() {\n\tconst parent = document.querySelector('.copy-to-clipboard')\n\tif (parent) {\n\t\tconst trigger = parent.querySelector('.copy-trigger')\n\t\ttrigger.addEventListener('click', function () {\n\t\t\tcopy(this.dataset.url, () => {\n\t\t\t\tparent.classList.add('is-copied')\n\t\t\t})\n\t\t})\n\t\ttrigger.addEventListener('mouseleave', function () {\n\t\t\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].delayedCall(0.3, () => {\n\t\t\t\tparent.classList.remove('is-copied')\n\t\t\t})\n\t\t})\n\t}\n}\n\nfunction testimonials() {\n\tconst section = document.getElementById('home-testimonials')\n\tif (!section) return\n\n\t// Scope the counter buttons to the single shared card so we never pick up\n\t// stray matches elsewhere in the section.\n\tconst card = section.querySelector('#testimonial-card')\n\tif (!card) return\n\n\tconst buttons = [...card.querySelectorAll('.testimonial-button')]\n\tconst images = [...section.querySelectorAll('.testimonial-image')]\n\tif (!buttons.length) return\n\n\tconst bottom = section.querySelector('.bottom')\n\tconst quote = section.querySelector('#testimonial-quote')\n\tconst author = section.querySelector('#testimonial-author')\n\tconst title = section.querySelector('#testimonial-title')\n\tconst company = section.querySelector('#testimonial-company')\n\n\tconst total = buttons.length\n\tlet current = 0\n\tlet animationContent = null\n\tlet animationImage = null\n\n\t// Navigate to a slide. The counter stays fixed; only the active highlight,\n\t// content and image change.\n\tfunction goTo(index) {\n\t\tconst next = ((index % total) + total) % total // wrap-around\n\t\tconst data = buttons[next].dataset\n\n\t\tif (quote) quote.textContent = data.quote ?? ''\n\t\tif (author) author.textContent = data.author ?? ''\n\t\tif (title) title.textContent = data.title ? `, ${data.title}` : ''\n\t\tif (company) company.textContent = data.company ?? ''\n\n\t\tbuttons.forEach((btn, i) => btn.classList.toggle('is-active', i === next))\n\n\t\tanimateImage(next)\n\t\tanimateContent()\n\t\tcurrent = next\n\t}\n\n\tfunction animateImage(index) {\n\t\tconst nextImage = images[index]\n\t\tif (!nextImage) return\n\n\t\t// Capture the currently-active image BEFORE toggling, so the crossfade\n\t\t// has a real \"from\" target.\n\t\tconst lastImage = section.querySelector('.testimonial-image.is-active')\n\t\timages.forEac
1h((img, i) => img.classList.toggle('is-active', i === index))\n\n\t\tif (animationImage) animationImage.kill()\n\n\t\tanimationImage = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline()\n\t\tif (lastImage && lastImage !== nextImage) {\n\t\t\tanimationImage.set([lastImage, nextImage], { clearProps: 'all' })\n\t\t} else {\n\t\t\tanimationImage.set(nextImage, { clearProps: 'all' })\n\t\t}\n\t\tanimationImage.from(nextImage, { opacity: 0, x: -30, duration: 0.5 })\n\t}\n\n\tfunction animateContent() {\n\t\tconst gap = 15\n\t\tconst targets = [quote, bottom].filter(Boolean)\n\t\tif (!targets.length) return\n\n\t\tif (animationContent) animationContent.kill()\n\n\t\tanimationContent = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline()\n\t\tanimationContent\n\t\t\t.set(targets, { y: gap, opacity: 0 })\n\t\t\t.to(targets, { delay: 0.05, y: 0, opacity: 1, stagger: 0.1 })\n\t}\n\n\t// Counter click navigation (desktop + mobile)\n\tbuttons.forEach((button, index) => {\n\t\tbutton.addEventListener('click', () => goTo(index))\n\t})\n\n\t// Touch-swipe navigation (mobile). Only acts on a horizontal-dominant swipe\n\t// so vertical page scrolling is never hijacked.\n\tconst swipeArea = section.querySelector('.slides') || card\n\tconst SWIPE_THRESHOLD = 40\n\tlet startX = 0\n\tlet startY = 0\n\tlet tracking = false\n\n\tswipeArea.addEventListener(\n\t\t'touchstart',\n\t\t(e) => {\n\t\t\tstartX = e.touches[0].clientX\n\t\t\tstartY = e.touches[0].clientY\n\t\t\ttracking = true\n\t\t},\n\t\t{ passive: true },\n\t)\n\n\tswipeArea.addEventListener(\n\t\t'touchend',\n\t\t(e) => {\n\t\t\tif (!tracking) return\n\t\t\ttracking = false\n\t\t\tconst dx = e.changedTouches[0].clientX - startX\n\t\t\tconst dy = e.changedTouches[0].clientY - startY\n\t\t\tif (Math.abs(dx) < SWIPE_THRESHOLD || Math.abs(dx) < Math.abs(dy)) return\n\t\t\tgoTo(current + (dx < 0 ? 1 : -1))\n\t\t},\n\t\t{ passive: true },\n\t)\n}\n\nfunction statCards() {\n\tconst modules = [...document.querySelectorAll('.custom-stat-cards')]\n\tif (!modules.length) return\n\n\tconst BREAKPOINT = 768\n\n\tmodules.forEach((module) => {\n\t\tconst track = module.querySelector('.stat-cards')\n\t\tconst progressWrap = module.querySelector('.carousel-progress-bar')\n\t\tconst progressBar = module.querySelector('.carousel-progress-current')\n\t\tif (!track) return\n\n\t\tlet flkty = null\n\n\t\tfunction initCarousel() {\n\t\t\tif (flkty) return\n\t\t\tflkty = new (flickity__WEBPACK_IMPORTED_MODULE_1___default())(track, {\n\t\t\t\tprevNextButtons: false,\n\t\t\t\tpageDots: false,\n\t\t\t\tcellAlign: 'left',\n\t\t\t\tcontain: true,\n\t\t\t\tfreeScroll: false,\n\t\t\t})\n\n\t\t\tflkty.cells.forEach((cell) => {\n\t\t\t\tcell.element.style.height = '100%'\n\t\t\t})\n\n\t\t\tif (progressBar) {\n\t\t\t\tconst n = flkty.slides.length\n\n\t\t\t\tfunction setProgress(progress) {\n\t\t\t\t\tconst clamped = Math.max(0, Math.min(1, progress))\n\t\t\t\t\tconst width = n > 1 ? ((clamped * (n - 1) + 1) / n) * 100 : 100\n\t\t\t\t\tprogressBar.style.width = width + '%'\n\t\t\t\t}\n\n\t\t\t\tsetProgress(0)\n\t\t\t\tflkty.on('scroll', setProgress)\n\t\t\t}\n\t\t}\n\n\t\tfunction destroyCarousel() {\n\t\t\tif (!flkty) return\n\t\t\tflkty.cells.forEach((cell) => {\n\t\t\t\tcell.element.style.height = 'auto'\n\t\t\t})\n\t\t\tflkty.destroy()\n\t\t\tflkty = null\n\t\t\tif (progressBar) progressBar.style.width = '0%'\n\t\t}\n\n\t\tconst cards = [...module.querySelectorAll('.stat-card')]\n\n\t\tfunction equalizeHeights() {\n\t\t\tcards.forEach((c) => (c.style.height = ''))\n\n\t\t\t// Reading offsetHeight right after clearing the inline height above\n\t\t\t// forces the browser to synchronously flush layout for the whole\n\t\t\t// page mid-script, rather than at its normal pre-paint point --\n\t\t\t// Lighthouse flags this as a forced reflow. Moving the read (and\n\t\t\t// the write that depends on it) into a rAF callback lets it land\n\t\t\t// where the browser was going to compute layout anyway, instead of\n\t\t\t// blocking whatever JS runs right after this call. One frame of\n\t\t\t// delay before the cards settle to their equalized height, not\n\t\t\t// noticeable and not depended on synchronously by any caller.\n\t\t\trequestAnimationFrame(() =>
1 {\n\t\t\t\tconst maxH = Math.max(...cards.map((c) => c.offsetHeight))\n\t\t\t\tcards.forEach((c) => (c.style.height = maxH + 'px'))\n\t\t\t})\n\t\t}\n\n\t\tfunction resetHeights() {\n\t\t\tcards.forEach((c) => (c.style.height = ''))\n\t\t}\n\n\t\tfunction check() {\n\t\t\tif (window.innerWidth < BREAKPOINT) {\n\t\t\t\t// resetHeights()\n\t\t\t\tif (progressWrap) progressWrap.style.display = ''\n\t\t\t\tinitCarousel()\n\t\t\t} else {\n\t\t\t\tdestroyCarousel()\n\t\t\t\tif (progressWrap) progressWrap.style.display = 'none'\n\t\t\t\tequalizeHeights()\n\t\t\t}\n\t\t}\n\n\t\tcheck()\n\t\twindow.addEventListener('resize', check)\n\t})\n}\n\nfunction copy(text, callback) {\n\ttry {\n\t\t// Create temporary textarea\n\t\tconst textArea = document.createElement('textarea')\n\t\ttextArea.value = text\n\n\t\t// Make the textarea invisible\n\t\ttextArea.style.position = 'fixed'\n\t\ttextArea.style.opacity = '0'\n\t\ttextArea.style.left = '-999999px'\n\t\ttextArea.style.top = '-999999px'\n\n\t\tdocument.body.appendChild(textArea)\n\t\ttextArea.focus()\n\t\ttextArea.select()\n\n\t\t// Execute copy command\n\t\tconst successful = document.execCommand('copy')\n\t\ttextArea.remove()\n\n\t\t// Execute callback if provided\n\t\tif (typeof callback === 'function') {\n\t\t\tcallback(successful)\n\t\t}\n\n\t\treturn successful\n\t} catch (error) {\n\t\tconsole.error('Copy failed:', error)\n\n\t\t// Execute callback with false if provided\n\t\tif (typeof callback === 'function') {\n\t\t\tcallback(false)\n\t\t}\n\n\t\treturn false\n\t}\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/action.js?\n}")},"./src/js/components/animation.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   AI: () => (/* binding */ AI),\n/* harmony export */   ball: () => (/* binding */ ball),\n/* harmony export */   homeWorkflow: () => (/* binding */ homeWorkflow),\n/* harmony export */   loader: () => (/* binding */ loader),\n/* harmony export */   parallax: () => (/* binding */ parallax),\n/* harmony export */   resetLoader: () => (/* binding */ resetLoader)\n/* harmony export */ });\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var gsap_MotionPathPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/MotionPathPlugin */ \"./node_modules/gsap/MotionPathPlugin.js\");\n/* harmony import */ var rellax__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! rellax */ \"./node_modules/rellax/rellax.js\");\n/* harmony import */ var rellax__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(rellax__WEBPACK_IMPORTED_MODULE_2__);\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./utils */ \"./src/js/components/utils.js\");\n\n\n\n\n\ngsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].registerPlugin(gsap_MotionPathPlugin__WEBPACK_IMPORTED_MODULE_1__.MotionPathPlugin)\n\nfunction ball() {\n\tconst wrapper = document.getElementById('hero-ball-wrapper')\n\n\tif (!wrapper) return\n\n\tconst ball = document.getElementById('hero-ball')\n\n\twrapper.addEventListener('mousemove', (e) => {\n\t\tconst rect = ball.getBoundingClientRect()\n\n\t\tconst s = e.clientX - rect.left\n\t\tconst o = e.clientY - rect.top\n\n\t\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].to(ball, {\n\t\t\tduration: 0.3,\n\t\t\tx: ((s - rect.width / 2) / rect.width) * 50,\n\t\t\ty: ((o - rect.height / 2) / rect.height) * 50,\n\t\t\tease: 'power2.out',\n\t\t})\n\t})\n\n\twrapper.addEventListener('mouseleave', () => {\n\t\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].to(ball, {\n\t\t\tduration: 1,\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tease: 'power2.out',\n\t\t})\n\t})\n}\n\nfunction parallax() {\n\tconst savedScroll = window.pageYOffset\n\twindow.scrollTo(0, 0)\n\tnew (rellax__WEBPACK_IMPORTED_MODULE_2___default())('.rellax')\n\twindow.scrollTo(0, savedScroll)\n}\n\n// Tracked so resetLoader() can tear down the intro timeline if it's still in\n// flight when the page is restored from cache.\nlet activeLoaderTimeline = null\n\n/**\n * Puts the loader back into its dormant state.\n *\n * Called on back/forward-cache restores, which hand the DOM back exactly as it\n * was left and fire no DOMContentLoaded — so loader() never runs again to clean\n * up after itself. If the visitor navigated away mid-intro, that leaves a\n * half-played loader frozen over the page. The historic version of this bug (the\n * \"stuck, glitching RI animation\" on back navigation) came from the old\n * pageTransition(), which held the loader at full opacity while navigating; that\n * is gone now, but a restore mid-intro can still strand it, and the reset is\n * cheap and idempotent.\n */\nfunction resetLoader() {\n\tdocument.body.classList.remove('overflow-hidden')\n\n\tconst loader = document.getElementById('loader')\n\tif (!loader) return\n\n\tif (activeLoaderTimeline) {\n\t\tactiveLoaderTimeline.kill()\n\t\tactiveLoaderTimeline = null\n\t}\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].killTweensOf(loader)\n\n\t// Clear the inline opacity rather than pinning it, so the next transition can\n\t// animate it from scratch.\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(loader, { clearProps: 'opacity' })\n\tloader.classList.add('hidden')\n}\n\nfunction loader(start, callback) {\n\tconst loader = document.getElementById('loader')\n\n\t// Worth shouting about: index.js runs the entire startup sequence from this\n\t// timeline's onStart/onComplete, so a missing #loader silently kills every\n\t// piece of JS on the site — smooth scroll, menus, filters, all of it — with\n\t// nothing in the console to explain why.\n\tif (!loader) {\n\t\tconsole.warn(\n\t\t\t'[loader] #loader element not found. Startup is gated on the loader ' +\n\t\t\t\t'timeline, so no page JS will initialise. Check that ' +\n\t\t\t\t'parts/components/loader.php is being output by header.php.',\n\t\t)\n\t\treturn\n\t}\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].utils.selector(loader)\n\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline({\n\t\tdefaults: {\n\t\t\tease: 'power2.out',\n\t\t\tduration: 0.5,\n\t\t},\n\t\tonStart: () => {\n\t\t\tstart()\n\t\t},\n\t\tonComplete: () => {\n\t\t\tcallback()\n\t\t\tdocument.body.classList.remove('overflow-hidden')\n\t\t\tloader.classList.add('hidden')\n\t\t\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(loader, {\n\t\t\t\t'--loader-progress': '0%',\n\t\t\t\t'--gradient-top-y': '0%',\n\t\t\t\t'--gradient-bottom-y': '100%',\n\t\t\t})\n\t\t},\n\t})\n\n\ttl.to(loader, {\n\t\t'--loader-progress': '100%',\n\t})\n\t\t.to(loader, {\n\t\t\t'--gradient-top-y': '100%',\n\t\t\t'--gradient-bottom-y': '0%',\n\t\t})\n\t\t.to(loader, {\n\t\t\tdelay: 0.3,\n\t\t\topacity: 0,\n\t\t})\n\n\tactiveLoaderTimeline = tl\n}\n\nfunction homeWorkflow() {\n\tconst triggers = document.querySelectorAll('.workflow-item')\n\tif (!triggers.length) return\n\n\tlet animation = false\n\tlet animationOut = false\n\tconst contentWrapper = document.querySelector('#workflow-content')\n\tconst headline = document.querySelector('#workflow-content .headline')\n\tconst content = document.querySelector('#workflow-content .content')\n\n\tif (!contentWrapper || !headline || !content) return\n\n\ttriggers.forEac
1h((trigger) => {\n\t\ttrigger.addEventListener('mouseenter', () => {\n\t\t\ttriggers.forEach((other) => {\n\t\t\t\tif (other !== trigger) other.classList.add('is-inactive')\n\t\t\t})\n\n\t\t\theadline.innerHTML = trigger.dataset.headline\n\t\t\tcontent.innerHTML = trigger.dataset.content\n\t\t\tanimate()\n\t\t})\n\n\t\ttrigger.addEventListener('mouseleave', () => {\n\t\t\ttriggers.forEach((other) => other.classList.remove('is-inactive'))\n\t\t\tanimateOut()\n\t\t})\n\t})\n\n\tfunction animate() {\n\t\tconst gap = 30\n\n\t\tif (animation) {\n\t\t\tanimation.kill()\n\t\t}\n\t\tif (animationOut) {\n\t\t\tanimationOut.kill()\n\t\t}\n\n\t\tanimation = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline({})\n\t\tanimation\n\t\t\t.set([headline, content], {\n\t\t\t\ty: gap,\n\t\t\t\topacity: 0,\n\t\t\t})\n\t\t\t.to([headline, content], {\n\t\t\t\tdelay: 0.05,\n\t\t\t\ty: 0,\n\t\t\t\topacity: 1,\n\t\t\t\tstagger: 0.1,\n\t\t\t})\n\t}\n\n\tfunction animateOut() {\n\t\tconst gap = 30\n\n\t\tif (animation) {\n\t\t\tanimation.kill()\n\t\t}\n\t\tif (animationOut) {\n\t\t\tanimationOut.kill()\n\t\t}\n\n\t\tanimationOut = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline({\n\t\t\tdelay: 0.5,\n\t\t})\n\t\tanimationOut\n\t\t\t.to([headline, content], {\n\t\t\t\ty: gap * -1,\n\t\t\t\topacity: 0,\n\t\t\t\tonComplete: () => {\n\t\t\t\t\theadline.innerHTML = contentWrapper.dataset.headline\n\t\t\t\t\tcontent.innerHTML = contentWrapper.dataset.content\n\t\t\t\t},\n\t\t\t})\n\t\t\t.set([headline, content], {\n\t\t\t\ty: gap,\n\t\t\t\topacity: 0,\n\t\t\t})\n\t\t\t.to([headline, content], {\n\t\t\t\tdelay: 0.05,\n\t\t\t\ty: 0,\n\t\t\t\topacity: 1,\n\t\t\t\tstagger: 0.1,\n\t\t\t})\n\t}\n}\n\nfunction AI() {\n\tconst section = document.getElementById(\n\t\t'hero-animation-artificial_intelligence',\n\t)\n\tif (!section) return\n\n\tconst AIButton = document.getElementById('ai-button')\n\n\tif (AIButton) {\n\t\tconst setButtonWidth = () => {\n\t\t\tdocument.documentElement.style.setProperty(\n\t\t\t\t'--spacing-ai-button',\n\t\t\t\t`${AIButton.clientWidth / 2}px`,\n\t\t\t)\n\t\t}\n\n\t\tsetButtonWidth()\n\t\twindow.addEventListener('resize', setButtonWidth)\n\n\t\tconst $ = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].utils.selector(AIButton)\n\t\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline({\n\t\t\tdefaults: {\n\t\t\t\tduration: 18,\n\t\t\t\tease: 'none',\n\t\t\t},\n\t\t})\n\n\t\ttl.to(AIButton, {\n\t\t\trotate: '+=512.5',\n\t\t\tease: 'none',\n\t\t\trepeat: -1,\n\t\t})\n\t\t\t.to(\n\t\t\t\t$('circle'),\n\t\t\t\t{\n\t\t\t\t\tfill: '#2660A7',\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t)\n\t\t\t.to(\n\t\t\t\t$('#center'),\n\t\t\t\t{\n\t\t\t\t\ttransformOrigin: 'center',\n\t\t\t\t\tscale: 1.2,\n\t\t\t\t},\n\t\t\t\t0,\n\t\t\t)\n\t}\n\n\tanimateButton(section, 'Inner')\n\tanimateButton(section, 'Outer')\n}\n\nfunction animateButton(section, direction) {\n\tif (direction !== 'Inner' && direction !== 'Outer') return\n\n\tconst config = {\n\t\tInner: { duration: 9, delay: 0 },\n\t\tOuter: {\n\t\t\tduration: 9,\n\t\t\tonStart: (el) => el.removeAttribute('hidden'),\n\t\t},\n\t}\n\n\tconst button = section.querySelector(`#Button-${direction}`)\n\tconst circle = section.querySelector(`#Circle-${direction}`)\n\n\tif (!button || !circle) return\n\n\tconst { duration, delay, onStart } = config[direction]\n\tconst [path] = gsap_MotionPathPlugin__WEBPACK_IMPORTED_MODULE_1__.MotionPathPlugin.convertToPath(circle)\n\tconst offset = 30 / path.getTotalLength()\n\n\tif (_utils__WEBPACK_IMPORTED_MODULE_3__.isMobile.any()) {\n\t\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(button, { scale: 1.5, transformOrigin: 'center' })\n\t}\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].to(button, {\n\t\tduration,\n\t\tdelay,\n\t\trepeat: -1,\n\t\tease: 'none',\n\t\tonStart: onStart ? () => onStart(button) : undefined,\n\t\tmotionPath: {\n\t\t\tpath,\n\t\t\talign: path,\n\t\t\talignOrigin: [0.5, 0.5],\n\t\t\tstart: 1 + offset,\n\t\t\tend: 0.5 - offset,\n\t\t},\n\t})\n}\n\n/*\n * pageTransition() lived here.\n *\n * It intercepted every same-origin link click, faded #loader up to full opacity,\n * then set window.location.href — a normal browser navigation with a ~0.5s delay\n * bolted on the front. Combined with the intro timeline re-running on arrival,\n * that meant the visitor met the loader twice per click.\n *\n * Removed deliberately: the loader is now a once-per-session preloader (see the\n * .preloader-seen gate in header.php and index.js), so links navigate natively.\n * This al
1so retires the stall-timer/pagehide workaround the interception needed,\n * and the .no-transition / .scroll-to opt-out classes it honoured — those are now\n * inert as far as navigation is concerned. (.scroll-to still has its own\n * anchor-scrolling behaviour elsewhere; .no-transition is no longer used at all.)\n */\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/animation.js?\n}")},"./src/js/components/cursor-box.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ CursorBox)\n/* harmony export */ });\nfunction clamp(value, min, max) {\n\treturn Math.min(Math.max(value, min), max)\n}\n\nfunction lerp(start, end, t) {\n\treturn start + (end - start) * t\n}\n\nclass Cell {\n\tconstructor(col, row, x, y, size, box) {\n\t\tthis.box = box\n\t\tthis.col = col\n\t\tthis.row = row\n\t\tthis.x = x\n\t\tthis.y = y\n\t\tthis.size = size\n\t\tthis.centerX = x + size / 2\n\t\tthis.centerY = y + size / 2\n\n\t\tthis.isAnimated = Math.random() < box.SETTINGS.background.activeCellChance\n\t\tthis.baseOpacity = 0\n\t\tthis.currentOpacity = 0\n\n\t\tconst min = box.SETTINGS.background.minOpacity\n\t\tconst max = box.SETTINGS.background.maxOpacity\n\t\tthis.staticOpacity = this.isAnimated ? lerp(min, max, Math.random()) : 0\n\t\tthis.hoverFade = 0\n\t\tthis.hoverTarget = 0\n\n\t\tthis.state = this.getInitialState()\n\t\tthis.startTime = performance.now()\n\t}\n\n\tgetInitialState() {\n\t\tconst init = this.box.SETTINGS.background.initialState\n\t\tif (init === 'fadingIn') return 'fadingIn'\n\t\tif (init === 'fadingOut') return 'fadingOut'\n\t\treturn Math.random() > 0.5 ? 'fadingIn' : 'fadingOut'\n\t}\n\n\tgetBaseOpacity(time) {\n\t\tif (!this.isAnimated) return 0\n\n\t\tconst elapsed = time - this.startTime\n\t\tconst progress = Math.min(\n\t\t\telapsed / this.box.SETTINGS.background.fadeDuration,\n\t\t\t1,\n\t\t)\n\t\tconst min = this.box.SETTINGS.background.minOpacity\n\t\tconst max = this.box.SETTINGS.background.maxOpacity\n\n\t\tif (this.state === 'fadingIn') {\n\t\t\tconst opacity = lerp(min, max, progress)\n\n\t\t\tif (progress >= 1) {\n\t\t\t\tthis.state = 'fadingOut'\n\t\t\t\tthis.startTime = time\n\t\t\t}\n\n\t\t\treturn opacity\n\t\t}\n\n\t\tconst opacity = lerp(max, min, progress)\n\n\t\tif (progress >= 1) {\n\t\t\tthis.state = 'fadingIn'\n\t\t\tthis.startTime = time\n\t\t}\n\n\t\treturn opacity\n\t}\n\n\tgetCursorTarget(time) {\n\t\tconst { mouse, SETTINGS } = this.box\n\t\tif (!mouse.active || mouse.hoveredCol === -1 || mouse.hoveredRow === -1)\n\t\t\treturn 0\n\n\t\tconst colDiff = this.col - mouse.hoveredCol\n\t\tconst rowDiff = this.row - mouse.hoveredRow\n\n\t\t// Cheap rejection before the expensive math below. The L1.6 norm used for\n\t\t// `distance` is always >= max(|colDiff|, |rowDiff|), so anything outside\n\t\t// this square is guaranteed to be outside the falloff radius and would\n\t\t// have returned 0 anyway. Without this, every cell on the canvas paid for\n\t\t// an atan2, two fractional Math.pow calls and two Math.sin calls on every\n\t\t// frame — 5,000+ cells on a full-bleed section, times one instance per\n\t\t// cursor-box on the page. That was the main cause of the dropped frames\n\t\t// that made scrolling feel bouncy and glitchy.\n\t\tconst maxOuter = this.box.maxFalloffCells\n\t\tif (colDiff > maxOuter || colDiff < -maxOuter) return 0\n\t\tif (rowDiff > maxOuter || rowDiff < -maxOuter) return 0\n\n\t\tconst angle = Math.atan2(rowDiff, colDiff)\n\n\t\tconst distance = Math.pow(\n\t\t\tMath.pow(Math.abs(colDiff), 1.6) + Math.pow(Math.abs(rowDiff), 1.6),\n\t\t\t1 / 1.6,\n\t\t)\n\n\t\tconst pulse =\n\t\t\tMath.sin(time * SETTINGS.cursor.pulseSpeed) * SETTINGS.cursor.pulseAmount\n\n\t\tconst wobble =\n\t\t\tMath.sin(\n\t\t\t\tangle * SETTINGS.cursor.wobbleFrequency +\n\t\t\t\t\ttime * SETTINGS.cursor.wobbleSpeed,\n\t\t\t) * SETTINGS.cursor.wobbleAmount\n\n\t\tconst inner = SETTINGS.cursor.baseRadius + pulse + wobble\n\t\tconst outer = SETTINGS.cursor.falloffRadius + pulse + wobble\n\n\t\tif (distance >= outer) return 0\n\t\tif (distance <= inner) return SETTINGS.cursor.maxStrength\n\n\t\tconst t = (distance - inner) / (outer - inner)\n\t\tconst eased = 1 - t * t * (3 - 2 * t)\n\n\t\treturn SETTINGS.cursor.maxStrength * eased\n\t}\n\n\tupdateHoverFade(time) {\n\t\tconst { SETTINGS } = this.box\n\t\tthis.hoverTarget = this.getCursorTarget(time)\n\n\t\tif (this.hoverFade < this.hoverTarget) {\n\t\t\tthis.hoverFade +=\n\t\t\t\t(this.hoverTarget - this.hoverFade) * SETTINGS.cursor.easeIn\n\t\t} else {\n\t\t\tthis.hoverFade +=\n\t\t\t\t(this.hoverTarget - this.hoverFade) * SETTINGS.cursor.easeOut\n\t\t}
1\n\n\t\tthis.hoverFade = clamp(this.hoverFade, 0, 1)\n\t}\n\n\tupdate(time) {\n\t\tthis.baseOpacity = this.getBaseOpacity(time)\n\t\tthis.updateHoverFade(time)\n\t\tthis.currentOpacity = clamp(this.baseOpacity * this.hoverFade, 0, 1)\n\t}\n\n\tdraw() {\n\t\tconst { ctx, SETTINGS, theme } = this.box\n\n\t\tif (this.box.isStatic) {\n\t\t\tctx.strokeRect(this.x, this.y, this.size, this.size)\n\n\t\t\tif (this.staticOpacity > SETTINGS.render.opacityCutoff) {\n\t\t\t\tctx.fillStyle = `rgba(${theme.fillColor}, ${this.staticOpacity})`\n\t\t\t\tctx.fillRect(this.x, this.y, this.size, this.size)\n\t\t\t}\n\t\t\treturn\n\t\t}\n\n\t\tconst borderOpacity = this.hoverFade\n\n\t\tif (borderOpacity > SETTINGS.render.opacityCutoff) {\n\t\t\tctx.lineWidth = SETTINGS.grid.borderWidth\n\t\t\tctx.strokeStyle = `rgba(${theme.borderColor}, ${borderOpacity})`\n\t\t\tctx.strokeRect(this.x, this.y, this.size, this.size)\n\t\t}\n\n\t\tif (this.currentOpacity > SETTINGS.render.opacityCutoff) {\n\t\t\tctx.fillStyle = `rgba(${theme.fillColor}, ${this.currentOpacity})`\n\t\t\tctx.fillRect(this.x, this.y, this.size, this.size)\n\t\t}\n\t}\n}\n\nclass CursorBox {\n\tconstructor(element, isStatic = false) {\n\t\tthis.canvas = element\n\t\tthis.isStatic = isStatic\n\t\tthis.ctx = this.canvas.getContext('2d')\n\n\t\tthis.SETTINGS = {\n\t\t\ttheme: this.canvas.dataset.theme,\n\n\t\t\tintro: {\n\t\t\t\tduration: 2000,\n\t\t\t},\n\n\t\t\tgrid: {\n\t\t\t\tcellSize: 16,\n\t\t\t\tgap: 0,\n\t\t\t\tborderWidth: 1,\n\t\t\t},\n\n\t\t\tbackground: {\n\t\t\t\tactiveCellChance: 0.25,\n\t\t\t\tfadeDuration: 4500,\n\t\t\t\tminOpacity: 0,\n\t\t\t\tmaxOpacity: 1,\n\t\t\t\tinitialState: 'random', // 'random' | 'fadingIn' | 'fadingOut'\n\t\t\t},\n\n\t\t\tcursor: {\n\t\t\t\tbaseRadius: 8,\n\t\t\t\tfalloffRadius: 12,\n\t\t\t\tmaxStrength: 1,\n\t\t\t\teaseIn: 0.16,\n\t\t\t\teaseOut: 0.012,\n\n\t\t\t\tpulseAmount: 1.2,\n\t\t\t\tpulseSpeed: 0.0012,\n\n\t\t\t\twobbleAmount: 1.4,\n\t\t\t\twobbleSpeed: 0.0016,\n\t\t\t\twobbleFrequency: 3,\n\t\t\t},\n\n\t\t\trender: {\n\t\t\t\topacityCutoff: 0.004,\n\t\t\t\tresizeDebounce: 150,\n\t\t\t},\n\n\t\t\tthemes: {\n\t\t\t\tgray: {\n\t\t\t\t\tborderColor: '230, 230, 230',\n\t\t\t\t\tfillColor: '230, 230, 230',\n\t\t\t\t},\n\t\t\t\t// #2660a7 (--color-blue-300) on the --color-blue-main (#05346d)\n\t\t\t\t// background these boxes sit on. Was #184e7f, which measured 1.42:1\n\t\t\t\t// against that background — enough separation on paper, but the navy\n\t\t\t\t// boxes are the *animated* variant, so unlike the static gray ones\n\t\t\t\t// there's no permanent full-alpha grid to carry the effect. Only what's\n\t\t\t\t// inside the cursor radius is ever visible, so the fill has to do all\n\t\t\t\t// the work on its own. This takes it to 1.93:1.\n\t\t\t\tnavy: {\n\t\t\t\t\tborderColor: '38, 96, 167',\n\t\t\t\t\tfillColor: '38, 96, 167',\n\t\t\t\t},\n\t\t\t},\n\t\t}\n\n\t\t// Resolved once instead of per cell, per frame.\n\t\tthis.theme =\n\t\t\tthis.SETTINGS.themes[this.SETTINGS.theme] || this.SETTINGS.themes.gray\n\n\t\t// Widest possible falloff in cells, used by Cell.getCursorTarget() to\n\t\t// reject far-away cells before doing any trigonometry.\n\t\tconst { falloffRadius, pulseAmount, wobbleAmount } = this.SETTINGS.cursor\n\t\tthis.maxFalloffCells = Math.ceil(falloffRadius + pulseAmount + wobbleAmount) + 1\n\n\t\tthis.width = 0\n\t\tthis.height = 0\n\t\tthis.cols = 0\n\t\tthis.rows = 0\n\t\tthis.cells = []\n\n\t\tthis.gridOffsetX = 0\n\t\tthis.gridOffsetY = 0\n\n\t\tthis.gridIntroStart = performance.now()\n\n\t\tthis.rafId = null\n\t\tthis.resizeTimer = null\n\t\tthis.isVisible = true\n\t\tthis.isSettled = false\n\n\t\t// Pointer coordinates are stashed on the event and only resolved against\n\t\t// the canvas once per frame. Reading getBoundingClientRect() inside the\n\t\t// mousemove handler forced a layout on every single pointer event, once\n\t\t// per cursor-box instance on the page.\n\t\tthis.pointer = { x: 0, y: 0, dirty: false }\n\n\t\tthis.mouse = {\n\t\t\tx: 0,\n\t\t\ty: 0,\n\t\t\tactive: false,\n\t\t\thoveredCol: -1,\n\t\t\thoveredRow: -1,\n\t\t}\n\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tif (!this.isStatic) {\n\t\t\tconst onPointer = (x, y) => {\n\t\t\t\tthis.pointer.x = x\n\t\t\t\tthis.pointer.y = y\n\t\t\t\tthis.pointer.dirty = true\n\t\t\t\tthis.requestFrame()\n\t\t\t}\n\n\t\t\twindow.addEventListener(\n\t\t\t\t'mousemove',\n\t\t\t\t(event) => onPointer(event.clientX, event.clientY),\n\t\t\t\t{ passive: true },\n\t\t\t)\n\n\t\t\twindow.addEventListener(\n\t\t\t\t'touchmove',\n\t\t\t\t(event) => {\n\t\t\t\t\tif (event.touches.length > 0) {\n\t\t\t\t\t\tonPointer(event.touches[0].clientX, event.touches[0].clientY)\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t{ passive: true },\n\t\t\t)\n\n\t\t\twindow.addEventListener('mouseleave', () => this.clearHover())\n\t\t\twindow.addEventListener('mouseout', (event) => {\n\t\t\t\tif (!event.relatedTarget) this.clearHover()\n\t\t\t})\n\t\t\twindow.addEventListener('touchend', () => this.clearHover())\n\t\t}\n\n\t\t// Observe the box's own parent rather than document.body. The homepage\n\t\t// feature cards animate their height for over a second, which made a\n\t\t// body-level observer fire on nearly every frame — and every fire\n\t\t// rebuilt the whole grid, allocating thousands of Cell objects.\n\t\tconst parent = this.canvas.parentElement\n\t\tif (parent && 'ResizeObserver' in window) {\
1n\t\t\tthis.sizeObserver = new ResizeObserver(() => this.scheduleResize())\n\t\t\tthis.sizeObserver.observe(parent)\n\t\t} else {\n\t\t\twindow.addEventListener('resize', () => this.scheduleResize())\n\t\t}\n\n\t\t// Don't burn frames on a grid that isn't on screen.\n\t\tif ('IntersectionObserver' in window) {\n\t\t\tthis.visibilityObserver = new IntersectionObserver(\n\t\t\t\t(entries) => {\n\t\t\t\t\tthis.isVisible = entries[entries.length - 1].isIntersecting\n\t\t\t\t\tif (this.isVisible) this.requestFrame()\n\t\t\t\t\telse this.cancelFrame()\n\t\t\t\t},\n\t\t\t\t{ rootMargin: '200px 0px' },\n\t\t\t)\n\t\t\tthis.visibilityObserver.observe(this.canvas)\n\t\t}\n\n\t\tthis.resizeCanvas()\n\t\tthis.requestFrame()\n\t}\n\n\tgetThemeConfig() {\n\t\treturn this.theme\n\t}\n\n\tgetStep() {\n\t\treturn this.SETTINGS.grid.cellSize + this.SETTINGS.grid.gap\n\t}\n\n\tupdateGridMetrics() {\n\t\tconst step = this.getStep()\n\n\t\tthis.cols = Math.ceil(this.width / step)\n\t\tthis.rows = Math.ceil(this.height / step)\n\n\t\tconst totalGridWidth = this.cols * step - this.SETTINGS.grid.gap\n\n\t\tthis.gridOffsetX = (this.width - totalGridWidth) / 2\n\t\tthis.gridOffsetY = -1\n\t}\n\n\tbuildGrid() {\n\t\tthis.cells = []\n\t\tthis.updateGridMetrics()\n\n\t\tconst step = this.getStep()\n\n\t\tfor (let row = 0; row < this.rows; row++) {\n\t\t\tfor (let col = 0; col < this.cols; col++) {\n\t\t\t\tconst x = this.gridOffsetX + col * step\n\t\t\t\tconst y = this.gridOffsetY + row * step\n\t\t\t\tthis.cells.push(\n\t\t\t\t\tnew Cell(col, row, x, y, this.SETTINGS.grid.cellSize, this),\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\tscheduleResize() {\n\t\tclearTimeout(this.resizeTimer)\n\t\tthis.resizeTimer = setTimeout(\n\t\t\t() => this.resizeCanvas(),\n\t\t\tthis.SETTINGS.render.resizeDebounce,\n\t\t)\n\t}\n\n\tresizeCanvas() {\n\t\tconst parent = this.canvas.parentElement\n\t\tif (!parent) return\n\n\t\tconst width = parent.clientWidth\n\t\tconst height = parent.clientHeight\n\n\t\t// Nothing to do — and crucially, no grid rebuild.\n\t\tif (width === this.width && height === this.height) return\n\t\tif (width === 0 || height === 0) return\n\n\t\tthis.width = width\n\t\tthis.height = height\n\n\t\tconst dpr = window.devicePixelRatio || 1\n\n\t\tthis.canvas.width = this.width * dpr\n\t\tthis.canvas.height = this.height * dpr\n\t\tthis.canvas.style.width = `${this.width}px`\n\t\tthis.canvas.style.height = `${this.height}px`\n\n\t\tthis.ctx.setTransform(1, 0, 0, 1, 0, 0)\n\t\tthis.ctx.scale(dpr, dpr)\n\n\t\tthis.buildGrid()\n\n\t\t// A settled static grid has stopped its loop, so it needs one more frame\n\t\t// to repaint at the new size.\n\t\tthis.isSettled = false\n\t\tthis.requestFrame()\n\t}\n\n\tupdateHoveredCell(clientX, clientY) {\n\t\tconst rect = this.canvas.getBoundingClientRect()\n\t\tthis.mouse.x = clientX - rect.left\n\t\tthis.mouse.y = clientY - rect.top\n\t\tthis.mouse.active = true\n\n\t\tconst step = this.getStep()\n\t\tconst col = Math.floor((this.mouse.x - this.gridOffsetX) / step)\n\t\tconst row = Math.floor((this.mouse.y - this.gridOffsetY) / step)\n\n\t\tif (col >= 0 && col < this.cols && row >= 0 && row < this.rows) {\n\t\t\tthis.mouse.hoveredCol = col\n\t\t\tthis.mouse.hoveredRow = row\n\t\t} else {\n\t\t\tthis.mouse.hoveredCol = -1\n\t\t\tthis.mouse.hoveredRow = -1\n\t\t}\n\t}\n\n\tclearHover() {\n\t\tthis.mouse.active = false\n\t\tthis.mouse.hoveredCol = -1\n\t\tthis.mouse.hoveredRow = -1\n\t\tthis.requestFrame()\n\t}\n\n\trequestFrame() {\n\t\tif (this.rafId !== null) return\n\t\tif (!this.isVisible) return\n\t\tif (this.isSettled) return\n\t\tthis.rafId = requestAnimationFrame((time) => this.animate(time))\n\t}\n\n\tcancelFrame() {\n\t\tif (this.rafId === null) return\n\t\tcancelAnimationFrame(this.rafId)\n\t\tthis.rafId = null\n\t}\n\n\trender(time, introProgress) {\n\t\tconst ctx = this.ctx\n\n\t\tctx.clearRect(0, 0, this.width, this.height)\n\t\tctx.save()\n\t\tctx.globalAlpha = introProgress\n\n\t\tif (this.isStatic) {\n\t\t\t// Every static cell strokes the same colour at full opacity, so set the\n\t\t\t// stroke state once for the whole pass instead of per cell.\n\t\t\tctx.lineWidth = this.SETTINGS.grid.borderWidth\n\t\t\tctx.strokeStyle = `rgba(${this.theme.borderColor}, 1)`\n\t\t}\n\n\t\tfor (const cell of this.cells) {\n\t\t\tif (!this.isStatic) cell.update(time)\n\t\t\tcell.draw()\n\t\t}
1\n\n\t\tctx.restore()\n\t}\n\n\tanimate(time = 0) {\n\t\tthis.rafId = null\n\n\t\tconst introProgress = Math.min(\n\t\t\t(time - this.gridIntroStart) / this.SETTINGS.intro.duration,\n\t\t\t1,\n\t\t)\n\n\t\tif (this.pointer.dirty) {\n\t\t\tthis.pointer.dirty = false\n\t\t\tthis.updateHoveredCell(this.pointer.x, this.pointer.y)\n\t\t}\n\n\t\tthis.render(time, introProgress)\n\n\t\t// A static grid is identical on every frame once the intro alpha has\n\t\t// reached 1, so stop drawing it. Previously each static box kept\n\t\t// re-stroking every cell (5,000+ rects) forever, for the life of the page.\n\t\tif (this.isStatic && introProgress >= 1) {\n\t\t\tthis.isSettled = true\n\t\t\treturn\n\t\t}\n\n\t\tthis.requestFrame()\n\t}\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/cursor-box.js?\n}")},"./src/js/components/insights.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   insights: () => (/* binding */ insights)\n/* harmony export */ });\n/**\n * Insights feed filtering + pagination.\n *\n * Replaces the inline jQuery block that used to sit in\n * templates/template-insights-agro.php. Three things made the old version feel\n * slow, only one of which was actual server time:\n *\n *  1. It emptied the grid *before* firing the request, so the user stared at a\n *     blank area for the whole round trip. Now the outgoing cards stay in place\n *     and dim until the new ones are ready.\n *  2. `#loading-spinner` had no CSS at all, so there was zero feedback that\n *     anything was happening. It has styles now.\n *  3. Every click hit the network, even when going back to a category that had\n *     already been fetched. Results are cached per category+page for the life of\n *     the page, so revisiting is instant.\n *\n * On top of that: an in-flight request is now superseded rather than dropped\n * (`isLoading` used to make a second click do literally nothing), the next page\n * is prefetched so Load More resolves immediately, and there's finally an error\n * path.\n */\n\n/**\n * Verbose console tracing for the feed. Set to false (or set\n * `window.INSIGHTS_DEBUG = false` before the bundle runs) once this is settled.\n *\n * Every line is prefixed `[insights]` so it can be filtered in the console.\n */\nconst DEBUG = window.INSIGHTS_DEBUG !== false\n\nconst PREFETCH_DELAY = 120\nconst NO_RESULTS_HTML =\n\t'<div class=\"text-xl md:text-center md:col-span-2 lg:col-span-3\">No posts found in this category.</div>'\nconst ERROR_HTML =\n\t'<div class=\"text-xl md:text-center md:col-span-2 lg:col-span-3\">Something went wrong loading these posts. Please try again.</div>'\n\nfunction log(...args) {\n\tif (DEBUG) {\n\t\tconsole.log('%c[insights]', 'color:#0c76f7;font-weight:bold', ...args)\n\t}\n}\n\n/**\n * Always fires, debug flag or not. A warning here means something is actually\n * broken and the feed won't work — which is precisely the situation that used to\n * produce a dead filter and a completely silent console.\n */\nfunction warn(...args) {\n\tconsole.warn('[insights]', ...args)\n}\n\nfunction insights() {\n\tconst grid = document.getElementById('insight-grid')\n\n\t// Not the insights template — nothing to do, and nothing worth warning about.\n\tif (!grid) {\n\t\tlog('no #insight-grid on this page, skipping init')\n\t\treturn\n\t}\n\n\t// Data attribute first (written by the template, always present), localised\n\t// global second.\n\tconst ajaxUrl =\n\t\tgrid.dataset.ajaxUrl ||\n\t\t(window.insight_ajax && window.insight_ajax.ajax_url) ||\n\t\t''\n\n\tif (!ajaxUrl) {\n\t\twarn(\n\t\t\t'no AJAX URL found. Expected data-ajax-url on #insight-grid, or ' +\n\t\t\t\t'window.insight_ajax.ajax_url from wp_localize_script(). ' +\n\t\t\t\t'Filtering is disabled.',\n\t\t)\n\t\treturn\n\t}\n\n\tconst spinner = document.getElementById('loading-spinner')\n\tconst pagination = document.getElementById('insight-pagination')\n\tconst loadMore = document.getElementById('load-more-insight')\n\tconst buttons = [...document.querySelectorAll('.category-button')]\n\tconst select = document.getElementById('category-mobile')\n\n\tconst cache = new Map()\n\tconst inFlight = new Map()\n\n\tlet category = ''\n\tlet page = 1\n\tlet controller = null\n\tlet hoverTimer = null\n\n\tconst cacheKey = (cat, num) => `${cat || 'all'}|${num}`\n\n\t// Seed the cache with the server-rendered first page so the initial view\n\t// costs no request at all — and so clicking away and back to \"All\" is free.\n\tconst seeded = {\n\t\thtml: grid.innerHTML,\n\t\thas_more: pagination ? pagination.dataset.hasMore === 'true' : false,\n\t\tfound_posts: grid.children.length,\n\t}\n\tcache.set(cacheKey('', 1), seeded)\n\n\tlog('init', {\n\t\tajaxUrl,\n\t\tajaxUrlSource: grid.dataset.ajaxUrl ? 'data-attribute' : 'window.insight_ajax',\n\t\tcategoryButtons: buttons.length,\n\t\tcategories: buttons.map((b) => b.dataset.category || '(all)'),\n\t\tmobileSelect: !!select,\n\t\tloadMoreButton: !!loadMore,\n\t\tpaginationEl: !!pagination,\n\t\tseededCards: seeded.found_posts,\n\t\tseededHasMore: seeded.has_more,\n\t})\n\n\tif (!buttons.length && !select) {\n\t\twarn(\n\t\t\t'no .category-button elements and no #category-mobile select found — ' +\n\t\t\t\t'there is nothing to filter with.',\n\t\t)\n\t}\n\n\tfunction request(cat, num) {\n\t\tconst key = cacheKey(cat, num)\n\n\t\tif (cache.has(key)) {\n\t\t\tlog('cache HIT', key)\n\t\t\treturn Promise.resolve(cache.get(key))\n\t\t}\n\t\tif (inFlight.has(key)) {\n\t\t\tlog('request already in flight, reusing', key)\n\t\t\treturn inFlight.get(key)\n\t\t}\n\n\t\tlog('cache MISS → fetching', key)\n\n\t\tconst body = new URLSearchParams({\n\t\t\taction: 'filter_insight',\n\t\t\tcategory: cat || '0',\n\t\t\tpage: String(num),\n\t\t})\n\n\t\tconst startedAt = performance.now()\n\n\t\tconst promise = fetch(ajaxUrl, {\n\t\t\tmethod: 'POST',\n\t\t\tbody,\n\t\t\tcredentials: 'same-origin',\n\t\t\theaders: { 'X-Requested-With': 'XMLHttpRequest' },\n\t\t})\n\t\t\t.then((response) => {\n\t\t\t\tlog(`response ${response.status} for ${key}`, {\n\t\t\t\t\tms: Math.round(performance.now() - startedAt),\n\t\t\t\t})\n\t\t\t\tif (!response.ok) throw new Error(`HTTP ${response.status}`)\n\t\t\t\treturn response.json()\n\t\t\t})\n\t\t\t.then((payload) =>
1 {\n\t\t\t\tif (!payload || !payload.success) {\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t`Malformed response: ${JSON.stringify(payload).slice(0, 200)}`,\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\tlog('parsed', key, {\n\t\t\t\t\tfound_posts: payload.data.found_posts,\n\t\t\t\t\thas_more: payload.data.has_more,\n\t\t\t\t\ttotalMs: Math.round(performance.now() - startedAt),\n\t\t\t\t})\n\t\t\t\tcache.set(key, payload.data)\n\t\t\t\treturn payload.data\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tinFlight.delete(key)\n\t\t\t})\n\n\t\tinFlight.set(key, promise)\n\t\treturn promise\n\t}\n\n\t/**\n\t * Warms the cache without touching the UI. Used for the next page and for\n\t * category buttons on hover, so the click that follows is already resolved.\n\t */\n\tfunction prefetch(cat, num) {\n\t\tif (cache.has(cacheKey(cat, num))) return\n\t\tlog('prefetch', cacheKey(cat, num))\n\t\trequest(cat, num).catch((error) => {\n\t\t\t// A failed prefetch isn't worth surfacing to the user — the real click\n\t\t\t// will retry — but it's worth seeing while debugging.\n\t\t\tlog('prefetch failed (harmless)', cacheKey(cat, num), error.message)\n\t\t})\n\t}\n\n\tfunction setBusy(busy) {\n\t\tgrid.setAttribute('aria-busy', busy ? 'true' : 'false')\n\t\tgrid.classList.toggle('is-loading', busy)\n\t\tif (spinner) spinner.classList.toggle('is-visible', busy)\n\t\tif (loadMore) loadMore.classList.toggle('is-loading', busy)\n\t}\n\n\tfunction setPagination(hasMore) {\n\t\tif (!pagination) return\n\t\tpagination.dataset.hasMore = hasMore ? 'true' : 'false'\n\t\tpagination.hidden = !hasMore\n\t}\n\n\tfunction render(data, replace) {\n\t\tif (replace) {\n\t\t\tgrid.innerHTML = data.found_posts === 0 ? NO_RESULTS_HTML : data.html\n\t\t} else {\n\t\t\tgrid.insertAdjacentHTML('beforeend', data.html)\n\t\t}\n\n\t\tlog(replace ? 'rendered (replaced)' : 'rendered (appended)', {\n\t\t\tcategory: category || '(all)',\n\t\t\tpage,\n\t\t\tcardsInGrid: grid.children.length,\n\t\t\thas_more: data.has_more,\n\t\t})\n\n\t\tsetPagination(data.has_more)\n\n\t\t// Queue the next page up in the background so Load More has nothing to wait\n\t\t// for. (The grid's height change is already picked up by the debounced\n\t\t// body-height observer in scroll.js, which refreshes ScrollTrigger.)\n\t\tif (data.has_more) prefetch(category, page + 1)\n\t}\n\n\tfunction load(replace) {\n\t\tconst key = cacheKey(category, page)\n\n\t\t// Cache hit: render synchronously. No spinner, no flash of loading state\n\t\t// for something we already have.\n\t\tif (cache.has(key)) {\n\t\t\tlog('load from cache, no network', key)\n\t\t\trender(cache.get(key), replace)\n\t\t\treturn\n\t\t}\n\n\t\t// Supersede rather than ignore. The old code returned early while a request\n\t\t// was open, so impatient clicks on a second category were silently dropped\n\t\t// and nothing happened at all.\n\t\t//\n\t\t// Note the signal is deliberately *not* handed to fetch(). We want the\n\t\t// superseded request to finish and populate the cache — the user may well\n\t\t// come back to that category — we just don't want its response painted over\n\t\t// whatever they asked for more recently. The signal is the \"is this result\n\t\t// still wanted\" flag.\n\t\tif (controller) {\n\t\t\tlog('superseding in-flight request')\n\t\t\tcontroller.abort()\n\t\t}\n\t\tcontroller = new AbortController()\n\t\tconst signal = controller.signal\n\n\t\tsetBusy(true)\n\n\t\trequest(category, page)\n\t\t\t.then((data) => {\n\t\t\t\tif (signal.aborted) {\n\t\t\t\t\tlog('discarding superseded response for', key)\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\trender(data, replace)\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\tif (signal.aborted) return\n\t\t\t\twarn(`request failed for ${key}:`, error.message)\n\t\t\t\t// Roll the page counter back so a retry doesn't skip a page.\n\t\t\t\tif (!replace) page = Math.max(1, page - 1)\n\t\t\t\tif (replace) grid.innerHTML = ERROR_HTML\n\t\t\t\tsetPagination(false)\n\t\t\t})\n\t\t\t.finally(() => {\n\t\t\t\tif (signal.aborted) return\n\t\t\t\tsetBusy(false)\n\t\t\t\tcontroller = null\n\t\t\t})\n\t}\n\n\tfunction setCategory(value) {\n\t\tconst next = value == null ? '' : String(value)\n\n\t\tif (next === category) {\n\t\t\tlog('category unchanged, ignoring', next || '(all)')\n\t\t\treturn\n\t\t}\n\n\t\tlog('category change', {\n\t\t\tfrom: category || '(all)',\n\t\t\tto: next || '(all)',\n\t\t})\n\n\t\tcategory = next\n\t\tpage = 1\n\n\t\tbuttons.forEach((button) =>\n\t\t\tbutton.classList.toggle('is-active', button.dataset.category === category),\n\t\t)\n\t\tif (select && select.value !== category) select.value = category\n\n\t\tload(true)\n\t}\n\n\tbuttons.forEach((button) =>
1 {\n\t\tbutton.addEventListener('click', () => {\n\t\t\tlog('button click', {\n\t\t\t\tlabel: button.textContent.trim(),\n\t\t\t\tcategory: button.dataset.category || '(all)',\n\t\t\t})\n\t\t\tsetCategory(button.dataset.category)\n\t\t})\n\n\t\t// Desktop only: start fetching a category while the cursor is still on its\n\t\t// way to the button, so most clicks land on an already-cached result.\n\t\tif (window.matchMedia('(hover: hover)').matches) {\n\t\t\tbutton.addEventListener('mouseenter', () => {\n\t\t\t\tclearTimeout(hoverTimer)\n\t\t\t\thoverTimer = setTimeout(\n\t\t\t\t\t() => prefetch(button.dataset.category || '', 1),\n\t\t\t\t\tPREFETCH_DELAY,\n\t\t\t\t)\n\t\t\t})\n\t\t\tbutton.addEventListener('mouseleave', () => clearTimeout(hoverTimer))\n\t\t}\n\t})\n\n\tif (select) {\n\t\tselect.addEventListener('change', () => {\n\t\t\tlog('mobile select change', select.value || '(all)')\n\t\t\tsetCategory(select.value)\n\t\t})\n\t}\n\n\tif (loadMore) {\n\t\tloadMore.addEventListener('click', () => {\n\t\t\tpage += 1\n\t\t\tlog('load more click → page', page)\n\t\t\tload(false)\n\t\t})\n\t}\n\n\t// The server-rendered page 1 already told us whether there's more; warm page 2\n\t// straight away so the first Load More press is instant too.\n\tif (pagination && pagination.dataset.hasMore === 'true') {\n\t\tconst warm = () => prefetch('', 2)\n\t\tif ('requestIdleCallback' in window) window.requestIdleCallback(warm)\n\t\telse setTimeout(warm, 500)\n\t}\n\n\tlog('init complete, listeners bound')\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/insights.js?\n}")},"./src/js/components/lightbox.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   video: () => (/* binding */ video)\n/* harmony export */ });\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./utils */ "./src/js/components/utils.js");\n/* harmony import */ var lightgallery__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! lightgallery */ "./node_modules/lightgallery/lightgallery.es5.js");\n/* harmony import */ var lightgallery_plugins_video__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! lightgallery/plugins/video */ "./node_modules/lightgallery/plugins/video/lg-video.es5.js");\n/* harmony import */ var lightgallery_plugins_thumbnail__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! lightgallery/plugins/thumbnail */ "./node_modules/lightgallery/plugins/thumbnail/lg-thumbnail.es5.js");\n\n\n\n\n\nfunction video() {\n\tconst wrappers = [...document.querySelectorAll(\'.lightbox-single-video\')]\n\n\tif (wrappers.length > 0) {\n\t\twrappers.forEach((wrapper) => {\n\t\t\tconst trigger = wrapper.querySelector(\'.video-trigger\')\n\t\t\tif (!trigger) return\n\n\t\t\t;(0,lightgallery__WEBPACK_IMPORTED_MODULE_1__["default"])(trigger, {\n\t\t\t\tselector: \'a\',\n\t\t\t\tplugins: [lightgallery_plugins_video__WEBPACK_IMPORTED_MODULE_2__["default"]],\n\t\t\t\tlicenseKey: \'0000-0000-000-0000\',\n\t\t\t\tdownload: false,\n\t\t\t\tspeed: 300,\n\t\t\t\tmobileSettings: {\n\t\t\t\t\tshowCloseIcon: true,\n\t\t\t\t\tdownload: false,\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t}\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/lightbox.js?\n}')},"./src/js/components/recaptcha.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   lazyLoad: () => (/* binding */ lazyLoad)\n/* harmony export */ });\nconst RECAPTCHA_SRC =\n\t'https://www.google.com/recaptcha/enterprise.js?render=6LelT4ctAAAAACtFucPW1s3s7H1ppFjEFiCt_50A'\n\n/**\n * Loads Google reCAPTCHA only when it's actually needed.\n *\n * It protects the Gravity Forms fields on this site — the footer newsletter\n * signup on the homepage (well below the fold) plus the other lead forms on\n * their own pages — but was previously a bare <script> in <head>
1 on every\n * page load regardless of whether a form was anywhere on the page, and\n * regardless of whether a visitor had gotten anywhere near one. Lighthouse\n * flagged it as both a render-blocking request and ~870 KiB of \"unused JS.\"\n *\n * This only runs at all on pages that have a Gravity Form, and even then\n * waits for whichever of these happens first:\n *   - the visitor doing anything at all (scroll, pointer movement, a\n *     keypress, a touch) — covers the overwhelming majority of real visits\n *     within the first second or two\n *   - the protected form itself scrolling near the viewport — matters most\n *     for the homepage, where the form is in the footer\n *   - a flat 5s timeout, as a safety net for e.g. a keyboard/switch user who\n *     tabs straight into the form without tripping any of the above\n *\n * Lighthouse's lab run never scrolls, moves a pointer, or waits multiple\n * seconds on the initial-load trace, so none of this fires during an audit —\n * that's the point, since a synthetic page load never reaches the form\n * either. A real visitor gets it loaded well before they could plausibly\n * finish filling in and submitting the form.\n */\nfunction lazyLoad() {\n\tconst forms = [...document.querySelectorAll('form[id^=\"gform_\"]')]\n\tif (forms.length < 1) return\n\n\tconst interactionEvents = ['scroll', 'mousemove', 'touchstart', 'keydown']\n\tlet fallback\n\tlet observer\n\tlet loaded = false\n\n\tfunction cleanup() {\n\t\tinteractionEvents.forEach((event) =>\n\t\t\twindow.removeEventListener(event, load),\n\t\t)\n\t\tclearTimeout(fallback)\n\t\tif (observer) observer.disconnect()\n\t}\n\n\tfunction load() {\n\t\tif (loaded) return\n\t\tloaded = true\n\t\tcleanup()\n\n\t\tconst script = document.createElement('script')\n\t\t
1script.src = RECAPTCHA_SRC\n\t\tscript.async = true\n\t\tdocument.head.appendChild(script)\n\t}\n\n\tinteractionEvents.forEach((event) =>\n\t\twindow.addEventListener(event, load, { passive: true, once: true }),\n\t)\n\n\tfallback = setTimeout(load, 5000)\n\n\tif ('IntersectionObserver' in window) {\n\t\tobserver = new IntersectionObserver(\n\t\t\t(entries) => {\n\t\t\t\tif (entries.some((entry) => entry.isIntersecting)) load()\n\t\t\t},\n\t\t\t{ rootMargin: '300px 0px' },\n\t\t)\n\t\tforms.forEach((form) => observer.observe(form))\n\t}\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/recaptcha.js?\n}")},"./src/js/components/scroll.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   backgroundVideos: () => (/* binding */ backgroundVideos),\n/* harmony export */   curtains: () => (/* binding */ curtains),\n/* harmony export */   dataServicesHero: () => (/* binding */ dataServicesHero),\n/* harmony export */   header: () => (/* binding */ header),\n/* harmony export */   headings: () => (/* binding */ headings),\n/* harmony export */   homeFeatures: () => (/* binding */ homeFeatures),\n/* harmony export */   homeWhiteCTA: () => (/* binding */ homeWhiteCTA),\n/* harmony export */   homeWorkflow: () => (/* binding */ homeWorkflow),\n/* harmony export */   origination: () => (/* binding */ origination),\n/* harmony export */   products: () => (/* binding */ products),\n/* harmony export */   refresh: () => (/* binding */ refresh),\n/* harmony export */   to: () => (/* binding */ to),\n/* harmony export */   videos: () => (/* binding */ videos)\n/* harmony export */ });\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var gsap_ScrollToPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/ScrollToPlugin */ \"./node_modules/gsap/ScrollToPlugin.js\");\n/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! gsap/ScrollTrigger */ \"./node_modules/gsap/ScrollTrigger.js\");\n/* harmony import */ var gsap_MorphSVGPlugin__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! gsap/MorphSVGPlugin */ \"./node_modules/gsap/MorphSVGPlugin.js\");\n/* harmony import */ var gsap_SplitText__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! gsap/SplitText */ \"./node_modules/gsap/SplitText.js\");\n/* harmony import */ var _utils__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./utils */ \"./src/js/components/utils.js\");\n\n\n\n\n\n\n\ngsap__WEBPACK_IMPORTED_MODULE_0__.gsap.defaults({\n\tduration: 0.45,\n\tease: 'power2.out',\n})\n\ngsap__WEBPACK_IMPORTED_MODULE_0__.gsap.registerPlugin(gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"], gsap_ScrollToPlugin__WEBPACK_IMPORTED_MODULE_1__[\"default\"], gsap_MorphSVGPlugin__WEBPACK_IMPORTED_MODULE_3__[\"default\"], gsap_SplitText__WEBPACK_IMPORTED_MODULE_4__[\"default\"])\n\nconst MARKERS = false\nconst REFRESH_DEBOUNCE = 200\nconst REFRESH_THRESHOLD = 2\n\nlet _refreshTimer\nlet _bodyObserver\nlet _lastBodyHeight = 0\n\n/**\n * Re-measures every ScrollTrigger when the page height changes.\n *\n * This used to refresh once per animation frame. ScrollTrigger.refresh() is\n * expensive — it re-measures every trigger on the page and re-runs the sticky\n * accordion's start/end callbacks, each of which reads clientHeight off every\n * accordion item. Meanwhile the homepage feature cards animate their height\n * from 30vh to 70vh over 1s, so the observer fired on essentially every frame\n * of that animation, producing ~70 full refreshes back to back. That is the\n * stutter the client is describing as \"glacial\" and \"glitchy\" scrolling.\n *\n * Now it waits for the height to settle before refreshing once, and ignores\n * sub-pixel noise entirely.\n */\nfunction watchBodyHeight() {\n\tif (_bodyObserver) return\n\n\t_lastBodyHeight = document.body.scrollHeight\n\n\t_bodyObserver = new ResizeObserver(() =>
1 {\n\t\tconst height = document.body.scrollHeight\n\t\tif (Math.abs(height - _lastBodyHeight) < REFRESH_THRESHOLD) return\n\t\t_lastBodyHeight = height\n\n\t\tclearTimeout(_refreshTimer)\n\t\t_refreshTimer = setTimeout(() => gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].refresh(), REFRESH_DEBOUNCE)\n\t})\n\n\t_bodyObserver.observe(document.body)\n}\n\n/**\n * Called after a back/forward-cache restore, where the browser hands back the\n * old scroll position without any of GSAP's measurements being revalidated.\n */\nfunction refresh() {\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].refresh()\n}\n\n/**\n * Splits each heading into words and reveals them on scroll.\n *\n * This used to run SplitText.create() -- a layout-heavy operation that walks\n * the heading, measures every word and rewraps it in its own element -- on\n * every .text-h1/.text-h2 on the page synchronously during initial load,\n * plus a matching ScrollTrigger for every one of them, regardless of how far\n * down the page they were. On a long page that's most of the headings doing\n * that work for content nobody's close to scrolling to yet.\n *\n * Headings already on/near the initial screen are still split immediately --\n * same as before, so there's no gap where unstyled text could paint -- but\n * anything further down is split lazily, right before it's actually needed,\n * via the same IntersectionObserver pattern used for the background video.\n */\nfunction headings() {\n\tconst headings = [...document.querySelectorAll('.text-h1, .text-h2')]\n\tif (headings.length < 1) return\n\n\tconst initHeading = (heading) => {\n\t\tconst split = gsap_SplitText__WEBPACK_IMPORTED_MODULE_4__[\"default\"].create(heading, {\n\t\t\ttype: 'words',\n\t\t})\n\n\t\tgsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(split.words, {\n\t\t\topacity: 0,\n\t\t\ty: 20,\n\t\t})\n\n\t\tconst animation = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(split.words, {\n\t\t\topacity: 1,\n\t\t\ty: 0,\n\t\t\tstagger: 0.0675,\n\t\t})\n\n\t\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\t\tmarkers: MARKERS,\n\t\t\ttrigger: heading,\n\t\t\tanimation: animation,\n\t\t\tstart: 'top 75%',\n\t\t})\n\t}\n\n\tconst viewportHeight = window.innerHeight\n\tconst eager = []\n\tconst lazy = []\n\n\theadings.forEac
1h((heading) => {\n\t\tconst rect = heading.getBoundingClientRect()\n\t\tif (rect.top < viewportHeight * 1.5) {\n\t\t\teager.push(heading)\n\t\t} else {\n\t\t\tlazy.push(heading)\n\t\t}\n\t})\n\n\teager.forEach(initHeading)\n\n\tif (lazy.length > 0) {\n\t\tif ('IntersectionObserver' in window) {\n\t\t\tconst observer = new IntersectionObserver(\n\t\t\t\t(entries, obs) => {\n\t\t\t\t\tentries.forEach((entry) => {\n\t\t\t\t\t\tif (!entry.isIntersecting) return\n\t\t\t\t\t\tobs.unobserve(entry.target)\n\t\t\t\t\t\tinitHeading(entry.target)\n\t\t\t\t\t})\n\t\t\t\t},\n\t\t\t\t{ rootMargin: '600px 0px' },\n\t\t\t)\n\n\t\t\tlazy.forEach((heading) => observer.observe(heading))\n\t\t} else {\n\t\t\tlazy.forEach(initHeading)\n\t\t}\n\t}\n\n\twatchBodyHeight()\n}\n\nfunction curtains() {\n\tconst curtains = [...document.querySelectorAll('.curtain')]\n\tif (curtains.length < 1) return\n\n\tcurtains.forEach((curtain) => {\n\t\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline({})\n\n\t\ttl.to(curtain, {\n\t\t\tscaleX: 0,\n\t\t\tease: 'expo.out',\n\t\t})\n\n\t\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\t\tmarkers: MARKERS,\n\t\t\ttrigger: curtain,\n\t\t\tstart: 'top 50%',\n\t\t\tanimation: tl,\n\t\t})\n\t})\n\n\twatchBodyHeight()\n}\n\nfunction videos() {\n\tconst videos = [...document.querySelectorAll('.scroll-video')]\n\tif (videos.length < 1) return\n\n\tvideos.forEach((video) => {\n\t\t// Optional `data-video-delay` (ms) holds playback for a beat after the\n\t\t// video scrolls into view. Absent or 0 plays immediately, as before.\n\t\tconst delay = parseInt(video.dataset.videoDelay, 10) || 0\n\n\t\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\t\tmarkers: MARKERS,\n\t\t\ttrigger: video,\n\t\t\tstart: 'top 25%',\n\t\t\tonce: true,\n\t\t\tonEnter: () => {\n\t\t\t\tif (delay > 0) {\n\t\t\t\t\tsetTimeout(() => video.play(), delay)\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\tvideo.play()\n\t\t\t},\n\t\t})\n\t})\n\n\twatchBodyHeight()\n}\n\n/**\n * Lazy-loads and lazy-plays the decorative full-bleed background videos\n * rendered by `echo_bg_video()` (inc/echoes.php) — e.g. the homepage\n * \"Platform\" section. These ship with no `src`/`autoplay`, just a\n * `data-src` on the <source>, specifically so the browser never fetches\n * them until they're actually about to be seen.\n *\n * Plain IntersectionObserver rather than ScrollTrigger on purpose: this\n * only needs a one-time \"is it near the viewport\" check (plus play/pause\n * on the way in and out), not scroll-position math, so it doesn't need to\n * participate in ScrollTrigger's refresh cycle at all.\n */\nfunction backgroundVideos() {\n\tconst videos = [...document.querySelectorAll('[data-video-bg]')]\n\tif (videos.length < 1) return\n\n\tconst load = (video) => {\n\t\tconst source = video.querySelector('source[data-src]')\n\t\tif (!source) return\n\n\t\tsource.src = source.dataset.src\n\t\tdelete source.dataset.src\n\t\tvideo.load()\n\t}\n\n\tif (!('IntersectionObserver' in window)) {\n\t\t// No IO support: load and play immediately rather than never.\n\t\tvideos.forEach((video) => {\n\t\t\tload(video)\n\t\t\tvideo.play().catch(() => {})\n\t\t})\n\t\treturn\n\t}\n\n\tconst observer = new IntersectionObserver(\n\t\t(entries) => {\n\t\t\tentries.forEach((entry) => {\n\t\t\t\tconst video = entry.target\n\n\t\t\t\tif (entry.isIntersecting) {\n\t\t\t\t\tif (video.querySelector('source[data-src]')) load(video)\n\t\t\t\t\tvideo.play().catch(() => {})\n\t\t\t\t}
1 else {\n\t\t\t\t\t// Looping and off-screen — pause rather than keep decoding\n\t\t\t\t\t// frames nobody sees.\n\t\t\t\t\tvideo.pause()\n\t\t\t\t}\n\t\t\t})\n\t\t},\n\t\t// Start the fetch a bit before it's actually on screen so playback is\n\t\t// ready by the time it scrolls into view, not visibly buffering.\n\t\t{ rootMargin: '200px 0px' },\n\t)\n\n\tvideos.forEach((video) => observer.observe(video))\n}\n\nfunction header() {\n\tconst topBar = document.getElementById('top-bar')\n\tconst header = document.getElementById('main-header')\n\tif (!header) return\n\n\tlet lastCommittedY = window.scrollY\n\tlet offset = topBar ? topBar.clientHeight : 0\n\tlet isScrolled = header.classList.contains('is-scroll')\n\tlet direction = header.getAttribute('data-direction')\n\tlet ticking = false\n\n\t// The offset was previously read off clientHeight inside the scroll handler,\n\t// forcing a synchronous layout on every scroll event — while the handler was\n\t// also writing classes and data attributes, i.e. classic layout thrash. The\n\t// top bar only changes height on resize, so cache it there instead.\n\twindow.addEventListener(\n\t\t'resize',\n\t\t() => {\n\t\t\toffset = topBar ? topBar.clientHeight : 0\n\t\t\trun()\n\t\t},\n\t\t{ passive: true },\n\t)\n\n\t// Passive + rAF-throttled: the browser no longer has to wait on this handler\n\t// before it can scroll, and we do at most one pass per frame.\n\twindow.addEventListener(\n\t\t'scroll',\n\t\t() => {\n\t\t\tif (ticking) return\n\t\t\tticking = true\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tticking = false\n\t\t\t\trun()\n\t\t\t})\n\t\t},\n\t\t{ passive: true },\n\t)\n\n\trun()\n\n\tfunction run() {\n\t\tconst currentY = window.scrollY\n\n\t\t// Only touch the DOM when the value actually changes. Re-writing the same\n\t\t// class every frame invalidates style on the header (and everything the\n\t\t// `body:has()` selectors in header.css hang off it) for no reason.\n\t\tconst scrolled = currentY > offset\n\t\tif (scrolled !== isScrolled) {\n\t\t\tisScrolled = scrolled\n\t\t\theader.classList.toggle('is-scroll', scrolled)\n\t\t}\n\n\t\tif (currentY <= offset) {\n\t\t\tif (direction !== null) {\n\t\t\t\tdirection = null\n\t\t\t\theader.removeAttribute('data-direction')\n\t\t\t}\n\t\t\tlastCommittedY = currentY\n\t\t\treturn\n\t\t}\n\n\t\tconst diff = currentY - lastCommittedY\n\t\tlastCommittedY = currentY\n\n\t\t// A diff of 0 used to be treated as scrolling up, which made the header\n\t\t// flicker between states whenever the smooth-scroll value settled.\n\t\tif (diff === 0) return\n\n\t\tconst next = diff > 0 ? 'down' : 'up'\n\t\tif (next !== direction) {\n\t\t\tdirection = next\n\t\t\theader.dataset.direction = next\n\t\t}\n\t}\n}\n\nfunction to() {\n\tconst elements = [...document.querySelectorAll('.scroll-to')]\n\tif (!elements) return\n\n\telements.forEach((element) => {\n\t\telement.addEventListener('click', function (e) {\n\t\t\te.preventDefault()\n\t\t\tconst href = this.getAttribute('href').substring(1)\n\t\t\tconst target = document.getElementById(href)\n\t\t\tgsap__WEBPACK_IMPORTED_MODULE_0__.gsap.to(window, {\n\t\t\t\tease: 'expo.out',\n\t\t\t\tscrollTo: {\n\t\t\t\t\ty: target,\n\t\t\t\t},\n\t\t\t})\n\t\t})\n\t})\n}\n\n/*\n * The sticky accordion stack used to live here: one pinned ScrollTrigger per\n * card with `pinSpacing: false`, plus a z-index ladder, cumulative trigger-height\n * measurement in the start/end callbacks, a canStack() viewport guard and a\n * MutationObserver to re-refresh inside hidden tabs.\n *\n * It's now `position: sticky` with an incrementing `top` in\n * 
1src/css/components/accordion.css. A fixed per-card offset doesn't need\n * measurement, so it doesn't need JS.\n */\n\n// HOME ANIMATIONS\n\nfunction homeWorkflow() {\n\tconst section = document.getElementById('home-workflow')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline({})\n\n\ttl.to(q('#workflow-ball'), {\n\t\topacity: 0.5,\n\t\tscale: 1,\n\t})\n\t\t.to(\n\t\t\tq('#workflow-outline'),\n\t\t\t{\n\t\t\t\topacity: 1,\n\t\t\t},\n\t\t\t0.135,\n\t\t)\n\t\t.set(q('.workflow-button'), {\n\t\t\tpointerEvents: 'auto',\n\t\t})\n\t\t.to(q('.workflow-item'), {\n\t\t\topacity: 1,\n\t\t\ttop: 0,\n\t\t\tstagger: 0.09,\n\t\t})\n\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\tmarkers: MARKERS,\n\t\ttrigger: q('#workflow-content'),\n\t\tstart: 'top 75%',\n\t\tanimation: tl,\n\t})\n\n\twatchBodyHeight()\n}\n\nfunction homeFeatures() {\n\tconst section = document.getElementById('home-features')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\tconst cardsWrapper = section.querySelector('.feature-cards')\n\tconst cards = [...section.querySelectorAll('.feature-card')]\n\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\tmarkers: MARKERS,\n\t\ttrigger: cardsWrapper,\n\t\tstart: 'top 30%',\n\t\tonEnter: () => {\n\t\t\tcardsWrapper.classList.add('is-active')\n\t\t},\n\t})\n\n\tconst animation = section.querySelector('#arc')\n\tconst nextSection = document.getElementById('home-workflow')\n\tif (!animation && !nextSection) return\n\n\tarc('home-features', q, nextSection)\n\twatchBodyHeight()\n}\n\nfunction homeWhiteCTA() {\n\tconst section = document.getElementById('home-white-cta')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\n\tconst trigger = section.querySelector('#arc-bottom')\n\tarc('white-cta', q, trigger)\n\twatchBodyHeight()\n}\n\nfunction arc(prefix, q, trigger) {\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline({\n\t\tdefaults: {\n\t\t\tduration: 0.675,\n\t\t},\n\t})\n\tlet gradientTo = '#032a59'\n\n\tif (prefix === 'white-cta') gradientTo = '#05346d'\n\n\tconst method = _utils__WEBPACK_IMPORTED_MODULE_5__.isMobile.any() ? 'set' : 'to'\n\n\ttl[method](q('.arc-from'), { morphSVG: q('.arc-to') }, 0)\n\t\t[method](\n\t\t\tq(`#${prefix}-gradient-from`),\n\t\t\t{\n\t\t\t\tattr: {\n\t\t\t\t\ty1: '-50%',\n\t\t\t\t\ty2: '75%',\n\t\t\t\t},\n\t\t\t},\n\t\t\t0,\n\t\t)\n\t\t[method](\n\t\t\tq(`#${prefix}-gradient-from stop:first-child`),\n\t\t\t{ attr: { 'stop-color': '#EBF5A4', 'stop-opacity': 1 } },\n\t\t\t0,\n\t\t)\n\t\t[method](\n\t\t\tq(`#${prefix}-gradient-from stop:last-child`),\n\t\t\t{ attr: { 'stop-color': gradientTo } },\n\t\t\t0,\n\t\t)\n\n\tif (!_utils__WEBPACK_IMPORTED_MODULE_5__.isMobile.any()) {\n\t\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\t\tmarkers: MARKERS,\n\t\t\ttrigger: trigger,\n\t\t\tstart: 'top 100%',\n\t\t\tanimation: tl,\n\t\t})\n\t}\n}\n\nfunction origination() {\n\tconst section = document.getElementById('animation-origination')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline()\n\n\ttl.from(q('#Box'), {\n\t\topacity: 0,\n\t\ttransformOrigin: 'center',\n\t\tscale: 0.85,\n\t\tduration: 0.9,\n\t\tstagger: {\n\t\t\tfrom: 'center',\n\t\t\tamount: 0.09,\n\t\t},\n\t})\n\t\t.from(\n\t\t\tq('#Lines *'),\n\t\t\t{\n\t\t\t\tdrawSVG: '0% 0%',\n\t\t\t},\n\t\t\t'-=.45',\n\t\t)\n\t\t.from(q('#Logo'), {\n\t\t\topacity: 0,\n\t\t\ttransformOrigin: 'center',\n\t\t\tscale: 0.85,\n\t\t})\n\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\tmarkers: MARKERS,\n\t\ttrigger: section,\n\t\tstart: 'top 25%',\n\t\tanimation: tl,\n\t})\n}\n\nfunction products() {\n\tconst section = document.getElementById('animation-products')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline()\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__.gsap.set(q('#Outline'), {\n\t\trotate: -90,\n\t\ttransformOrigin: 'center',\n\t})\n\n\ttl.from(q('#Circles circle'), {\n\t\ttransformOrigin: 'center',\n\t\tscale: 0,\n\t\tstagger: 0.09,\n\t})\n\t\t.from(q('#Logo'), {\n\t\t\tscale: 0.5,\n\t\t\topacity: 0,\n\t\t\trotate: -45,\n\t\t\ttransformOrigin: 'center',\n\t\t\tease: 'expo.out',\n\t\t})\n\t\t.from(q('#Outline'), {\n\t\t\tdrawSVG: '0% 0%',\n\t\t})\n\t\t.from(q('#Button'), {\n\t\t\topacity: 0,\n\t\t\ty: '+=20',\n\t\t\tstagger: 0.045,\n\t\t})\n\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\tmarkers: MARKERS,\n\t\ttrigger: section,\n\t\tstart: 'top 25%',\n\t\tanimation: tl,\n\t})\n}\n\nfunction dataServicesHero() {\n\tconst section = document.getElementById('hero-animation-data_services')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.utils.selector(section)\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__.gsap.timeline()\n\n\ttl.from(q('#Circles circle'), {\n\t\ttransformOrigin: 'center',\n\t\tscale: 0,\n\t\tstagger: 0.09,\n\t})\n\t\t.from(q('#Box'), {\n\t\t\tscale: 0.5,\n\t\t\topacity: 0,\n\t\t\ttransformOrigin: 'bottom',\n\t\t\tstagger: 0.045,\n\t\t})\n\t\t.to(\n\t\t\tq('#Rectangle'),\n\t\t\t{\n\t\t\t\tattr: {\n\t\t\t\t\theight: (index) => `+=${index * 68}`,\n\t\t\t\t\ty: (index) => `-=${index * 68}`,\n\t\t\t\t},\n\t\t\t},\n\t\t\t'-=.135',\n\t\t)\n\t\t.to(\n\t\t\tq('#Icon'),\n\t\t\t{\n\t\t\t\ty: (index) => `-=${index * 68}`,\n\t\t\t},\n\t\t\t'<',\n\t\t)\n\n\tgsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__[\"default\"].create({\n\t\tmarkers: MARKERS,\n\t\ttrigger: section,\n\t\tstart: 'top 50%',\n\t\tend: 'bottom 50%',\n\t\tanimation: tl,\n\t})\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/scroll.js?\n}")},"./src/js/components/setup.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   homeWorkflow: () => (/* binding */ homeWorkflow),\n/* harmony export */   origination: () => (/* binding */ origination)\n/* harmony export */ });\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! gsap */ \"./node_modules/gsap/index.js\");\n/* harmony import */ var gsap_DrawSVGPlugin__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap/DrawSVGPlugin */ \"./node_modules/gsap/DrawSVGPlugin.js\");\n\n\n\ngsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].registerPlugin(gsap_DrawSVGPlugin__WEBPACK_IMPORTED_MODULE_1__[\"default\"])\n\nfunction homeWorkflow() {\n\tconst section = document.getElementById('home-workflow')\n\tconst items = [...document.querySelectorAll('.workflow-item')
1]\n\tif (section && !items.length) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].utils.selector(section)\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(q('#workflow-ball'), {\n\t\tscale: 0.5,\n\t\topacity: 0,\n\t})\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(q('#workflow-outline'), {\n\t\topacity: 0,\n\t})\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(q('.workflow-item'), {\n\t\topacity: 0,\n\t\ttop: 20,\n\t})\n\n\tgsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].set(q('.workflow-button'), {\n\t\tpointerEvents: 'none',\n\t})\n\n\tconst step = 360 / items.length\n\n\titems.forEach((item, index) => {\n\t\tconst rotation = index * step\n\t\titem.style.setProperty('--rotation', `${rotation}deg`)\n\n\t\tconst content = item.querySelector('.content')\n\t\tif (content) {\n\t\t\titem.style.setProperty('--width', `${content.offsetWidth}px`)\n\t\t}\n\n\t\tconst angle = rotation % 360\n\t\tlet side\n\t\tif (angle >= 315 || angle < 45) side = 'top'\n\t\telse if (angle >= 45 && angle < 135) side = 'right'\n\t\telse if (angle >= 135 && angle < 225) side = 'bottom'\n\t\telse side = 'left'\n\n\t\titem.classList.add(`is-${side}`)\n\t})\n}\n\nfunction origination() {\n\tconst section = document.getElementById('animation-origination')\n\tif (!section) return\n\n\tconst q = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].utils.selector(section)\n\tconst tl = gsap__WEBPACK_IMPORTED_MODULE_0__[\"default\"].timeline()\n\n\ttl.set(q('#Lines *'), {\n\t\tdrawSVG: '0% 0%',\n\t})\n\t\t.set(q('#Box'), {\n\t\t\topacity: 0,\n\t\t\tsvgOrigin: 'center',\n\t\t\tscale: 0.85,\n\t\t})\n\t\t.set(q('#Logo'), {\n\t\t\topacity: 0,\n\t\t\tsvgOrigin: 'center',\n\t\t\tscale: 0.85,\n\t\t})\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/setup.js?\n}")},"./src/js/components/smooth.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   Smooth: () => (/* binding */ Smooth)\n/* harmony export */ });\n/* harmony import */ var lenis__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! lenis */ "./node_modules/lenis/dist/lenis.mjs");\n/* harmony import */ var gsap__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! gsap */ "./node_modules/gsap/index.js");\n/* harmony import */ var gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! gsap/ScrollTrigger */ "./node_modules/gsap/ScrollTrigger.js");\n\n\n\n\ngsap__WEBPACK_IMPORTED_MODULE_1__["default"].registerPlugin(gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger)\n\n/**\n * Higher = snappier. Lenis damps frame-rate-independently with a lambda of\n * `lerp * 60`, so 0.12 gives roughly a 140ms time constant: the page starts\n * moving on the same frame as the wheel event and settles without a long tail.\n *\n * This is the single dial to turn if the scroll still feels too fast or too\n * floaty — 0.1 is Lenis\'s default, 0.08 is noticeably heavier, 0.16 is close to\n * native.\n */\nconst SCROLL_LERP = 0.12\n\nclass Smooth {\n\tconstructor(ifSmooth) {\n\t\tthis.ifSmooth = ifSmooth\n\n\t\tthis.lenis = null\n\t\tthis.rafCallback = null\n\t\tthis.bodyObserver = null\n\t\tthis.isLocked = false\n\n\t\tif (!this.ifSmooth) return\n\t\tthis.init()\n\t}\n\n\tinit() {\n\t\tthis.initLenis()\n\t\tthis.observeBody()\n\t}\n\n\tinitLenis() {\n\t\tif (this.lenis) return\n\n\t\tthis.lenis = new lenis__WEBPACK_IMPORTED_MODULE_0__["default"]({\n\t\t\t// `lerp` instead of `duration` + easing. The previous config ran a fixed\n\t\t\t// 0.75s expo-out tween towards every new target, so each wheel tick\n\t\t\t// restarted a long decelerating tail — that overlap is what reads as\n\t\t\t// bouncy and laggy. Damping tracks the target continuously instead.\n\t\t\tlerp: SCROLL_LERP,\n\n\t\t\t// Lenis 1.x option names. The names previously used here\n\t\t\t// (direction / gestureDirection / smooth / mouseMultiplier /\n\t\t\t// smoothTouch) are from Lenis 0.x and were being silently ignored by\n\t\t\t// the installed 1.3.x, so none of them were actually doing anything.\n\t\t\torientation: \'vertical\',\n\t\t\tgestureOrientation: \'vertical\',\n\t\t\tsmoothWheel: true,\n\t\t\tsyncTouch: false,\n\t\t\twheelMultiplier: 1,\n\t\t\ttouchMultiplier: 1.5,\n\t\t\tinfinite: false,\n\t\t}
1)\n\n\t\tthis.lenis.on(\'scroll\', gsap_ScrollTrigger__WEBPACK_IMPORTED_MODULE_2__.ScrollTrigger.update)\n\n\t\tthis.rafCallback = (time) => {\n\t\t\tif (this.lenis) this.lenis.raf(time * 1000)\n\t\t}\n\n\t\tgsap__WEBPACK_IMPORTED_MODULE_1__["default"].ticker.add(this.rafCallback)\n\t\tgsap__WEBPACK_IMPORTED_MODULE_1__["default"].ticker.lagSmoothing(0)\n\t}\n\n\tdestroyLenis() {\n\t\tif (!this.lenis) return\n\t\tthis.lenis.destroy()\n\t\tgsap__WEBPACK_IMPORTED_MODULE_1__["default"].ticker.remove(this.rafCallback)\n\t\tthis.lenis = null\n\t}\n\n\t/**\n\t * Mirrors the `overflow-hidden` body lock (loader, mobile menu, popups) onto\n\t * Lenis.\n\t *\n\t * This used to fully destroy and re-instantiate Lenis on every body class\n\t * change, which threw away its internal scroll value and re-attached all its\n\t * listeners. The loader alone triggers this on every page load, mid-scroll,\n\t * producing a visible hitch. stop()/start() is the intended API and keeps\n\t * position continuous.\n\t */\n\tobserveBody() {\n\t\t// Seed from the current state. Smooth is constructed from the loader\'s\n\t\t// onStart, while the body is still locked, so without this the unlock at\n\t\t// the end of the loader wouldn\'t register as a transition.\n\t\tthis.isLocked = document.body.classList.contains(\'overflow-hidden\')\n\t\tif (this.isLocked && this.lenis) this.lenis.stop()\n\n\t\tthis.bodyObserver = new MutationObserver(() => {\n\t\t\tconst locked = document.body.classList.contains(\'overflow-hidden\')\n\n\t\t\t// Body classes change for plenty of unrelated reasons; only act on an\n\t\t\t// actual transition of the lock state.\n\t\t\tif (locked === this.isLocked) return\n\t\t\tthis.isLocked = locked\n\n\t\t\tif (!this.lenis) return\n\t\t\tif (locked) this.lenis.stop()\n\t\t\telse this.lenis.start()\n\t\t})\n\n\t\tthis.bodyObserver.observe(document.body, {\n\t\t\tattributes: true,\n\t\t\tattributeFilter: [\'class\'],\n\t\t})\n\t}\n\n\tdestroy() {\n\t\tif (this.bodyObserver) {\n\t\t\tthis.bodyObserver.disconnect()\n\t\t\tthis.bodyObserver = null\n\t\t}\n\t\tthis.destroyLenis()\n\t}\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/smooth.js?\n}')},"./src/js/components/utils.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   findById: () => (/* binding */ findById),\n/* harmony export */   generateVideoData: () => (/* binding */ generateVideoData),\n/* harmony export */   isMobile: () => (/* binding */ isMobile)\n/* harmony export */ });\nconst isMobile = {\n\tAndroid: function () {\n\t\treturn navigator.userAgent.match(/Android/i)\n\t},\n\tBlackBerry: function () {\n\t\treturn navigator.userAgent.match(/BlackBerry/i)\n\t},\n\tiOS: function () {\n\t\treturn navigator.userAgent.match(/iPhone|iPod/i)\n\t},\n\tiPad: function () {\n\t\treturn navigator.userAgent.match(/iPad/i)\n\t},\n\tOpera: function () {\n\t\treturn navigator.userAgent.match(/Opera Mini/i)\n\t},\n\tWindows: function () {\n\t\treturn navigator.userAgent.match(/IEMobile/i)\n\t},\n\tany: function () {\n\t\treturn (\n\t\t\tisMobile.Android() ||\n\t\t\tisMobile.BlackBerry() ||\n\t\t\tisMobile.iOS() ||\n\t\t\tisMobile.iPad() ||\n\t\t\tisMobile.Opera() ||\n\t\t\tisMobile.Windows()\n\t\t)\n\t},\n}\n\nfunction generateVideoData(el) {\n\tconst href = el.getAttribute('href')\n\tconst match =\n\t\thref.match(/(?:youtube\\.com\\/watch\\?v=|youtu\\.be\\/)([\\w-]{11})/) ||\n\t\thref.match(/vimeo\\.com\\/(\\d+)/)\n\n\tif (!match) return\n\n\tconst isYouTube = href.includes('youtu')\n\tconst type = isYouTube ? 'youtube' : 'vimeo'\n\tconst videoId = match[1]\n\n\tel.setAttribute(\n\t\t'data-lg-video',\n\t\tJSON.stringify({\n\t\t\tsource: [{ src: videoId, type }],\n\t\t\tattributes: {\n\t\t\t\tautoplay: true,\n\t\t\t\tmute: false,\n\t\t\t\tallow: 'autoplay; encrypted-media',\n\t\t\t},\n\t\t})\n\t)\n\n\tel.setAttribute('data-lg-size', '1000-563') // 16:9 ratio at width 1000\n}\n\nfunction findById(array, targetId) {\n\treturn array.find((item) => item.id === targetId)\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/components/utils.js?\n}")},"./src/js/index.js"(__unused_webpack_module,__webpack_exports__,__webpack_require__){"use strict";eval("{__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _components_cursor_box__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./components/cursor-box */ \"./src/js/components/cursor-box.js\");\n/* harmony import */ var _components_smooth__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! ./components/smooth */ \"./src/js/components/smooth.js\");\n/* harmony import */ var _components_scroll__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./components/scroll */ \"./src/js/components/scroll.js\");\n/* harmony import */ var _components_action__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./components/
1action */ \"./src/js/components/action.js\");\n/* harmony import */ var _components_lightbox__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./components/lightbox */ \"./src/js/components/lightbox.js\");\n/* harmony import */ var _components_animation__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./components/animation */ \"./src/js/components/animation.js\");\n/* harmony import */ var _components_insights__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./components/insights */ \"./src/js/components/insights.js\");\n/* harmony import */ var _components_setup__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./components/setup */ \"./src/js/components/setup.js\");\n/* harmony import */ var _components_recaptcha__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./components/recaptcha */ \"./src/js/components/recaptcha.js\");\nconst settings = {\n\tsmooth: true,\n\tloader: true,\n}\n\n;\n\n\n\n\n\n\n\n  \n\n// Back/forward-cache restores replay no DOMContentLoaded — the browser just\n// hands the page back with its DOM frozen exactly as we left it, so nothing\n// re-runs to clear a loader or re-measure the page. Kept as a belt-and-braces\n// reset now that nothing holds the loader open during navigation, and to give\n// ScrollTrigger a chance to recalculate against the restored scroll position.\n// Registered outside DOMContentLoaded so it's live as early as possible.\nwindow.addEventListener('pageshow', (event) => {\n\tif (!event.persisted) return\n\t_components_animation__WEBPACK_IMPORTED_MODULE_5__.resetLoader()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.refresh()\n})\n\n// The preloader is a first-impression animation, not a page transition, so it\n// plays once per browsing session — on whichever page the visitor lands on\n// first. The decision is made pre-paint by the inline script in header.php,\n// which flags repeat documents with .preloader-seen on <html>; reading that\n// class here rather than sessionStorage directly keeps one source of truth\n// shared with the CSS that hides the loader before it can flash.\nconst preloaderSeen =\n\tdocument.documentElement.classList.contains('preloader-seen')\nconst runLoader = settings.loader && !preloaderSeen\n\ndocument.addEventListener('DOMContentLoaded', () => {\n\tif (runLoader) {\n\t\t_components_animation__WEBPACK_IMPORTED_MODULE_5__.loader(\n\t\t\t() => {\n\t\t\t\tisStarted()\n\t\t\t},\n\t\t\t() => {\n\t\t\t\tisLoaded()\n\t\t\t},\n\t\t)\n\t} else {\n\t\t// Both callbacks still have to fire, in this order: isStarted() sets headings\n\t\t// to opacity 0 and isLoaded() creates the ScrollTriggers that reveal them, so\n\t\t// skipping either leaves the page permanently blank in places.\n\t\tconst loader = document.getElementById('loader')\n\t\tif (loader) loader.classList.add('hidden')\n\t\tdocument.body.classList.remove('overflow-hidden')\n\t\tisStarted()\n\t\tisLoaded()\n\t}\n})\n\nfunction isStarted() {\n\tif (settings.smooth) new _components_smooth__WEBPACK_IMPORTED_MODULE_1__.Smooth(settings.smooth)\n\n\t_components_setup__WEBPACK_IMPORTED_MODULE_7__.homeWorkflow()\n\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.statCards()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.testimonials()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.accordion()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.menu()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.share()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.heroObject()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.customOverlapAccordion()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.overlapAccordionToggle()\n\t_components_action__WEBPACK_IMPORTED_MODULE_3__.storylane()\n\n\t// Bound in isStarted rather than isLoaded: page 1 is already in the markup, so\n\t// the only thing waiting on this is the user's first click. Binding it behind\n\t// the loader would leave the filters dead for the ~1.8s the loader runs.\n\t_components_insights__WEBPACK_IMPORTED_MODULE_6__.insights()\n\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.header()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.curtains()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.videos()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.backgroundVideos()\n\n\t_components_recaptcha__WEBPACK_IMPORTED_MODULE_8__.lazyLoad()\n\n\t_components_animation__WEBPACK_IMPORTED_MODULE_5__.homeWorkflow()\n\t_components_animation__WEBPACK_IMPORTED_MODULE_5__.AI()\n\t_components_animation__WEBPACK_IMPORTED_MODULE_5__.ball()\n\n\t// CursorBox's constructor synchronously builds its full cell grid --\n\t// on a full-bleed section that's thousands of Cell objects allocated at\n\t// once. Boxes already on/near the initial screen are still constructed\n\t// immediately, same as before; ones further down the page are\n\t// constructed lazily, right before they'd scroll into view, so their\n\t// grid isn't built (and doesn't cost anything) until it's actually\n\t// about to be seen.\n\tconst boxes = [...document.querySelectorAll('canvas.cursor-box')]\n\tif (boxes.length > 0) {\n\t\tconst initBox = (box) => {\n\t\t\tconst isStatic = box.dataset.static === 'true'\n\t\t\tnew _components_cursor_box__WEBPACK_IMPORTED_MODULE_0__[\"default\"](box, isStatic)\n\t\t}
1\n\n\t\tconst viewportHeight = window.innerHeight\n\t\tconst eagerBoxes = []\n\t\tconst lazyBoxes = []\n\n\t\tboxes.forEach((box) => {\n\t\t\tconst rect = box.getBoundingClientRect()\n\t\t\tif (rect.top < viewportHeight * 1.5) {\n\t\t\t\teagerBoxes.push(box)\n\t\t\t} else {\n\t\t\t\tlazyBoxes.push(box)\n\t\t\t}\n\t\t})\n\n\t\teagerBoxes.forEach(initBox)\n\n\t\tif (lazyBoxes.length > 0) {\n\t\t\tif ('IntersectionObserver' in window) {\n\t\t\t\tconst boxObserver = new IntersectionObserver(\n\t\t\t\t\t(entries, obs) => {\n\t\t\t\t\t\tentries.forEach((entry) => {\n\t\t\t\t\t\t\tif (!entry.isIntersecting) return\n\t\t\t\t\t\t\tobs.unobserve(entry.target)\n\t\t\t\t\t\t\tinitBox(entry.target)\n\t\t\t\t\t\t})\n\t\t\t\t\t},\n\t\t\t\t\t{ rootMargin: '600px 0px' },\n\t\t\t\t)\n\n\t\t\t\tlazyBoxes.forEach((box) => boxObserver.observe(box))\n\t\t\t} else {\n\t\t\t\tlazyBoxes.forEach(initBox)\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction isLoaded() {\n\t// homepage\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.homeFeatures()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.homeWorkflow()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.homeWhiteCTA()\n\n\t// svg animations\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.origination()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.products()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.dataServicesHero()\n\t_components_scroll__WEBPACK_IMPORTED_MODULE_2__.headings()\n\n\t_components_lightbox__WEBPACK_IMPORTED_MODULE_4__.video()\n}\n\n\n//# sourceURL=webpack://real-insight/./src/js/index.js?\n}")},"./node_modules/lenis/dist/lenis.mjs"(__unused_webpack___webpack_module__,__webpack_exports__,__webpack_require__){"use strict";eval('{__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   "default": () => (/* binding */ Lenis)\n/* harmony export */ });\n//#region package.json\nvar version = "1.3.23";\n//#endregion\n//#region packages/core/src/maths.ts\n/**\n* Clamp a value between a minimum and maximum value\n*\n* @param min Minimum value\n* @param input Value to clamp\n* @param max Maximum value\n* @returns Clamped value\n*/\nfunction clamp(min, input, max) {\n\treturn Math.max(min, Math.min(input, max));\n}\n/**\n*  Linearly interpolate between two values using an amount (0 <= t <= 1)\n*\n* @param x First value\n* @param y Second value\n* @param t Amount to interpolate (0 <= t <= 1)\n* @returns Interpolated value\n*/\nfunction lerp(x, y, t) {\n\treturn (1 - t) * x + t * y;\n}\n/**\n* Damp a value over time using a damping factor\n* {@link http://www.rorydriscoll.com/2016/03/07/frame-rate-independent-damping-using-lerp/}\n*\n* @param x Initial value\n* @param y Target value\n* @param lambda Damping factor\n* @param dt Time elapsed since the last update\n* @returns Damped value\n*/\nfunction damp(x, y, lambda, deltaTime) {\n\treturn lerp(x, y, 1 - Math.exp(-lambda * deltaTime));\n}\n/**\n* Calculate the modulo of the dividend and divisor while keeping the result within the same sign as the divisor\n* {@link https://anguscroll.com/just/just-modulo}\n*\n* @param n Dividend\n* @param d Divisor\n* @returns Modulo\n*/\nfunction modulo(n, d) {\n\treturn (n % d + d) % d;\n}\n//#endregion\n//#region packages/core/src/animate.ts\n/**\n* Animate class to handle value animations with lerping or easing\n*\n* @example\n* const animate = new Animate()\n* animate.fromTo(0, 100, { duration: 1, easing: (t) => t })\n* animate.advance(0.5) // 50\n*/\nvar Animate = class {\n\tisRunning = false;\n\tvalue = 0;\n\tfrom = 0;\n\tto = 0;\n\tcurrentTime = 0;\n\tlerp;\n\tduration;\n\teasing;\n\tonUpdate;\n\t/**\n\t* Advance the animation by the given delta time\n\t*\n\t* @param deltaTime - The time in seconds to advance the animation\n\t*/\n\tadvance(deltaTime) {\n\t\tif (!this.isRunning) return;\n\t\tlet completed = false;\n\t\tif (this.duration && this.easing) {\n\t\t\tthis.currentTime += deltaTime;\n\t\t\tconst linearProgress = clamp(0, this.currentTime / this.duration, 1);\n\t\t\tcompleted = linearProgress >= 1;\n\t\t\tconst easedProgress = completed ? 1 : this.easing(linearProgress);\n\t\t\tthis.value = this.from + (this.to - this.from) * easedProgress;\n\t\t}
1 else if (this.lerp) {\n\t\t\tthis.value = damp(this.value, this.to, this.lerp * 60, deltaTime);\n\t\t\tif (Math.round(this.value) === Math.round(this.to)) {\n\t\t\t\tthis.value = this.to;\n\t\t\t\tcompleted = true;\n\t\t\t}\n\t\t} else {\n\t\t\tthis.value = this.to;\n\t\t\tcompleted = true;\n\t\t}\n\t\tif (completed) this.stop();\n\t\tthis.onUpdate?.(this.value, completed);\n\t}\n\t/** Stop the animation */\n\tstop() {\n\t\tthis.isRunning = false;\n\t}\n\t/**\n\t* Set up the animation from a starting value to an ending value\n\t* with optional parameters for lerping, duration, easing, and onUpdate callback\n\t*\n\t* @param from - The starting value\n\t* @param to - The ending value\n\t* @param options - Options for the animation\n\t*/\n\tfromTo(from, to, { lerp, duration, easing, onStart, onUpdate }) {\n\t\tthis.from = this.value = from;\n\t\tthis.to = to;\n\t\tthis.lerp = lerp;\n\t\tthis.duration = duration;\n\t\tthis.easing = easing;\n\t\tthis.currentTime = 0;\n\t\tthis.isRunning = true;\n\t\tonStart?.();\n\t\tthis.onUpdate = onUpdate;\n\t}\n};\n//#endregion\n//#region packages/core/src/debounce.ts\nfunction debounce(callback, delay) {\n\tlet timer;\n\treturn function(...args) {\n\t\tclearTimeout(timer);\n\t\ttimer = setTimeout(() => {\n\t\t\ttimer = void 0;\n\t\t\tcallback.apply(this, args);\n\t\t}, delay);\n\t};\n}\n//#endregion\n//#region packages/core/src/dimensions.ts\n/**\n* Dimensions class to handle the size of the content and wrapper\n*\n* @example\n* const dimensions = new Dimensions(wrapper, content)\n* dimensions.on(\'resize\', (e) => {\n*   console.log(e.width, e.height)\n* })\n*/\nvar Dimensions = class {\n\twidth = 0;\n\theight = 0;\n\tscrollHeight = 0;\n\tscrollWidth = 0;\n\tdebouncedResize;\n\twrapperResizeObserver;\n\tcontentResizeObserver;\n\tconstructor(wrapper, content, { autoResize = true, debounce: debounceValue = 250 } = {}) {\n\t\tthis.wrapper = wrapper;\n\t\tthis.content = content;\n\t\tif (autoResize) {\n\t\t\tthis.debouncedResize = debounce(this.resize, debounceValue);\n\t\t\tif (this.wrapper instanceof Window) window.addEventListener("resize", this.debouncedResize);\n\t\t\telse {\n\t\t\t\tthis.wrapperResizeObserver = new ResizeObserver(this.debouncedResize);\n\t\t\t\tthis.wrapperResizeObserver.observe(this.wrapper);\n\t\t\t}\n\t\t\tthis.contentResizeObserver = new ResizeObserver(this.debouncedResize);\n\t\t\tthis.contentResizeObserver.observe(this.content);\n\t\t}\n\t\tthis.resize();\n\t}\n\tdestroy() {\n\t\tthis.wrapperResizeObserver?.disconnect();\n\t\tthis.contentResizeObserver?.disconnect();\n\t\tif (this.wrapper === window && this.debouncedResize) window.removeEventListener("resize", this.debouncedResize);\n\t}\n\tresize = () => {\n\t\tthis.onWrapperResize();\n\t\tthis.onContentResize();\n\t};\n\tonWrapperResize = () => {\n\t\tif (this.wrapper instanceof Window) {\n\t\t\tthis.width = window.innerWidth;\n\t\t\tthis.height = window.innerHeight;\n\t\t} else {\n\t\t\tthis.width = this.wrapper.clientWidth;\n\t\t\tthis.height = this.wrapper.clientHeight;\n\t\t}\n\t};\n\tonContentResize = () => {\n\t\tif (this.wrapper instanceof Window) {\n\t\t\tthis.scrollHeight = this.content.scrollHeight;\n\t\t\tthis.scrollWidth = this.content.scrollWidth;\n\t\t} else {\n\t\t\tthis.scrollHeight = this.wrapper.scrollHeight;\n\t\t\tthis.scrollWidth = this.wrapper.scrollWidth;\n\t\t}\n\t};\n\tget limit() {\n\t\treturn {\n\t\t\tx: this.scrollWidth - this.width,\n\t\t\ty: this.scrollHeight - this.height\n\t\t};\n\t}\n};\n//#endregion\n//#region packages/core/src/emitter.ts\n/**\n* Emitter class to handle events\n* @example\n* const emitter = new Emitter()\n* emitter.on(\'event\', (data) => {\n*   console.log(data)\n* })\n* emitter.emit(\'event\', \'data\')\n*/\nvar Emitter = class {\n\tevents = {};\n\t/**\n\t* Emit an event with the given data\n\t* @param event Event name\n\t* @param args Data to pass to the event handlers\n\t*/\n\temit(event, ...args) {\n\t\tconst callbacks = this.events[event] || [];\n\t\tfor (let i = 0, length = callbacks.length; i < length; i++) callbacks[i]?.(...args);\n\t}\n\t/**\n\t* Add a callback to the event\n\t* @param event Event name\n\t* @param cb Callback function\n\t* @returns Unsubscribe function\n\t*/\n\ton(event, cb) {\n\t\tif (this.events[event]) this.events[event].push(cb);\n\t\telse this.events[event] = [cb];\n\t\treturn () => {\n\t\t\tthis.events[event] = this.events[event]?.filter((i) => cb !== i);\n\t\t};\n\t}\n\t/**\n\t* Remove a callback from the event\n\t* @param event Event name\n\t* @param callback Callback function\n\t*/\n\toff(event, callback) {\n\t\tthis.events[event] = this.events[event]?.filter((i) => callback !== i);\n\t}\n\t/**\n\t* Remove all event listeners and clean up\n\t*/\n\tdestroy() {\n\t\tthis.events = {};\n\t}\n};\n//#endregion\n//#region packages/core/src/virtual-scroll.ts\nconst LINE_HEIGHT = 100 / 6;\nconst listenerOptions = { passive: false };\nfunction getDeltaMultiplier(deltaMode, size) {\n\tif (deltaMode === 1) return LINE_HEIGHT;\n\tif (deltaMode === 2) return size;\n\treturn 1;\n}
1\nvar VirtualScroll = class {\n\ttouchStart = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\tlastDelta = {\n\t\tx: 0,\n\t\ty: 0\n\t};\n\twindow = {\n\t\twidth: 0,\n\t\theight: 0\n\t};\n\temitter = new Emitter();\n\tconstructor(element, options = {\n\t\twheelMultiplier: 1,\n\t\ttouchMultiplier: 1\n\t}) {\n\t\tthis.element = element;\n\t\tthis.options = options;\n\t\twindow.addEventListener("resize", this.onWindowResize);\n\t\tthis.onWindowResize();\n\t\tthis.element.addEventListener("wheel", this.onWheel, listenerOptions);\n\t\tthis.element.addEventListener("touchstart", this.onTouchStart, listenerOptions);\n\t\tthis.element.addEventListener("touchmove", this.onTouchMove, listenerOptions);\n\t\tthis.element.addEventListener("touchend", this.onTouchEnd, listenerOptions);\n\t}\n\t/**\n\t* Add an event listener for the given event and callback\n\t*\n\t* @param event Event name\n\t* @param callback Callback function\n\t*/\n\ton(event, callback) {\n\t\treturn this.emitter.on(event, callback);\n\t}\n\t/** Remove all event listeners and clean up */\n\tdestroy() {\n\t\tthis.emitter.destroy();\n\t\twindow.removeEventListener("resize", this.onWindowResize);\n\t\tthis.element.removeEventListener("wheel", this.onWheel, listenerOptions);\n\t\tthis.element.removeEventListener("touchstart", this.onTouchStart, listenerOptions);\n\t\tthis.element.removeEventListener("touchmove", this.onTouchMove, listenerOptions);\n\t\tthis.element.removeEventListener("touchend", this.onTouchEnd, listenerOptions);\n\t}\n\t/**\n\t* Event handler for \'touchstart\' event\n\t*\n\t* @param event Touch event\n\t*/\n\tonTouchStart = (event) => {\n\t\tconst { clientX, clientY } = event.targetTouches ? event.targetTouches[0] : event;\n\t\tthis.touchStart.x = clientX;\n\t\tthis.touchStart.y = clientY;\n\t\tthis.lastDelta = {\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t};\n\t\tthis.emitter.emit("scroll", {\n\t\t\tdeltaX: 0,\n\t\t\tdeltaY: 0,\n\t\t\tevent\n\t\t});\n\t};\n\t/** Event handler for \'touchmove\' event */\n\tonTouchMove = (event) => {\n\t\tconst { clientX, clientY } = event.targetTouches ? event.targetTouches[0] : event;\n\t\tconst deltaX = -(clientX - this.touchStart.x) * this.options.touchMultiplier;\n\t\tconst deltaY = -(clientY - this.touchStart.y) * this.options.touchMultiplier;\n\t\tthis.touchStart.x = clientX;\n\t\tthis.touchStart.y = clientY;\n\t\tthis.lastDelta = {\n\t\t\tx: deltaX,\n\t\t\ty: deltaY\n\t\t};\n\t\tthis.emitter.emit("scroll", {\n\t\t\tdeltaX,\n\t\t\tdeltaY,\n\t\t\tevent\n\t\t});\n\t};\n\tonTouchEnd = (event) => {\n\t\tthis.emitter.emit("scroll", {\n\t\t\tdeltaX: this.lastDelta.x,\n\t\t\tdeltaY: this.lastDelta.y,\n\t\t\tevent\n\t\t});\n\t};\n\t/** Event handler for \'wheel\' event */\n\tonWheel = (event) => {\n\t\tlet { deltaX, deltaY, deltaMode } = event;\n\t\tconst multiplierX = getDeltaMultiplier(deltaMode, this.window.width);\n\t\tconst multiplierY = getDeltaMultiplier(deltaMode, this.window.height);\n\t\tdeltaX *= multiplierX;\n\t\tdeltaY *= multiplierY;\n\t\tdeltaX *= this.options.wheelMultiplier;\n\t\tdeltaY *= this.options.wheelMultiplier;\n\t\tthis.emitter.emit("scroll", {\n\t\t\tdeltaX,\n\t\t\tdeltaY,\n\t\t\tevent\n\t\t});\n\t};\n\tonWindowResize = () => {\n\t\tthis.window = {\n\t\t\twidth: window.innerWidth,\n\t\t\theight: window.innerHeight\n\t\t};\n\t};\n};\n//#endregion\n//#region packages/core/src/lenis.ts\nconst defaultEasing = (t) => Math.min(1, 1.001 - 2 ** (-10 * t));\nvar Lenis = class {\n\t_isScrolling = false;\n\t_isStopped = false;\n\t_isLocked = false;\n\t_preventNextNativeScrollEvent = false;\n\t_resetVelocityTimeout = null;\n\t_rafId = null;\n\t/**\n\t* Whether or not the user is touching the screen\n\t*/\n\tisTouching;\n\t/**\n\t* The time in ms since the lenis instance was created\n\t*/\n\ttime = 0;\n\t/**\n\t* User data that will be forwarded through the scroll event\n\t*\n\t* @example\n\t* lenis.scrollTo(100, {\n\t*   userData: {\n\t*     foo: \'bar\'\n\t*   }\n\t* })\n\t*/\n\tuserData = {};\n\t/**\n\t* The last velocity of the scroll\n\t*/\n\tlastVelocity = 0;\n\t/**\n\t* The current velocity of the scroll\n\t*/\n\tvelocity = 0;\n\t/**\n\t* The direction of the scroll\n\t*/\n\tdirection = 0;\n\t/**\n\t* The options passed to the lenis instance\n\t*/\n\toptions;\n\t/**\n\t* The target scroll value\n\t*/\n\ttargetScroll;\n\t/**\n\t* The animated scroll value\n\t*/\n\tanimatedScroll;\n\tanimate = new Animate();\n\temitter = new Emitter();\n\tdimensions;\n\tvirtualScroll;\n\tconstructor({ wrapper = window, content = document.documentElement, eventsTarget = wrapper, smoothWheel = true, syncTouch = false, syncTouchLerp = .075, touchInertiaExponent = 1.7, duration, easing, lerp = .1, infinite = false, orientation = "vertical", gestureOrientation = orientation === "horizontal" ? "both" : "vertical", touchMultiplier = 1, wheelMultiplier = 1, autoResize = true, prevent, virtualScroll, overscroll = true, autoRaf = false, anchors = false, autoToggle = false, allowNestedScroll = false, __experimental__naiveDimensions = false, naiveDimensions = __experimental__naiveDimensions, stopInertiaOnNavigate = false } = {}) {\n\t\twindow.lenisVersion = version;\n\t\tif (!window.lenis) window.lenis = {};\n\t\twindow.lenis.version = version;\n\t\tif (orientation === "horizontal") window.lenis.horizontal = true;\n\t\tif (syncTouch === true) window.lenis.touch = true;\n\t\tif (!wrapper || wrapper === document.documentElement) wrapper = window;\n\t\tif (typeof duration === "number" && typeof easing !== "function") easing = defaultEasing;\n\t\telse if (typeof easing === "function" && typeof duration !== "number") duration = 1;\n\t\tthis.options = {\n\t\t\twrapper,\n\t\t\tcontent,\n\t\t\teventsTarget,\n\t\t\tsmoothWheel,\n\t\t\tsyncTouch,\n\t\t\tsyncTouchLerp,\n\t\t\ttouchInertiaExponent,\n\t\t\tduration,\n\t\t\teasing,\n\t\t\tlerp,\n\t\t\tinfinite,\n\t\t\tgestureOrientation,\n\t\t\torientation,\n\t\t\ttouchMultiplier,\n\t\t\twheelMultiplier,\n\t\t\tautoResize,\n\t\t\tprevent,\n\t\t\tvirtualScroll,\n\t\t\toverscroll,\n\t\t\tautoRaf,\n\t\t\tanchors,\n\t\t\tautoToggle,\n\t\t\tallowNestedScroll,\n\t\t\tnaiveDimensions,\n\t\t\tstopInertiaOnNavigate\n\t\t};\n\t\tthis.dimensions = new Dimensions(wrapper, content, { autoResize });\n\t\tthis.updateClassName();\n\t\tthis.targetScroll = this.animatedScroll = this.actualScroll;\n\t\tthis.options.wrapper.addEventListener("scroll", this.onNativeScroll);\n\t\tthis.options.wrapper.addEventListener("scrollend", this.onScrollEnd, { capture: true });\n\t\tif (this.options.anchors || this.options.stopInertiaOnNavigate) this.options.wrapper.addEventListener("click", this.onClick);\n\t\tthis.options.wrapper.addEventListener("pointerdown", this.onPointerDown);\n\t\tthis.virtualScroll = new VirtualScroll(eventsTarget, {\n\t\t\ttouchMultiplier,\n\t\t\twheelMultiplier\n\t\t});\n\t\tthis.virtualScroll.on("scroll", this.onVirtualScroll);\n\t\tif (this.options.autoToggle) {\n\t\t\tthis.checkOverflow();\n\t\t\tthis.rootElement.addEventListener("transitionend", this.onTransitionEnd);\n\t\t}\n\t\tif (this.options.autoRaf) this._rafId = requestAnimationFrame(this.raf);\n\t}\n\t/**\n\t* Destroy the lenis instance, remove all event listeners and clean up the class name\n\t*/\n\tdestroy() {\n\t\tthis.emitter.destroy();\n\t\tthis.options.wrapper.removeEventListener("scroll", this.onNativeScroll);\n\t\tthis.options.wrapper.removeEventListener("scrollend", this.onScrollEnd, { capture: true });\n\t\tthis.options.wrapper.removeEventListener("pointerdown", this.onPointerDown);\n\t\tif (this.options.anchors || this.options.stopInertiaOnNavigate) this.options.wrapper.removeEventListener("click", this.onClick);\n\t\tthis.virtualScroll.destroy();\n\t\tthis.dimensions.destroy();\n\t\tthis.cleanUpClassName();\n\t\tif (this._rafId) cancelAnimationFrame(this._rafId);\n\t}\n\ton(event, callback) {\n\t\treturn this.emitter.on(event, callback);\n\t}\n\toff(event, callback) {\n\t\treturn this.emitter.off(event, callback);\n\t}\n\tonScrollEnd = (e) => {\n\t\tif (!(e instanceof CustomEvent)) {\n\t\t\tif (this.isScrolling === "smooth" || this.isScrolling === false) e.stopPropagation();\n\t\t}\n\t};\n\tdispatchScrollendEvent = () => {\n\t\tthis.options.wrapper.dispatchEvent(new CustomEvent("scrollend", {\n\t\t\tbubbles: this.options.wrapper === window,\n\t\t\tdetail
1: { lenisScrollEnd: true }\n\t\t}));\n\t};\n\tget overflow() {\n\t\tconst property = this.isHorizontal ? "overflow-x" : "overflow-y";\n\t\treturn getComputedStyle(this.rootElement)[property];\n\t}\n\tcheckOverflow() {\n\t\tif (["hidden", "clip"].includes(this.overflow)) this.internalStop();\n\t\telse this.internalStart();\n\t}\n\tonTransitionEnd = (event) => {\n\t\tif (event.propertyName?.includes("overflow") && event.target === this.rootElement) this.checkOverflow();\n\t};\n\tsetScroll(scroll) {\n\t\tif (this.isHorizontal) this.options.wrapper.scrollTo({\n\t\t\tleft: scroll,\n\t\t\tbehavior: "instant"\n\t\t});\n\t\telse this.options.wrapper.scrollTo({\n\t\t\ttop: scroll,\n\t\t\tbehavior: "instant"\n\t\t});\n\t}\n\tonClick = (event) => {\n\t\tconst linkElementsUrls = event.composedPath().filter((node) => node instanceof HTMLAnchorElement && node.href).map((element) => new URL(element.href));\n\t\tconst currentUrl = new URL(window.location.href);\n\t\tif (this.options.anchors) {\n\t\t\tconst anchorElementUrl = linkElementsUrls.find((targetUrl) => currentUrl.host === targetUrl.host && currentUrl.pathname === targetUrl.pathname && targetUrl.hash);\n\t\t\tif (anchorElementUrl) {\n\t\t\t\tconst options = typeof this.options.anchors === "object" && this.options.anchors ? this.options.anchors : void 0;\n\t\t\t\tconst target = `#${anchorElementUrl.hash.split("#")[1]}`;\n\t\t\t\tthis.scrollTo(target, options);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t\tif (this.options.stopInertiaOnNavigate) {\n\t\t\tif (linkElementsUrls.some((targetUrl) => currentUrl.host === targetUrl.host && currentUrl.pathname !== targetUrl.pathname)) {\n\t\t\t\tthis.reset();\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t};\n\tonPointerDown = (event) => {\n\t\tif (event.button === 1) this.reset();\n\t};\n\tonVirtualScroll = (data) => {\n\t\tif (typeof this.options.virtualScroll === "function" && this.options.virtualScroll(data) === false) return;\n\t\tconst { deltaX, deltaY, event } = data;\n\t\tthis.emitter.emit("virtual-scroll", {\n\t\t\tdeltaX,\n\t\t\tdeltaY,\n\t\t\tevent\n\t\t});\n\t\tif (event.ctrlKey) return;\n\t\tif (event.lenisStopPropagation) return;\n\t\tconst isTouch = event.type.includes("touch");\n\t\tconst isWheel = event.type.includes("wheel");\n\t\tthis.isTouching = event.type === "touchstart" || event.type === "touchmove";\n\t\tconst isClickOrTap = deltaX === 0 && deltaY === 0;\n\t\tif (this.options.syncTouch && isTouch && event.type === "touchstart" && isClickOrTap && !this.isStopped && !this.isLocked) {\n\t\t\tthis.reset();\n\t\t\treturn;\n\t\t}\n\t\tconst isUnknownGesture = this.options.gestureOrientation === "vertical" && deltaY === 0 || this.options.gestureOrientation === "horizontal" && deltaX === 0;\n\t\tif (isClickOrTap || isUnknownGesture) return;\n\t\tlet composedPath = event.composedPath();\n\t\tcomposedPath = composedPath.slice(0, composedPath.indexOf(this.rootElement));\n\t\tconst prevent = this.options.prevent;\n\t\tconst gestureOrientation = Math.abs(deltaX) >= Math.abs(deltaY) ? "horizontal" : "vertical";\n\t\tif (composedPath.find((node) => node instanceof HTMLElement && (typeof prevent === "function" && prevent?.(node) || node.hasAttribute?.("data-lenis-prevent") || gestureOrientation === "vertical" && node.hasAttribute?.("data-lenis-prevent-vertical") || gestureOrientation === "horizontal" && node.hasAttribute?.("data-lenis-prevent-horizontal") || isTouch && node.hasAttribute?.("data-lenis-prevent-touch") || isWheel && node.hasAttribute?.("data-lenis-prevent-wheel") || this.options.allowNestedScroll && this.hasNestedScroll(node, {\n\t\t\tdeltaX,\n\t\t\tdeltaY\n\t\t})))) return;\n\t\tif (this.isStopped || this.isLocked) {\n\t\t\tif (event.cancelable) event.preventDefault();\n\t\t\treturn;\n\t\t}\n\t\tif (!(this.options.syncTouch && isTouch || this.options.smoothWheel && isWheel)) {\n\t\t\tthis.isScrolling = "native";\n\t\t\tthis.animate.stop();\n\t\t\tevent.lenisStopPropagation = true;\n\t\t\treturn;\n\t\t}\n\t\tlet delta = deltaY;\n\t\tif (this.options.gestureOrientation === "both") delta = Math.abs(deltaY) > Math.abs(deltaX) ? deltaY : deltaX;\n\t\telse if (this.options.gestureOrientation === "horizontal") delta = deltaX;\n\t\tif (!this.options.overscroll || this.options.infinite || this.options.wrapper !== window && this.limit > 0 && (this.animatedScroll > 0 && this.animatedScroll < this.limit || this.animatedScroll === 0 && deltaY > 0 || this.animatedScroll === this.limit && deltaY < 0)) event.lenisStopPropagation = true;\n\t\tif (event.cancelable) event.preventDefault();\n\t\tconst isSyncTouch = isTouch && this.options.syncTouch;\n\t\tconst hasTouchInertia = isTouch && event.type === "touchend";\n\t\tif (hasTouchInertia) delta = Math.sign(delta) * Math.abs(this.velocity) ** this.options.touchInertiaExponent;
1\n\t\tthis.scrollTo(this.targetScroll + delta, {\n\t\t\tprogrammatic: false,\n\t\t\t...isSyncTouch ? { lerp: hasTouchInertia ? this.options.syncTouchLerp : 1 } : {\n\t\t\t\tlerp: this.options.lerp,\n\t\t\t\tduration: this.options.duration,\n\t\t\t\teasing: this.options.easing\n\t\t\t}\n\t\t});\n\t};\n\t/**\n\t* Force lenis to recalculate the dimensions\n\t*/\n\tresize() {\n\t\tthis.dimensions.resize();\n\t\tthis.animatedScroll = this.targetScroll = this.actualScroll;\n\t\tthis.emit();\n\t}\n\temit() {\n\t\tthis.emitter.emit("scroll", this);\n\t}\n\tonNativeScroll = () => {\n\t\tif (this._resetVelocityTimeout !== null) {\n\t\t\tclearTimeout(this._resetVelocityTimeout);\n\t\t\tthis._resetVelocityTimeout = null;\n\t\t}\n\t\tif (this._preventNextNativeScrollEvent) {\n\t\t\tthis._preventNextNativeScrollEvent = false;\n\t\t\treturn;\n\t\t}\n\t\tif (this.isScrolling === false || this.isScrolling === "native") {\n\t\t\tconst lastScroll = this.animatedScroll;\n\t\t\tthis.animatedScroll = this.targetScroll = this.actualScroll;\n\t\t\tthis.lastVelocity = this.velocity;\n\t\t\tthis.velocity = this.animatedScroll - lastScroll;\n\t\t\tthis.direction = Math.sign(this.animatedScroll - lastScroll);\n\t\t\tif (!this.isStopped) this.isScrolling = "native";\n\t\t\tthis.emit();\n\t\t\tif (this.velocity !== 0) this._resetVelocityTimeout = setTimeout(() => {\n\t\t\t\tthis.lastVelocity = this.velocity;\n\t\t\t\tthis.velocity = 0;\n\t\t\t\tthis.isScrolling = false;\n\t\t\t\tthis.emit();\n\t\t\t}, 400);\n\t\t}\n\t};\n\treset() {\n\t\tthis.isLocked = false;\n\t\tthis.isScrolling = false;\n\t\tthis.animatedScroll = this.targetScroll = this.actualScroll;\n\t\tthis.lastVelocity = this.velocity = 0;\n\t\tthis.animate.stop();\n\t}\n\t/**\n\t* Start lenis scroll after it has been stopped\n\t*/\n\tstart() {\n\t\tif (!this.isStopped) return;\n\t\tif (this.options.autoToggle) {\n\t\t\tthis.rootElement.style.removeProperty("overflow");\n\t\t\treturn;\n\t\t}\n\t\tthis.internalStart();\n\t}\n\tinternalStart() {\n\t\tif (!this.isStopped) return;\n\t\tthis.reset();\n\t\tthis.isStopped = false;\n\t\tthis.emit();\n\t}\n\t/**\n\t* Stop lenis scroll\n\t*/\n\tstop() {\n\t\tif (this.isStopped) return;\n\t\tif (this.options.autoToggle) {\n\t\t\tthis.rootElement.style.setProperty("overflow", "clip");\n\t\t\treturn;\n\t\t}\n\t\tthis.internalStop();\n\t}\n\tinternalStop() {\n\t\tif (this.isStopped) return;\n\t\tthis.reset();\n\t\tthis.isStopped = true;\n\t\tthis.emit();\n\t}\n\t/**\n\t* RequestAnimationFrame for lenis\n\t*\n\t* @param time The time in ms from an external clock like `requestAnimationFrame` or Tempus\n\t*/\n\traf = (time) => {\n\t\tconst deltaTime = time - (this.time || time);\n\t\tthis.time = time;\n\t\tthis.animate.advance(deltaTime * .001);\n\t\tif (this.options.autoRaf) this._rafId = requestAnimationFrame(this.raf);\n\t};\n\t/**\n\t* Scroll to a target value\n\t*\n\t* @param target The target value to scroll to\n\t* @param options The options for the scroll\n\t*\n\t* @example\n\t* lenis.scrollTo(100, {\n\t*   offset: 100,\n\t*   duration: 1,\n\t*   easing: (t) => 1 - Math.cos((t * Math.PI) / 2),\n\t*   lerp: 0.1,\n\t*   onStart: () => {\n\t*     console.log(\'onStart\')\n\t*   },\n\t*   onComplete: () => {\n\t*     console.log(\'onComplete\')\n\t*   },\n\t* })\n\t*/\n\tscrollTo(_target, { offset = 0, immediate = false, lock = false, programmatic = true, lerp = programmatic ? this.options.lerp : void 0, duration = programmatic ? this.options.duration : void 0, easing = programmatic ? this.options.easing : void 0, onStart, onComplete, force = false, userData } = {}) {\n\t\tif ((this.isStopped || this.isLocked) && !force) return;\n\t\tlet target = _target;\n\t\tlet adjustedOffset = offset;\n\t\tif (typeof target === "string" && [\n\t\t\t"top",\n\t\t\t"left",\n\t\t\t"start",\n\t\t\t"#"\n\t\t].includes(target)) target = 0;\n\t\telse if (typeof target === "string" && [\n\t\t\t"bottom",\n\t\t\t"right",\n\t\t\t"end"\n\t\t].includes(target)) target = this.limit;\n\t\telse {\n\t\t\tlet node = null;
1\n\t\t\tif (typeof target === "string") {\n\t\t\t\tnode = document.querySelector(target);\n\t\t\t\tif (!node) if (target === "#top") target = 0;\n\t\t\t\telse console.warn("Lenis: Target not found", target);\n\t\t\t} else if (target instanceof HTMLElement && target?.nodeType) node = target;\n\t\t\tif (node) {\n\t\t\t\tif (this.options.wrapper !== window) {\n\t\t\t\t\tconst wrapperRect = this.rootElement.getBoundingClientRect();\n\t\t\t\t\tadjustedOffset -= this.isHorizontal ? wrapperRect.left : wrapperRect.top;\n\t\t\t\t}\n\t\t\t\tconst rect = node.getBoundingClientRect();\n\t\t\t\tconst targetStyle = getComputedStyle(node);\n\t\t\t\tconst scrollMargin = this.isHorizontal ? Number.parseFloat(targetStyle.scrollMarginLeft) : Number.parseFloat(targetStyle.scrollMarginTop);\n\t\t\t\tconst containerStyle = getComputedStyle(this.rootElement);\n\t\t\t\tconst scrollPadding = this.isHorizontal ? Number.parseFloat(containerStyle.scrollPaddingLeft) : Number.parseFloat(containerStyle.scrollPaddingTop);\n\t\t\t\ttarget = (this.isHorizontal ? rect.left : rect.top) + this.animatedScroll - (Number.isNaN(scrollMargin) ? 0 : scrollMargin) - (Number.isNaN(scrollPadding) ? 0 : scrollPadding);\n\t\t\t}\n\t\t}\n\t\tif (typeof target !== "number") return;\n\t\ttarget += adjustedOffset;\n\t\tif (this.options.infinite) {\n\t\t\tif (programmatic) {\n\t\t\t\tthis.targetScroll = this.animatedScroll = this.scroll;\n\t\t\t\tconst distance = target - this.animatedScroll;\n\t\t\t\tif (distance > this.limit / 2) target -= this.limit;\n\t\t\t\telse if (distance < -this.limit / 2) target += this.limit;\n\t\t\t}\n\t\t} else target = clamp(0, target, this.limit);\n\t\tif (target === this.targetScroll) {\n\t\t\tonStart?.(this);\n\t\t\tonComplete?.(this);\n\t\t\treturn;\n\t\t}\n\t\tthis.userData = userData ?? {};\n\t\tif (immediate) {\n\t\t\tthis.animatedScroll = this.targetScroll = target;\n\t\t\tthis.setScroll(this.scroll);\n\t\t\tthis.reset();\n\t\t\tthis.preventNextNativeScrollEvent();\n\t\t\tthis.emit();\n\t\t\tonComplete?.(this);\n\t\t\tthis.userData = {};\n\t\t\trequestAnimationFrame(() => {\n\t\t\t\tthis.dispatchScrollendEvent();\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tif (!programmatic) this.targetScroll = target;\n\t\tif (typeof duration === "number" && typeof easing !== "function") easing = defaultEasing;\n\t\telse if (typeof easing === "function" && typeof duration !== "number") duration = 1;\n\t\tthis.animate.fromTo(this.animatedScroll, target, {\n\t\t\tduration,\n\t\t\teasing,\n\t\t\tlerp,\n\t\t\tonStart: () => {\n\t\t\t\tif (lock) this.isLocked = true;\n\t\t\t\tthis.isScrolling = "smooth";\n\t\t\t\tonStart?.(this);\n\t\t\t},\n\t\t\tonUpdate: (value, completed) => {\n\t\t\t\tthis.isScrolling = "smooth";\n\t\t\t\tthis.lastVelocity = this.velocity;\n\t\t\t\tthis.velocity = value - this.animatedScroll;\n\t\t\t\tthis.direction = Math.sign(this.velocity);\n\t\t\t\tthis.animatedScroll = value;\n\t\t\t\tthis.setScroll(this.scroll);\n\t\t\t\tif (programmatic) this.targetScroll = value;\n\t\t\t\tif (!completed) this.emit();\n\t\t\t\tif (completed) {\n\t\t\t\t\tthis.reset();\n\t\t\t\t\tthis.emit();\n\t\t\t\t\tonComplete?.(this);\n\t\t\t\t\tthis.userData = {};\n\t\t\t\t\trequestAnimationFrame(() => {\n\t\t\t\t\t\tthis.dispatchScrollendEvent();\n\t\t\t\t\t});\n\t\t\t\t\tthis.preventNextNativeScrollEvent();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\tpreventNextNativeScrollEvent() {\n\t\tthis._preventNextNativeScrollEvent = true;\n\t\trequestAnimationFrame(() => {\n\t\t\tthis._preventNextNativeScrollEvent = false;\n\t\t});\n\t}\n\thasNestedScroll(node, { deltaX, deltaY }) {\n\t\tconst time = Date.now();\n\t\tif (!node._lenis) node._lenis = {};\n\t\tconst cache = node._lenis;\n\t\tlet hasOverflowX;\n\t\tlet hasOverflowY;\n\t\tlet isScrollableX;\n\t\tlet isScrollableY;\n\t\tlet hasOverscrollBehaviorX;\n\t\tlet hasOverscrollBehaviorY;\n\t\tlet scrollWidth;\n\t\tlet scrollHeight;\n\t\tlet clientWidth;\n\t\tlet clientHeight;\n\t\tif (time - (cache.time ?? 0) > 2e3) {\n\t\t\tcache.time = Date.now();\n\t\t\tconst computedStyle = window.getComputedStyle(node);\n\t\t\tcache.computedStyle = computedStyle;\n\t\t\thasOverflowX = [\n\t\t\t\t"auto",\n\t\t\t\t"overlay",\n\t\t\t\t"scroll"\n\t\t\t].includes(computedStyle.overflowX);\n\t\t\thasOverflowY = [\n\t\t\t\t"auto",\n\t\t\t\t"overlay",\n\t\t\t\t"scroll"\n\t\t\t].includes(computedStyle.overflowY);\n\t\t\thasOverscrollBehaviorX = ["auto"].includes(computedStyle.overscrollBehaviorX);\n\t\t\thasOverscrollBehaviorY = ["auto"].includes(computedStyle.overscrollBehaviorY);\n\t\t\tcache.hasOverflowX = hasOverflowX;\n\t\t\tcache.hasOverflowY = hasOverflowY;\n\t\t\tif (!(hasOverflowX || hasOverflowY)) return false;\n\t\t\tscrollWidth = node.scrollWidth;\n\t\t\tscrollHeight = node.scrollHeight;\n\t\t\tclientWidth = node.clientWidth;\n\t\t\tclientHeight = node.clientHeight;\n\t\t\tisScrollableX = scrollWidth > clientWidth;\n\t\t\tisScrollableY = scrollHeight > clientHeight;\n\t\t\tcache.isScrollableX = isScrollableX;\n\t\t\tcache.isScrollableY = isScrollableY;\n\t\t\tcache.scrollWidth = scrollWidth;\n\t\t\tcache.scrollHeight = scrollHeight;\n\t\t\tcache.clientWidth = clientWidth;\n\t\t\tcache.clientHeight = clientHeight;\n\t\t\tcache.hasOverscrollBehaviorX = hasOverscrollBehaviorX;\n\t\t\tcache.hasOverscrollBehaviorY = hasOverscrollBehaviorY;\n\t\t} else {\n\t\t\tisScrollableX = cache.isScrollableX;\n\t\t\tisScrollableY = cache.isScrollableY;\n\t\t\thasOverflowX = cache.hasOverflowX;\n\t\t\thasOverflowY = cache.hasOverflowY;
1\n\t\t\tscrollWidth = cache.scrollWidth;\n\t\t\tscrollHeight = cache.scrollHeight;\n\t\t\tclientWidth = cache.clientWidth;\n\t\t\tclientHeight = cache.clientHeight;\n\t\t\thasOverscrollBehaviorX = cache.hasOverscrollBehaviorX;\n\t\t\thasOverscrollBehaviorY = cache.hasOverscrollBehaviorY;\n\t\t}\n\t\tif (!(hasOverflowX && isScrollableX || hasOverflowY && isScrollableY)) return false;\n\t\tconst orientation = Math.abs(deltaX) >= Math.abs(deltaY) ? "horizontal" : "vertical";\n\t\tlet scroll;\n\t\tlet maxScroll;\n\t\tlet delta;\n\t\tlet hasOverflow;\n\t\tlet isScrollable;\n\t\tlet hasOverscrollBehavior;\n\t\tif (orientation === "horizontal") {\n\t\t\tscroll = Math.round(node.scrollLeft);\n\t\t\tmaxScroll = scrollWidth - clientWidth;\n\t\t\tdelta = deltaX;\n\t\t\thasOverflow = hasOverflowX;\n\t\t\tisScrollable = isScrollableX;\n\t\t\thasOverscrollBehavior = hasOverscrollBehaviorX;\n\t\t} else if (orientation === "vertical") {\n\t\t\tscroll = Math.round(node.scrollTop);\n\t\t\tmaxScroll = scrollHeight - clientHeight;\n\t\t\tdelta = deltaY;\n\t\t\thasOverflow = hasOverflowY;\n\t\t\tisScrollable = isScrollableY;\n\t\t\thasOverscrollBehavior = hasOverscrollBehaviorY;\n\t\t} else return false;\n\t\tif (!hasOverscrollBehavior && (scroll >= maxScroll || scroll <= 0)) return true;\n\t\treturn (delta > 0 ? scroll < maxScroll : scroll > 0) && hasOverflow && isScrollable;\n\t}\n\t/**\n\t* The root element on which lenis is instanced\n\t*/\n\tget rootElement() {\n\t\treturn this.options.wrapper === window ? document.documentElement : this.options.wrapper;\n\t}\n\t/**\n\t* The limit which is the maximum scroll value\n\t*/\n\tget limit() {\n\t\tif (this.options.naiveDimensions) {\n\t\t\tif (this.isHorizontal) return this.rootElement.scrollWidth - this.rootElement.clientWidth;\n\t\t\treturn this.rootElement.scrollHeight - this.rootElement.clientHeight;\n\t\t}\n\t\treturn this.dimensions.limit[this.isHorizontal ? "x" : "y"];\n\t}\n\t/**\n\t* Whether or not the scroll is horizontal\n\t*/\n\tget isHorizontal() {\n\t\treturn this.options.orientation === "horizontal";\n\t}\n\t/**\n\t* The actual scroll value\n\t*/\n\tget actualScroll() {\n\t\tconst wrapper = this.options.wrapper;\n\t\treturn this.isHorizontal ? wrapper.scrollX ?? wrapper.scrollLeft : wrapper.scrollY ?? wrapper.scrollTop;\n\t}\n\t/**\n\t* The current scroll value\n\t*/\n\tget scroll() {\n\t\treturn this.options.infinite ? modulo(this.animatedScroll, this.limit) : this.animatedScroll;\n\t}\n\t/**\n\t* The progress of the scroll relative to the limit\n\t*/\n\tget progress() {\n\t\treturn this.limit === 0 ? 1 : this.scroll / this.limit;\n\t}\n\t/**\n\t* Current scroll state\n\t*/\n\tget isScrolling() {\n\t\treturn this._isScrolling;\n\t}\n\tset isScrolling(value) {\n\t\tif (this._isScrolling !== value) {\n\t\t\tthis._isScrolling = value;\n\t\t\tthis.updateClassName();\n\t\t}\n\t}\n\t/**\n\t* Check if lenis is stopped\n\t*/\n\tget isStopped() {\n\t\treturn this._isStopped;\n\t}\n\tset isStopped(value) {\n\t\tif (this._isStopped !== value) {\n\t\t\tthis._isStopped = value;\n\t\t\tthis.updateClassName();\n\t\t}\n\t}\n\t/**\n\t* Check if lenis is locked\n\t*/\n\tget isLocked() {\n\t\treturn this._isLocked;\n\t}\n\tset isLocked(value) {\n\t\tif (this._isLocked !== value) {\n\t\t\tthis._isLocked 
1= value;\n\t\t\tthis.updateClassName();\n\t\t}\n\t}\n\t/**\n\t* Check if lenis is smooth scrolling\n\t*/\n\tget isSmooth() {\n\t\treturn this.isScrolling === "smooth";\n\t}\n\t/**\n\t* The class name applied to the wrapper element\n\t*/\n\tget className() {\n\t\tlet className = "lenis";\n\t\tif (this.options.autoToggle) className += " lenis-autoToggle";\n\t\tif (this.isStopped) className += " lenis-stopped";\n\t\tif (this.isLocked) className += " lenis-locked";\n\t\tif (this.isScrolling) className += " lenis-scrolling";\n\t\tif (this.isScrolling === "smooth") className += " lenis-smooth";\n\t\treturn className;\n\t}\n\tupdateClassName() {\n\t\tthis.cleanUpClassName();\n\t\tthis.className.split(" ").forEach((className) => {\n\t\t\tthis.rootElement.classList.add(className);\n\t\t});\n\t}\n\tcleanUpClassName() {\n\t\tfor (const className of Array.from(this.rootElement.classList)) if (className === "lenis" || className.startsWith("lenis-")) this.rootElement.classList.remove(className);\n\t}\n};\n//#endregion\n\n\n//# sourceMappingURL=lenis.mjs.map\n\n//# sourceURL=webpack://real-insight/./node_modules/lenis/dist/lenis.mjs?\n}')}},__webpack_module_cache__={};function __webpack_require__(e){var n=__webpack_module_cache__[e];if(void 0!==n)return n.exports;var t=__webpack_module_cache__[e]={exports:{}};if(!(e in __webpack_modules__)){delete __webpack_module_cache__[e];var r=new Error("Cannot find module '"+e+"'");throw r.code="MODULE_NOT_FOUND",r}return __webpack_modules__[e].call(t.exports,t,t.exports,__webpack_require__),t.exports}__webpack_require__.n=e=>{var n=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(n,{a:n}),n},__webpack_require__.d=(e,n)=>{for(var t in n)__webpack_require__.o(n,t)&&!__webpack_require__.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:n[t]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__=__webpack_require__("./src/js/index.js")})();

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.