1var _____WB$wombat$assign$function_____=function(name){return (self._wb_wombat && self._wb_wombat.local_init && self._wb_wombat.local_init(name))||self[name];};if(!self.__WB_pmw){self.__WB_pmw=function(obj){this.__WB_source=obj;return this;}}{ 2let window = _____WB$wombat$assign$function_____("window"); 3let self = _____WB$wombat$assign$function_____("self"); 4let document = _____WB$wombat$assign$function_____("document"); 5let location = _____WB$wombat$assign$function_____("location"); 6let top = _____WB$wombat$assign$function_____("top"); 7let parent = _____WB$wombat$assign$function_____("parent"); 8let frames = _____WB$wombat$assign$function_____("frames"); 9let opens = _____WB$wombat$assign$function_____("opens"); 10// SmoothScroll for websites v1.2.1 11// Licensed under the terms of the MIT license. 12 13// People involved 14// - Balazs Galambosi (maintainer) 15// - Michael Herf (Pulse Algorithm) 16 17(function(){ 18"use strict"; 19// Scroll Variables (tweakable) 20var defaultOptions = { 21 22 // Scrolling Core 23 frameRate : 150, // [Hz] 24 animationTime : 400, // [px] 25 stepSize : 120, // [px] 26 27 // Pulse (less tweakable) 28 // ratio of "tail" to "acceleration" 29 pulseAlgorithm : true, 30 pulseScale : 8, 31 pulseNormalize : 1, 32 33 // Acceleration 34 accelerationDelta : 20, // 20 35 accelerationMax : 1, // 1 36 37 // Keyboard Settings 38 keyboardSupport : true, // option 39 arrowScroll : 50, // [px] 40 41 // Other 42 touchpadSupport : true, 43 fixedBackground : true, 44 excluded : "" 45}; 46 47var options = defaultOptions; 48 49 50// Other Variables 51var isExcluded = false; 52var isFrame = false; 53var direction = { x: 0, y: 0 }; 54var initDone = false; 55var root = document.documentElement; 56var activeElement; 57var observer; 58var deltaBuffer = [ 120, 120, 120 ]; 59 60var key = { left: 37, up: 38, right: 39, down: 40, spacebar: 32, 61 pageup: 33, pagedown: 34, end: 35, home: 36 }; 62 63 64/*********************************************** 65 * SETTINGS 66 ***********************************************/ 67 68var options = defaultOptions; 69 70 71/*********************************************** 72 * INITIALIZE 73 ***********************************************/ 74 75/** 76 * Tests if smooth scrolling is allowed. Shuts down everything if not. 77 */ 78function initTest() { 79 80 var disableKeyboard = false; 81 82 // disable keyboard support if anything above requested it 83 if (disableKeyboard) { 84 removeEvent("keydown", keydown); 85 } 86 87 if (options.keyboardSupport && !disableKeyboard) { 88 addEvent("keydown", keydown); 89 } 90} 91 92/** 93 * Sets up scrolls array, determines if frames are involved. 94 */ 95function init() { 96 97 if (!document.body) return; 98 99 var body = document.body; 100 var html = document.documentElement; 101 var windowHeight = window.innerHeight; 102 var scrollHeight = body.scrollHeight; 103 104 // check compat mode for root element 105 root = (document.compatMode.indexOf('CSS') >= 0) ? html : body; 106 activeElement = body; 107 108 initTest(); 109 initDone = true; 110 111 // Checks if this script is running in a frame 112 if (top != self) { 113 isFrame = true; 114 } 115 116 /** 117 * This fixes a bug where the areas left and right to 118 * the content does not trigger the onmousewheel event 119 * on some pages. e.g.: html, body { height: 100% } 120 */ 121 else if (scrollHeight > windowHeight && 122 (body.offsetHeight <= windowHeight || 123 html.offsetHeight <= windowHeight)) { 124 125 var pending = false; 126 var refresh = function () { 127 if (!pending && html.scrollHeight != document.height) { 128 pending = true; // add a new pending action 129 setTimeout(function () { 130 html.style.height = document.height + 'px'; 131 pending = false; 132 }, 500); // act rarely to stay fast 133 } 134 }; 135 html.style.height = 'auto'; 136 setTimeout(refresh, 10); 137 138 // clearfix 139 if (root.offsetHeight <= windowHeight) { 140 var underlay = document.createElement("div"); 141 underlay.style.clear = "both";
142 body.appendChild(underlay); 143 } 144 } 145 146 // disable fixed background 147 if (!options.fixedBackground && !isExcluded) { 148 body.style.backgroundAttachment = "scroll"; 149 html.style.backgroundAttachment = "scroll"; 150 } 151} 152 153 154/************************************************ 155 * SCROLLING 156 ************************************************/ 157 158var que = []; 159var pending = false; 160var lastScroll = +new Date; 161 162/** 163 * Pushes scroll actions to the scrolling queue. 164 */ 165function scrollArray(elem, left, top, delay) { 166 167 delay || (delay = 1000); 168 directionCheck(left, top); 169 170 if (options.accelerationMax != 1) { 171 var now = +new Date; 172 var elapsed = now - lastScroll; 173 if (elapsed < options.accelerationDelta) { 174 var factor = (1 + (30 / elapsed)) / 2; 175 if (factor > 1) { 176 factor = Math.min(factor, options.accelerationMax); 177 left *= factor; 178 top *= factor; 179 } 180 } 181 lastScroll = +new Date; 182 } 183 184 // push a scroll command 185 que.push({ 186 x: left, 187 y: top, 188 lastX: (left < 0) ? 0.99 : -0.99, 189 lastY: (top < 0) ? 0.99 : -0.99, 190 start: +new Date 191 }); 192 193 // don't act if there's a pending queue 194 if (pending) { 195 return; 196 } 197 198 var scrollWindow = (elem === document.body); 199 200 var step = function (time) { 201 202 var now = +new Date; 203 var scrollX = 0; 204 var scrollY = 0; 205 206 for (var i = 0; i < que.length; i++) { 207 208 var item = que[i]; 209 var elapsed = now - item.start; 210 var finished = (elapsed >= options.animationTime); 211 212 // scroll position: [0, 1] 213 var position = (finished) ? 1 : elapsed / options.animationTime; 214 215 // easing [optional] 216 if (options.pulseAlgorithm) { 217 position = pulse(position); 218 } 219 220 // only need the difference 221 var x = (item.x * position - item.lastX) >> 0; 222 var y = (item.y * position - item.lastY) >> 0; 223 224 // add this to the total scrolling 225 scrollX += x; 226 scrollY += y; 227 228 // update last values 229 item.lastX += x; 230 item.lastY += y; 231 232 // delete and step back if it's over 233 if (finished) { 234 que.splice(i, 1); i--; 235 } 236 } 237 238 // scroll left and top 239 if (scrollWindow) { 240 window.scrollBy(scrollX, scrollY); 241 } 242 else { 243 if (scrollX) elem.scrollLeft += scrollX; 244 if (scrollY) elem.scrollTop += scrollY; 245 } 246 247 // clean up if there's nothing left to do 248 if (!left && !top) { 249 que = []; 250 } 251 252 if (que.length) { 253 requestFrame(step, elem, (delay / options.frameRate + 1)); 254 } else { 255 pending = false; 256 } 257 }; 258 259 // start a new queue of actions 260 requestFrame(step, elem, 0); 261 pending = true; 262} 263 264 265/*********************************************** 266 * EVENTS 267 ***********************************************/ 268 269/** 270 * Mouse wheel handler. 271 * @param {Object} event 272 */ 273function wheel(event) { 274 275 if (!initDone) { 276 init(); 277 } 278 279 var target = event.target; 280 var overflowing = overflowingAncestor(target); 281 282 // use default if there's no overflowing 283 // element or default action is prevented 284 if (!overflowing || event.defaultPrevented || 285 isNodeName(activeElement, "embed") || 286 (isNodeName(target, "embed") && /\.pdf/i.test(target.src))) { 287 return true; 288 } 289 290 var deltaX = event.wheelDeltaX || 0; 291 var deltaY = event.wheelDeltaY || 0; 292 293 // use wheelDelta if deltaX/Y is not available 294 if (!deltaX && !deltaY) { 295 deltaY = event.wheelDelta || 0; 296 } 297 298 // check if it's a touchpad scroll that should be ignored 299 if (!options.touchpadSupport && isTouchpad(deltaY)) { 300 return true; 301 } 302 303 // scale by step size 304 // delta is 120 most of the time
305 // synaptics seems to send 1 sometimes 306 if (Math.abs(deltaX) > 1.2) { 307 deltaX *= options.stepSize / 120; 308 } 309 if (Math.abs(deltaY) > 1.2) { 310 deltaY *= options.stepSize / 120; 311 } 312 313 scrollArray(overflowing, -deltaX, -deltaY); 314 event.preventDefault(); 315} 316 317/** 318 * Keydown event handler. 319 * @param {Object} event 320 */ 321function keydown(event) { 322 323 var target = event.target; 324 var modifier = event.ctrlKey || event.altKey || event.metaKey || 325 (event.shiftKey && event.keyCode !== key.spacebar); 326 327 // do nothing if user is editing text 328 // or using a modifier key (except shift) 329 // or in a dropdown 330 if ( /input|textarea|select|embed/i.test(target.nodeName) || 331 target.isContentEditable || 332 event.defaultPrevented || 333 modifier ) { 334 return true; 335 } 336 // spacebar should trigger button press 337 if (isNodeName(target, "button") && 338 event.keyCode === key.spacebar) { 339 return true; 340 } 341 342 var shift, x = 0, y = 0; 343 var elem = overflowingAncestor(activeElement); 344 var clientHeight = elem.clientHeight; 345 346 if (elem == document.body) { 347 clientHeight = window.innerHeight; 348 } 349 350 switch (event.keyCode) { 351 case key.up: 352 y = -options.arrowScroll; 353 break; 354 case key.down: 355 y = options.arrowScroll; 356 break; 357 case key.spacebar: // (+ shift) 358 shift = event.shiftKey ? 1 : -1; 359 y = -shift * clientHeight * 0.9; 360 break; 361 case key.pageup: 362 y = -clientHeight * 0.9; 363 break; 364 case key.pagedown: 365 y = clientHeight * 0.9; 366 break; 367 case key.home: 368 y = -elem.scrollTop; 369 break; 370 case key.end: 371 var damt = elem.scrollHeight - elem.scrollTop - clientHeight; 372 y = (damt > 0) ? damt+10 : 0; 373 break; 374 case key.left: 375 x = -options.arrowScroll; 376 break; 377 case key.right: 378 x = options.arrowScroll; 379 break; 380 default: 381 return true; // a key we don't care about 382 } 383 384 scrollArray(elem, x, y); 385 event.preventDefault(); 386} 387 388/** 389 * Mousedown event only for updating activeElement 390 */ 391function mousedown(event) { 392 activeElement = event.target; 393} 394 395 396/*********************************************** 397 * OVERFLOW 398 ***********************************************/ 399 400var cache = {}; // cleared out every once in while 401setInterval(function () { cache = {}; }, 10 * 1000); 402 403var uniqueID = (function () { 404 var i = 0; 405 return function (el) { 406 return el.uniqueID || (el.uniqueID = i++); 407 }; 408})(); 409 410function setCache(elems, overflowing) { 411 for (var i = elems.length; i--;) 412 cache[uniqueID(elems[i])] = overflowing; 413 return overflowing; 414} 415 416function overflowingAncestor(el) { 417 var elems = []; 418 var rootScrollHeight = root.scrollHeight; 419 do { 420 var cached = cache[uniqueID(el)]; 421 if (cached) { 422 return setCache(elems, cached); 423 } 424 elems.push(el); 425 if (rootScrollHeight === el.scrollHeight) { 426 if (!isFrame || root.clientHeight + 10 < rootScrollHeight) { 427 return setCache(elems, document.body); // scrolling root in WebKit 428 } 429 } else if (el.clientHeight + 10 < el.scrollHeight) { 430 var overflow = getComputedStyle(el, "").getPropertyValue("overflow-y"); 431 if (overflow === "scroll" || overflow === "auto") { 432 return setCache(elems, el); 433 } 434 } 435 } while (el = el.parentNode); 436} 437 438 439/*********************************************** 440 * HELPERS 441 ***********************************************/ 442 443function addEvent(type, fn, bubble) { 444 window.addEventListener(type, fn, (bubble||false)); 445} 446 447function removeEvent(type, fn, bubble) { 448 window.removeEventListener(type, fn, (bubble||false)); 449} 450 451function isNodeName(el, tag) { 452 return (el.nodeName||"").toLowerCase() === tag.toLowerCase(); 453} 454 455function directionCheck(x, y) { 456 x = (x > 0) ? 1 : -1; 457 y = (y > 0) ? 1 : -1; 458 if (direction.x !== x || direction.y !== y) { 459 direction.x = x; 460 direction.y = y; 461 que = []; 462 lastScroll = 0; 463 } 464} 465 466var deltaBufferTimer; 467 468function isTouchpad(deltaY) { 469 if (!deltaY) return; 470 deltaY = Math.abs(deltaY) 471 deltaBuffer.push(deltaY); 472 deltaBuffer.shift(); 473 clearTimeout(deltaBufferTimer); 474 var allDivisable = (isDivisible(deltaBuffer[0], 120) && 475 isDivisible(deltaBuffer[1], 120) && 476 isDivisible(deltaBuffer[2], 120)); 477 return !allDivisable; 478} 479 480function isDivisible(n, divisor) { 481 return (Math.floor(n / divisor) == n / divisor); 482} 483 484var requestFrame = (function () { 485 return window.requestAnimationFrame || 486 window.webkitRequestAnimationFrame || 487 function (callback, element, delay) { 488 window.setTimeout(callback, delay || (1000/60)); 489 }; 490})(); 491 492 493/*********************************************** 494 * PULSE 495 ***********************************************/ 496 497/** 498 * Viscous fluid with a pulse for part and decay for the rest. 499 * - Applies a fixed force over an interval (a damped acceleration), and 500 * - Lets the exponential bleed away the velocity over a longer interval 501 * - Michael Herf, http://stereopsis.com/stopping/ 502 */ 503function pulse_(x) { 504 var val, start, expx; 505 // test 506 x = x * options.pulseScale; 507 if (x < 1) { // acceleartion 508 val = x - (1 - Math.exp(-x)); 509 } else { // tail 510 // the previous animation ended here: 511 start = Math.exp(-1); 512 // simple viscous drag 513 x -= 1; 514 expx = 1 - Math.exp(-x); 515 val = start + (expx * (1 - start)); 516 }
517 return val * options.pulseNormalize; 518} 519 520function pulse(x) { 521 if (x >= 1) return 1; 522 if (x <= 0) return 0; 523 524 if (options.pulseNormalize == 1) { 525 options.pulseNormalize /= pulse_(1); 526 } 527 return pulse_(x); 528} 529 530var isChrome = /chrome/i.test(window.navigator.userAgent); 531var wheelEvent = null; 532if ("onwheel" in document.createElement("div")) 533 wheelEvent = "wheel"; 534else if ("onmousewheel" in document.createElement("div")) 535 wheelEvent = "mousewheel"; 536 537if (wheelEvent && isChrome) { 538 addEvent(wheelEvent, wheel); 539 addEvent("mousedown", mousedown); 540 addEvent("load", init); 541} 542 543})(jQuery); 544}
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.