PageSourceSearch

https://www.puregelato.com.au/wp-content/plugins/quickiebar/public/js/qb.js?ver=1.8.4

js puregelato.com.au collected 2026-09-24 11:26:21 UTC 23,129 bytes, 753 lines download raw bytes

1function QuickieBar() {
2
3	//local reference to wp jQuery
4	var $ = jQuery;
5
6	var self = this;
7
8	self.previewingOnAdminPage = false;
9	self.preventHidingWithCloseButton = false;//prevents hiding the bar using the close button
10
11	/*Default Options*/
12	self.options = {
13
14		bar_uuid: 0,													//the bar's id
15
16		bar_height: 'thin',								// regular || thin || tall || skinny
17		new_tab: 'enabled',										// enabled || disabled
18		placement: 'top',											// top || bottom
19		devices: 'all',												// all || desktoponly || mobileonly
20		attribution: 'hidden',								// visible || hidden
21		alignment: 'leftright',								// centered || leftright
22		sticky: 'enabled',										// enabled || disabled
23		animation: 'slidein',									// slidein || none
24		button_style: 'rounded',							// rounded || pill || square || outline
25		close_button_visibility: 'onhover',		// onhover || always || hidden
26
27		color_bar_background: '#56C4C3',
28		color_bar_text: '#FFFFFF',
29		color_button_background: '#062332',
30		color_button_text: '#FFFFFF',
31
32		bar_text: 'Get the most powerful conversion dropdown for Wordpress {{arrow-right}}',
33		button_text: 'FREE DOWNLOAD {{download}}',
34
35		destination: 'https://quickiebar.com',
36
37		fixed_compatibility: 'off',
38		bar_zindex: '100'
39	};
40
41	self.init = function(options){
42
43		if(options){
44
45			//for each option, update self.options
46			$.each(options, function(index, option){
47
48				//unescape strings that might contain special characters
49				if(index == 'bar_text' ||
50					index == 'button_text' ||
51					index == 'subscribe_text' ||
52					index == 'bar_html'
53				){
54					option = unescape(option);
55				}
56				self.options[index] = option;
57			});
58
59		}
60	}
61
62	self.initAndCreateBar = function(options){
63		self.init(options);
64
65		self.createBar();
66
67		self.bindEventsToBar();
68	}
69
70	self.initAndShowBar = function(options, isAdminPage){
71
72		//we have to set up the bar slightly differently for admin page preview
73		if(isAdminPage){
74			self.previewingOnAdminPage = true;
75			self.preventHidingWithCloseButton = true;
76		}
77
78		self.init(options);
79
80		self.createBar();
81
82		self.bindEventsToBar();
83
84		self.show();
85	}
86
87	self.prepareBarOrButtonText = function(text, removeRightArrows){
88		if(!text || text == ''){
89			return '';
90		}
91
92		//only remove right arrows when page width < 900px
93		if(removeRightArrows && $('body').width() < 900){
94			text = text.replace(/ {{(.*?)(-right)(.*?)}}/g, '');
95		}
96
97		//remove {{}} if text includes "-right" so as to not show right arrows on mobile devices
98
99		//find each inserted icon and replace with <i> html
100		return text.replace(/{{(.*?)}}/g, '&nbsp;<i class="fa fa-$1"></i>&nbsp;');
101	}
102
103	self.getQuickieBarTopLevelClasses = function(){
104		var qbClasses = '';
105
106		//add the associated classes based on bar options to quickiebar div
107		qbClasses += 'qb-bar_height-' + self.options.bar_height + ' ';
108		qbClasses += 'qb-sticky-' + (self.options.fixed_compatibility == 'on' ? 'enabled' : self.options.sticky) + ' ';//overwrite default sticky option if fixed_compatibility mode is on
109		qbClasses += 'qb-placement-' + self.options.placement + ' ';
110		qbClasses += 'qb-attribution-' + self.options.attribution + ' ';
111		qbClasses += 'qb-alignment-' + self.options.alignment + ' ';
112		qbClasses += 'qb-button_style-' + self.options.button_style + ' ';
113		qbClasses += 'qb-close_button_visibility-' + self.options.close_button_visibility + ' ';
114
115		if(self.previewingOnAdminPage){
116			qbClasses += 'qb-admin-preview ';
117		}
118
119		return qbClasses;
120	}
121
122	//create html block to be placed before #page div that contains all the html for the quickiebar
123	self.craftHtml = function(){
124
125		var barText = self.options.bar_text ? self.prepareBarOrButtonText(self.options.bar_text, true) : self.prepareBarOrButtonText('Bar Text goes here', true);
126		var buttonText = self.options.button_text ? self.prepareBarOrButtonText(self.options.button_text) : '';
127
128		$qbHtml = '';
129
130		$qbHtml = '<div id="quickiebar-show-button" class="show-button-sticky-' + (self.options.fixed_compatibility == 'on' ? 'enabled' : self.options.sticky) + ' show-button-placement-' + self.options.placement + '" style="color:' + self.options.color_bar_text + ';background:' + self.options.color_bar_background + ';z-index:' + self.options.bar_zindex + ';"><div class="show-button" style="color:' + self.options.color_bar_text + ';background:' + self.options.color_bar_background + ';"><i class="fa fa-chevron-down"></i><i class="fa fa-chevron-up"></i></div></div>';
131
132		$qbHtml += '<div id="quickiebar" class="qb-' + self.options.bar_uuid + ' qb-' + self.options.id + ' qb ' + self.getQuickieBarTopLevelClasses() + '" style="background:' + self.options.color_bar_background + ';z-index:' + self.options.bar_zindex + ';">';
133
134			$qbHtml += '<div class="hover-background-overlay"></div>';
135
136			if(self.options.attribution == 'visible'){
137				$qbHtml += '<a href="https://quickiebar.com/" target="_blank"><div class="qb-attribution ' + (GetLuminance(self.options.color_bar_background) > 200 ? 'qb-attribution-dark' : '') + '"></div></a>';
138			}
139
140			$qbHtml += '<div class="wrap">';
141				$qbHtml += '<div class="qb-wrap">';
142					$qbHtml += '<span class="bar-text" style="color:' + self.options.color_bar_text + ';">' + barText + '</span>';
143					$qbHtml += '<span class="bar-button" style="' + (buttonText == '' ? 'display:none;' : '') + 'color:' + self.options.color_button_text + ';background:' + self.options.color_button_background + ';border-color:' + self.options.color_button_text + ';">' + buttonText + '</span>';
144				$qbHtml += '</div>';//end .qb-wrap
145			$qbHtml += '</div>';//end .wrap
146
147			$qbHtml += '<div class="qb-close-button ' + (GetLuminance(self.options.color_bar_background) > 200 ? 'qb-close-button-dark' : '') + '"><i class="fa fa-times-circle-o"></i></div>';
148
149			$qbHtml += '<a href="' + self.options.destination + '" ' + (self.options.new_tab == 'enabled' && (self.options.destination.indexOf('#') != 0) ? 'target="_blank"' : '') + ' class="link-overlay" style="' + (self.options.destination == '' ? 'display:none;' : '') + '"></a>'
150
151			$qbHtml += '<div class="qb-close-bar"><i class="fa fa-chevron-up"></i></div>';
152
153		$qbHtml += '</div>';//end #quickiebar
154
155		return $qbHtml;
156	}
157
158	self.createBar = function(){
159
160		$page = self.getPage();
161
162		//self.getPage().before(self.craftCSS());
163		$page.before(self.craftHtml());
164
165		//TODO implement this / put this in function
166		//$qbReviveHtml = '<div id="quickiebar-revive"><i class="fa fa-bolt"></i></div>';
167	}
168
169	self.hideAndDestroyBar = function(){
170
171		self.hide(0, function(){
172			$('#quickiebar.qb').remove();
173		});
174
175	}
176
177	self.bindEventsToBar = function(){
178
179		//Bind hover functions to show close button & attribution (if applicable)
180		$('#quickiebar.qb').on('mouseover', function(){
181			$(".qb-attribution").stop().addClass('visible');
182			$(".qb-close-button").stop().addClass('visible');
183		}).on('mouseout', function(){
184			$(".qb-attribution").stop().removeClass('visible');
185			$(".qb-close-button").stop().removeClass('visible');
186		});
187
188		//Bind close functions
189		$('.qb-close-bar,.qb-close-button').click(function(){
190			if(self.preventHidingWithCloseButton || self.previewingOnAdminPage){
191				return;
192			}
193
194			self.hide();
195		});
196
197		//Bind conversion tracking on bar click
198		$("#quickiebar.qb .link-overlay").click(function(){
199			self.trackConversion();
200			//console.log("TRACK CONVERSION");
201		});
202
203		//Bind show function on show-button
204		$("#quickiebar-show-button").click(function(){
205			qb.show();
206
207			//if we're showing the bar again, we should clear the dismissal tracking
208			qb.resetCurrentBarDismissalTracking();
209		});
210	}
211
212	self.getPage = function(){
213		if(self.previewingOnAdminPage){
214			return $('html > body');
215		}
216		else{
217			return $('html > body');
218		}
219	}
220
221	self.getFixedHeader = function(){
222
223		if($('.qb-fixed-header') && $('.qb-fixed-header').length > 0){
224			return $('.qb-fixed-header');
225		}
226
227		if($('.qbp-fixed-header') && $('.qbp-fixed-header').length > 0){
228			return $('.qbp-fixed-header');
229		}
230
231		if($('header') && $('header').length > 0){
232			return $('header');
233		}
234
235		if($('#header') && $('#header').length > 0){
236		  return $('#header');
237		}
238
239		if($('#masthead') && $('#masthead').length > 0){
240			return $('#masthead');
241		}
242
243		if($('.site-header') && $('.site-header').length > 0){
244			return $('.site-header').first();
245		}
246
247		//if we can't find it with selectors, the loop through every element in <body> - stopping once we find a position:fixed element and return that.
248		//TODO
249		return false;
250	}
251
252	//Just show the toggle for the bar, not the bar itself (show bar in "minimized" display)
253	self.showBarToggle = function(){
254
255		if(self.options.placement == 'top'){
256			$("#quickiebar-show-button").css('margin-top', -24);
257		}
258		else if(self.options.placement == 'bottom'){
259			$("#quickiebar-show-button").css('margin-bottom', -24);
260		}
261
262		$('#quickiebar-show-button').show();
263		$("#quickiebar-show-button").stop().animate({'margin-top': 0,'margin-bottom': 0}, 250);
264	}
265
266	self.show = function(){
267
268		$page = self.getPage();
269
270		$qbHeight = $('#quickiebar').height();
271
272		$slideIn = self.options.animation === 'slidein';
273
274		//if we need to make page adjustments
275		if((self.options.fixed_compatibility == 'on' || self.options.sticky == 'enabled' || self.options.placement == 'bottom' || self.previewingOnAdminPage) && $('body').width() > 900){
276
277			if(self.options.placement == 'top'){
278
279				if($slideIn){
280					$page.addClass('qb-disable-animation').animate({'padding-top': $qbHeight}, 300, 'swing', function(){
281						$page.removeClass('qb-disable-animation');
282					});
283				}
284				else{
285					$page.addClass('qb-disable-animation');
286					$page.css('padding-top', $qbHeight);
287
288					//not sure why...but I have to do this after a slight delay
289					setTimeout(function(){
290						$page.removeClass('qb-disable-animation');
291					}, 20);
292				}
293
294				//adjust fixed header if required
295				if(self.options.fixed_compatibility == 'on'){
296					$fixedHeader = self.getFixedHeader();
297
298					if($fixedHeader){
299
300						if($slideIn){
301							$fixedHeader.animate({'margin-top': $qbHeight}, 300, 'swing');
302						}
303						else{
304							$fixedHeader.css('margin-top', $qbHeight);
305						}
306
307					}
308				}
309
310				//adjust for WordPress admin top bar if required AND not previewing on Bars page (since we remove the admin bar in this situation)
311				if($('#wpadminbar') && !self.previewingOnAdminPage){
312					$page.css('padding-top', $qbHeight + $('#wpadminbar').height());
313
314					$('#quickiebar').css('marginTop', $('#wpadminbar').height());
315				}
316
317			}
318			else if(self.options.placement === 'bottom'){
319				$page.css('margin-bottom', $qbHeight);
320			}
321		}
322
323		//Animate the bar itself
324		if($slideIn){
325
326			$('#quickiebar').stop().slideDown(300);
327		}
328		else{
329			$('#quickiebar').stop().show();
330		}
331
332		//Hide the show button if visible
333		$('#quickiebar-show-button').hide();
334
335	}
336
337	self.hide = function(animationDuration, callback){
338
339		//track the dismissal first before any other code, just in case errors are thrown
340		//we want to make sure to not show this bar to the user again
341		self.trackDismissal();
342
343		if(typeof animationDuration == 'undefined'){
344			animationDuration = 200;
345		}
346
347		$page = self.getPage();
348
349		$page.addClass('qb-disable-animation').animate({'padding-top': 0, 'margin-bottom': 0}, animationDuration, 'swing', function(){
350			$page.removeClass('qb-disable-animation');
351		});
352
353		$('#quickiebar').stop().slideUp(animationDuration, function(){
354			//execute callback when bar hidden from page
355			if(typeof callback == 'function'){
356				callback();
357			}
358		});
359
360		//adjust fixed header if required
361		if(self.options.fixed_compatibility == 'on' && self.options.placement == 'top'){
362			$fixedHeader = self.getFixedHeader();
363
364			if($fixedHeader){
365
366				if($slideIn){
367					$fixedHeader.animate({'margin-top': 0}, 300, 'swing');
368				}
369				else{
370					$fixedHeader.css('margin-top', 0);
371				}
372
373			}
374		}
375
376		//Show the show button
377		self.showBarToggle();
378
379		if(typeof callback === 'function'){
380			callback();
381		}
382
383	}
384
385	self.fetchBar = function(callback){
386		$.ajax({
387			type: "POST",
388			url: ajaxurl,
389			data: {
390				action: 'qb_public_ajax',
391				endpoint: 'get_bar',
392				qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE
393			},
394			success: function(bar){
395				callback(bar);
396			},
397			dataType: 'json'
398		});
399	}
400
401	self.getUserUuid = function(){
402		var user_uuid = QBGetCookie('qb_user_uuid');
403
404		if(!user_uuid){
405			//if no user_uuid created, create it now
406			user_uuid = QBGenerateUuid();
407
408			//persist uuid to local storage
409			QBSetCookie('qb_user_uuid', user_uuid, 7);//TODO allow user to set the expiration days
410		}
411
412		return user_uuid;
413	}
414
415	self.getBarViews = function(){
416
417		var bar_views_cookie = QBGetCookie('qb_bar_views');
418		var bar_views;
419
420		if(!bar_views_cookie){
421
422			//initialize empty array as bar_views property
423			bar_views = [];
424
425			QBSetCookie('qb_bar_views', JSON.stringify(bar_views), 7);
426		}
427		else{
428
429			//load bars_viewed from cookie
430			bar_views = JSON.parse(QBGetCookie('qb_bar_views'));
431		}
432
433		return bar_views;
434
435	}
436
437	self.getBarConversions = function(){
438
439		var bar_conversions_cookie = QBGetCookie('qb_bar_conversions');
440		var bar_conversions;
441
442		if(!bar_conversions_cookie){
443
444			//initialize empty array as bar_conversions property
445			bar_conversions = [];
446
447			QBSetCookie('qb_bar_conversions', JSON.stringify(bar_conversions), 7);
448		}
449		else{
450
451			//load bars_viewed from cookie
452			bar_conversions = JSON.parse(QBGetCookie('qb_bar_conversions'));
453		}
454
455		return bar_conversions;
456
457	}
458
459	self.getBarDismissals = function(){
460
461		var bar_dismissals_cookie = QBGetCookie('qb_bar_dismissals');
462		var bar_dismissals;
463
464		if(!bar_dismissals_cookie){
465
466			//initialize empty array as bar_conversions property
467			bar_dismissals = [];
468
469			QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7);
470		}
471		else{
472
473			//load bars_viewed from cookie
474			bar_dismissals = JSON.parse(QBGetCookie('qb_bar_dismissals'));
475		}
476
477		return bar_dismissals;
478
479	}
480
481	self.resetAllTracking = function(){
482		QBDeleteCookie('qb_user_uuid');
483		QBDeleteCookie('qb_bar_views');
484		QBDeleteCookie('qb_bar_conversions');
485		QBDeleteCookie('qb_bar_dismissals');
486	}
487
488	self.resetCurrentBarDismissalTracking = function(){
489		var bar_dismissals = self.getBarDismissals();
490
491		for(var i = bar_dismissals.length; i >= 0; i--){
492			if(bar_dismissals[i] == qb.options.bar_uuid){
493				bar_dismissals.splice(i, 1);
494			}
495		}
496
497		QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7);
498	}
499
500	self.trackView = function(){
501
502		var bar_uuid = self.options.bar_uuid;
503		var bar_views = self.getBarViews();
504
505		//if bar_uuid == 0, don't track the view
506		if(bar_uuid == 0){
507			return;
508		}
509
510
511		if(bar_views.indexOf(bar_uuid) < 0){
512
513			//if user hasn't viewed bar yet, track the view to the db then update locally
514			$.ajax({
515				type: "POST",
516				url: ajaxurl,
517				data: {
518					action: 'qb_public_ajax',
519					endpoint: 'save_view',
520					user_uuid: self.getUserUuid(),
521					bar_uuid: bar_uuid,
522					qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE
523				},
524				success: function(){
525
526					//push the current bar onto the list of viewed bars
527					bar_views.push(bar_uuid);
528
529					//persist viewed bars as cookie
530					QBSetCookie('qb_bar_views', JSON.stringify(bar_views), 7);
531
532				},
533				dataType: 'json'
534			});
535		}
536
537	}
538
539	self.trackConversion = function(){
540
541		var bar_uuid = self.options.bar_uuid;
542		var bar_conversions = self.getBarConversions();
543
544		//if bar_uuid == 0, don't track the view
545		if(bar_uuid == 0){
546			return;
547		}
548
549
550		if(bar_conversions.indexOf(bar_uuid) < 0){
551
552			//if user hasn't converted on the bar yet, track the conversion to the db then update locally
553			$.ajax({
554				type: "POST",
555				url: ajaxurl,
556				data: {
557					action: 'qb_public_ajax',
558					endpoint: 'save_conversion',
559					user_uuid: self.getUserUuid(),
560					bar_uuid: bar_uuid,
561					qb_public_nonce: QB_PUBLIC_GLOBALS.QB_PUBLIC_NONCE
562				},
563				success: function(){
564
565					//push the current bar onto the list of viewed bars
566					bar_conversions.push(bar_uuid);
567
568					//persist viewed bars as cookie
569					QBSetCookie('qb_bar_conversions', JSON.stringify(bar_conversions), 7);
570
571				},
572				dataType: 'json'
573			});
574		}
575
576	}
577
578	self.trackDismissal = function(){
579		var bar_uuid = self.options.bar_uuid;
580		var bar_dismissals = self.getBarDismissals();
581
582		//if bar_uuid == 0, don't track the view
583		if(bar_uuid == 0){
584			return;
585		}
586
587		//we don't persist this information to the server...
588		//instead, just updated user's cookie so they are not shown the bar again
589
590		//push the current bar onto the list of viewed bars
591		bar_dismissals.push(bar_uuid);
592
593		//persist viewed bars as cookie
594		QBSetCookie('qb_bar_dismissals', JSON.stringify(bar_dismissals), 7);
595	}
596
597}
598
599jQuery(document).ready(function($){
600
601	//if qbhide is toggled in URL, don't create & show the quickiebar
602	//this is used on quickiebar.com for previewing the bar on third-party sites
603	if(location.hash.indexOf('qbhide') > -1 || location.href.indexOf('wp-admin/admin.php') > -1 || location.href.indexOf('wp-login.php') > -1){
604		return;
605	}
606
607	//globally instantiate a new QuickieBar object
608	qb = new QuickieBar();
609
610	qb.fetchBar(function(bar){
611
612		//if on admin page
613
614
615		if(!bar || !bar.bar_uuid){//need to check bar_uuid also just in case default qb options come back (depending on php version & debuggin settings, this might happen)
616			//if no bar is live, nothing more to do
617			return;
618		}
619		//immedialy show bar if debug_mode and hash
620		else if(bar.debug_mode == 'on' && location.hash.toLowerCase().indexOf('qbshow') > -1){
621			qb.initAndShowBar(bar);
622			qb.trackView();
623		}
624		//if bar that is returned has already been dismissed, show toggle instead of bar
625		else if(qb.getBarDismissals().indexOf(bar.bar_uuid) > -1 && (QB_PUBLIC_GLOBALS.USER_TYPE != 'admin')){
626			qb.initAndCreateBar(bar);//create the bar but don't show it
627			qb.showBarToggle();
628		}
629		//more logic to determine whether or not to show bar
630		else{
631			//if fixed header compatibility mode is on, don't show if on mobile devices (< 900 px)
632			if(bar.fixed_compatibility == 'on' && $('body').width() < 900){
633				return;
634			}
635
636			if(bar.device_visibility != 'all'){
637				if(bar.device_visibility == 'desktoponly' && isMobileDevice()
637){
638					return;
639				}
640				else if(bar.device_visibility == 'mobileonly' && !isMobileDevice()){
641					return;
642				}
643			}
644
645			qb.initAndShowBar(bar);
646			qb.trackView();
647		}
648
649	});
650
651});
652
653
654/*
655Sample Init Code:
656
657qb.init({
658	bar_height: 'thin',								// regular || thin || tall || skinny
659	new_tab: 'enabled',										// true || false
660	placement: 'top',											// top || bottom
661	devices: 'all',												// all || desktoponly || mobileonly
662	attribution: 'visible',								// visible || hidden
663	alignment: 'leftright',								// centered || leftright
664	sticky: 'enabled',										// true || false
665	animation: 'slidein',									// slidein || none
666	button_style: 'rounded',							// rounded || pill || square || outline
667	close_button_visibility: 'onhover',		// onhover || alwaysshow || alwayshide
668
669	color_bar_background: '#56C4C3',
670	color_bar_text: '#FFFFFF',
671	color_button_background: '#062332',
672	color_button_text: '#FFFFFF',
673
674	bar_text: 'Get the most powerful conversion dropdown for Wordpress {{arrow-right}}',
675	button_text: 'FREE DOWNLOAD {{download}}'
676});*/
677
678function isMobileDevice(){
679	var check = false;
680	  (function(a,b){if(/(android|bb\d+|meego).+mobile|android|ipad|playbook|silk|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0,4)))check = true})(navigator.userAgent||navigator.vendor||window.opera);
681	return check;
682}
683
684function QBSetCookie(name, value, days) {
685	var d = new Date();
686  d.setTime(d.getTime() + (days*24*60*60*1000));
687  var expires = "expires="+d.toUTCString();
688  document.cookie = name + "=" + value + "; " + expires + '; path=/';
689}
690
691function QBGetCookie(name) {
692    name += "=";
693    var ca = document.cookie.split(';');
694    for(var i=0; i<ca.length; i++) {
695        var c = ca[i];
696        while (c.charAt(0)==' ') c = c.substring(1);
697        if (c.indexOf(name) == 0) return c.substring(name.length, c.length);
698    }
699    return false;
700}
701
702function QBDeleteCookie(name) {
703	if(QBGetCookie(name)){
704		QBSetCookie(name, '', -1);
705	}
706}
707
708//creates 13 hexidecimal random number as hash / practical "uuid"
709function QBGenerateUuid(){
710	//return Math.random().toString(36).slice(2);
711
712	var id = [];
713	var hexDigits = "0123456789abcdef";
714	for(var i = 0;i<13;i++){
715		id[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1);
716	}
717
718	return id.join("");
719}
720
721
722function ColorLuminance(hex, lum) {
723
724	// validate hex string
725	hex = String(hex).replace(/[^0-9a-f]/gi, '');
726	if (hex.length < 6) {
727		hex = hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];
728	}
729	lum = lum || 0;
730
731	// convert to decimal and change luminosity
732	var rgb = "#", c, i;
733	for (i = 0; i < 3; i++) {
734		c = parseInt(hex.substr(i*2,2), 16);
735		c = Math.round(Math.min(Math.max(0, c + (c * lum)), 255)).toString(16);
736		rgb += ("00"+c).substr(c.length);
737	}
738
739	return rgb;
740}
741
742/*http://stackoverflow.com/questions/12043187/how-to-check-if-hex-color-is-too-black*/
743function GetLuminance(hex){
744	var c = hex.substring(1);      // strip #
745	var rgb = parseInt(c, 16);   // convert rrggbb to decimal
746	var r = (rgb >> 16) & 0xff;  // extract red
747	var g = (rgb >>  8) & 0xff;  // extract green
748	var b = (rgb >>  0) & 0xff;  // extract blue
749
750	var luma = 0.2126 * r + 0.7152 * g + 0.0722 * b; // per ITU-R BT.709
751
752	return luma
753}

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.