1;(function ($) { 2 "use strict"; 3 4 $.fn.get_transparent_selector = function get_transparent_selector(){ 5 let transparent_header_selector = $(this).closest('.hthb-notification.hthb-pos--top[data-transparent_header_selector]').last().data('transparent_header_selector'); 6 if($(this).closest('.hthb-notification.hthb-pos--top').hasClass('hthb-transparent')){ 7 return transparent_header_selector; 8 } 9 10 return false; 11 } 12 13 $.fn.add_transparent_header_spacing = function add_transparent_header_spacing(top_notification_height){ 14 if( $('body').find('#wpadminbar').length ){ 15 top_notification_height = Number.parseInt(top_notification_height + $('body').find('#wpadminbar').height()); 16 } 17 } 18 19 function calculate_top_zero(){ 20 if( $('body').find('#wpadminbar').length ){ 21 return '32px'; 22 } else{ 23 return '0px'; 24 } 25 } 26 27 $(document).ready(function () { 28 $('body').prepend($('.hthb-notification')); 29 }); 30 31 var timeout = 400; 32 $(window).on('load',function(){ 33 var top_notification_height = Number.parseInt($('.hthb-notification.hthb-pos--top').last().height()), 34 bottom_notification_height = $('.hthb-notification.hthb-pos--bottom').last().height(), 35 left_wall_notification_width = $('.hthb-notification.hthb-pos--left-wall').last().width(), 36 right_wall_notification_width = $('.hthb-notification.hthb-pos--right-wall').last().width(); 37 38 var position; 39 40 // if load as minimized disabled 41 $('.hthb-notification.hthb-state--open').each(function(){ 42 position = $(this).getPostion(); 43 44 if( position == 'top' ){ 45 $('body').addClass('hthb hthb-pt--' + top_notification_height ); 46 if( $(this).get_transparent_selector() ){ 47 if(window.getComputedStyle(document.querySelector($(this).get_transparent_selector())).getPropertyValue("position") !== 'sticky') { 48 $($(this).get_transparent_selector()).addClass('hthb-top-unset'); 49 $($(this).get_transparent_selector()).css( {'top':'unset'} ); 50 } else { 51 $($(this).get_transparent_selector()).addClass('hthb-top-'+top_notification_height); 52 $($(this).get_transparent_selector()).css( {'top':top_notification_height+'px'} ); 53 } 54 } 55 } else if( position == 'bottom'){ 56 $('body').css('padding-bottom', bottom_notification_height + 'px'); 57 } 58 59 // Implement how many time to show 60 var time_to_show = $(this).data('time_to_show'), 61 id = $(this).data('id') ? '_' + $(this).data('id') : '', 62 coockie_count = Cookies.get('hashbarpro_cookiecount' + id), 63 hashbarpro_oldcookie = Cookies.get('hashbarpro_oldcookie' + id); 64 65 if( time_to_show && time_to_show > 0 ){ 66 67 if(document.cookie.indexOf("hashbarpro_oldcookie" + id) >= 0){ 68 if(time_to_show == hashbarpro_oldcookie){ 69 coockie_count++; 70 Cookies.set('hashbarpro_cookiecount' + id, coockie_count, { expires: 7 }); 71 } else { 72 Cookies.set('hashbarpro_oldcookie' + id, time_to_show, { expires: 7 }); 73 Cookies.set('hashbarpro_cookiecount' + id, 1, { expires: 7 }); 74 } 75 } else { 76 Cookies.set('hashbarpro_oldcookie' + id, time_to_show, { expires: 7 }); 77 Cookies.set('hashbarpro_cookiecount' + id, 1, { expires: 7 }); 78 } 79 } 80 81 if( coockie_count > time_to_show ){ 82 $(this).css({'display': 'none'}); 83 $(this).removeClass('hthb-state--open').addClass('hthb-state--minimized'); 84 85 if( position == 'top' ){ 86 $('body').removeClass('hthb'); 87 } 88 } 89 90 }); 91 92 // Load as mimimized if option is set to minimized 93 $('.hthb-notification.hthb-state--minimized').each(function(){ 94 var position = $(this).getPostion(); 95 if( position == 'top' || position == 'top-promo' || position == 'bottom' || position == 'bottom-promo' ){ 96 $(this).find('.hthb-row').css('display', 'none'); 97 } 98 99 }); 100 101 // Left/right wall 102 $('.hthb-notification.hthb-state--minimized').each(function(){ 103 var position = $(this).getPostion(); 104 if( position == 'left-wall' ){ 105 $(this).css('left', '-' + left_wall_notification_width + 'px' ); 106 } else if( position == 'right-wall' ){ 107 $(this).css('right', '-' + right_wall_notification_width + 'px' ); 108 } 109 110 }); 111 112 setTimeout(function(){ 113 $('.hthb-notification').addClass('hthb-loaded'); 114 }, timeout ); 115 116 117 $('.hthb-notification').each(function() { 118 const delay_time = $(this).attr('data-delay_time'); 119 if(+delay_time) { 120 setTimeout(() => { 121 $(this).showNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width ); 122 }, +delay_time*1000); 123 } 124 }) 125 126 // When click close button 127 $('.hthb-close-toggle').on('click', function(e){ 128 const $notification = $(this).closest('.hthb-notification'); 129 const $id = e.currentTarget.dataset.id; 130 let $expire_time = +hashbar_localize.cn_cookies_expire_time 131 if(hashbar_localize.cn_cookies_expire_type === 'hours') { 132 $expire_time = $expire_time/24; 133 } 134 if(hashbar_localize.cn_cookies_expire_type === 'minutes') { 135 $expire_time = $expire_time/1440; 136 } 137 138 $(this).minimizeNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width); 139 140 // Mark as manually closed to prevent scroll-based reopening 141 $notification.addClass('hthb-manually-closed'); 142 143 // Keep closed 144 if( hashbar_localize.bar_keep_closed == '1' ){ 145 Cookies.set(`keep_closed_bar_${$id}`, '1', { expires: $expire_time, path: '/' }); 146 } 147 148 // Don't show forever 149 if( hashbar_localize.dont_show_bar_after_close == '1' ) { 150 Cookies.set( `dont_show_bar_${$id}`, '1', { expires: $expire_time, path: '/' } ); 151 } 152 }); 153 154 // When clicked open button 155 $('.hthb-open-toggle').on('click', function(){ 156 // Remove manually-closed class to allow reopening 157 $(this).closest('.hthb-notification').removeClass('hthb-manually-closed'); 158 $(this).showNotification( top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width ); 159 }); 160 161 // Enter / Space on custom controls (role="button" on <span>) 162 $('.hthb-close-toggle, .hthb-open-toggle').on('keydown', function (e) { 163 if (e.key !== 'Enter' && e.key !== ' ') { 164 return; 165 } 166 e.preventDefault(); 167 $(this).trigger('click'); 168 }); 169 170 // When scroll position matched with a notification 171 // Show the notifications 172 var window_inner_height = $(window).height(), 173 page_height = $('body').height(); 174 175 let current_scroll_position = window.pageYOffset || document.documentElement.scrollTop, 176 current_scroll_position_percent = current_scroll_position / scroll_pos_max * 100; 177 current_scroll_position_percent = Number.parseInt(current_scroll_position_percent); 178 179 var scroll_pos_max = $(document).height() - $(window).height(); 180 181 $(window).on('scroll', function(e){ 182 current_scroll_position = $(window).scrollTop(), 183 current_scroll_position_percent = current_scroll_position / scroll_pos_max * 100; 184 current_scroll_position_percent = Number.parseInt(current_scroll_position_percent); 185 186 $(`.hthb-scroll`).each(function(){ 187 let scroll_to_show = $(this).data('scroll_to_show'), 188 scroll_to_hide = $(this).data('scroll_to_hide'); 189 190 $(this).trigger_notification_on_scroll(scroll_to_show, scroll_to_hide, current_scroll_position, scroll_pos_max); 191 }); 192 }); 193 }); 194 195 /** 196 * Calculate % of a given value. 197 * For example, If the give value is 1000 & we want to know the 75% of it. 198 * It will return 750 as the result. 199 * 200 * @param number percent_amount, % amount. 201 * @param number percent_of, Total amount from where the % should be calculated. 202 * @return number 203 */ 204 function percent_of(percent_amount, percent_of){ 205 percent_of = Number.parseInt(percent_of); 206 percent_amount = Number.parseInt(percent_amount); 207 208 return percent_of * percent_amount / 100; 209 } 210 211 $.fn.getPostion = function(){ 212 if(this.closest('.hthb-notification').hasClass('hthb-pos--top')){ 213 return 'top'; 214 } 215 216 if(this.closest('.hthb-notification').hasClass('hthb-pos--bottom')){ 217 return 'bottom'; 218 } 219 220 if(this.closest('.hthb-notification').hasClass('hthb-pos--left-wall')){ 221 return 'left-wall'; 222 } 223 224 if(this.closest('.hthb-notification').hasClass('hthb-pos--right-wall')){ 225 return 'right-wall'; 226 } 227 228 if(this.closest('.hthb-notification').hasClass('hthb-pos--bottom-promo')){ 229 return 'bottom-promo'; 230 } 231 232 if(this.closest('.hthb-notification').hasClass('hthb-pos--top-promo')){ 233 return 'top-promo'; 234 } 235 } 236 237 $.fn.minimizeNotification = function(top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width){ 238 var postion = this.getPostion(), 239 left_wall_notification_width = this.closest('.hthb-notification').width(), 240 right_wall_notification_width = this.closest('.hthb-notification').width(); 241 242 this.closest('.hthb-notification').removeClass('hthb-state--open'); 243 this.closest('.hthb-notification').addClass('hthb-state--minimized'); 244 245 if(postion != 'left-wall' && postion != 'right-wall'){
246 // Use slideUp instead of slideToggle to prevent double-toggle issue 247 this.closest('.hthb-notification').find('.hthb-row').slideUp(); 248 } 249 250 if( postion == 'top' ){ 251 $('body').removeClass('hthb'); 252 253 // for sticky 254 if( this.get_transparent_selector() ){ 255 $(this.get_transparent_selector()).addClass('hthb-top-unset'); 256 $(this.get_transparent_selector()).css({'top': calculate_top_zero()}); 257 } 258 } else if( postion == 'bottom' ){ 259 $('body').css('padding-bottom', ''); 260 } else if( postion == 'left-wall' ){ 261 this.closest('.hthb-notification').css('left', '-' + left_wall_notification_width + 'px' ); 262 } else if( postion == 'right-wall' ){ 263 this.closest('.hthb-notification').css('right', '-' + right_wall_notification_width + 'px' ); 264 } 265 } 266 267 $.fn.showNotification = function(top_notification_height, bottom_notification_height, left_wall_notification_width, right_wall_notification_width){ 268 // Don't reopen if user manually closed the notification 269 if( this.closest('.hthb-notification').is('.hthb-manually-closed') ){ 270 return; 271 } 272 273 var postion = this.getPostion(), 274 left_wall_notification_width = this.closest('.hthb-notification').width(), 275 right_wall_notification_width = this.closest('.hthb-notification').width(); 276 277 this.closest('.hthb-notification').removeClass('hthb-state--minimized'); 278 this.closest('.hthb-notification').addClass('hthb-state--open'); 279 280 if(postion != 'left-wall' && postion != 'right-wall'){ 281 // Use slideDown instead of slideToggle to prevent double-toggle issue 282 this.closest('.hthb-notification').find('.hthb-row').slideDown(); 283 } 284 285 if( postion == 'top' ){ 286 $('body').addClass('hthb hthb-pt--'+ top_notification_height ); 287 288 // for sticky 289 if( this.get_transparent_selector() ){ 290 $(this.get_transparent_selector()).addClass('hthb-top-unset'); 291 $(this.get_transparent_selector()).css({'top': 'unset'}); 292 } 293 } else if( postion == 'bottom' ){ 294 $('body').css('padding-bottom', bottom_notification_height + 'px'); 295 } else if( postion == 'left-wall' ){ 296 this.closest('.hthb-notification').css('left', ''); 297 } else if( postion == 'right-wall' ){ 298 this.closest('.hthb-notification').css('right', ''); 299 } 300 } 301 302 $.fn.trigger_click_on_open_button = function(){ 303 // Don't reopen if user manually closed the notification 304 if( $(this).is('.hthb-manually-closed') ){ 305 return; 306 } 307 $(this).addClass('hthb-trigger-open-clicked').removeClass('hthb-trigger-close-clicked'); 308 $(this).find('.hthb-open-toggle').trigger('click'); 309 } 310 311 $.fn.trigger_click_on_close_button = function(){ 312 $(this).removeClass('hthb-trigger-open-clicked').addClass('hthb-trigger-close-clicked'); 313 $(this).find('.hthb-close-toggle').trigger('click'); 314 } 315 316 $.fn.trigger_notification_on_scroll = function( scroll_to_show, scroll_to_hide, current_scroll_position, scroll_pos_max ){ 317 // Don't reopen if user manually closed the notification 318 if( $(this).is('.hthb-manually-closed') ){ 319 return; 320 } 321 322 if( (scroll_to_show && typeof scroll_to_show == 'string' && scroll_to_show.indexOf('%')) > 0 && (scroll_to_hide && typeof scroll_to_hide == 'string' && scroll_to_hide.indexOf('%')) > 1 ){ 323 scroll_to_show = Number.parseInt(scroll_to_show); 324 scroll_to_hide = Number.parseInt(scroll_to_hide); 325 // 20% , 80% 326 // console.log(1,scroll_to_show,scroll_to_hide,current_scroll_position, percent_of(scroll_to_hide, scroll_pos_max)); 327 328 if(current_scroll_position > percent_of(scroll_to_show, scroll_pos_max) && current_scroll_position < percent_of(scroll_to_hide, scroll_pos_max) ){ 329 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 330 $(this).trigger_click_on_open_button(); // show 331 } 332 } else{ 333 if( !$(this).is('.hthb-state--minimized') ){ 334 $(this).trigger_click_on_close_button(); // hide 335 } 336 } 337 } else if( (scroll_to_show && typeof scroll_to_show == 'string' && scroll_to_show.indexOf('%')) && (scroll_to_hide === '' || scroll_to_hide == undefined) ){ 338 scroll_to_show = Number.parseInt(scroll_to_show); 339 // 20% , ''/undefined 340 // console.log(2,scroll_to_show,scroll_to_hide,current_scroll_position, percent_of(scroll_to_hide, scroll_pos_max)); 341 342 if( current_scroll_position > percent_of(scroll_to_show, scroll_pos_max) ){ 343 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 344 $(this).trigger_click_on_open_button(); // show 345 } 346 } else { 347 if( !$(this).is('.hthb-state--minimized') ){ 348 $(this).trigger_click_on_close_button(); // hide 349 } 350 } 351 } else if( (scroll_to_show && typeof scroll_to_show == 'number') && (scroll_to_hide && typeof scroll_to_hide == 'string')){ 352 // 300 , 80% 353 // console.log(3,scroll_to_show,scroll_to_hide,current_scroll_position, percent_of(scroll_to_hide, scroll_pos_max)); 354 355 if( current_scroll_position > scroll_to_show && current_scroll_position < percent_of(scroll_to_hide, scroll_pos_max) ){ 356 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 357 $(this).trigger_click_on_open_button(); // show 358 } 359 } else{ 360 if( !$(this).is('.hthb-state--minimized') ){ 361 $(this).trigger_click_on_close_button(); // hide 362 } 363 } 364 365 } else if( (scroll_to_show === '' || scroll_to_show == undefined) && (scroll_to_hide && typeof scroll_to_hide == 'string' && scroll_to_hide.indexOf('%')) ){ 366 scroll_to_hide = Number.parseInt(scroll_to_hide); 367 // empty / undefined , 90% 368 // console.log(4,scroll_to_show,scroll_to_hide,current_scroll_position, percent_of(scroll_to_hide, scroll_pos_max)); 369 370 if( current_scroll_position > percent_of(scroll_to_hide, scroll_pos_max) ){ 371 if( !$(this).is('.hthb-state--minimized') ){ 372 $(this).trigger_click_on_close_button(); // hide 373 } 374 } else{ 375 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 376 $(this).trigger_click_on_open_button(); // show 377 } 378 } 379 380 } else if( (scroll_to_show && typeof scroll_to_show == 'number') && (scroll_to_hide === '' || scroll_to_hide == undefined) ){ 381 // 300 , empty/undefined 382 // console.log(5,scroll_to_show,scroll_to_hide,current_scroll_position, percent_of(scroll_to_hide, scroll_pos_max)); 383 if( current_scroll_position < scroll_to_show ){ 384 if( !$(this).is('.hthb-state--minimized') ){ 385 $(this).trigger_click_on_close_button(); // hide 386 } 387 388 } else{ 389 if( !$(this).is('.hthb-state--open') && !$(this).is('.hthb-trigger-open-clicked') ){ 390 $(this).trigger_click_on_open_button(); // show 391 } 392 } 393 394 } else { 395 console.log(`Invalid formate Scroll to show=${typeof scroll_to_show} ${scroll_to_show } scroll_to_hide=${typeof scroll_to_hide} ${scroll_to_hide}`); 396 } 397 } 398 399 $(document).ready(function(){ 400 $(".hthb-countdown").each(function(){ 401 var countdown_id = "#"+$(this).attr('id')+" .hthb-countdown-section .hthb-countdown-wrap", 402 finalDate = $(countdown_id).data('countdown'), 403 customLabel = $(countdown_id).data('custom_label'); 404 $(countdown_id).countdown(finalDate, function (event) { 405 $(countdown_id+' .countdown-day').html(event.strftime('%D')); 406 $(countdown_id+' .countdown-day-text').html(customLabel.day); 407 $(countdown_id+' .countdown-hour').html(event.strftime('%H')); 408 $(countdown_id+' .countdown-hour-text').html(customLabel.hour); 409 $(countdown_id+' .countdown-minute').html(event.strftime('%M')); 410 $(countdown_id+' .countdown-minite-text').html(customLabel.min); 411 $(countdown_id+' .countdown-second').html(event.strftime('%S')); 412 $(countdown_id+' .countdown-second-text').html(customLabel.sec); 413 }); 414 }); 415 416 // Initialize new announcement bar countdowns 417 initializeNewAnnouncementBars(); 418 }); 419 420 /** 421 * Initialize new announcement bars with countdown timers 422 */ 423 function initializeNewAnnouncementBars() { 424 var bars = document.querySelectorAll('.hashbar-announcement-bar'); 425 if (bars.length === 0) { 426 return; 427 } 428
429 bars.forEach(function(bar) { 430 if (bar.getAttribute('data-countdown-enabled') === 'true') { 431 initializeCountdown(bar); 432 } 433 }); 434 } 435 436 /** 437 * Initialize countdown timer 438 */ 439 function initializeCountdown(bar) { 440 // Prevent multiple initializations on the same bar 441 if (bar.hasAttribute('data-countdown-initialized')) { 442 return; 443 } 444 bar.setAttribute('data-countdown-initialized', 'true'); 445 446 var countdownType = bar.getAttribute('data-countdown-type'); 447 var countdownDate = bar.getAttribute('data-countdown-date'); 448 449 // Find the bar wrapper (parent of the bar if it exists) 450 var barWrapper = bar.parentElement && bar.parentElement.classList.contains('hashbar-announcement-bar-wrapper') 451 ? bar.parentElement 452 : bar; 453 454 // Query all countdown timers in the wrapper (could be before, inline, after, or below) 455 var timerElements = barWrapper.querySelectorAll('.hashbar-countdown-timer'); 456 457 if (timerElements.length === 0 || !countdownDate) { 458 return; 459 } 460 461 // Update all countdown timers immediately and then every second 462 timerElements.forEach(function(timerElement) { 463 updateCountdown(timerElement, countdownDate, countdownType); 464 }); 465 466 // Store the interval ID on the bar for potential cleanup 467 var intervalId = setInterval(function() { 468 timerElements.forEach(function(timerElement) { 469 updateCountdown(timerElement, countdownDate, countdownType); 470 }); 471 }, 1000); 472 473 bar.setAttribute('data-countdown-interval', intervalId); 474 } 475 476 /** 477 * Update countdown display 478 */ 479 function updateCountdown(timerElement, countdownDate, countdownType) { 480 var now = new Date().getTime(); 481 var countDate = new Date(countdownDate).getTime(); 482 var distance = countDate - now; 483 484 if (distance < 0) { 485 timerElement.textContent = 'Ended'; 486 return; 487 } 488 489 var days = Math.floor(distance / (1000 * 60 * 60 * 24)); 490 var hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60)); 491 var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60)); 492 var seconds = Math.floor((distance % (1000 * 60)) / 1000); 493 494 // Get display options from element attributes 495 var showDays = timerElement.getAttribute('data-show-days') !== 'false'; 496 var showHours = timerElement.getAttribute('data-show-hours') !== 'false'; 497 var showMinutes = timerElement.getAttribute('data-show-minutes') !== 'false'; 498 var showSeconds = timerElement.getAttribute('data-show-seconds') !== 'false'; 499 500 // Determine style (simple, digital, circular) 501 var style = timerElement.getAttribute('data-countdown-style') || 'simple'; 502 503 if (style === 'simple') { 504 // Simple text format: "5d 3h 45m 30s" 505 var parts = []; 506 if (showDays && days > 0) parts.push(days + 'd'); 507 if (showHours && hours > 0) parts.push(hours + 'h'); 508 if (showMinutes && minutes > 0) parts.push(minutes + 'm'); 509 if (showSeconds) parts.push(seconds + 's'); 510 511 timerElement.textContent = parts.length > 0 ? parts.join(' ') : '0s'; 512 } else if (style === 'digital') { 513 // Digital format: "05:03:45:30" 514 var displayText = ''; 515 if (showDays) displayText += padZero(days) + ':'; 516 if (showHours) displayText += padZero(hours) + ':'; 517 if (showMinutes) displayText += padZero(minutes) + ':'; 518 if (showSeconds) displayText += padZero(seconds); 519 520 // Remove trailing colon if no seconds are shown 521 timerElement.textContent = displayText.replace(/:$/, ''); 522 } else if (style === 'circular' || style === 'box') { 523 // Circular or box format - update boxes 524 updateBoxCountdown(timerElement, days, hours, minutes, seconds, showDays, showHours, showMinutes, showSeconds); 525 } else if (countdownType === 'compact') { 526 // Legacy compact format 527 if (days > 0) { 528 timerElement.textContent = days + 'd ' + hours + 'h'; 529 } else if (hours > 0) { 530 timerElement.textContent = hours + 'h ' + minutes + 'm'; 531 } else { 532 timerElement.textContent = minutes + 'm ' + seconds + 's'; 533 } 534 } else { 535 // Legacy detailed format 536 timerElement.textContent = padZero(days) + ':' + padZero(hours) + ':' + padZero(minutes) + ':' + padZero(seconds); 537 } 538 } 539 540 /** 541 * Update box-style countdown display (circular or rounded squares) 542 */ 543 function updateBoxCountdown(timerElement, days, hours, minutes, seconds, showDays, showHours, showMinutes, showSeconds) { 544 // Update days box (works with both .countdown-circle-box and .countdown-box classes) 545 if (showDays) { 546 var daysBox = timerElement.querySelector('.countdown-days'); 547 if (daysBox) { 548 daysBox.textContent = String(days).padStart(2, '0'); 549 } 550 } 551 552 // Update hours box 553 if (showHours) { 554 var hoursBox = timerElement.querySelector('.countdown-hours'); 555 if (hoursBox) { 556 hoursBox.textContent = String(hours).padStart(2, '0'); 557 } 558 } 559 560 // Update minutes box 561 if (showMinutes) { 562 var minutesBox = timerElement.querySelector('.countdown-minutes');
563 if (minutesBox) { 564 minutesBox.textContent = String(minutes).padStart(2, '0'); 565 } 566 } 567 568 // Update seconds box 569 if (showSeconds) { 570 var secondsBox = timerElement.querySelector('.countdown-seconds'); 571 if (secondsBox) { 572 secondsBox.textContent = String(seconds).padStart(2, '0'); 573 } 574 } 575 } 576 577 /** 578 * Pad number with leading zero 579 */ 580 function padZero(num) { 581 return (num < 10 ? '0' : '') + num; 582 } 583})(jQuery);
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.