Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:58:30

0001 /*!

0002  * perfect-scrollbar v1.3.0

0003  * (c) 2017 Hyunje Jun

0004  * @license MIT

0005  */
0006 function get(element) {
0007   return getComputedStyle(element);
0008 }
0009 
0010 function set(element, obj) {
0011   for (var key in obj) {
0012     var val = obj[key];
0013     if (typeof val === 'number') {
0014       val = val + "px";
0015     }
0016     element.style[key] = val;
0017   }
0018   return element;
0019 }
0020 
0021 function div(className) {
0022   var div = document.createElement('div');
0023   div.className = className;
0024   return div;
0025 }
0026 
0027 var elMatches =
0028   typeof Element !== 'undefined' &&
0029   (Element.prototype.matches ||
0030     Element.prototype.webkitMatchesSelector ||
0031     Element.prototype.msMatchesSelector);
0032 
0033 function matches(element, query) {
0034   if (!elMatches) {
0035     throw new Error('No element matching method supported');
0036   }
0037 
0038   return elMatches.call(element, query);
0039 }
0040 
0041 function remove(element) {
0042   if (element.remove) {
0043     element.remove();
0044   } else {
0045     if (element.parentNode) {
0046       element.parentNode.removeChild(element);
0047     }
0048   }
0049 }
0050 
0051 function queryChildren(element, selector) {
0052   return Array.prototype.filter.call(element.children, function (child) { return matches(child, selector); }
0053   );
0054 }
0055 
0056 var cls = {
0057   main: 'ps',
0058   element: {
0059     thumb: function (x) { return ("ps__thumb-" + x); },
0060     rail: function (x) { return ("ps__rail-" + x); },
0061     consuming: 'ps__child--consume',
0062   },
0063   state: {
0064     focus: 'ps--focus',
0065     active: function (x) { return ("ps--active-" + x); },
0066     scrolling: function (x) { return ("ps--scrolling-" + x); },
0067   },
0068 };
0069 
0070 /*

0071  * Helper methods

0072  */
0073 var scrollingClassTimeout = { x: null, y: null };
0074 
0075 function addScrollingClass(i, x) {
0076   var classList = i.element.classList;
0077   var className = cls.state.scrolling(x);
0078 
0079   if (classList.contains(className)) {
0080     clearTimeout(scrollingClassTimeout[x]);
0081   } else {
0082     classList.add(className);
0083   }
0084 }
0085 
0086 function removeScrollingClass(i, x) {
0087   scrollingClassTimeout[x] = setTimeout(
0088     function () { return i.isAlive && i.element.classList.remove(cls.state.scrolling(x)); },
0089     i.settings.scrollingThreshold
0090   );
0091 }
0092 
0093 function setScrollingClassInstantly(i, x) {
0094   addScrollingClass(i, x);
0095   removeScrollingClass(i, x);
0096 }
0097 
0098 var EventElement = function EventElement(element) {
0099   this.element = element;
0100   this.handlers = {};
0101 };
0102 
0103 var prototypeAccessors = { isEmpty: { configurable: true } };
0104 
0105 EventElement.prototype.bind = function bind (eventName, handler) {
0106   if (typeof this.handlers[eventName] === 'undefined') {
0107     this.handlers[eventName] = [];
0108   }
0109   this.handlers[eventName].push(handler);
0110   this.element.addEventListener(eventName, handler, false);
0111 };
0112 
0113 EventElement.prototype.unbind = function unbind (eventName, target) {
0114     var this$1 = this;
0115 
0116   this.handlers[eventName] = this.handlers[eventName].filter(function (handler) {
0117     if (target && handler !== target) {
0118       return true;
0119     }
0120     this$1.element.removeEventListener(eventName, handler, false);
0121     return false;
0122   });
0123 };
0124 
0125 EventElement.prototype.unbindAll = function unbindAll () {
0126     var this$1 = this;
0127 
0128   for (var name in this$1.handlers) {
0129     this$1.unbind(name);
0130   }
0131 };
0132 
0133 prototypeAccessors.isEmpty.get = function () {
0134     var this$1 = this;
0135 
0136   return Object.keys(this.handlers).every(
0137     function (key) { return this$1.handlers[key].length === 0; }
0138   );
0139 };
0140 
0141 Object.defineProperties( EventElement.prototype, prototypeAccessors );
0142 
0143 var EventManager = function EventManager() {
0144   this.eventElements = [];
0145 };
0146 
0147 EventManager.prototype.eventElement = function eventElement (element) {
0148   var ee = this.eventElements.filter(function (ee) { return ee.element === element; })[0];
0149   if (!ee) {
0150     ee = new EventElement(element);
0151     this.eventElements.push(ee);
0152   }
0153   return ee;
0154 };
0155 
0156 EventManager.prototype.bind = function bind (element, eventName, handler) {
0157   this.eventElement(element).bind(eventName, handler);
0158 };
0159 
0160 EventManager.prototype.unbind = function unbind (element, eventName, handler) {
0161   var ee = this.eventElement(element);
0162   ee.unbind(eventName, handler);
0163 
0164   if (ee.isEmpty) {
0165     // remove

0166     this.eventElements.splice(this.eventElements.indexOf(ee), 1);
0167   }
0168 };
0169 
0170 EventManager.prototype.unbindAll = function unbindAll () {
0171   this.eventElements.forEach(function (e) { return e.unbindAll(); });
0172   this.eventElements = [];
0173 };
0174 
0175 EventManager.prototype.once = function once (element, eventName, handler) {
0176   var ee = this.eventElement(element);
0177   var onceHandler = function (evt) {
0178     ee.unbind(eventName, onceHandler);
0179     handler(evt);
0180   };
0181   ee.bind(eventName, onceHandler);
0182 };
0183 
0184 function createEvent(name) {
0185   if (typeof window.CustomEvent === 'function') {
0186     return new CustomEvent(name);
0187   } else {
0188     var evt = document.createEvent('CustomEvent');
0189     evt.initCustomEvent(name, false, false, undefined);
0190     return evt;
0191   }
0192 }
0193 
0194 var processScrollDiff = function(
0195   i,
0196   axis,
0197   diff,
0198   useScrollingClass,
0199   forceFireReachEvent
0200 ) {
0201   if ( useScrollingClass === void 0 ) useScrollingClass = true;
0202   if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;
0203 
0204   var fields;
0205   if (axis === 'top') {
0206     fields = [
0207       'contentHeight',
0208       'containerHeight',
0209       'scrollTop',
0210       'y',
0211       'up',
0212       'down' ];
0213   } else if (axis === 'left') {
0214     fields = [
0215       'contentWidth',
0216       'containerWidth',
0217       'scrollLeft',
0218       'x',
0219       'left',
0220       'right' ];
0221   } else {
0222     throw new Error('A proper axis should be provided');
0223   }
0224 
0225   processScrollDiff$1(i, diff, fields, useScrollingClass, forceFireReachEvent);
0226 };
0227 
0228 function processScrollDiff$1(
0229   i,
0230   diff,
0231   ref,
0232   useScrollingClass,
0233   forceFireReachEvent
0234 ) {
0235   var contentHeight = ref[0];
0236   var containerHeight = ref[1];
0237   var scrollTop = ref[2];
0238   var y = ref[3];
0239   var up = ref[4];
0240   var down = ref[5];
0241   if ( useScrollingClass === void 0 ) useScrollingClass = true;
0242   if ( forceFireReachEvent === void 0 ) forceFireReachEvent = false;
0243 
0244   var element = i.element;
0245 
0246   // reset reach

0247   i.reach[y] = null;
0248 
0249   // 1 for subpixel rounding

0250   if (element[scrollTop] < 1) {
0251     i.reach[y] = 'start';
0252   }
0253 
0254   // 1 for subpixel rounding

0255   if (element[scrollTop] > i[contentHeight] - i[containerHeight] - 1) {
0256     i.reach[y] = 'end';
0257   }
0258 
0259   if (diff) {
0260     element.dispatchEvent(createEvent(("ps-scroll-" + y)));
0261 
0262     if (diff < 0) {
0263       element.dispatchEvent(createEvent(("ps-scroll-" + up)));
0264     } else if (diff > 0) {
0265       element.dispatchEvent(createEvent(("ps-scroll-" + down)));
0266     }
0267 
0268     if (useScrollingClass) {
0269       setScrollingClassInstantly(i, y);
0270     }
0271   }
0272 
0273   if (i.reach[y] && (diff || forceFireReachEvent)) {
0274     element.dispatchEvent(createEvent(("ps-" + y + "-reach-" + (i.reach[y]))));
0275   }
0276 }
0277 
0278 function toInt(x) {
0279   return parseInt(x, 10) || 0;
0280 }
0281 
0282 function isEditable(el) {
0283   return (
0284     matches(el, 'input,[contenteditable]') ||
0285     matches(el, 'select,[contenteditable]') ||
0286     matches(el, 'textarea,[contenteditable]') ||
0287     matches(el, 'button,[contenteditable]')
0288   );
0289 }
0290 
0291 function outerWidth(element) {
0292   var styles = get(element);
0293   return (
0294     toInt(styles.width) +
0295     toInt(styles.paddingLeft) +
0296     toInt(styles.paddingRight) +
0297     toInt(styles.borderLeftWidth) +
0298     toInt(styles.borderRightWidth)
0299   );
0300 }
0301 
0302 var env = {
0303   isWebKit:
0304     typeof document !== 'undefined' &&
0305     'WebkitAppearance' in document.documentElement.style,
0306   supportsTouch:
0307     typeof window !== 'undefined' &&
0308     ('ontouchstart' in window ||
0309       (window.DocumentTouch && document instanceof window.DocumentTouch)),
0310   supportsIePointer:
0311     typeof navigator !== 'undefined' && navigator.msMaxTouchPoints,
0312   isChrome:
0313     typeof navigator !== 'undefined' &&
0314     /Chrome/i.test(navigator && navigator.userAgent),
0315 };
0316 
0317 var updateGeometry = function(i) {
0318   var element = i.element;
0319 
0320   i.containerWidth = element.clientWidth;
0321   i.containerHeight = element.clientHeight;
0322   i.contentWidth = element.scrollWidth;
0323   i.contentHeight = element.scrollHeight;
0324 
0325   if (!element.contains(i.scrollbarXRail)) {
0326     // clean up and append

0327     queryChildren(element, cls.element.rail('x')).forEach(function (el) { return remove(el); }
0328     );
0329     element.appendChild(i.scrollbarXRail);
0330   }
0331   if (!element.contains(i.scrollbarYRail)) {
0332     // clean up and append

0333     queryChildren(element, cls.element.rail('y')).forEach(function (el) { return remove(el); }
0334     );
0335     element.appendChild(i.scrollbarYRail);
0336   }
0337 
0338   if (
0339     !i.settings.suppressScrollX &&
0340     i.containerWidth + i.settings.scrollXMarginOffset < i.contentWidth
0341   ) {
0342     i.scrollbarXActive = true;
0343     i.railXWidth = i.containerWidth - i.railXMarginWidth;
0344     i.railXRatio = i.containerWidth / i.railXWidth;
0345     i.scrollbarXWidth = getThumbSize(
0346       i,
0347       toInt(i.railXWidth * i.containerWidth / i.contentWidth)
0348     );
0349     i.scrollbarXLeft = toInt(
0350       (i.negativeScrollAdjustment + element.scrollLeft) *
0351         (i.railXWidth - i.scrollbarXWidth) /
0352         (i.contentWidth - i.containerWidth)
0353     );
0354   } else {
0355     i.scrollbarXActive = false;
0356   }
0357 
0358   if (
0359     !i.settings.suppressScrollY &&
0360     i.containerHeight + i.settings.scrollYMarginOffset < i.contentHeight
0361   ) {
0362     i.scrollbarYActive = true;
0363     i.railYHeight = i.containerHeight - i.railYMarginHeight;
0364     i.railYRatio = i.containerHeight / i.railYHeight;
0365     i.scrollbarYHeight = getThumbSize(
0366       i,
0367       toInt(i.railYHeight * i.containerHeight / i.contentHeight)
0368     );
0369     i.scrollbarYTop = toInt(
0370       element.scrollTop *
0371         (i.railYHeight - i.scrollbarYHeight) /
0372         (i.contentHeight - i.containerHeight)
0373     );
0374   } else {
0375     i.scrollbarYActive = false;
0376   }
0377 
0378   if (i.scrollbarXLeft >= i.railXWidth - i.scrollbarXWidth) {
0379     i.scrollbarXLeft = i.railXWidth - i.scrollbarXWidth;
0380   }
0381   if (i.scrollbarYTop >= i.railYHeight - i.scrollbarYHeight) {
0382     i.scrollbarYTop = i.railYHeight - i.scrollbarYHeight;
0383   }
0384 
0385   updateCss(element, i);
0386 
0387   if (i.scrollbarXActive) {
0388     element.classList.add(cls.state.active('x'));
0389   } else {
0390     element.classList.remove(cls.state.active('x'));
0391     i.scrollbarXWidth = 0;
0392     i.scrollbarXLeft = 0;
0393     element.scrollLeft = 0;
0394   }
0395   if (i.scrollbarYActive) {
0396     element.classList.add(cls.state.active('y'));
0397   } else {
0398     element.classList.remove(cls.state.active('y'));
0399     i.scrollbarYHeight = 0;
0400     i.scrollbarYTop = 0;
0401     element.scrollTop = 0;
0402   }
0403 };
0404 
0405 function getThumbSize(i, thumbSize) {
0406   if (i.settings.minScrollbarLength) {
0407     thumbSize = Math.max(thumbSize, i.settings.minScrollbarLength);
0408   }
0409   if (i.settings.maxScrollbarLength) {
0410     thumbSize = Math.min(thumbSize, i.settings.maxScrollbarLength);
0411   }
0412   return thumbSize;
0413 }
0414 
0415 function updateCss(element, i) {
0416   var xRailOffset = { width: i.railXWidth };
0417   if (i.isRtl) {
0418     xRailOffset.left =
0419       i.negativeScrollAdjustment +
0420       element.scrollLeft +
0421       i.containerWidth -
0422       i.contentWidth;
0423   } else {
0424     xRailOffset.left = element.scrollLeft;
0425   }
0426   if (i.isScrollbarXUsingBottom) {
0427     xRailOffset.bottom = i.scrollbarXBottom - element.scrollTop;
0428   } else {
0429     xRailOffset.top = i.scrollbarXTop + element.scrollTop;
0430   }
0431   set(i.scrollbarXRail, xRailOffset);
0432 
0433   var yRailOffset = { top: element.scrollTop, height: i.railYHeight };
0434   if (i.isScrollbarYUsingRight) {
0435     if (i.isRtl) {
0436       yRailOffset.right =
0437         i.contentWidth -
0438         (i.negativeScrollAdjustment + element.scrollLeft) -
0439         i.scrollbarYRight -
0440         i.scrollbarYOuterWidth;
0441     } else {
0442       yRailOffset.right = i.scrollbarYRight - element.scrollLeft;
0443     }
0444   } else {
0445     if (i.isRtl) {
0446       yRailOffset.left =
0447         i.negativeScrollAdjustment +
0448         element.scrollLeft +
0449         i.containerWidth * 2 -
0450         i.contentWidth -
0451         i.scrollbarYLeft -
0452         i.scrollbarYOuterWidth;
0453     } else {
0454       yRailOffset.left = i.scrollbarYLeft + element.scrollLeft;
0455     }
0456   }
0457   set(i.scrollbarYRail, yRailOffset);
0458 
0459   set(i.scrollbarX, {
0460     left: i.scrollbarXLeft,
0461     width: i.scrollbarXWidth - i.railBorderXWidth,
0462   });
0463   set(i.scrollbarY, {
0464     top: i.scrollbarYTop,
0465     height: i.scrollbarYHeight - i.railBorderYWidth,
0466   });
0467 }
0468 
0469 var clickRail = function(i) {
0470   i.event.bind(i.scrollbarY, 'mousedown', function (e) { return e.stopPropagation(); });
0471   i.event.bind(i.scrollbarYRail, 'mousedown', function (e) {
0472     var positionTop =
0473       e.pageY -
0474       window.pageYOffset -
0475       i.scrollbarYRail.getBoundingClientRect().top;
0476     var direction = positionTop > i.scrollbarYTop ? 1 : -1;
0477 
0478     i.element.scrollTop += direction * i.containerHeight;
0479     updateGeometry(i);
0480 
0481     e.stopPropagation();
0482   });
0483 
0484   i.event.bind(i.scrollbarX, 'mousedown', function (e) { return e.stopPropagation(); });
0485   i.event.bind(i.scrollbarXRail, 'mousedown', function (e) {
0486     var positionLeft =
0487       e.pageX -
0488       window.pageXOffset -
0489       i.scrollbarXRail.getBoundingClientRect().left;
0490     var direction = positionLeft > i.scrollbarXLeft ? 1 : -1;
0491 
0492     i.element.scrollLeft += direction * i.containerWidth;
0493     updateGeometry(i);
0494 
0495     e.stopPropagation();
0496   });
0497 };
0498 
0499 var dragThumb = function(i) {
0500   bindMouseScrollHandler(i, [
0501     'containerWidth',
0502     'contentWidth',
0503     'pageX',
0504     'railXWidth',
0505     'scrollbarX',
0506     'scrollbarXWidth',
0507     'scrollLeft',
0508     'x' ]);
0509   bindMouseScrollHandler(i, [
0510     'containerHeight',
0511     'contentHeight',
0512     'pageY',
0513     'railYHeight',
0514     'scrollbarY',
0515     'scrollbarYHeight',
0516     'scrollTop',
0517     'y' ]);
0518 };
0519 
0520 function bindMouseScrollHandler(
0521   i,
0522   ref
0523 ) {
0524   var containerHeight = ref[0];
0525   var contentHeight = ref[1];
0526   var pageY = ref[2];
0527   var railYHeight = ref[3];
0528   var scrollbarY = ref[4];
0529   var scrollbarYHeight = ref[5];
0530   var scrollTop = ref[6];
0531   var y = ref[7];
0532 
0533   var element = i.element;
0534 
0535   var startingScrollTop = null;
0536   var startingMousePageY = null;
0537   var scrollBy = null;
0538 
0539   function mouseMoveHandler(e) {
0540     element[scrollTop] =
0541       startingScrollTop + scrollBy * (e[pageY] - startingMousePageY);
0542     addScrollingClass(i, y);
0543     updateGeometry(i);
0544 
0545     e.stopPropagation();
0546     e.preventDefault();
0547   }
0548 
0549   function mouseUpHandler() {
0550     removeScrollingClass(i, y);
0551     i.event.unbind(i.ownerDocument, 'mousemove', mouseMoveHandler);
0552   }
0553 
0554   i.event.bind(i[scrollbarY], 'mousedown', function (e) {
0555     startingScrollTop = element[scrollTop];
0556     startingMousePageY = e[pageY];
0557     scrollBy =
0558       (i[contentHeight] - i[containerHeight]) /
0559       (i[railYHeight] - i[scrollbarYHeight]);
0560 
0561     i.event.bind(i.ownerDocument, 'mousemove', mouseMoveHandler);
0562     i.event.once(i.ownerDocument, 'mouseup', mouseUpHandler);
0563 
0564     e.stopPropagation();
0565     e.preventDefault();
0566   });
0567 }
0568 
0569 var keyboard = function(i) {
0570   var element = i.element;
0571 
0572   var elementHovered = function () { return matches(element, ':hover'); };
0573   var scrollbarFocused = function () { return matches(i.scrollbarX, ':focus') || matches(i.scrollbarY, ':focus'); };
0574 
0575   function shouldPreventDefault(deltaX, deltaY) {
0576     var scrollTop = element.scrollTop;
0577     if (deltaX === 0) {
0578       if (!i.scrollbarYActive) {
0579         return false;
0580       }
0581       if (
0582         (scrollTop === 0 && deltaY > 0) ||
0583         (scrollTop >= i.contentHeight - i.containerHeight && deltaY < 0)
0584       ) {
0585         return !i.settings.wheelPropagation;
0586       }
0587     }
0588 
0589     var scrollLeft = element.scrollLeft;
0590     if (deltaY === 0) {
0591       if (!i.scrollbarXActive) {
0592         return false;
0593       }
0594       if (
0595         (scrollLeft === 0 && deltaX < 0) ||
0596         (scrollLeft >= i.contentWidth - i.containerWidth && deltaX > 0)
0597       ) {
0598         return !i.settings.wheelPropagation;
0599       }
0600     }
0601     return true;
0602   }
0603 
0604   i.event.bind(i.ownerDocument, 'keydown', function (e) {
0605     if (
0606       (e.isDefaultPrevented && e.isDefaultPrevented()) ||
0607       e.defaultPrevented
0608     ) {
0609       return;
0610     }
0611 
0612     if (!elementHovered() && !scrollbarFocused()) {
0613       return;
0614     }
0615 
0616     var activeElement = document.activeElement
0617       ? document.activeElement
0618       : i.ownerDocument.activeElement;
0619     if (activeElement) {
0620       if (activeElement.tagName === 'IFRAME') {
0621         activeElement = activeElement.contentDocument.activeElement;
0622       } else {
0623         // go deeper if element is a webcomponent

0624         while (activeElement.shadowRoot) {
0625           activeElement = activeElement.shadowRoot.activeElement;
0626         }
0627       }
0628       if (isEditable(activeElement)) {
0629         return;
0630       }
0631     }
0632 
0633     var deltaX = 0;
0634     var deltaY = 0;
0635 
0636     switch (e.which) {
0637       case 37: // left

0638         if (e.metaKey) {
0639           deltaX = -i.contentWidth;
0640         } else if (e.altKey) {
0641           deltaX = -i.containerWidth;
0642         } else {
0643           deltaX = -30;
0644         }
0645         break;
0646       case 38: // up

0647         if (e.metaKey) {
0648           deltaY = i.contentHeight;
0649         } else if (e.altKey) {
0650           deltaY = i.containerHeight;
0651         } else {
0652           deltaY = 30;
0653         }
0654         break;
0655       case 39: // right

0656         if (e.metaKey) {
0657           deltaX = i.contentWidth;
0658         } else if (e.altKey) {
0659           deltaX = i.containerWidth;
0660         } else {
0661           deltaX = 30;
0662         }
0663         break;
0664       case 40: // down

0665         if (e.metaKey) {
0666           deltaY = -i.contentHeight;
0667         } else if (e.altKey) {
0668           deltaY = -i.containerHeight;
0669         } else {
0670           deltaY = -30;
0671         }
0672         break;
0673       case 32: // space bar

0674         if (e.shiftKey) {
0675           deltaY = i.containerHeight;
0676         } else {
0677           deltaY = -i.containerHeight;
0678         }
0679         break;
0680       case 33: // page up

0681         deltaY = i.containerHeight;
0682         break;
0683       case 34: // page down

0684         deltaY = -i.containerHeight;
0685         break;
0686       case 36: // home

0687         deltaY = i.contentHeight;
0688         break;
0689       case 35: // end

0690         deltaY = -i.contentHeight;
0691         break;
0692       default:
0693         return;
0694     }
0695 
0696     if (i.settings.suppressScrollX && deltaX !== 0) {
0697       return;
0698     }
0699     if (i.settings.suppressScrollY && deltaY !== 0) {
0700       return;
0701     }
0702 
0703     element.scrollTop -= deltaY;
0704     element.scrollLeft += deltaX;
0705     updateGeometry(i);
0706 
0707     if (shouldPreventDefault(deltaX, deltaY)) {
0708       e.preventDefault();
0709     }
0710   });
0711 };
0712 
0713 var wheel = function(i) {
0714   var element = i.element;
0715 
0716   function shouldPreventDefault(deltaX, deltaY) {
0717     var isTop = element.scrollTop === 0;
0718     var isBottom =
0719       element.scrollTop + element.offsetHeight === element.scrollHeight;
0720     var isLeft = element.scrollLeft === 0;
0721     var isRight =
0722       element.scrollLeft + element.offsetWidth === element.offsetWidth;
0723 
0724     var hitsBound;
0725 
0726     // pick axis with primary direction

0727     if (Math.abs(deltaY) > Math.abs(deltaX)) {
0728       hitsBound = isTop || isBottom;
0729     } else {
0730       hitsBound = isLeft || isRight;
0731     }
0732 
0733     return hitsBound ? !i.settings.wheelPropagation : true;
0734   }
0735 
0736   function getDeltaFromEvent(e) {
0737     var deltaX = e.deltaX;
0738     var deltaY = -1 * e.deltaY;
0739 
0740     if (typeof deltaX === 'undefined' || typeof deltaY === 'undefined') {
0741       // OS X Safari

0742       deltaX = -1 * e.wheelDeltaX / 6;
0743       deltaY = e.wheelDeltaY / 6;
0744     }
0745 
0746     if (e.deltaMode && e.deltaMode === 1) {
0747       // Firefox in deltaMode 1: Line scrolling

0748       deltaX *= 10;
0749       deltaY *= 10;
0750     }
0751 
0752     if (deltaX !== deltaX && deltaY !== deltaY /* NaN checks */) {
0753       // IE in some mouse drivers

0754       deltaX = 0;
0755       deltaY = e.wheelDelta;
0756     }
0757 
0758     if (e.shiftKey) {
0759       // reverse axis with shift key

0760       return [-deltaY, -deltaX];
0761     }
0762     return [deltaX, deltaY];
0763   }
0764 
0765   function shouldBeConsumedByChild(target, deltaX, deltaY) {
0766     // FIXME: this is a workaround for <select> issue in FF and IE #571

0767     if (!env.isWebKit && element.querySelector('select:focus')) {
0768       return true;
0769     }
0770 
0771     if (!element.contains(target)) {
0772       return false;
0773     }
0774 
0775     var cursor = target;
0776 
0777     while (cursor && cursor !== element) {
0778       if (cursor.classList.contains(cls.element.consuming)) {
0779         return true;
0780       }
0781 
0782       var style = get(cursor);
0783       var overflow = [style.overflow, style.overflowX, style.overflowY].join(
0784         ''
0785       );
0786 
0787       // if scrollable

0788       if (overflow.match(/(scroll|auto)/)) {
0789         var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;
0790         if (maxScrollTop > 0) {
0791           if (
0792             !(cursor.scrollTop === 0 && deltaY > 0) &&
0793             !(cursor.scrollTop === maxScrollTop && deltaY < 0)
0794           ) {
0795             return true;
0796           }
0797         }
0798         var maxScrollLeft = cursor.scrollLeft - cursor.clientWidth;
0799         if (maxScrollLeft > 0) {
0800           if (
0801             !(cursor.scrollLeft === 0 && deltaX < 0) &&
0802             !(cursor.scrollLeft === maxScrollLeft && deltaX > 0)
0803           ) {
0804             return true;
0805           }
0806         }
0807       }
0808 
0809       cursor = cursor.parentNode;
0810     }
0811 
0812     return false;
0813   }
0814 
0815   function mousewheelHandler(e) {
0816     var ref = getDeltaFromEvent(e);
0817     var deltaX = ref[0];
0818     var deltaY = ref[1];
0819 
0820     if (shouldBeConsumedByChild(e.target, deltaX, deltaY)) {
0821       return;
0822     }
0823 
0824     var shouldPrevent = false;
0825     if (!i.settings.useBothWheelAxes) {
0826       // deltaX will only be used for horizontal scrolling and deltaY will

0827       // only be used for vertical scrolling - this is the default

0828       element.scrollTop -= deltaY * i.settings.wheelSpeed;
0829       element.scrollLeft += deltaX * i.settings.wheelSpeed;
0830     } else if (i.scrollbarYActive && !i.scrollbarXActive) {
0831       // only vertical scrollbar is active and useBothWheelAxes option is

0832       // active, so let's scroll vertical bar using both mouse wheel axes

0833       if (deltaY) {
0834         element.scrollTop -= deltaY * i.settings.wheelSpeed;
0835       } else {
0836         element.scrollTop += deltaX * i.settings.wheelSpeed;
0837       }
0838       shouldPrevent = true;
0839     } else if (i.scrollbarXActive && !i.scrollbarYActive) {
0840       // useBothWheelAxes and only horizontal bar is active, so use both

0841       // wheel axes for horizontal bar

0842       if (deltaX) {
0843         element.scrollLeft += deltaX * i.settings.wheelSpeed;
0844       } else {
0845         element.scrollLeft -= deltaY * i.settings.wheelSpeed;
0846       }
0847       shouldPrevent = true;
0848     }
0849 
0850     updateGeometry(i);
0851 
0852     shouldPrevent = shouldPrevent || shouldPreventDefault(deltaX, deltaY);
0853     if (shouldPrevent && !e.ctrlKey) {
0854       e.stopPropagation();
0855       e.preventDefault();
0856     }
0857   }
0858 
0859   if (typeof window.onwheel !== 'undefined') {
0860     i.event.bind(element, 'wheel', mousewheelHandler);
0861   } else if (typeof window.onmousewheel !== 'undefined') {
0862     i.event.bind(element, 'mousewheel', mousewheelHandler);
0863   }
0864 };
0865 
0866 var touch = function(i) {
0867   if (!env.supportsTouch && !env.supportsIePointer) {
0868     return;
0869   }
0870 
0871   var element = i.element;
0872 
0873   function shouldPrevent(deltaX, deltaY) {
0874     var scrollTop = element.scrollTop;
0875     var scrollLeft = element.scrollLeft;
0876     var magnitudeX = Math.abs(deltaX);
0877     var magnitudeY = Math.abs(deltaY);
0878 
0879     if (magnitudeY > magnitudeX) {
0880       // user is perhaps trying to swipe up/down the page

0881 
0882       if (
0883         (deltaY < 0 && scrollTop === i.contentHeight - i.containerHeight) ||
0884         (deltaY > 0 && scrollTop === 0)
0885       ) {
0886         // set prevent for mobile Chrome refresh

0887         return window.scrollY === 0 && deltaY > 0 && env.isChrome;
0888       }
0889     } else if (magnitudeX > magnitudeY) {
0890       // user is perhaps trying to swipe left/right across the page

0891 
0892       if (
0893         (deltaX < 0 && scrollLeft === i.contentWidth - i.containerWidth) ||
0894         (deltaX > 0 && scrollLeft === 0)
0895       ) {
0896         return true;
0897       }
0898     }
0899 
0900     return true;
0901   }
0902 
0903   function applyTouchMove(differenceX, differenceY) {
0904     element.scrollTop -= differenceY;
0905     element.scrollLeft -= differenceX;
0906 
0907     updateGeometry(i);
0908   }
0909 
0910   var startOffset = {};
0911   var startTime = 0;
0912   var speed = {};
0913   var easingLoop = null;
0914 
0915   function getTouch(e) {
0916     if (e.targetTouches) {
0917       return e.targetTouches[0];
0918     } else {
0919       // Maybe IE pointer

0920       return e;
0921     }
0922   }
0923 
0924   function shouldHandle(e) {
0925     if (e.pointerType && e.pointerType === 'pen' && e.buttons === 0) {
0926       return false;
0927     }
0928     if (e.targetTouches && e.targetTouches.length === 1) {
0929       return true;
0930     }
0931     if (
0932       e.pointerType &&
0933       e.pointerType !== 'mouse' &&
0934       e.pointerType !== e.MSPOINTER_TYPE_MOUSE
0935     ) {
0936       return true;
0937     }
0938     return false;
0939   }
0940 
0941   function touchStart(e) {
0942     if (!shouldHandle(e)) {
0943       return;
0944     }
0945 
0946     var touch = getTouch(e);
0947 
0948     startOffset.pageX = touch.pageX;
0949     startOffset.pageY = touch.pageY;
0950 
0951     startTime = new Date().getTime();
0952 
0953     if (easingLoop !== null) {
0954       clearInterval(easingLoop);
0955     }
0956   }
0957 
0958   function shouldBeConsumedByChild(target, deltaX, deltaY) {
0959     if (!element.contains(target)) {
0960       return false;
0961     }
0962 
0963     var cursor = target;
0964 
0965     while (cursor && cursor !== element) {
0966       if (cursor.classList.contains(cls.element.consuming)) {
0967         return true;
0968       }
0969 
0970       var style = get(cursor);
0971       var overflow = [style.overflow, style.overflowX, style.overflowY].join(
0972         ''
0973       );
0974 
0975       // if scrollable

0976       if (overflow.match(/(scroll|auto)/)) {
0977         var maxScrollTop = cursor.scrollHeight - cursor.clientHeight;
0978         if (maxScrollTop > 0) {
0979           if (
0980             !(cursor.scrollTop === 0 && deltaY > 0) &&
0981             !(cursor.scrollTop === maxScrollTop && deltaY < 0)
0982           ) {
0983             return true;
0984           }
0985         }
0986         var maxScrollLeft = cursor.scrollLeft - cursor.clientWidth;
0987         if (maxScrollLeft > 0) {
0988           if (
0989             !(cursor.scrollLeft === 0 && deltaX < 0) &&
0990             !(cursor.scrollLeft === maxScrollLeft && deltaX > 0)
0991           ) {
0992             return true;
0993           }
0994         }
0995       }
0996 
0997       cursor = cursor.parentNode;
0998     }
0999 
1000     return false;
1001   }
1002 
1003   function touchMove(e) {
1004     if (shouldHandle(e)) {
1005       var touch = getTouch(e);
1006 
1007       var currentOffset = { pageX: touch.pageX, pageY: touch.pageY };
1008 
1009       var differenceX = currentOffset.pageX - startOffset.pageX;
1010       var differenceY = currentOffset.pageY - startOffset.pageY;
1011 
1012       if (shouldBeConsumedByChild(e.target, differenceX, differenceY)) {
1013         return;
1014       }
1015 
1016       applyTouchMove(differenceX, differenceY);
1017       startOffset = currentOffset;
1018 
1019       var currentTime = new Date().getTime();
1020 
1021       var timeGap = currentTime - startTime;
1022       if (timeGap > 0) {
1023         speed.x = differenceX / timeGap;
1024         speed.y = differenceY / timeGap;
1025         startTime = currentTime;
1026       }
1027 
1028       if (shouldPrevent(differenceX, differenceY)) {
1029         e.preventDefault();
1030       }
1031     }
1032   }
1033   function touchEnd() {
1034     if (i.settings.swipeEasing) {
1035       clearInterval(easingLoop);
1036       easingLoop = setInterval(function() {
1037         if (i.isInitialized) {
1038           clearInterval(easingLoop);
1039           return;
1040         }
1041 
1042         if (!speed.x && !speed.y) {
1043           clearInterval(easingLoop);
1044           return;
1045         }
1046 
1047         if (Math.abs(speed.x) < 0.01 && Math.abs(speed.y) < 0.01) {
1048           clearInterval(easingLoop);
1049           return;
1050         }
1051 
1052         applyTouchMove(speed.x * 30, speed.y * 30);
1053 
1054         speed.x *= 0.8;
1055         speed.y *= 0.8;
1056       }, 10);
1057     }
1058   }
1059 
1060   if (env.supportsTouch) {
1061     i.event.bind(element, 'touchstart', touchStart);
1062     i.event.bind(element, 'touchmove', touchMove);
1063     i.event.bind(element, 'touchend', touchEnd);
1064   } else if (env.supportsIePointer) {
1065     if (window.PointerEvent) {
1066       i.event.bind(element, 'pointerdown', touchStart);
1067       i.event.bind(element, 'pointermove', touchMove);
1068       i.event.bind(element, 'pointerup', touchEnd);
1069     } else if (window.MSPointerEvent) {
1070       i.event.bind(element, 'MSPointerDown', touchStart);
1071       i.event.bind(element, 'MSPointerMove', touchMove);
1072       i.event.bind(element, 'MSPointerUp', touchEnd);
1073     }
1074   }
1075 };
1076 
1077 var defaultSettings = function () { return ({
1078   handlers: ['click-rail', 'drag-thumb', 'keyboard', 'wheel', 'touch'],
1079   maxScrollbarLength: null,
1080   minScrollbarLength: null,
1081   scrollingThreshold: 1000,
1082   scrollXMarginOffset: 0,
1083   scrollYMarginOffset: 0,
1084   suppressScrollX: false,
1085   suppressScrollY: false,
1086   swipeEasing: true,
1087   useBothWheelAxes: false,
1088   wheelPropagation: false,
1089   wheelSpeed: 1,
1090 }); };
1091 
1092 var handlers = {
1093   'click-rail': clickRail,
1094   'drag-thumb': dragThumb,
1095   keyboard: keyboard,
1096   wheel: wheel,
1097   touch: touch,
1098 };
1099 
1100 var PerfectScrollbar = function PerfectScrollbar(element, userSettings) {
1101   var this$1 = this;
1102   if ( userSettings === void 0 ) userSettings = {};
1103 
1104   if (typeof element === 'string') {
1105     element = document.querySelector(element);
1106   }
1107 
1108   if (!element || !element.nodeName) {
1109     throw new Error('no element is specified to initialize PerfectScrollbar');
1110   }
1111 
1112   this.element = element;
1113 
1114   element.classList.add(cls.main);
1115 
1116   this.settings = defaultSettings();
1117   for (var key in userSettings) {
1118     this$1.settings[key] = userSettings[key];
1119   }
1120 
1121   this.containerWidth = null;
1122   this.containerHeight = null;
1123   this.contentWidth = null;
1124   this.contentHeight = null;
1125 
1126   var focus = function () { return element.classList.add(cls.state.focus); };
1127   var blur = function () { return element.classList.remove(cls.state.focus); };
1128 
1129   this.isRtl = get(element).direction === 'rtl';
1130   this.isNegativeScroll = (function () {
1131     var originalScrollLeft = element.scrollLeft;
1132     var result = null;
1133     element.scrollLeft = -1;
1134     result = element.scrollLeft < 0;
1135     element.scrollLeft = originalScrollLeft;
1136     return result;
1137   })();
1138   this.negativeScrollAdjustment = this.isNegativeScroll
1139     ? element.scrollWidth - element.clientWidth
1140     : 0;
1141   this.event = new EventManager();
1142   this.ownerDocument = element.ownerDocument || document;
1143 
1144   this.scrollbarXRail = div(cls.element.rail('x'));
1145   element.appendChild(this.scrollbarXRail);
1146   this.scrollbarX = div(cls.element.thumb('x'));
1147   this.scrollbarXRail.appendChild(this.scrollbarX);
1148   this.scrollbarX.setAttribute('tabindex', 0);
1149   this.event.bind(this.scrollbarX, 'focus', focus);
1150   this.event.bind(this.scrollbarX, 'blur', blur);
1151   this.scrollbarXActive = null;
1152   this.scrollbarXWidth = null;
1153   this.scrollbarXLeft = null;
1154   var railXStyle = get(this.scrollbarXRail);
1155   this.scrollbarXBottom = parseInt(railXStyle.bottom, 10);
1156   if (isNaN(this.scrollbarXBottom)) {
1157     this.isScrollbarXUsingBottom = false;
1158     this.scrollbarXTop = toInt(railXStyle.top);
1159   } else {
1160     this.isScrollbarXUsingBottom = true;
1161   }
1162   this.railBorderXWidth =
1163     toInt(railXStyle.borderLeftWidth) + toInt(railXStyle.borderRightWidth);
1164   // Set rail to display:block to calculate margins

1165   set(this.scrollbarXRail, { display: 'block' });
1166   this.railXMarginWidth =
1167     toInt(railXStyle.marginLeft) + toInt(railXStyle.marginRight);
1168   set(this.scrollbarXRail, { display: '' });
1169   this.railXWidth = null;
1170   this.railXRatio = null;
1171 
1172   this.scrollbarYRail = div(cls.element.rail('y'));
1173   element.appendChild(this.scrollbarYRail);
1174   this.scrollbarY = div(cls.element.thumb('y'));
1175   this.scrollbarYRail.appendChild(this.scrollbarY);
1176   this.scrollbarY.setAttribute('tabindex', 0);
1177   this.event.bind(this.scrollbarY, 'focus', focus);
1178   this.event.bind(this.scrollbarY, 'blur', blur);
1179   this.scrollbarYActive = null;
1180   this.scrollbarYHeight = null;
1181   this.scrollbarYTop = null;
1182   var railYStyle = get(this.scrollbarYRail);
1183   this.scrollbarYRight = parseInt(railYStyle.right, 10);
1184   if (isNaN(this.scrollbarYRight)) {
1185     this.isScrollbarYUsingRight = false;
1186     this.scrollbarYLeft = toInt(railYStyle.left);
1187   } else {
1188     this.isScrollbarYUsingRight = true;
1189   }
1190   this.scrollbarYOuterWidth = this.isRtl ? outerWidth(this.scrollbarY) : null;
1191   this.railBorderYWidth =
1192     toInt(railYStyle.borderTopWidth) + toInt(railYStyle.borderBottomWidth);
1193   set(this.scrollbarYRail, { display: 'block' });
1194   this.railYMarginHeight =
1195     toInt(railYStyle.marginTop) + toInt(railYStyle.marginBottom);
1196   set(this.scrollbarYRail, { display: '' });
1197   this.railYHeight = null;
1198   this.railYRatio = null;
1199 
1200   this.reach = {
1201     x:
1202       element.scrollLeft <= 0
1203         ? 'start'
1204         : element.scrollLeft >= this.contentWidth - this.containerWidth
1205           ? 'end'
1206           : null,
1207     y:
1208       element.scrollTop <= 0
1209         ? 'start'
1210         : element.scrollTop >= this.contentHeight - this.containerHeight
1211           ? 'end'
1212           : null,
1213   };
1214 
1215   this.isAlive = true;
1216 
1217   this.settings.handlers.forEach(function (handlerName) { return handlers[handlerName](this$1); });
1218 
1219   this.lastScrollTop = element.scrollTop; // for onScroll only

1220   this.lastScrollLeft = element.scrollLeft; // for onScroll only

1221   this.event.bind(this.element, 'scroll', function (e) { return this$1.onScroll(e); });
1222   updateGeometry(this);
1223 };
1224 
1225 PerfectScrollbar.prototype.update = function update () {
1226   if (!this.isAlive) {
1227     return;
1228   }
1229 
1230   // Recalcuate negative scrollLeft adjustment

1231   this.negativeScrollAdjustment = this.isNegativeScroll
1232     ? this.element.scrollWidth - this.element.clientWidth
1233     : 0;
1234 
1235   // Recalculate rail margins

1236   set(this.scrollbarXRail, { display: 'block' });
1237   set(this.scrollbarYRail, { display: 'block' });
1238   this.railXMarginWidth =
1239     toInt(get(this.scrollbarXRail).marginLeft) +
1240     toInt(get(this.scrollbarXRail).marginRight);
1241   this.railYMarginHeight =
1242     toInt(get(this.scrollbarYRail).marginTop) +
1243     toInt(get(this.scrollbarYRail).marginBottom);
1244 
1245   // Hide scrollbars not to affect scrollWidth and scrollHeight

1246   set(this.scrollbarXRail, { display: 'none' });
1247   set(this.scrollbarYRail, { display: 'none' });
1248 
1249   updateGeometry(this);
1250 
1251   processScrollDiff(this, 'top', 0, false, true);
1252   processScrollDiff(this, 'left', 0, false, true);
1253 
1254   set(this.scrollbarXRail, { display: '' });
1255   set(this.scrollbarYRail, { display: '' });
1256 };
1257 
1258 PerfectScrollbar.prototype.onScroll = function onScroll (e) {
1259   if (!this.isAlive) {
1260     return;
1261   }
1262 
1263   updateGeometry(this);
1264   processScrollDiff(this, 'top', this.element.scrollTop - this.lastScrollTop);
1265   processScrollDiff(
1266     this,
1267     'left',
1268     this.element.scrollLeft - this.lastScrollLeft
1269   );
1270 
1271   this.lastScrollTop = this.element.scrollTop;
1272   this.lastScrollLeft = this.element.scrollLeft;
1273 };
1274 
1275 PerfectScrollbar.prototype.destroy = function destroy () {
1276   if (!this.isAlive) {
1277     return;
1278   }
1279 
1280   this.event.unbindAll();
1281   remove(this.scrollbarX);
1282   remove(this.scrollbarY);
1283   remove(this.scrollbarXRail);
1284   remove(this.scrollbarYRail);
1285   this.removePsClasses();
1286 
1287   // unset elements

1288   this.element = null;
1289   this.scrollbarX = null;
1290   this.scrollbarY = null;
1291   this.scrollbarXRail = null;
1292   this.scrollbarYRail = null;
1293 
1294   this.isAlive = false;
1295 };
1296 
1297 PerfectScrollbar.prototype.removePsClasses = function removePsClasses () {
1298   this.element.className = this.element.className
1299     .split(' ')
1300     .filter(function (name) { return !name.match(/^ps([-_].+|)$/); })
1301     .join(' ');
1302 };
1303 
1304 export default PerfectScrollbar;