PageSourceSearch

https://www.communitylandscotland.org.uk/wp-content/plugins/dynami…/jquery.scrollify.js?ver=3.4.10

js communitylandscotland.org.uk collected 2026-09-24 09:41:55 UTC 26,517 bytes, 853 lines download raw bytes

1/*!
2 * jQuery Scrollify
3 * Version 1.0.21
4 *
5 * Requires:
6 * - jQuery 1.7 or higher
7 *
8 * https://github.com/lukehaas/Scrollify
9 *
10 * Copyright 2016, Luke Haas
11 * Permission is hereby granted, free of charge, to any person obtaining a copy of
12 * this software and associated documentation files (the "Software"), to deal in
13 * the Software without restriction, including without limitation the rights to
14 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
15 * the Software, and to permit persons to whom the Software is furnished to do so,
16 * subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice shall be included in all
19 * copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
24 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
25 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
26 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
28
29
30if touchScroll is false - update index
31
32 */
33(function (global,factory) {
34  "use strict";
35  if (typeof define === 'function' && define.amd) {
36    // AMD. Register as an anonymous module.
37    define(['jquery'], function($) {
38      return factory($, global, global.document);
39    });
40  } else if (typeof module === 'object' && module.exports) {
41    // Node/CommonJS
42    module.exports = factory(require('jquery'), global, global.document);
43  } else {
44    // Browser globals
45    factory(jQuery, global, global.document);
46  }
47}(typeof window !== 'undefined' ? window : this, function ($, window, document, undefined) {
48  "use strict";
49  var heights = [],
50    names = [],
51    elements = [],
52    overflow = [],
53    index = 0,
54    currentIndex = 0,
55    interstitialIndex = 1,
56    hasLocation = false,
57    timeoutId,
58    timeoutId2,
59    $window = $(window),
60    portHeight,
61    top = $window.scrollTop(),
62    scrollable = false,
63    locked = false,
64    scrolled = false,
65    manualScroll,
66    swipeScroll,
67    util,
68    disabled = false,
69    scrollSamples = [],
70    scrollTime = new Date().getTime(),
71    firstLoad = true,
72    initialised = false,
73    destination = 0,
74    wheelEvent = 'onwheel' in document ? 'wheel' : document.onmousewheel !== undefined ? 'mousewheel' : 'DOMMouseScroll',
75    eventListenerOptions = { passive: false },
76    settings = {
77      //section should be an identifier that is the same for each section
78      section: ".section",
79      sectionName: "section-name",
80      interstitialSection: "",
81      easing: "easeOutExpo",
82      scrollSpeed: 1100,
83      offset: 0,
84      scrollbars: true,
85      target:"html,body",
86      standardScrollElements: false,
87      setHeights: true,
88      overflowScroll:true,
89      updateHash: true,
90      touchScroll:true,
91      before:function() {},
92      after:function() {},
93      afterResize:function() {},
94      afterRender:function() {}
95    };
96  function getportHeight() {
97    return (window.innerHeight + settings.offset);
98  }
99  function animateScroll(index,instant,callbacks,toTop) {
100    if(currentIndex===index) {
101      callbacks = false;
102    }
103    if(disabled===true) {
104      return true;
105    }
106    if(names[index]) {
107      scrollable = false;
108      if(firstLoad===true) {
109        firstLoad = false;
110        settings.afterRender();
111      }
112      if(callbacks) {
113        if( typeof settings.before == 'function' && settings.before(index,elements) === false ){
114          return true;
115        }
116      }
117      interstitialIndex = 1;
118      destination = (!index) ? 0 : heights[index];
119      if(firstLoad===false && currentIndex>index && toTop===false) {
120        //We're going backwards
121        if(overflow[index]) {
122          portHeight = getportHeight();
123
124          interstitialIndex = parseInt(elements[index].outerHeight()/portHe
124ight);
125
126          destination = parseInt(heights[index])+(elements[index].outerHeight()-portHeight);
127        }
128      }
129
130
131      if(settings.updateHash && settings.sectionName && !(firstLoad===true && index===0)) {
132        if(history.pushState) {
133            try {
134              history.replaceState(null, null, names[index]);
135            } catch (e) {
136              if(window.console) {
137                console.warn("Scrollify warning: Page must be hosted to manipulate the hash value.");
138              }
139            }
140
141        } else {
142          window.location.hash = names[index];
143        }
144      }
145
146      currentIndex = index;
147      if(instant) {
148        $(settings.target).stop().scrollTop(destination);
149        if(callbacks) {
150          settings.after(index,elements);
151        }
152      } else {
153        locked = true;
154        if( $().velocity ) {
155          $(settings.target).stop().velocity('scroll', {
156            duration: settings.scrollSpeed,
157            easing: settings.easing,
158            offset: destination,
159            mobileHA: false
160          });
161        } else {
162          $(settings.target).stop().animate({
163            scrollTop: destination
164          }, settings.scrollSpeed,settings.easing);
165        }
166
167        if(window.location.hash.length && settings.sectionName && window.console) {
168          try {
169            if($(window.location.hash).length) {
170              console.warn("Scrollify warning: ID matches hash value - this will cause the page to anchor.");
171            }
172          } catch (e) {}
173        }
174        $(settings.target).promise().done(function(){
175          locked = false;
176          firstLoad = false;
177          if(callbacks) {
178            settings.after(index,elements);
179          }
180        });
181      }
182
183    }
184  }
185
186  function isAccelerating(samples) {
187    function average(num) {
188      var sum = 0;
189
190      var lastElements = samples.slice(Math.max(samples.length - num, 1));
191
192      for(var i = 0; i < lastElements.length; i++){
193          sum += lastElements[i];
194      }
195
196      return Math.ceil(sum/num);
197    }
198
199    var avEnd = average(10);
200    var avMiddle = average(70);
201
202    if(avEnd >= avMiddle) {
203      return true;
204    } else {
205      return false;
206    }
207  }
208  var scrollify = function(options) {
209    initialised = true;
210    $.easing['easeOutExpo'] = function(x, t, b, c, d) {
211      return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
212    };
213
214    manualScroll = {
215      handleMousedown:function() {
216        if(disabled===true) {
217          return true;
218        }
219        scrollable = false;
220        scrolled = false;
221      },
222      handleMouseup:function() {
223        if(disabled===true) {
224          return true;
225        }
226        scrollable = true;
227        if(scrolled) {
228          //instant,callbacks
229          manualScroll.calculateNearest(false,true);
230        }
231      },
232      handleScroll:function() {
233        if(disabled===true) {
234          return true;
235        }
236        if(timeoutId){
237          clearTimeout(timeoutId);
238        }
239
240        timeoutId = setTimeout(function(){
241          scrolled = true;
242          if(scrollable===false) {
243            return false;
244          }
245          scrollable = false;
246          //instant,callbacks
247          manualScroll.calculateNearest(false,true);
248        }, 200);
249      },
250      calculateNearest:function(instant,callbacks) {
251        top = $window.scrollTop();
252        var i =1,
253          max = heights.length,
254          closest = 0,
255          prev = Math.abs(heights[0] - top),
256          diff;
257        for(;i<max;i++) {
258          diff = Math.abs(heights[i] - top);
259
260          if(diff < prev) {
261            prev = diff;
262            closest = i;
263          }
264        }
265        if((atBottom() && closest>index) || atTop()) {
266          index = closest;
267          //index, instant, callbacks, toTop
268          animateScroll(closest,instant,callbacks,false);
269        }
270      },
271      wheelHandler:function(e) {
272        if(disabled===true) {
273          return true;
274        } else if(settings.standardScrollElements) {
275          if($(e.target).is(settings.standardScrollElements) || $(e.target).closest(settings.standardScrollElements).length) {
276            return true;
277          }
278        }
279        if(!overflow[index]) {
280          e.preventDefault();
281        }
282        var currentScrollTime = new Date().getTime();
283
284
285        e = e || window.event;
286        var value;
287        if (e.originalEvent) {
288            value = e.originalEvent.wheelDelta || -e.originalEvent.deltaY || -e.originalEvent.detail;
289        } else {
290            value = e.wheelDelta || -e.deltaY || -e.detail;
291        }
292        var delta = Math.max(-1, Math.min(1, value));
293
294        //delta = delta || -e.originalEvent.detail / 3 || e.originalEvent.wheelDelta / 120;
295
296        if(scrollSamples.length > 149){
297          scrollSamples.shift();
298        }
299        //scrollSamples.push(Math.abs(delta*10));
300        scrollSamples.push(Math.abs(value));
301
302        if((currentScrollTime-scrollTime) > 200){
303          scrollSamples = [];
304        }
305        scrollTime = currentScrollTime;
306
307
308        if(locked) {
309          return false;
310        }
311        if(delta<0) {
312          if(index<heights.length-1) {
313            if(atBottom()) {
314              if(isAccelerating(scrollSamples)) {
315                e.preventDefault();
316                index++;
317                locked = true;
318                //index, instant, callbacks, toTop
319                animateScroll(index,false,true, false);
320              } else {
321                return false;
322              }
323            }
324          }
325        } else if(delta>0) {
326          if(index>0) {
327            if(atTop()) {
328              if(isAccelerating(scrollSamples)) {
329                e.preventDefault();
330                index--;
331                locked = true;
332                //index, instant, callbacks, toTop
333                animateScroll(index,false,true, false);
334              } else {
335                return false
336              }
337            }
338          }
339        }
340
341      },
342      keyHandler:function(e) {
343        if(disabled===true || document.activeElement.readOnly===false) {
344          return true;
345        } else if(settings.standardScrollElements) {
346          if($(e.target).is(settings.standardScrollElements) || $(e.target).closest(settings.standardScrollElements).length) {
347            return true;
348          }
349        }
350        if(locked===true) {
351          return false;
352        }
353        if(e.keyCode==38 || e.keyCode==33) {
354          if(index>0) {
355            if(atTop()) {
356              e.preventDefault();
357              index--;
358              //index, instant, callbacks, toTop
359              animateScroll(index,false,true,false);
360            }
361          }
362        } else if(e.keyCode==40 || e.keyCode==34) {
363          if(index<heights.length-1) {
364            if(atBottom()) {
365              e.preventDefault();
366              index++;
367              //index, instant, callbacks, toTop
368              animateScroll(index,false,true,false);
369            }
370          }
371        }
372      },
373      init:function() {
374        if(settings.scrollbars) {
375          $window.on('mousedown', manualScroll.handleMousedown);
376          $window.on('mouseup', manualScroll.handleMouseup);
377          $window.on('scroll', manualScroll.handleScroll);
378        } else {
379          $("body").css({"overflow":"hidden"});
380        }
381        window.addEventListener(wheelEvent, manualScroll.wheelHandler, { passive: false });
382        //$(document).bind(wheelEvent,manualScroll.wheelHandler);
383        $window.on('keydown', manualScroll.keyHandler);
384      }
385    };
386
387    swipeScroll = {
388      touches : {
389        "touchstart": {"y":-1,"x":-1},
390        "touchmove" : {"y":-1,"x":-1},
391        "touchend"  : false,
392        "direction" : "undetermined"
393      },
394      options:{
395        "distance" : 30,
396        "timeGap" : 800,
397        "timeStamp" : new Date().getTime()
398      },
399      touchHandler: function(event) {
400        if(disabled===true) {
401          return true;
402        } else if(settings.standardScrollElements) {
403          if($(event.target).is(settings.standardScrollElements) || $(event.target).closest(settings.standardScrollElements).length) {
404            return true;
405          }
406        }
407        var touch;
408        if (typeof event !== 'undefined'){
409          if (typeof event.touches !== 'undefined') {
410            touch = event.touches[0];
411            switch (event.type) {
412              case 'touchstart':
413                swipeScroll.touches.touchstart.y = touch.pageY;
414                swipeScroll.touches.touchmove.y = -1;
415
416                swipeScroll.touches.touchstart.x = touch.pageX;
417                swipeScroll.touches.touchmove.x = -1;
418
419                swipeScroll.options.timeStamp = new Date().getTime();
420                swipeScroll.touches.touchend = false;
421              case 'touchmove':
422                swipeScroll.touches.touchmove.y = touch.pageY;
423                swipeScroll.touches.touchmove.x = touch.pageX;
424                if(swipeScroll.touches.touchstart.y!==swipeScroll.touches.touchmove.y && (Math.abs(swipeScroll.touches.touchstart.y-swipeScroll.touches.touchmove.y)>Math.abs(swipeScroll.touches.touchstart.x-swipeScroll.touches.touchmove.x))) {
425                  //if(!overflow[index]) {
426                    event.preventDefault();
427                  //}
428                  swipeScroll.touches.direction = "y";
429                  if((swipeScroll.options.timeStamp+swipeScroll.options.timeGap)<(new Date().getTime()) && swipeScroll.touches.touchend == false) {
430
431                    swipeScroll.touches.touchend = true;
432                    if (swipeScroll.touches.touchstart.y > -1) {
433
434                      if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) {
435                        if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) {
436
437                          swipeScroll.up();
438
439                        } else {
440                          swipeScroll.down();
441
442                        }
443                      }
444                    }
445                  }
446                }
447                break;
448              case 'touchend':
449                if(swipeScroll.touches[event.type]===false) {
450                  swipeScroll.touches[event.type] = true;
451                  if (swipeScroll.touches.touchstart.y > -1 && swipeScroll.touches.touchmove.y > -1 && swipeScroll.touches.direction==="y") {
452
453                    if(Math.abs(swipeScroll.touches.touchmove.y-swipeScroll.touches.touchstart.y)>swipeScroll.options.distance) {
454                      if(swipeScroll.touches.touchstart.y < swipeScroll.touches.touchmove.y) {
455                        swipeScroll.up();
456
457                      } else {
458                        swipeScroll.down();
459
460                      }
461                    }
462                    swipeScroll.touches.touchstart.y = -1;
463                    swipeScroll.touches.touchstart.x = -1;
464                    swipeScroll.touches.direction = "undetermined";
465                  }
466                }
467              default:
468                break;
469            }
470          }
471        }
472      },
473      down: function() {
474
475        if(index<heights.length) {
476
477          if(atBottom() && index<heights.length-1) {
478
479            index++;
480            //index, instant, callbacks, toTop
481            animateScroll(index,false,true,false);
482          } else {
483            portHeight = getportHeight();
484            if(Math.floor(elements[index].height()/portHeight)>interstitialIndex) {
485
486              interstitialScroll(parseInt(heights[index])+(portHeight*interstitialIndex));
487              interstitialIndex += 1;
488
489            } else {
490              interstitialScroll(parseInt(heights[index])+(elements[index].outerHeight()-portHeight));
491            }
492
493          }
494        }
495      },
496      up: function() {
497        if(index>=0) {
498          if(atTop() && index>0) {
499
500            index--;
501            //index, instant, callbacks, toTop
502            animateScroll(index,false,true,false);
503          } else {
504
505            if(interstitialIndex>2) {
506              portHeight = getportHeight();
507
508              interstitialIndex -= 1;
509              interstitialScroll(parseInt(heights[index])+(portHeight*interstitialIndex));
510
511            } else {
512
513              interstitialIndex = 1;
514              interstitialScroll(parseInt(heights[index]));
515            }
516          }
517
518        }
519      },
520      init: function() {
521        if (document.addEventListener && settings.touchScroll) {
522          document.addEventListener('touchstart', swipeScroll.touchHandler, eventListenerOptions);
523          document.addEventListener('touchmove', swipeScroll.touchHandler, eventListenerOptions);
524          document.addEventListener('touchend', swipeScroll.touchHandler, eventListenerOptions);
525        }
526      }
527    };
528
529
530    util = {
531      refresh:function(withCallback,scroll) {
532        clearTimeout(timeoutId2);
533        timeoutId2 = setTimeout(function() {
534          //retain position
535          sizePanels(true);
536          //scroll, firstLoad
537          calculatePositions(scroll,false);
538          if(withCallback) {
539              settings.afterResize();
540          }
541        },400);
542      },
543      handleUpdate:function() {
544        //callbacks, scroll
545        //changed from false,true to false,false
546        util.refresh(false,false);
547      },
548      handleResize:function() {
549        //callbacks, scroll
550        util.refresh(true,false);
551      },
552      handleOrientation:function() {
553        //callbacks, scroll
554        util.refresh(true,true);
555      }
556    };
557    settings = $.extend(settings, options);
558
559    //retain position
560    sizePanels(false);
561
562    calculatePositions(false,true);
563
564    if(true===hasLocation) {
565      //index, instant, callbacks, toTop
566      animateScroll(index,false,true,true);
567    } else {
568      setTimeout(function() {
569        //instant,callbacks
570        manualScroll.calculateNearest(true,false);
571      },200);
572    }
573    if(heights.length) {
574      manualScroll.init();
575      swipeScroll.init();
576
577      $window.on("resize",util.handleResize);
578      if (document.addEventListener) {
579        window.addEventListener("orientationchange", util.handleOrientation, false);
580      }
581    }
582    function interstitialScroll(pos) {
583      if( $().velocity ) {
584        $(settings.target).stop().velocity('scroll', {
585          duration: settings.scrollSpeed,
586          easing: settings.easing,
587          offset: pos,
588          mobileHA: false
589        });
590      } else {
591        $(settings.target).stop().animate({
592          scrollTop: pos
593        }, settings.scrollSpeed,settings.easing);
594      }
595    }
596
597    function sizePanels(keepPosition) {
598      if(keepPosition) {
599        top = $window.scrollTop();
600      }
601
602      var selector = settings.section;
603      overflow = [];
604      if(settings.interstitialSection.length) {
605        selector += "," + settings.interstitialSection;
606      }
607      if(settings.scrollbars===false) {
608        settings.overflowScroll = false;
609      }
610      portHeight = getportHeight();
611      $(selector).each(function(i) {
612        var $this = $(this);
613
614        if(settings.setHeights) {
615          if($this.is(settings.interstitialSection)) {
616            overflow[i] = false;
617          } else {
618            if(($this.css("height","auto").outerHeight()<portHeight) || $this.css("overflow")==="hidden") {
619              $this.css({"height":portHeight});
620
621              overflow[i] = false;
622            } else {
623
624              $this.css({"height":$this.outerHeight()});
625
626              if(settings.overflowScroll) {
627                overflow[i] = true;
628              } else {
629                overflow[i] = false;
630              }
631            }
632
633          }
634
635        } else {
636
637          if(($this.outerHeight()<portHeight) || (settings.overflowScroll===false)) {
638            overflow[i] = false;
639          } else {
640            overflow[i] = true;
641          }
642        }
643      });
644      if(keepPosition) {
645        $window.scrollTop(top);
646      }
647    }
648    function calculatePositions(scroll,firstLoad) {
649      var selector = settings.section;
650      if(settings.interstitialSection.length) {
651        selector += "," + settings.interstitialSection;
652      }
653      heights = [];
654      names = [];
655      elements = [];
656      $(selector).each(function(i){
657          var $this = $(this);
658          if(i>0) {
659            heights[i] = parseInt($this.offset().top) + settings.offset;
660          } else {
661            heights[i] = parseInt($this.offset().top);
662          }
663          if(settings.sectionName && $this.data(settings.sectionName)) {
664            names[i] = "#" + $this.data(settings.sectionName).toString().replace(/ /g,"-");
665          } else {
666            if($this.is(settings.interstitialSection)===false) {
667              names[i] = "#" + (i + 1);
668            } else {
669              names[i] = "#";
670              if(i===$(selector).length-1 && i>1) {
671                heights[i] = heights[i-1] + (parseInt($($(selector)[i-1]).outerHeight()) - parseInt($(window).height())) + parseInt($this.outerHeight());
672              }
673            }
674          }
675          elements[i] = $this;
676          try {
677            if($(names[i]).length && window.console) {
678              console.warn("Scrollify warning: Section names can't match IDs - this will cause the browser to anchor.");
679            }
680          } catch (e) {}
681
682          if(window.location.hash===names[i]) {
683            index = i;
684            hasLocation = true;
685          }
686
687      });
688
689      if(true===scroll) {
690        //index, instant, callbacks, toTop
691        animateScroll(index,false,false,false);
692      }
693    }
694
695    function atTop() {
696      if(!overflow[index]) {
697        return true;
698      }
699      top = $window.scrollTop();
700      if(top>parseInt(heights[index])) {
701        return false;
702      } else {
703        return true;
704      }
705    }
706    function atBottom() {
707      if(!overflow[index]) {
708        return true;
709      }
710      top = $window.scrollTop();
711      portHeight = getportHeight();
712
713      if(top<parseInt(heights[index])+(elements[index].outerHeight()-portHeight)-28) {
714
715        return false;
716
717      } else {
718        return true;
719      }
720    }
721  }
722
723  function move(panel,instant) {
724    var z = names.length;
725    for(;z>=0;z--) {
726      if(typeof panel === 'string') {
727        if (names[z]===panel) {
728          index = z;
729          //index, instant, callbacks, toTop
730          animateScroll(z,instant,true,true);
731        }
732      } else {
733        if(z===panel) {
734          index = z;
735          //index, instant, callbacks, toTop
736          animateScroll(z,instant,true,true);
737        }
738      }
739    }
740  }
741  scrollify.move = function(panel) {
742    if(panel===undefined) {
743      return false;
744    }
745    if(typeof panel!=="number" && panel.originalEvent) {
746      panel = $(this).attr("href");
747    }
748    move(panel,false);
749  };
750  scrollify.instantMove = function(panel) {
751    if(panel===undefined) {
752      return false;
753    }
754    move(panel,true);
755  };
756  scrollify.next = function() {
757    if(index<names.length) {
758      index += 1;
759      //index, instant, callbacks, toTop
760      animateScroll(index,false,true,true);
761    }
762  };
763  scrollify.previous = function() {
764    if(index>0) {
765      index -= 1;
766      //index, instant, callbacks, toTop
767      animateScroll(index,false,true,true);
768    }
769  };
770  scrollify.instantNext = function() {
771    if(index<names.length) {
772      index += 1;
773      //index, instant, callbacks, toTop
774      animateScroll(index,true,true,true);
775    }
776  };
777  scrollify.instantPrevious = function() {
778    if(index>0) {
779      index -= 1;
780      //index, instant, callbacks, toTop
781      animateScroll(index,true,true,true);
782    }
783  };
784  scrollify.destroy = function() {
785    if(!initialised) {
786      return false;
787    }
788    if(settings.setHeights) {
789      $(settings.section).each(function() {
790        $(this).css("height","auto");
791      });
792    }
793    $window.off("resize",util.handleResize);
794    if(settings.scrollbars) {
795      $window.off('mousedown', manualScroll.handleMousedown);
796      $window.off('mouseup', manualScroll.handleMouseup);
797      $window.off('scroll', manualScroll.handleScroll);
798    }
799    // $window.off(wheelEvent,manualScroll.wheelHandler);
800    window.removeEventListener(wheelEvent,manualScroll.wheelHandler);
801    $window.off('keydown', manualScroll.keyHandler);
802
803    if (document.addEventListener && settings.touchScroll) {
804      document.removeEventListener('touchstart', swipeScroll.touchHandler, eventListenerOptions);
805      document.removeEventListener('touchmove', swipeScroll.touchHandler, eventListenerOptions);
806      document.removeEventListener('touchend', swipeScroll.touchHandler, eventListenerOptions);
807    }
808    heights = [];
809    names = [];
810    elements = [];
811    overflow = [];
812    firstLoad = true;
813    initialised = false;
814  };
815  scrollify.update = function() {
816    if(!initialised) {
817      return false;
818    }
819    util.handleUpdate();
820  };
821  scrollify.current = function() {
822    return elements[index];
823  };
824  scrollify.currentIndex = function() {
825    return index;
826  };
827  scrollify.disable = function() {
828    disabled = true;
829  };
830  scrollify.enable = function() {
831    disabled = false;
832    if (initialised) {
833      //instant,callbacks
834      manualScroll.calculateNearest(false,false);
835    }
836  };
837  scrollify.isDisabled = function() {
838    return disabled;
839  };
840  scrollify.setOptions = function(updatedOptions) {
841    if(!initialised) {
842      return false;
843    }
844    if(typeof updatedOptions === "object") {
845      settings = $.extend(settings, updatedOptions);
846      util.handleUpdate();
847    } else if(window.console) {
848      console.warn("Scrollify warning: setOptions expects an object.");
849    }
850  };
851  $.scrollify = scrollify;
852  return scrollify;
853}));

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.