PageSourceSearch

https://bardotbrush.com/wp-content/themes/mayosis/js/smoothscroll.min.js?ver=1.1

js bardotbrush.com collected 2026-09-24 20:22:20 UTC 25,360 bytes, 817 lines download raw bytes

1//
2// SmoothScroll for websites v1.5.1 (Balazs Galambosi)
3// http://www.smoothscroll.net/
4//
5// Licensed under the terms of the MIT license.
6//
7// You may use it in your theme if you credit me. 
8// It is also free to use on any individual website.
9//
10// Exception:
11// The only restriction is to not publish any  
12// extension for browsers or native application
13// without getting a written permission first.
14//
15if (!document.body.classList.contains('logged-in')) {
16(function () {
17  
18// Scroll Variables (tweakable)
19var defaultOptions = {
20
21    // Scrolling Core
22    frameRate        : 150, // [Hz]
23    animationTime    : 400, // [ms]
24    stepSize         : 100, // [px]
25
26    // Pulse (less tweakable)
27    // ratio of "tail" to "acceleration"
28    pulseAlgorithm   : true,
29    pulseScale       : 4,
30    pulseNormalize   : 1,
31
32    // Acceleration
33    accelerationDelta : 50,  // 50
34    accelerationMax   : 3,   // 3
35
36    // Keyboard Settings
37    keyboardSupport   : true,  // option
38    arrowScroll       : 50,    // [px]
39
40    // Other
41    fixedBackground   : true, 
42    excluded          : ''    
43};
44
45var options = defaultOptions;
46
47
48// Other Variables
49var isExcluded = false;
50var isFrame = false;
51var direction = { x: 0, y: 0 };
52var initDone  = false;
53var root = document.documentElement;
54var activeElement;
55var observer;
56var refreshSize;
57var deltaBuffer = [];
58var deltaBufferTimer;
59var isMac = /^Mac/.test(navigator.platform);
60
61/***********************************************
62 * INITIALIZE
63 ***********************************************/
64
65/**
66 * Tests if smooth scrolling is allowed. Shuts down everything if not.
67 */
68function initTest() {
69    if (options.keyboardSupport) {
70        addEvent('keydown', keydown);
71    }
72}
73
74/**
75 * Sets up scrolls array, determines if frames are involved.
76 */
77function init() {
78  
79    if (initDone || !document.body) return;
80
81    initDone = true;
82
83    var body = document.body;
84    var html = document.documentElement;
85    var windowHeight = window.innerHeight; 
86    var scrollHeight = body.scrollHeight;
87    
88    // check compat mode for root element
89    root = (document.compatMode.indexOf('CSS') >= 0) ? html : body;
90    activeElement = body;
91    
92    initTest();
93
94    // Checks if this script is running in a frame
95    if (top != self) {
96        isFrame = true;
97    }
98
99    /**
100     * Safari 10 fixed it, Chrome fixed it in v45:
101     * This fixes a bug where the areas left and right to 
102     * the content does not trigger the onmousewheel event
103     * on some pages. e.g.: html, body { height: 100% }
104     */
105    else if (isOldSafari &&
106             scrollHeight > windowHeight &&
107            (body.offsetHeight <= windowHeight || 
108             html.offsetHeight <= windowHeight)) {
109
110        var fullPageElem = document.createElement('div');
111        fullPageElem.style.cssText = 'position:absolute; z-index:-10000; ' +
112                                     'top:0; left:0; right:0; height:' + 
113                                      root.scrollHeight + 'px';
114        document.body.appendChild(fullPageElem);
115        
116        // DOM changed (throttled) to fix height
117        var pendingRefresh;
118        refreshSize = function () {
119            if (pendingRefresh) return; // could also be: clearTimeout(pendingRefresh);
120            pendingRefresh = setTimeout(function () {
121                if (isExcluded) return; // could be running after cleanup
122                fullPageElem.style.height = '0';
123                fullPageElem.style.height = root.scrollHeight + 'px';
124                pendingRefresh = null;
125            }, 500); // act rarely to stay fast
126        };
127  
128        setTimeout(refreshSize, 10);
129
130        addEvent('resize', refreshSize);
131
132        // TODO: attributeFilter?
133        var config = {
134            attributes: true, 
135            childList: true, 
136            characterData: false 
137            // subtree: true
138        };
139
140        observer = new MutationObserver(refreshSize);
141        observer.observe(body, config);
142
143        if (root.offsetHeight <= windowHeight) {
144            var clearfix = document.createElement('div');   
145            clearfix.style.clear = 'both';
146            body.appendChild(clearfix);
147        }
148    }
149
150    // disable fixed background
151    if (!options.fixedBackground && !isExcluded) {
152        body.style.backgroundAttachment = 'scroll';
153        html.style.backgroundAttachment = 'scroll';
154    }
155}
156
157/**
158 * Removes event listeners and other traces left on the page.
159 */
160function cleanup() {
161    observer && observer.disconnect();
162    removeEvent(wheelEvent, wheel);
163    removeEvent('mousedown', mousedown);
164    removeEvent('keydown', keydown);
165    removeEvent('resize', refreshSize);
166    removeEvent('load', init);
167}
168
169
170/************************************************
171 * SCROLLING 
172 ************************************************/
173 
174var que = [];
175var pending = false;
176var lastScroll = Date.now();
177
178/**
179 * Pushes scroll actions to the scrolling queue.
180 */
181function scrollArray(elem, left, top) {
182    
183    directionCheck(left, top);
184
185    if (options.accelerationMax != 1) {
186        var now = Date.now();
187        var elapsed = now - lastScroll;
188        if (elapsed < options.accelerationDelta) {
189            var factor = (1 + (50 / elapsed)) / 2;
190            if (factor > 1) {
191                factor = Math.min(factor, options.accelerationMax);
192                left *= factor;
193                top  *= factor;
194            }
195        }
196        lastScroll = Date.now();
197    }          
198    
199    // push a scroll command
200    que.push({
201        x: left, 
202        y: top, 
203        lastX: (left < 0) ? 0.99 : -0.99,
204        lastY: (top  < 0) ? 0.99 : -0.99, 
205        start: Date.now()
206    });
207        
208    // don't act if there's a pending queue
209    if (pending) {
210        return;
211    }  
212
213    var scrollRoot = getScrollRoot();
214    var isWindowScroll = (elem === scrollRoot || elem === document.body);
215    
216    // if we haven't already fixed the behavior, 
217    // and it needs fixing for this sesh
218    if (elem.$scrollBehavior == null && isScrollBehaviorSmooth(elem)) {
219        elem.$scrollBehavior = elem.style.scrollBehavior;
220        elem.style.scrollBehavior = 'auto';
221    }
222
223    var step = function (time) {
224        
225        var now = Date.now();
226        var scrollX = 0;
227        var scrollY = 0; 
228    
229        for (var i = 0; i < que.length; i++) {
230            
231            var item = que[i];
232            var elapsed  = now - item.start;
233            var finished = (elapsed >= options.animationTime);
234            
235            // scroll position: [0, 1]
236            var position = (finished) ? 1 : elapsed / options.animationTime;
237            
238            // easing [optional]
239            if (options.pulseAlgorithm) {
240                position = pulse(position);
241            }
242            
243            // only need the difference
244            var x = (item.x * position - item.lastX) >> 0;
245            var y = (item.y * position - item.lastY) >> 0;
246            
247            // add this to the total scrolling
248            scrollX += x;
249            scrollY += y;            
250            
251            // update last values
252            item.lastX += x;
253            item.lastY += y;
254        
255            // delete and step back if it's over
256            if (finished) {
257                que.splice(i, 1); i--;
258            }           
259        }
260
261        // scroll left and top
262        if (isWindowScroll) {
263            window.scrollBy(scrollX, scrollY);
264        } 
265        else {
266            if (scrollX) elem.scrollLeft += scrollX;
267            if (scrollY) elem.scrollTop  += scrollY;                    
268        }
269        
270        // clean up if there's nothing left to do
271        if (!left && !top) {
272            que = [];
273        }
274        
275        if (que.length) { 
276            requestFrame(step, elem, (1000 / options.frameRate + 1)); 
277        } else { 
278            pending = false;
279            // restore default behavior at the end of scrolling sesh
280            if (elem.$scrollBehavior != null) {
281                elem.style.scrollBehavior = elem.$scrollBehavior;
282                elem.$scrollBehavior = null;
283            }
284        }
285    };
286    
287    // start a new queue of actions
288    requestFrame(step, elem, 0);
289    pending = true;
290}
291
292
293/***********************************************
294 * EVENTS
295 ***********************************************/
296
297/**
298 * Mouse wheel handler.
299 * @param {Object} event
300 */
301function wheel(event) {
302
303    if (!initDone) {
304        init();
305    }
306    
307    var target = getEventTargetDeep(event);
308
309    // leave early if default action is prevented   
310    // or it's a zooming event with CTRL 
311    if (event.defaultPrevented || event.ctrlKey) {
312        return true;
313    }
314    
315    // leave embedded content alone (flash & pdf)
316    if (isNodeName(activeElement, 'embed') || 
317       (isNodeName(target, 'embed') && /\.pdf/i.test(target.src)) ||
318        isNodeName(activeElement, 'object')) {
319        return true;
320    }
321
322    // TODO:
323    //
324    // wheelDeltaY (DEPRECATED):
325    //   - Mac: positive (+) for scrolling down; Win: negative (-) for up
326    //   - Mac & Win: in simple case multiple of 120 or 100 (except Firefox maybe)
327    //   - scaled by zoom level (hard to detect, devicePixelRatio affected by ppi)
328    // deltaY (NEW):
329    //   - Mac: negative (-) for scrolling down; Win: positive (+) for up
330    //   - Win: in simple case it's multiple of 300
331    //   - Mac: can be any number because of default shitty "acceleration"
332    //          some third party apps might change it to line-based (120x)
333    //   - scaled by zoom level (hard to detect, devicePixelRatio affected by ppi)
334    //
335    // For touchpad in Chromium this seems to hold true: 
336    //    e.wheelDeltaY === (e.deltaY * -3)
337    // but it also holds for mouses on Safari Mac with default "acceleration".
338    // Also not future-proof because wheelDeltaY is deprecated
339
340    var deltaX = -event.wheelDeltaX || event.deltaX || 0;
341    var deltaY = -event.wheelDeltaY || event.deltaY || 0;
342    
343    if (isMac) {
344        if (event.wheelDeltaX && isDivisible(event.wheelDeltaX, 120)) {
345            deltaX = -120 * (event.wheelDeltaX / Math.abs(event.wheelDeltaX));
346        }
347        if (event.wheelDeltaY && isDivisible(event.wheelDeltaY, 120)) {
348            deltaY = -120 * (event.wheelDeltaY / Math.abs(event.wheelDeltaY));
349        }
350    }
351    
352    // use wheelDelta if deltaX/Y is not available
353    if (!deltaX && !deltaY) {
354        deltaY = -event.wheelDelta || 0;
355    }
356
357    // line based scrolling (Firefox mostly)
358    if (event.deltaMode === 1) {
359        deltaX *= 40;
360        deltaY *= 40;
361    }
362
363    var overflowing = overflowingAncestor(target);
364
365    // nothing to do if there's no element that's scrollable
366    if (!overflowing) {
367        // except Chrome iframes seem to eat wheel events, which we need to 
368        // propagate up, if the iframe has nothing overflowing to scroll
369        if (isFrame && isChrome)  {
370            // change target to iframe element itself for the parent frame
371            Object.defineProperty(event, "target", {value: window.frameElement});
372            return parent.wheel(event);
373        }
374        return true;
375    }
376    
377    // check if it's a touchpad scroll that should be ignored
378    if (isTouchpad(deltaY)) {
379        return true;
380    }
381
382    // scale by step size
383    // delta is 120 most of the time
384    // synaptics seems to send 1 sometimes
385    if (Math.abs(deltaX) > 1.2) {
386        deltaX *= options.stepSize / 120;
387    }
388    if (Math.abs(deltaY) > 1.2) {
389        deltaY *= options.stepSize / 120;
390    }
391    
392    scrollArray(overflowing, deltaX, deltaY);
393    event.preventDefault();
394    scheduleClearCache();
395}
396
397/**
398 * Keydown event handler.
399 * @param {Object} event
400 */
401function keydown(event) {
402
403    var target = getEventTargetDeep(event);
404    var modifier = event.ctrlKey || event.altKey || event.metaKey || 
405                  (event.shiftKey && event.code !== 'Space');
406    
407    // our own tracked active element could've been removed from the DOM
408    if (!document.body.contains(activeElement)) {
409        activeElement = document.activeElement;
410    }
411
412    // do nothing if user is editing text
413    // or using a modifier key (except shift)
414    // or in a dropdown
415    // or inside interactive elements
416    var inputNodeNames = /^(textarea|select|embed|object)$/i;
417    var buttonTypes = /^(button|submit|radio|checkbox|file|color|image)$/i;
418    if ( event.defaultPrevented ||
419         inputNodeNames.test(target.nodeName) ||
420         isNodeName(target, 'input') && !buttonTypes.test(target.type) ||
421         isNodeName(activeElement, 'video') ||
422         isInsideYoutubeVideo(event) ||
423         target.isContentEditable || 
424         modifier ) {
425      return true;
426    }
427
428    // [spacebar] should trigger button press, leave it alone
429    if ((isNodeName(target, 'button') ||
430         isNodeName(target, 'input') && buttonTypes.test(target.type)) &&
431        event.code === 'Space') {
432      return true;
433    }
434
435    // [arrow keys] on radio buttons should be left alone
436    if (isNodeName(target, 'input') && target.type == 'radio' &&
437        (event.code === 'ArrowUp' || event.code === 'ArrowDown' || 
438         event.code === 'ArrowLeft' || event.code === 'ArrowRight'))  {
439      return true;
440    }
441    
442    var shift, x = 0, y = 0;
443    var overflowing = overflowingAncestor(activeElement);
444
445    if (!overflowing) {
446        // Chrome iframes seem to eat key events, which we need to 
447        // propagate up, if the iframe has nothing overflowing to scroll
448        return (isFrame && isChrome) ? parent.keydown(event) : true;
449    }
450
451    var clientHeight = overflowing.clientHeight; 
452
453    if (overflowing == document.body) {
454        clientHeight = window.innerHeight;
455    }
456
457    switch (event.code) {
458        case 'ArrowUp':
459            y = -options.arrowScroll;
460            break;
461        case 'ArrowDown':
462            y = options.arrowScroll;
463            break;         
464        case 'Space':
465            shift = event.shiftKey ? 1 : -1;
466            y = -shift * clientHeight * 0.9;
467            break;
468        case 'PageUp':
469            y = -clientHeight * 0.9;
470            break;
471        case 'PageDown':
472            y = clientHeight * 0.9;
473            break;
474        case 'Home':
475            if (overflowing == document.body && document.scrollingElement)
476                overflowing = document.scrollingElement;
477            y = -overflowing.scrollTop;
478            break;
479        case 'End':
480            var scroll = overflowing.scrollHeight - overflowing.scrollTop;
481            var scrollRemaining = scroll - clientHeight;
482            y = (scrollRemaining > 0) ? scrollRemaining + 10 : 0;
483            break;
484        case 'ArrowLeft':
485            x = -options.arrowScroll;
486            break;
487        case 'ArrowRight':
488            x = options.arrowScroll;
489            break;            
490        default:
491            return true; // a key we don't care about
492    }
493
494    scrollArray(overflowing, x, y);
495    event.preventDefault();
496    scheduleClearCache();
497}
498
499/**
500 * Mousedown event only for updating activeElement
501 */
502function mousedown(event) {
503    activeElement = getEventTargetDeep(event);
504}
505
506/**
507 * Get the deepest event target even through shadow DOM.
508 * @param {Object} event
509 * @return {Element}
510 */
511function getEventTargetDeep(event) {
512    return event.composedPath ? event.composedPath()[0] : event.target;
513}
514
515
516/***********************************************
517 * OVERFLOW
518 ***********************************************/
519
520var uniqueID = (function () {
521    var i = 0;
522    return function (el) {
523        return el.uniqueID || (el.uniqueID = i++);
524    };
525})();
526
527var cacheX = {}; // cleared out after a scrolling session
528var cacheY = {}; // cleared out after a scrolling session
529var clearCacheTimer;
530var smoothBehaviorForElement = {};
531
532//setInterval(function () { cache = {}; }, 10 * 1000);
533
534function scheduleClearCache() {
535    clearTimeout(clearCacheTimer);
536    clearCacheTimer = setInterval(function () { 
537        cacheX = cacheY = smoothBehaviorForElement = {}; 
538    }, 1*1000);
539}
540
541function setCache(elems, overflowing, x) {
542    var cache = x ? cacheX : cacheY;
543    for (var i = elems.length; i--;)
544        cache[uniqueID(elems[i])] = overflowing;
545    return overflowing;
546}
547
548function getCache(el, x) {
549    return (x ? cacheX : cacheY)[uniqueID(el)];
550}
551
552//  (body)                (root)
553//         | hidden | visible | scroll |  auto  |
554// hidden  |   no   |    no   |   YES  |   YES  |
555// visible |   no   |   YES   |   YES  |   YES  |
556// scroll  |   no   |   YES   |   YES  |   YES  |
557// auto    |   no   |   YES   |   YES  |   YES  |
558
559function overflowingAncestor(el) {
560    var elems = [];
561    var body = document.body;
562    var rootScrollHeight = root.scrollHeight;
563    while (el) {
564        var cached = getCache(el, false);
565        if (cached) {
566            return setCache(elems, cached);
567        }
568        elems.push(el);
569        if (rootScrollHeight === el.scrollHeight) {
570            var topOverflowsNotHidden = overflowNotHidden(root) && overflowNotHidden(body);
571            var isOverflowCSS = topOverflowsNotHidden || overflowAutoOrScroll(root);
572            if (isFrame && isContentOverflowing(root) || 
573               !isFrame && isOverflowCSS) {
574                return setCache(elems, getScrollRoot()); 
575            }
576        } else if (isContentOverflowing(el) && overflowAutoOrScroll(el)) {
577            return setCache(elems, el);
578        }
579        // Support shadow DOM
580        el = el.parentElement || (el.getRootNode && el.getRootNode().host); 
581    }
582}
583
584function isContentOverflowing(el) {
585    return (el.clientHeight + 10 < el.scrollHeight);
586}
587
588// typically for <body> and <html>
589function overflowNotHidden(el) {
590    var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
591    return (overflow !== 'hidden');
592}
593
594// for all other elements
595function overflowAutoOrScroll(el) {
596    var overflow = getComputedStyle(el, '').getPropertyValue('overflow-y');
597    return (overflow === 'scroll' || overflow === 'auto');
598}
599
600// for all other elements
601function isScrollBehaviorSmooth(el) {
602    var id = uniqueID(el);
603    if (smoothBehaviorForElement[id] == null) {
604        var scrollBehavior = getComputedStyle(el, '')['scroll-behavior'];
605        smoothBehaviorForElement[id] = ('smooth' == scrollBehavior);
606    }
607    return smoothBehaviorForElement[id];
608}
609
610
611/***********************************************
612 * HELPERS
613 ***********************************************/
614
615function addEvent(type, fn, arg) {
616    window.addEventListener(type, fn, arg || false);
617}
618
619function removeEvent(type, fn, arg) {
620    window.removeEventListener(type, fn, arg || false);  
621}
622
623function isNodeName(el, tag) {
624    return el && (el.nodeName||'').toLowerCase() === tag.toLowerCase();
625}
626
627function directionCheck(x, y) {
628    x = (x > 0) ? 1 : -1;
629    y = (y > 0) ? 1 : -1;
630    if (direction.x !== x || direction.y !== y) {
631        direction.x = x;
632        direction.y = y;
633        que = [];
634        lastScroll = 0;
635    }
636}
637
638try { // #46 Safari throws in private browsing for localStorage 
639    if (localStorage.SS_deltaBuffer) {
640        deltaBuffer = localStorage.SS_deltaBuffer.split(',');
641    }
642} catch (e) { } 
643
644function isTouchpad(deltaY) {
645    if (!deltaY) return;
646    if (!deltaBuffer.length) {
647        deltaBuffer = [deltaY, deltaY, deltaY];
648    }
649    deltaY = Math.abs(deltaY);
650    deltaBuffer.push(deltaY);
651    deltaBuffer.shift();
652    clearTimeout(deltaBufferTimer);
653    deltaBufferTimer = setTimeout(function () {
654        try { // #46 Safari throws in private browsing for localStorage
655            localStorage.SS_deltaBuffer = deltaBuffer.join(',');
656        } catch (e) { }  
657    }, 1000);
658    var dpiScaledWheelDelta = deltaY > 120 && allDeltasDivisableBy(deltaY); // win64 
659    var tp = !allDeltasDivisableBy(120) && !allDeltasDivisableBy(100) && !dpiScaledWheelDelta;
660    if (deltaY < 50) return true;
661    return tp;
662} 
663
664function isDivisible(n, divisor) {
665    return (Math.floor(n / divisor) == n / divisor);
666}
667
668function allDeltasDivisableBy(divisor) {
669    return (isDivisible(deltaBuffer[0], divisor) &&
670            isDivisible(deltaBuffer[1], divisor) &&
671            isDivisible(deltaBuffer[2], divisor));
672}
673
674function isInsideYoutubeVideo(event) {
675    var elem = getEventTargetDeep(event);
676    var isControl = false;
677    if (document.URL.indexOf ('www.youtube.com/watch') != -1) {
678        do {
679            isControl = (elem.classList && 
680                         elem.classList.contains('html5-video-controls'));
681            if (isControl) break;
682        } while ((elem = elem.parentNode));
683    }
684    return isControl;
685}
686
687var requestFrame = (function () {
688      return (window.requestAnimationFrame       || 
689              window.webkitRequestAnimationFrame || 
690              window.mozRequestAnimationFrame    ||
691              function (callback, element, delay) {
692                 window.setTimeout(callback, delay || (1000/60));
693             });
694})();
695
696var MutationObserver = (window.MutationObserver || 
697                        window.WebKitMutationObserver ||
698                        window.MozMutationObserver);  
699
700var getScrollRoot = (function() {
701  var SCROLL_ROOT = document.scrollingElement;
702  return function() {
703    if (!SCROLL_ROOT) {
704      var dummy = document.createElement('div');
705      dummy.style.cssText = 'height:10000px;width:1px;';
706      document.body.appendChild(dummy);
707      var bodyScrollTop  = document.body.scrollTop;
708      var docElScrollTop = document.documentElement.scrollTop;
709      window.scrollBy(0, 3);
710      if (document.body.scrollTop != bodyScrollTop)
711        (SCROLL_ROOT = document.body);
712      else 
713        (SCROLL_ROOT = document.documentElement);
714      window.scrollBy(0, -3);
715      document.body.removeChild(dummy);
716    }
717    return SCROLL_ROOT;
718  };
719})();
720
721
722/***********************************************
723 * PULSE (by Michael Herf)
724 ***********************************************/
725 
726/**
727 * Viscous fluid with a pulse for part and decay for the rest.
728 * - Applies a fixed force over an interval (a damped acceleration), and
729 * - Lets the exponential bleed away the velocity over a longer interval
730 * - Michael Herf, http://stereopsis.com/stopping/
731 */
732function pulse_(x) {
733    var val, start, expx;
734    // test
735    x = x * options.pulseScale;
736    if (x < 1) { // acceleartion
737        val = x - (1 - Math.exp(-x));
738    } else {     // tail
739        // the previous animation ended here:
740        start = Math.exp(-1);
741        // simple viscous drag
742        x -= 1;
743        expx = 1 - Math.exp(-x);
744        val = start + (expx * (1 - start));
745    }
746    return val * options.pulseNormalize;
747}
748
749function pulse(x) {
750    if (x >= 1) return 1;
751    if (x <= 0) return 0;
752
753    if (options.pulseNormalize == 1) {
754        options.pulseNormalize /= pulse_(1);
755    }
756    return pulse_(x);
757}
758
759
760/***********************************************
761 * FIRST RUN
762 ***********************************************/
763
764var userAgent = window.navigator.userAgent;
765var isEdge    = /Edge/.test(userAgent); // thank you MS
766var isChrome  = /chrome/i.test(userAgent) && !isEdge; 
767var isSafari  = /safari/i.test(userAgent) && !isEdge; 
768var isMobile  = /mobile/i.test(userAgent);
769var isIEWin7  = /Windows NT 6.1/i.test(userAgent) && /rv:11/i.test(userAgent);
770var isOldSafari = isSafari && (/Version\/8/i.test(userAgent) || /Version\/9/i.test(userAgent));
771var isEnabledForBrowser = (isChrome || isSafari || isIEWin7) && !isMobile;
772
773var supportsPassive = false;
774try {
775  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
776    get: function () {
777            supportsPassive = true;
778        } 
779    }));
780} catch(e) {}
781
782var wheelOpt = supportsPassive ? { passive: false } : false;
783var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel'; 
784
785if (wheelEvent && isEnabledForBrowser) {
786    addEvent(wheelEvent, wheel, wheelOpt);
787    addEvent('mousedown', mousedown);
788    addEvent('load', init);
789}
790
791
792/***********************************************
793 * PUBLIC INTERFACE
794 ***********************************************/
795
796function SmoothScroll(optionsToSet) {
797    for (var key in optionsToSet)
798        if (defaultOptions.hasOwnProperty(key)) 
799            options[key] = optionsToSet[key];
800}
801SmoothScroll.destroy = cleanup;
802
803if (window.SmoothScrollOptions) // async API
804    SmoothScroll(window.SmoothScrollOptions);
805
806if (typeof define === 'function' && define.amd)
807    define(function() {
808        return SmoothScroll;
809    });
810else if ('object' == typeof exports)
811    module.exports = SmoothScroll;
812else
813    window.SmoothScroll = SmoothScroll;
814
815})();
816
817}

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.