<commit_before>/**
 * jquery.scrollbox.js
 * 
 * @version    0.2.2
 * @author     <NAME>
 * @copyright  (c) 2013-2014, <NAME>
 * @license    MIT http://www.opensource.org/licenses/mit-license.php
 */
+function ($, window, document, undefined) {

    'use strict';
    
    var name = 'scrollbox',
        Scrollbox = function ($element, options) {
            var o = this.options = $.extend({}, $.fn[name].defaults, options);

            this.$element = $element;
            this.$rail = $(o.templates.rail);
            this.$bar = $(o.templates.bar);

            this.init = o.init || this.init;
            this.addListeners = o.addListeners || this.addListeners;
            this.removeListeners = o.removeListeners || this.removeListeners;
            this.scroll = o.scroll || this.scroll;
            this.jump = o.jump || this.jump;
            this.update = o.update || this.update;
            this.destroy = o.destroy || this.destroy;

            this._isOver = this._isCaptured = this._isShown = false;
            this._prevY = this._scrolledTo = 0;
            this._isReachTriggered = {top: false, bottom: false};
            this._scrollHeight = undefined;
            
            this._listeners = {};

            this.init();
        };
    
    Scrollbox.prototype = {
        
        init: function () {
            var options = this.options;
            
            this.$wrapper = this.$element
                .trigger('init.' + name)
                .css('overflow', 'hidden')
                .wrap(options.templates.wrapper).parent()
                .append(this.$rail)
                .append(this.$bar);
            
            this._updateBarHeight();
            
            if ('top' !== options.start) {
                this.jump(options.start);
            }
            
            if (this._isShown) {
                this.addListeners();
            }
        },
        
        addListeners: function () {
            this._listeners.wheel = $.proxy(this._onWheel, this);
            
            this.$wrapper.on({
                mouseenter: $.proxy(this._onEnter, this),
                mouseleave: $.proxy(this._onLeave, this)
            });
            
            if (window.addEventListener) {
                window.addEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.addEventListener('mousewheel', this._listeners.wheel, false);
            }
            else {
                document.attachEvent('onmousewheel', this._listeners.wheel);
            }
            
            this.$bar.on('mousedown', $.proxy(this._onCapture, this));
            
            $(document).on({
                mouseup: $.proxy(this._onRelease, this),
                mousemove: $.proxy(this._onMove, this)
            });
        },
        
        removeListeners: function () {
            this.$wrapper.off({
                mouseenter: this._onEnter,
                mouseleave: this._onLeave
            });
            
            if (window.removeEventListener) {
                window.removeEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.removeEventListener('mousewheel', this._listeners.wheel, false);
            }
            else {
                document.detachEvent('onmousewheel', this._listeners.wheel);
            }
            
            this.$bar.off('mousedown', this._onCapture);
            
            $(document).off({
                mouseup: this._onRelease,
                mousemove: this._onMove
            });
        },
        
        _onEnter: function (e) {
            var event = $.Event('enter.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                e.preventDefault();
                this._isOver = true;
            }
        },
        
        _onLeave: function (e) {
            var event = $.Event('leave.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                e.preventDefault();
                this._isOver = false;
            }
        },
        
        _onWheel: function (e) {
            if (!this._isOver) {
                return;
            }
            
            var e = e || window.event,
                event = $.Event('wheel.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                if (e.preventDefault) {
                    e.preventDefault();
                }
                else {
                    e.returnValue = false;
                }

                this.scroll((e.detail ? e.detail / 3 : - e.wheelDelta / 120) * this.options.sensitivity);
            }
        },
        
        _onCapture: function (e) {
            if (1 === e.which) {
                e.preventDefault();
                this.$element.trigger('dragstart.' + name);
                this._isCaptured = true;
                this._prevY = e.pageY;
            }
        },
        
        _onMove: function (e) {
            if (!this._isCaptured) return;
            this.$element.trigger('drag.' + name);
            e.preventDefault();
            this.scroll((e.pageY - this._prevY) / this._getRatio());
            this._prevY = e.pageY;
        },
        
        _onRelease: function (e) {
            if (!this._isCaptured || 1 !== e.which) {
                return;
            }
            
            this.$element.trigger('dragstop.' + name);
            e.preventDefault();
            this._isCaptured = false;
        },
        
        scroll: function (delta) {
            var max = this._getScrollHeight() - this.$element.outerHeight(),
                scrollTo = this._scrolledTo + delta,
                options = this.options,
                position;
            
            this.$element.trigger('scroll.' + name);
            
            if (scrollTo >= max) {
                this._scrolledTo = max;
            }
            else if (scrollTo <= 0) {
                this._scrolledTo = 0;
            }
            else {
                this._scrolledTo = scrollTo;
            }
            
            this.$element.scrollTop(this._scrolledTo);
            this._updateBarPosition();
            
            if (!this._isReachTriggered.bottom && this._scrolledTo + options.buffer >= max) {
                position = 'bottom';
            }
            else if (!this._isReachTriggered.top && this._scrolledTo - options.buffer <= 0) {
                position = 'top';
            }
            
            if (position) {
                this.$element.trigger($.Event('reach.' + name, {position: position}));
                this._isReachTriggered[position] = true;
            }
        },
        
        jump: function (y) {
            if ('top' === y) {
                y = 0;
            }
            else if ('bottom' === y) {
                y = this._getScrollHeight() - this.$element.height();
            }
            
            this.scroll(y - this._scrolledTo);
        },
        <commit_msg>Added new feature - tracking programmatically scrolling<commit_after>/**
 * jquery.scrollbox.js
 * 
 * @version    0.2.2
 * @author     <NAME>
 * @copyright  (c) 2013-2014, <NAME>
 * @license    MIT http://www.opensource.org/licenses/mit-license.php
 */
+function ($, window, document, undefined) {

    'use strict';
    
    var name = 'scrollbox',
        Scrollbox = function ($element, options) {
            var o = this.options = $.extend({}, $.fn[name].defaults, options);

            this.$element = $element;
            this.$rail = $(o.templates.rail);
            this.$bar = $(o.templates.bar);

            this.init = o.init || this.init;
            this.addListeners = o.addListeners || this.addListeners;
            this.removeListeners = o.removeListeners || this.removeListeners;
            this.scroll = o.scroll || this.scroll;
            this.jump = o.jump || this.jump;
            this.update = o.update || this.update;
            this.destroy = o.destroy || this.destroy;

            this._isOver = this._isCaptured = this._isShown = false;
            this._prevY = this._scrolledTo = 0;
            this._isReachTriggered = {top: false, bottom: false};
            this._scrollHeight = undefined;
            this._scrolledBySelf = false;
            
            this._listeners = {};

            this.init();
        };
    
    Scrollbox.prototype = {
        
        init: function () {
            var options = this.options;
            
            this.$wrapper = this.$element
                .trigger('init.' + name)
                .css('overflow', 'hidden')
                .wrap(options.templates.wrapper).parent()
                .append(this.$rail)
                .append(this.$bar);
            
            this._updateBarHeight();
            
            if ('top' !== options.start) {
                this.jump(options.start);
            }
            
            if (this._isShown) {
                this.addListeners();
            }
        },
        
        addListeners: function () {
            this._listeners.wheel = $.proxy(this._onWheel, this);
            
            this.$wrapper.on({
                mouseenter: $.proxy(this._onEnter, this),
                mouseleave: $.proxy(this._onLeave, this)
            });
            
            if (window.addEventListener) {
                window.addEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.addEventListener('mousewheel', this._listeners.wheel, false);
            }
            else {
                document.attachEvent('onmousewheel', this._listeners.wheel);
            }
            
            this.$bar.on('mousedown', $.proxy(this._onCapture, this));
            
            $(document).on({
                mouseup: $.proxy(this._onRelease, this),
                mousemove: $.proxy(this._onMove, this)
            });
            
            this.$element.on('scroll', $.proxy(this._onScroll, this));
        },
        
        removeListeners: function () {
            this.$wrapper.off({
                mouseenter: this._onEnter,
                mouseleave: this._onLeave
            });
            
            if (window.removeEventListener) {
                window.removeEventListener('DOMMouseScroll', this._listeners.wheel, false);
                window.removeEventListener('mousewheel', this._listeners.wheel, false);
            }
            else {
                document.detachEvent('onmousewheel', this._listeners.wheel);
            }
            
            this.$bar.off('mousedown', this._onCapture);
            
            $(document).off({
                mouseup: this._onRelease,
                mousemove: this._onMove
            });
            
            this.$element.off('scroll', this._onScroll);
        },
        
        _onEnter: function (e) {
            var event = $.Event('enter.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                e.preventDefault();
                this._isOver = true;
            }
        },
        
        _onLeave: function (e) {
            var event = $.Event('leave.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                e.preventDefault();
                this._isOver = false;
            }
        },
        
        _onWheel: function (e) {
            if (!this._isOver) {
                return;
            }
            
            var e = e || window.event,
                event = $.Event('wheel.' + name);
            
            this.$element.trigger(event);
            
            if (!event.isDefaultPrevented()) {
                if (e.preventDefault) {
                    e.preventDefault();
                }
                else {
                    e.returnValue = false;
                }

                this.scroll((e.detail ? e.detail / 3 : - e.wheelDelta / 120) * this.options.sensitivity);
            }
        },
        
        _onCapture: function (e) {
            if (1 === e.which) {
                e.preventDefault();
                this.$element.trigger('dragstart.' + name);
                this._isCaptured = true;
                this._prevY = e.pageY;
            }
        },
        
        _onMove: function (e) {
            if (!this._isCaptured) return;
            this.$element.trigger('drag.' + name);
            e.preventDefault();
            this.scroll((e.pageY - this._prevY) / this._getRatio());
            this._prevY = e.pageY;
        },
        
        _onRelease: function (e) {
            if (!this._isCaptured || 1 !== e.which) {
                return;
            }
            
            this.$element.trigger('dragstop.' + name);
            e.preventDefault();
            this._isCaptured = false;
        },
        
        _onScroll: function () {
            if (!this._scrolledBySelf) {
                this._scrolledTo = this.$element.scrollTop();
                this.update();
            }
        },
        
        scroll: function (delta) {
            var max = this._getScrollHeight() - this.$element.outerHeight(),
                scrollTo = this._scrolledTo + delta,
                options = this.options,
                position;
            
            this.$element.trigger('scroll.' + name);
            
            if (scrollTo >= max) {
                this._scrolledTo = max;
            }
            else if (scrollTo <= 0) {
                this._scrolledTo = 0;
            }
            else {
                this._scrolledTo = scrollTo;
            }
            
            this._scrolledBySelf = true;
            this.$element.scrollTop(this._scrolledTo);
            this._scrolledBySelf = false;
            
            this._updateBarPosition();
            
            if (!this._isReachTriggered.bottom && this._scrolledTo + options.buffer >= max) {
                position = 'bottom';
            }
            else if (!this._isReachTriggered.top && this._scrolledTo - options.buffer <= 0) {
                position = 'top';
            }
            
            if (position) {
                this.$element.trigger($.Event('reach.' + name, {position: position}));
                this._isReachTriggered[position] = true;
            }
        },
        
        jump: function (y) {
            if ('top' === y) {
                y = 0;
            }
            else if ('bottom' === y) {
                y = this._getScrollHeight() - this.$element.height();
            }
            
            this.scroll(y - this._scrolledTo);
        },
        
{'fraction_non_alphanumeric': 0.12321608040201006, 'fraction_numerical': 0.002948073701842546, 'mean_word_length': 1.178978102189781, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5487082', 'n_tokens_mistral': 3924, 'n_tokens_neox': 3783, 'n_words': 665}