1/*! 2 * ClockPicker v{package.version} (https://weareoutman.github.io/clockpicker/) 3 * Copyright 2014 Wang Shenwei. 4 * Licensed under MIT (https://github.com/weareoutman/clockpicker/blob/gh-pages/LICENSE) 5 */ 6 7;(function(){ 8 var $ = window.jQuery, 9 $win = $(window), 10 $doc = $(document), 11 $body; 12 13 // Can I use inline svg ? 14 var svgNS = 'https
vendor: 20,781 bytes, lines 14-729
14://www.w3.org/2000/svg', 15 svgSupported = 'SVGAngle' in window && (function(){ 16 var supported, 17 el = document.createElement('div'); 18 el.innerHTML = '<svg/>'; 19 supported = (el.firstChild && el.firstChild.namespaceURI) == svgNS; 20 el.innerHTML = ''; 21 return supported; 22 })(); 23 24 // Can I use transition ? 25 var transitionSupported = (function(){ 26 var style = document.createElement('div').style; 27 return 'transition' in style || 28 'WebkitTransition' in style || 29 'MozTransition' in style || 30 'msTransition' in style || 31 'OTransition' in style; 32 })(); 33 34 // Listen touch events in touch screen device, instead of mouse events in desktop. 35 var touchSupported = 'ontouchstart' in window, 36 mousedownEvent = 'mousedown' + ( touchSupported ? ' touchstart' : ''), 37 mousemoveEvent = 'mousemove.clockpicker' + ( touchSupported ? ' touchmove.clockpicker' : ''), 38 mouseupEvent = 'mouseup.clockpicker' + ( touchSupported ? ' touchend.clockpicker' : ''); 39 40 // Vibrate the device if supported 41 var vibrate = navigator.vibrate ? 'vibrate' : navigator.webkitVibrate ? 'webkitVibrate' : null; 42 43 function createSvgElement(name) { 44 return document.createElementNS(svgNS, name); 45 } 46 47 function leadingZero(num) { 48 return (num < 10 ? '0' : '') + num; 49 } 50 51 // Get a unique id 52 var idCounter = 0; 53 function uniqueId(prefix) { 54 var id = ++idCounter + ''; 55 return prefix ? prefix + id : id; 56 } 57 58 // Clock size 59 var dialRadius = 100, 60 outerRadius = 80, 61 // innerRadius = 80 on 12 hour clock 62 innerRadius = 54, 63 tickRadius = 13, 64 diameter = dialRadius * 2, 65 duration = transitionSupported ? 350 : 1; 66 67 // Popover template 68 var tpl = [ 69 '<div class="popover clockpicker-popover">', 70 '<div class="arrow"></div>', 71 '<div class="popover-title">', 72 '<span class="clockpicker-span-hours text-primary"></span>', 73 ' : ', 74 '<span class="clockpicker-span-minutes"></span>', 75 '<span class="clockpicker-span-am-pm"></span>', 76 '</div>', 77 '<div class="popover-content">', 78 '<div class="clockpicker-plate">', 79 '<div class="clockpicker-canvas"></div>', 80 '<div class="clockpicker-dial clockpicker-hours"></div>', 81 '<div class="clockpicker-dial clockpicker-minutes clockpicker-dial-out"></div>', 82 '</div>', 83 '<span class="clockpicker-am-pm-block">', 84 '</span>', 85 '</div>', 86 '</div>' 87 ].join(''); 88 89 // ClockPicker 90 function ClockPicker(element, options) { 91 var popover = $(tpl), 92 plate = popover.find('.clockpicker-plate'), 93 hoursView = popover.find('.clockpicker-hours'), 94 minutesView = popover.find('.clockpicker-minutes'), 95 amPmBlock = popover.find('.clockpicker-am-pm-block'), 96 isInput = element.prop('tagName') === 'INPUT', 97 input = isInput ? element : element.find('input'), 98 addon = element.find('.input-group-addon'), 99 self = this, 100 timer; 101 102 this.id = uniqueId('cp'); 103 this.element = element; 104 this.options = options; 105 this.isAppended = false; 106 this.isShown = false; 107 this.currentView = 'hours'; 108 this.isInput = isInput; 109 this.input = input; 110 this.addon = addon; 111 this.popover = popover; 112 this.plate = plate; 113 this.hoursView = hoursView; 114 this.minutesView = minutesView; 115 this.amPmBlock = amPmBlock; 116 this.spanHours = popover.find('.clockpicker-span-hours'); 117 this.spanMinutes = popover.find('.clockpicker-span-minutes'); 118 this.spanAmPm = popover.find('.clockpicker-span-am-pm'); 119 this.amOrPm = "PM"; 120 121 // Setup for for 12 hour clock if option is selected 122 if (options.twelvehour) { 123 124 var amPmButtonsTemplate = ['<div class="clockpicker-am-pm-block">', 125 '<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-am-button">', 126 'AM</button>', 127 '<button type="button" class="btn btn-sm btn-default clockpicker-button clockpicker-pm-button">', 128 'PM</button>', 129 '</div>'].join(''); 130 131 var amPmButtons = $(amPmButtonsTemplate); 132 //amPmButtons.appendTo(plate); 133 134 ////Not working b/c they are not shown when this runs 135 //$('clockpicker-am-button') 136 // .on("click", function() { 137 // self.amOrPm = "AM"; 138 // $('.clockpicker-span-am-pm').empty().append('AM'); 139 // }); 140 // 141 //$('clockpicker-pm-button') 142 // .on("click", function() { 143 // self.amOrPm = "PM"; 144 // $('.clockpicker-span-am-pm').empty().append('PM'); 145 // }); 146 147 $('<button type="button" class="btn btn-sm btn-default clockpicker-button am-button">' + "AM" + '</button>') 148 .on("click", function() { 149 self.amOrPm = "AM"; 150 $('.clockpicker-span-am-pm').empty().append('AM'); 151 }).appendTo(this.amPmBlock); 152 153 154 $('<button type="button" class="btn btn-sm btn-default clockpicker-button pm-button">' + "PM" + '</button>') 155 .on("click", function() { 156 self.amOrPm = 'PM'; 157 $('.clockpicker-span-am-pm').empty().append('PM'); 158 }).appendTo(this.amPmBlock); 159 160 } 161 162 if (! options.autoclose) { 163 // If autoclose is not setted, append a button 164 $('<button type="button" class="btn btn-sm btn-default btn-block clockpicker-button">' + options.donetext + '</button>') 165 .click($.proxy(this.done, this)) 166 .appendTo(popover); 167 } 168 169 // Placement and arrow align - make sure they make sense. 170 if ((options.placement === 'top' || options.placement === 'bottom') && (options.align === 'top' || options.align === 'bottom')) options.align = 'left'; 171 if ((options.placement === 'left' || options.placement === 'right') && (options.align === 'left' || options.align === 'right')) options.align = 'top'; 172 173 popover.addClass(options.placement); 174 popover.addClass('clockpicker-align-' + options.align); 175 176 this.spanHours.click($.proxy(this.toggleView, this, 'hours')); 177 this.spanMinutes.click($.proxy(this.toggleView, this, 'minutes')); 178 179 // Show or toggle 180 input.on('focus.clockpicker click.clockpicker', $.proxy(this.show, this)); 181 addon.on('click.clockpicker', $.proxy(this.toggle, this)); 182 183 // Build ticks 184 var tickTpl = $('<div class="clockpicker-tick"></div>'), 185 i, tick, radian, radius; 186 187 // Hours view 188 if (options.twelvehour) { 189 for (i = 1; i < 13; i += 1) { 190 tick = tickTpl.clone(); 191 radian = i / 6 * Math.PI; 192 radius = outerRadius; 193 tick.css('font-size', '120%'); 194 tick.css({ 195 left: dialRadius + Math.sin(radian) * radius - tickRadius, 196 top: dialRadius - Math.cos(radian) * radius - tickRadius 197 }); 198 tick.html(i === 0 ? '00' : i); 199 hoursView.append(tick); 200 tick.on(mousedownEvent, mousedown); 201 } 202 } else { 203 for (i = 0; i < 24; i += 1) { 204 tick = tickTpl.clone(); 205 radian = i / 6 * Math.PI; 206 var inner = i > 0 && i < 13; 207 radius = inner ? innerRadius : outerRadius; 208 tick.css({ 209 left: dialRadius + Math.sin(radian) * radius - tickRadius, 210 top: dialRadius - Math.cos(radian) * radius - tickRadius 211 }); 212 if (inner) { 213 tick.css('font-size', '120%'); 214 } 215 tick.html(i === 0 ? '00' : i); 216 hoursView.append(tick); 217 tick.on(mousedownEvent, mousedown); 218 } 219 } 220 221 // Minutes view 222 for (i = 0; i < 60; i += 5) { 223 tick = tickTpl.clone(); 224 radian = i / 30 * Math.PI; 225 tick.css({ 226 left: dialRadius + Math.sin(radian) * outerRadius - tickRadius, 227 top: dialRadius - Math.cos(radian) * outerRadius - tickRadius 228 }); 229 tick.css('font-size', '120%'); 230 tick.html(leadingZero(i)); 231 minutesView.append(tick); 232 tick.on(mousedownEvent, mousedown); 233 } 234 235 // Clicking on minutes view space 236 plate.on(mousedownEvent, function(e){ 237 if ($(e.target).closest('.clockpicker-tick').length === 0) { 238 mousedown(e, true); 239 } 240 }); 241 242 // Mousedown or touchstart 243 function mousedown(e, space) { 244 var offset = plate.offset(), 245 isTouch = /^touch/.test(e.type), 246 x0 = offset.left + dialRadius, 247 y0 = offset.top + dialRadius, 248 dx = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, 249 dy = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0, 250 z = Math.sqrt(dx * dx + dy * dy), 251 moved = false; 252 253 // When clicking on minutes view space, check the mouse position 254 if (space && (z < outerRadius - tickRadius || z > outerRadius + tickRadius)) { 255 return; 256 } 257 e.preventDefault(); 258 259 // Set cursor style of body after 200ms 260 var movingTimer = setTimeout(function(){ 261 $body.addClass('clockpicker-moving'); 262 }, 200); 263 264 // Place the canvas to top 265 if (svgSupported) { 266 plate.append(self.canvas); 267 } 268 269 // Clock 270 self.setHand(dx, dy, ! space, true); 271 272 // Mousemove on document 273 $doc.off(mousemoveEvent).on(mousemoveEvent, function(e){ 274 e.preventDefault(); 275 var isTouch = /^touch/.test(e.type), 276 x = (isTouch ? e.originalEvent.touches[0] : e).pageX - x0, 277 y = (isTouch ? e.originalEvent.touches[0] : e).pageY - y0; 278 if (! moved && x === dx && y === dy) { 279 // Clicking in chrome on windows will trigger a mousemove event 280 return; 281 } 282 moved = true; 283 self.setHand(x, y, false, true); 284 }); 285 286 // Mouseup on document 287 $doc.off(mouseupEvent).on(mouseupEvent, function(e){ 288 $doc.off(mouseupEvent); 289 e.preventDefault(); 290 var isTouch = /^touch/.test(e.type), 291 x = (isTouch ? e.originalEvent.changedTouches[0] : e).pageX - x0, 292 y = (isTouch ? e.originalEvent.changedTouches[0] : e).pageY - y0; 293 if ((space || moved) && x === dx && y === dy) { 294 self.setHand(x, y); 295 } 296 if (self.currentView === 'hours') { 297 self.toggleView('minutes', duration / 2); 298 } else { 299 if (options.autoclose) { 300 self.minutesView.addClass('clockpicker-dial-out'); 301 setTimeout(function(){ 302 self.done(); 303 }, duration / 2); 304 } 305 } 306 plate.prepend(canvas); 307 308 // Reset cursor style of body 309 clearTimeout(movingTimer); 310 $body.removeClass('clockpicker-moving'); 311 312 // Unbind mousemove event 313 $doc.off(mousemoveEvent); 314 }); 315 } 316 317 if (svgSupported) { 318 // Draw clock hands and others 319 var canvas = popover.find('.clockpicker-canvas'), 320 svg = createSvgElement('svg'); 321 svg.setAttribute('class', 'clockpicker-svg'); 322 svg.setAttribute('width', diameter); 323 svg.setAttribute('height', diameter); 324 var g = createSvgElement('g'); 325 g.setAttribute('transform', 'translate(' + dialRadius + ',' + dialRadius + ')'); 326 var bearing = createSvgElement('circle'); 327 bearing.setAttribute('class', 'clockpicker-canvas-bearing'); 328 bearing.setAttribute('cx', 0); 329 bearing.setAttribute('cy', 0); 330 bearing.setAttribute('r', 2); 331 var hand = createSvgElement('line'); 332 hand.setAttribute('x1', 0); 333 hand.setAttribute('y1', 0); 334 var bg = createSvgElement('circle'); 335 bg.setAttribute('class', 'clockpicker-canvas-bg'); 336 bg.setAttribute('r', tickRadius); 337 var fg = createSvgElement('circle'); 338 fg.setAttribute('class', 'clockpicker-canvas-fg'); 339 fg.setAttribute('r', 3.5); 340 g.appendChild(hand); 341 g.appendChild(bg); 342 g.appendChild(fg); 343 g.appendChild(bearing); 344 svg.appendChild(g); 345 canvas.append(svg); 346 347 this.hand = hand; 348 this.bg = bg; 349 this.fg = fg; 350 this.bearing = bearing; 351 this.g = g; 352 this.canvas = canvas; 353 } 354 355 raiseCallback(this.options.init); 356 } 357 358 function raiseCallback(callbackFunction) { 359 if (callbackFunction && typeof callbackFunction === "function") { 360 callbackFunction(); 361 } 362 } 363 364 // Default options 365 ClockPicker.DEFAULTS = { 366 'default': '', // default time, 'now' or '13:14' e.g. 367 fromnow: 0, // set default time to * milliseconds from now (using with default = 'now') 368 placement: 'bottom', // clock popover placement 369 align: 'left', // popover arrow align 370 donetext: '宿', // done button text 371 autoclose: false, // auto close when minute is selected 372 twelvehour: false, // change to 12 hour AM/PM clock from 24 hour 373 vibrate: true // vibrate the device when dragging clock hand 374 }; 375 376 // Show or hide popover 377 ClockPicker.prototype.toggle = function(){ 378 this[this.isShown ? 'hide' : 'show'](); 379 }; 380 381 // Set popover position 382 ClockPicker.prototype.locate = function(){ 383 var element = this.element, 384 popover = this.popover, 385 offset = element.offset(), 386 width = element.outerWidth(), 387 height = element.outerHeight(), 388 placement = this.options.placement, 389 align = this.options.align, 390 styles = {}, 391 self = this; 392 393 popover.show(); 394 395 // Place the popover 396 switch (placement) { 397 case 'bottom': 398 styles.top = offset.top + height; 399 break; 400 case 'right': 401 styles.left = offset.left + width; 402 break; 403 case 'top': 404 styles.top = offset.top - popover.outerHeight(); 405 break; 406 case 'left': 407 styles.left = offset.left - popover.outerWidth(); 408 break; 409 } 410 411 // Align the popover arrow 412 switch (align) { 413 case 'left': 414 styles.left = offset.left; 415 break; 416 case 'right': 417 styles.left = offset.left + width - popover.outerWidth(); 418 break; 419 case 'top': 420 styles.top = offset.top; 421 break; 422 case 'bottom': 423 styles.top = offset.top + height - popover.outerHeight(); 424 break; 425 } 426 427 popover.css(styles); 428 }; 429 430 // Show popover 431 ClockPicker.prototype.show = function(e){ 432 // Not show again 433 if (this.isShown) { 434 return; 435 } 436 437 raiseCallback(this.options.beforeShow); 438 439 var self = this; 440 441 // Initialize 442 if (! this.isAppended) { 443 // Append popover to body 444 $body = $(document.body).append(this.popover); 445 446 // Reset position when resize 447 $win.on('resize.clockpicker' + this.id, function(){ 448 if (self.isShown) { 449 self.locate(); 450 } 451 }); 452 453 this.isAppended = true; 454 } 455 456 // Get the time 457 var value = ((this.input.prop('value') || this.options['default'] || '') + '').split(':'); 458 if (value[0] === 'now') { 459 var now = new Date(+ new Date() + this.options.fromnow); 460 value = [ 461 now.getHours(), 462 now.getMinutes() 463 ]; 464 } 465 this.hours = + value[0] || 0; 466 this.minutes = + value[1] || 0; 467 this.spanHours.html(leadingZero(this.hours)); 468 this.spanMinutes.html(leadingZero(this.minutes)); 469 470 // Toggle to hours view 471 this.toggleView('hours'); 472 473 // Set position 474 this.locate(); 475 476 this.isShown = true; 477 478 // Hide when clicking or tabbing on any element except the clock, input and addon 479 $doc.on('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id, function(e){ 480 var target = $(e.target); 481 if (target.closest(self.popover).length === 0 && 482 target.closest(self.addon).length === 0 && 483 target.closest(self.input).length === 0) { 484 self.hide(); 485 } 486 }); 487 488 // Hide when ESC is pressed 489 $doc.on('keyup.clockpicker.' + this.id, function(e){ 490 if (e.keyCode === 27) { 491 self.hide(); 492 } 493 }); 494 495 raiseCallback(this.options.afterShow); 496 }; 497 498 // Hide popover 499 ClockPicker.prototype.hide = function(){ 500 raiseCallback(this.options.beforeHide); 501 502 this.isShown = false; 503 504 // Unbinding events on document 505 $doc.off('click.clockpicker.' + this.id + ' focusin.clockpicker.' + this.id); 506 $doc.off('keyup.clockpicker.' + this.id); 507 508 this.popover.hide(); 509 510 raiseCallback(this.options.afterHide); 511 }; 512 513 // Toggle to hours or minutes view 514 ClockPicker.prototype.toggleView = function(view, delay){ 515 var raiseAfterHourSelect = false; 516 if (view === 'minutes' && $(this.hoursView).css("visibility") === "visible") { 517 raiseCallback(this.options.beforeHourSelect); 518 raiseAfterHourSelect = true; 519 } 520 var isHours = view === 'hours', 521 nextView = isHours ? this.hoursView : this.minutesView, 522 hideView = isHours ? this.minutesView : this.hoursView; 523 524 this.currentView = view; 525 526 this.spanHours.toggleClass('text-primary', isHours); 527 this.spanMinutes.toggleClass('text-primary', ! isHours); 528 529 // Let's make transitions 530 hideView.addClass('clockpicker-dial-out'); 531 nextView.css('visibility', 'visible').removeClass('clockpicker-dial-out'); 532 533 // Reset clock hand 534 this.resetClock(delay); 535 536 // After transitions ended 537 clearTimeout(this.toggleViewTimer); 538 this.toggleViewTimer = setTimeout(function(){ 539 hideView.css('visibility', 'hidden'); 540 }, duration); 541 542 if (raiseAfterHourSelect) { 543 raiseCallback(this.options.afterHourSelect); 544 } 545 }; 546 547 // Reset clock hand 548 ClockPicker.prototype.resetClock = function(delay){ 549 var view = this.currentView, 550 value = this[view], 551 isHours = view === 'hours', 552 unit = Math.PI / (isHours ? 6 : 30), 553 radian = value * unit, 554 radius = isHours && value > 0 && value < 13 ? innerRadius : outerRadius, 555 x = Math.sin(radian) * radius, 556 y = - Math.cos(radian) * radius, 557 self = this; 558 if (svgSupported && delay) { 559 self.canvas.addClass('clockpicker-canvas-out'); 560 setTimeout(function(){ 561 self.canvas.removeClass('clockpicker-canvas-out'); 562 self.setHand(x, y); 563 }, delay); 564 } else { 565 this.setHand(x, y); 566 } 567 }; 568 569 // Set clock hand to (x, y) 570 ClockPicker.prototype.setHand = function(x, y, roundBy5, dragging){ 571 var radian = Math.atan2(x, - y), 572 isHours = this.currentView === 'hours', 573 unit = Math.PI / (isHours || roundBy5 ? 6 : 30), 574 z = Math.sqrt(x * x + y * y), 575 options = this.options, 576 inner = isHours && z < (outerRadius + innerRadius) / 2, 577 radius = inner ? innerRadius : outerRadius, 578 value; 579 580 if (options.twelvehour) { 581 radius = outerRadius; 582 } 583 584 // Radian should in range [0, 2PI] 585 if (radian < 0) { 586 radian = Math.PI * 2 + radian; 587 } 588 589 // Get the round value 590 value = Math.round(radian / unit); 591 592 // Get the round radian 593 radian = value * unit; 594 595 // Correct the hours or minutes 596 if (options.twelvehour) { 597 if (isHours) { 598 if (value === 0) { 599 value = 12; 600 } 601 } else { 602 if (roundBy5) { 603 value *= 5; 604 } 605 if (value === 60) { 606 value = 0; 607 } 608 } 609 } else { 610 if (isHours) { 611 if (value === 12) { 612 value = 0; 613 } 614 value = inner ? (value === 0 ? 12 : value) : value === 0 ? 0 : value + 12; 615 } else { 616 if (roundBy5) { 617 value *= 5; 618 } 619 if (value === 60) { 620 value = 0; 621 } 622 } 623 } 624 625 // Once hours or minutes changed, vibrate the device 626 if (this[this.currentView] !== value) { 627 if (vibrate && this.options.vibrate) { 628 // Do not vibrate too frequently 629 if (! this.vibrateTimer) { 630 navigator[vibrate](10); 631 this.vibrateTimer = setTimeout($.proxy(function(){ 632 this.vibrateTimer = null; 633 }, this), 100); 634 } 635 } 636 } 637 638 this[this.currentView] = value; 639 this[isHours ? 'spanHours' : 'spanMinutes'].html(leadingZero(value)); 640 641 // If svg is not supported, just add an active class to the tick 642 if (! svgSupported) { 643 this[isHours ? 'hoursView' : 'minutesView'].find('.clockpicker-tick').each(function(){ 644 var tick = $(this); 645 tick.toggleClass('active', value === + tick.html()); 646 }); 647 return; 648 } 649 650 // Place clock hand at the top when dragging 651 if (dragging || (! isHours && value % 5)) { 652 this.g.insertBefore(this.hand, this.bearing); 653 this.g.insertBefore(this.bg, this.fg); 654 this.bg.setAttribute('class', 'clockpicker-canvas-bg clockpicker-canvas-bg-trans'); 655 } else { 656 // Or place it at the bottom 657 this.g.insertBefore(this.hand, this.bg); 658 this.g.insertBefore(this.fg, this.bg); 659 this.bg.setAttribute('class', 'clockpicker-canvas-bg'); 660 } 661 662 // Set clock hand and others' position 663 var cx = Math.sin(radian) * radius, 664 cy = - Math.cos(radian) * radius; 665 this.hand.setAttribute('x2', cx); 666 this.hand.setAttribute('y2', cy); 667 this.bg.setAttribute('cx', cx); 668 this.bg.setAttribute('cy', cy); 669 this.fg.setAttribute('cx', cx); 670 this.fg.setAttribute('cy', cy); 671 }; 672 673 // Hours and minutes are selected 674 ClockPicker.prototype.done = function() { 675 raiseCallback(this.options.beforeDone); 676 this.hide(); 677 var last = this.input.prop('value'), 678 value = leadingZero(this.hours) + ':' + leadingZero(this.minutes); 679 if (this.options.twelvehour) { 680 value = value + this.amOrPm; 681 } 682 683 this.input.prop('value', value); 684 if (value !== last) { 685 this.input.triggerHandler('change'); 686 if (! this.isInput) { 687 this.element.trigger('change'); 688 } 689 } 690 691 if (this.options.autoclose) { 692 this.input.trigger('blur'); 693 } 694 695 raiseCallback(this.options.afterDone); 696 }; 697 698 // Remove clockpicker from input 699 ClockPicker.prototype.remove = function() { 700 this.element.removeData('clockpicker'); 701 this.input.off('focus.clockpicker click.clockpicker'); 702 this.addon.off('click.clockpicker'); 703 if (this.isShown) { 704 this.hide(); 705 } 706 if (this.isAppended) { 707 $win.off('resize.clockpicker' + this.id); 708 this.popover.remove(); 709 } 710 }; 711 712 // Extends $.fn.clockpicker 713 $.fn.clockpicker = function(option){ 714 var args = Array.prototype.slice.call(arguments, 1); 715 return this.each(function(){ 716 var $this = $(this), 717 data = $this.data('clockpicker'); 718 if (! data) { 719 var options = $.extend({}, ClockPicker.DEFAULTS, $this.data(), typeof option == 'object' && option); 720 $this.data('clockpicker', new ClockPicker($this, options)); 721 } else { 722 // Manual operatsions. show, hide, remove, e.g. 723 if (typeof data[option] === 'function') { 724 data[option].apply(data, args); 725 } 726 } 727 }); 728 }; 729}());
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.