HEX
Server: Apache/2.4.41
System: Linux mainweb 5.4.0-182-generic #202-Ubuntu SMP Fri Apr 26 12:29:36 UTC 2024 x86_64
User: nationalmedicaregrp (1119)
PHP: 8.3.7
Disabled: exec,passthru,shell_exec,system,popen,proc_open,pcntl_exec
Upload Files
File: /home/accuhealthinsuranceagency/public_html/ScrollTrigger-master/ScrollTrigger.js
/**
 * Written by Erik Terwan on 03/07/16.
 *
 * Erik Terwan - development + design
 * https://erikterwan.com
 * https://github.com/terwanerik
 *
 * MIT license.
 */

(function (root, factory) {
	if (typeof define === 'function' && define.amd) {
		// AMD. Register as an anonymous module.
		define([], factory);
	} else if (typeof module === 'object' && module.exports) {
		// Node. Does not work with strict CommonJS, but
		// only CommonJS-like environments that support module.exports,
		// like Node.
		module.exports = factory();
	} else {
		// Browser globals (root is window)
		root.ScrollTrigger = factory();
	}
}(this, function () {

	'use strict';

	return function(defaultOptions, bindTo, scrollIn) {
		/**
		 * Trigger object, represents a single html element with the
		 * data-scroll tag. Stores the options given in that tag.
		 */
		var Trigger = function(_defaultOptions, _element) {
			this.element = _element;
			this.defaultOptions = _defaultOptions;
			this.showCallback = null;
			this.hideCallback = null;
			this.visibleClass = 'visible';
			this.hiddenClass = 'invisible';
			this.addWidth = false;
			this.addHeight = false;
			this.once = false;

			var xOffset = 0;
			var yOffset = 0;

			this.left = function(_this){
				return function(){
					return _this.element.getBoundingClientRect().left;
				};
			}(this);

			this.top = function(_this){
				return function(){
					return _this.element.getBoundingClientRect().top;
				};
			}(this);

			this.xOffset = function(_this){
				return function(goingLeft){
					var offset = xOffset;

					// add the full width of the element to the left position, so the
					// visibleClass is only added after the element is completely
					// in the viewport
					if (_this.addWidth && !goingLeft) {
						offset += _this.width();
					} else if (goingLeft && !_this.addWidth) {
						offset -= _this.width();
					}

					return offset;
				};
			}(this);

			this.yOffset = function(_this){
				return function(goingUp){
					var offset = yOffset;

					// add the full height of the element to the top position, so the
					// visibleClass is only added after the element is completely
					// in the viewport
					if (_this.addHeight && !goingUp) {
						offset += _this.height();
					} else if (goingUp && !_this.addHeight) {
						offset -= _this.height();
					}

					return offset;
				};
			}(this);

			this.width = function(_this) {
				return function(){
					return _this.element.offsetWidth;
				};
			}(this);

			this.height = function(_this) {
				return function(){
					return _this.element.offsetHeight;
				};
			}(this);

			this.reset = function(_this) {
				return function() {
					_this.removeClass(_this.visibleClass);
					_this.removeClass(_this.hiddenClass);
				};
			}(this);

			this.addClass = function(_this){
				var addClass = function(className, didAddCallback) {
					if (!_this.element.classList.contains(className)) {
						_this.element.classList.add(className);
						if ( typeof didAddCallback === 'function' ) {
							didAddCallback();
						}
					}
				};

				var retroAddClass = function(className, didAddCallback) {
					className = className.trim();
					var regEx = new RegExp('(?:^|\\s)' + className + '(?:(\\s\\w)|$)', 'ig');
					var oldClassName = _this.element.className;
					if ( !regEx.test(oldClassName) ) {
						_this.element.className += " " + className;
						if ( typeof didAddCallback === 'function' ) {
							didAddCallback();
						}
					}
				};

				return _this.element.classList ? addClass : retroAddClass;
			}(this);

			this.removeClass = function(_this){
				var removeClass = function(className, didRemoveCallback) {
					if (_this.element.classList.contains(className)) {
						_this.element.classList.remove(className);
						if ( typeof didRemoveCallback === 'function' ) {
							didRemoveCallback();
						}
					}
				};

				var retroRemoveClass = function(className, didRemoveCallback) {
					className = className.trim();
					var regEx = new RegExp('(?:^|\\s)' + className + '(?:(\\s\\w)|$)', 'ig');
					var oldClassName = _this.element.className;
					if ( regEx.test(oldClassName) ) {
						_this.element.className = oldClassName.replace(regEx, "$1").trim();
						if ( typeof didRemoveCallback === 'function' ) {
							didRemoveCallback();
						}
					}
				};

				return _this.element.classList ? removeClass : retroRemoveClass;
			}(this);

			this.init = function(_this){
				return function(){
					// set the default options
					var options = _this.defaultOptions;
					// parse the options given in the data-scroll attribute, if any
					var optionString = _this.element.getAttribute('data-scroll');

					if (options) {
						if (options.toggle && options.toggle.visible) {
							_this.visibleClass = options.toggle.visible;
						}

						if (options.toggle && options.toggle.hidden) {
							_this.hiddenClass = options.toggle.hidden;
						}

						if (options.showCallback) {
							_this.showCallback = options.showCallback;
						}

						if (options.hideCallback) {
							_this.hideCallback = options.hideCallback;
						}

						if (options.centerHorizontal === true) {
							xOffset = _this.element.offsetWidth / 2;
						}

						if (options.centerVertical === true) {
							yOffset = _this.element.offsetHeight / 2;
						}

						if (options.offset && options.offset.x) {
							xOffset+= options.offset.x;
						}

						if (options.offset && options.offset.y) {
							yOffset+= options.offset.y;
						}

						if (options.addWidth) {
							_this.addWidth = options.addWidth;
						}

						if (options.addHeight) {
							_this.addHeight = options.addHeight;
						}

						if (options.once) {
							_this.once = options.once;
						}
					}

					// parse the boolean options
					var parsedAddWidth = optionString.indexOf("addWidth") > -1;
					var parsedAddHeight = optionString.indexOf("addHeight") > -1;
					var parsedOnce = optionString.indexOf("once") > -1;

					// check if the 'addHeight' was toggled via the data-scroll tag, that overrides the default settings object
					if (_this.addWidth === false && parsedAddWidth === true) {
						_this.addWidth = parsedAddWidth;
					}

					if (_this.addHeight === false && parsedAddHeight === true) {
						_this.addHeight = parsedAddHeight;
					}

					if (_this.once === false && parsedOnce === true) {
						_this.once = parsedOnce;
					}

					// parse callbacks
					_this.showCallback = _this.element.hasAttribute('data-scroll-showCallback') ? _this.element.getAttribute('data-scroll-showCallback') : _this.showCallback;
					_this.hideCallback = _this.element.hasAttribute('data-scroll-hideCallback') ? _this.element.getAttribute('data-scroll-hideCallback') : _this.hideCallback;

					// split the options on the toggle() parameter
					var classParts = optionString.split('toggle(');
					if (classParts.length > 1) {
						// the toggle() parameter was given, split it at ) to get the
						// content inside the parentheses, then split them on the comma
						var classes = classParts[1].split(')')[0].split(',');

						// Check if trim exists if not, add the polyfill
						// courtesy of MDN
						if (!String.prototype.trim) {
							String.prototype.trim = function () {
								return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
							};
						}

						// trim and remove the dot
						_this.visibleClass = classes[0].trim().replace('.', '');
						_this.hiddenClass = classes[1].trim().replace('.', '');
					}

					// adds the half of the offsetWidth/Height to the x/yOffset
					if (optionString.indexOf("centerHorizontal") > -1) {
						xOffset = _this.element.offsetWidth / 2;
					}

					if (optionString.indexOf("centerVertical") > -1) {
						yOffset = _this.element.offsetHeight / 2;
					}

					// split the options on the offset() parameter
					var offsetParts = optionString.split('offset(');
					if (offsetParts.length > 1) {
						// the offset() parameter was given, split it at ) to get the
						// content inside the parentheses, then split them on the comma
						var offsets = offsetParts[1].split(')')[0].split(',');

						// remove the px unit and parse as integer
						xOffset += parseInt(offsets[0].replace('px', ''));
						yOffset += parseInt(offsets[1].replace('px', ''));
					}

					// return this for chaining
					return _this;
				};
			}(this);
		};

		// the element to detect the scroll in
		this.scrollElement = window;

		// the element to get the data-scroll elements from
		this.bindElement = document.body;

		// the scope to call the callbacks in, defaults to window
		this.callScope = window;

		// the Trigger objects
		var triggers = [];

		// attached callbacks for the requestAnimationFrame loop,
		// this is handy for custom scroll based animation. So you
		// don't have multiple, unnecessary loops going.
		var attached = [];

		// the previous scrollTop position, to determine if a user
		// is scrolling up or down. Set that to -1 -1 so the loop
		// always runs at least once
		var previousScroll = {
			left: -1,
			top: -1
		};

		// the loop method to use, preferred window.requestAnimationFrame
		var loop = window.requestAnimationFrame ||
			window.webkitRequestAnimationFrame ||
			window.mozRequestAnimationFrame ||
			window.msRequestAnimationFrame ||
			window.oRequestAnimationFrame ||
			function(callback){ setTimeout(callback, 1000 / 60); };

		// if the requestAnimationFrame is looping
		var isLooping = false;


		/**
		 * Initializes the scrollTrigger
		 */
		var init = function(_this) {
			return function(defaultOptions, bindTo, scrollIn) {
				// check if bindTo is not undefined or null,
				// otherwise use the document.body
				if (bindTo != undefined && bindTo != null) {
					_this.bindElement = bindTo;
				} else {
					_this.bindElement = document.body;
				}

				// check if the scrollIn is not undefined or null,
				// otherwise use the window
				if (scrollIn != undefined && scrollIn != null) {
					_this.scrollElement = scrollIn;
				} else {
					_this.scrollElement = window;
				}

				// Initially bind all elements with the data-scroll attribute
				_this.bind(_this.bindElement.querySelectorAll("[data-scroll]"));

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Binds new HTMLElement objects to the trigger array
		 */
		this.bind = function(_this) {
			return function(elements) {
				// check if an array is given
				if (elements instanceof HTMLElement) {
					// if it's a single HTMLElement just create an array
					elements = [elements];
				}

				// get all trigger elements, e.g. all elements with
				// the data-scroll attribute and turn it from a NodeList
				// into a plain old array
				var newTriggers = [].slice.call(elements);

				// map all the triggers to Trigger objects, and initialize them
				// so the options get parsed
				newTriggers = newTriggers.map(function (element, index) {
					var trigger = new Trigger(defaultOptions, element);

					return trigger.init();
				});

				// add to the triggers array
				triggers = triggers.concat(newTriggers);

				if (triggers.length > 0 && isLooping == false) {
					isLooping = true;

					// start the update loop
					update();
				} else {
					isLooping = false;
				}

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Returns a trigger object from a htmlElement object (e.g. via querySelector())
		 */
		this.triggerFor = function(_this) {
			return function(htmlElement){
				var returnTrigger = null;

				triggers.each(function(trigger, index) {
					if (trigger.element == htmlElement) {
						returnTrigger = trigger;
					}
				});

				return returnTrigger;
			};
		}(this);

		/**
		 * Removes a Trigger by its HTMLElement object, e.g via querySelector()
		 */
		this.destroy = function(_this) {
			return function(htmlElement) {
				triggers.each(function(trigger, index) {
					if (trigger.element == htmlElement) {
						triggers.splice(index, 1);
					}
				});

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Removes all Trigger objects from the Trigger array
		 */
		this.destroyAll = function(_this) {
			return function() {
				triggers = [];

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Resets a Trigger object, removes all added classes and then removes it from the triggers array. Like nothing
		 * ever happened..
		 */
		this.reset = function(_this) {
			return function(htmlElement) {
				var trigger = _this.triggerFor(htmlElement);

				if (trigger != null) {
					trigger.reset();

					var index = triggers.indexOf(trigger);

					if (index > -1) {
						triggers.splice(index, 1);
					}
				}

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Does the same as .reset() but for all triggers
		 */
		this.resetAll = function(_this) {
			return function() {
				triggers.each(function(trigger, index) {
					trigger.reset();
				});

				triggers = [];

				// return 'this' for chaining
				return _this;
			};
		}(this);

		/**
		 * Attaches a callback that get's called every time
		 * the update method is called
		 */
		this.attach = function(_this) {
			return function(callback) {
				// add callback to array
				attached.push(callback);

				if (!isLooping) {
					isLooping = true;

					// start the update loop
					update();
				}

				// return 'this' for chaining
				return _this;
			};
		}(this);


		/**
		 * Detaches a callback
		 */
		this.detach = function(_this) {
			return function(callback) {
				// remove callback from array
				var index = attached.indexOf(callback);

				if (index > -1) {
					attached.splice(index, 1);
				}

				return _this;
			};
		}(this);


		// store _this for use in the update function scope (strict)
		var _this = this;


		/**
		 * Gets called everytime the browser is ready for it, or when the user
		 * scrolls (on legacy browsers)
		 */
		function update() {
			// FF and IE use the documentElement instead of body
			var currentTop = !_this.bindElement.scrollTop ? document.documentElement.scrollTop : _this.bindElement.scrollTop;
			var currentLeft = !_this.bindElement.scrollLeft ? document.documentElement.scrollLeft : _this.bindElement.scrollLeft;

			// if the user scrolled
			if (previousScroll.left != currentLeft || previousScroll.top != currentTop) {
				_this.scrollDidChange();
			}

			if (triggers.length > 0 || attached.length > 0) {
				isLooping = true;

				// and loop again
				loop(update);
			} else {
				isLooping = false;
			}
		}

		this.scrollDidChange = function(_this) {
			return function() {
				var windowWidth = _this.scrollElement.innerWidth || _this.scrollElement.offsetWidth;
				var windowHeight = _this.scrollElement.innerHeight || _this.scrollElement.offsetHeight;

				// FF and IE use the documentElement instead of body
				var currentTop = !_this.bindElement.scrollTop ? document.documentElement.scrollTop : _this.bindElement.scrollTop;
				var currentLeft = !_this.bindElement.scrollLeft ? document.documentElement.scrollLeft : _this.bindElement.scrollLeft;

				var onceTriggers = [];

				// loop through all triggers
				triggers.each(function(trigger, index){
					var triggerLeft = trigger.left();
					var triggerTop = trigger.top();

					if (previousScroll.left > currentLeft) {
						// scrolling left, so we subtract the xOffset
						triggerLeft -= trigger.xOffset(true);
					} else if (previousScroll.left < currentLeft) {
						// scrolling right, so we add the xOffset
						triggerLeft += trigger.xOffset(false);
					}

					if (previousScroll.top > currentTop) {
						// scrolling up, so we subtract the yOffset
						triggerTop -= trigger.yOffset(true);
					} else if (previousScroll.top < currentTop){
						// scrolling down so then we add the yOffset
						triggerTop += trigger.yOffset(false);
					}

					// toggle the classes
					if (triggerLeft < windowWidth && triggerLeft >= 0 &&
						triggerTop < windowHeight && triggerTop >= 0) {
						// the element is visible
						trigger.addClass(trigger.visibleClass, function(){
							if (trigger.showCallback) {
								functionCall(trigger, trigger.showCallback);
							}
						});

						trigger.removeClass(trigger.hiddenClass);

						if (trigger.once) {
							// remove trigger from triggers array
							onceTriggers.push(trigger);
						}
					} else {
						// the element is invisible
						trigger.addClass(trigger.hiddenClass);
						trigger.removeClass(trigger.visibleClass, function(){
							if (trigger.hideCallback) {
								functionCall(trigger, trigger.hideCallback);
							}
						});
					}
				});

				// call the attached callbacks, if any
				attached.each(function(callback) {
					callback.call(_this, currentLeft, currentTop, windowWidth, windowHeight);
				});

				// remove the triggers that are 'once'
				onceTriggers.each(function(trigger){
					var index = triggers.indexOf(trigger);

					if (index > -1) {
						triggers.splice(index, 1);
					}
				});

				// save the current scroll position
				previousScroll.left = currentLeft;
				previousScroll.top = currentTop;
			};
		}(this);

		function functionCall(trigger, functionAsString) {
			var params = functionAsString.split('(');
			var method = params[0];

			if (params.length > 1) {
				params = params[1].split(')')[0]; // get the value between the parentheses

				// check if there are multiple attributes
				if (params.indexOf("', '") > -1) {
					params = params.split("', '");
				} else if (params.indexOf("','") > -1) {
					params = params.split("','");
				} else if (params.indexOf('", "') > -1) {
					params = params.split('", "');
				} else if (params.indexOf('","') > -1) {
					params = params.split('","');
				} else {
					// nope, just a single parameter
					params = [params];
				}
			} else {
				params = [];
			}

			// remove all quotes from the parameters
			params = params.map(function (param) {
				return removeQuotes(param);
			});

			if (typeof _this.callScope[method] == "function") {
				// function exists in the call scope so let's try to call it. Some methods don't like to have the HTMLElement
				// passed as 'this', so retry without that if it fails.
				try {
					_this.callScope[method].apply(trigger.element, params);
				} catch (e) {
					// alright let's try again
					try {
						_this.callScope[method].apply(null, params);
					} catch (e) {
						// ah to bad.
					}
				}
			}
		}

		// removes quotes from a string, e.g. turns 'foo' or "foo" into foo
		// typeof foo is string
		function removeQuotes(str) {
			str = str + ""; // force a string

			if (str[0] == '"') {
				str = str.substr(1);
			}

			if (str[0] == "'") {
				str = str.substr(1);
			}

			if (str[str.length - 1] == '"') {
				str = str.substr(0, str.length - 1);
			}

			if (str[str.length - 1] == "'") {
				str = str.substr(0, str.length - 1);
			}

			return str;
		}

		// Faster than .forEach
		Array.prototype.each = function(a) {
			var l = this.length;
			for(var i = 0; i < l; i++) {
				var e = this[i];

				if (e) {
					a(e,i);
				}
			}
		};

		return init(defaultOptions, bindTo, scrollIn);
	};
}));