PageSourceSearch

https://www.masterlock.com/legacy-scripts/featherlight.js

js masterlock.com collected 2026-10-01 12:36:31 UTC 24,442 bytes, 668 lines download raw bytes

vendor: 24,442 bytes, lines 1-668
1/**
2 * Featherlight - ultra slim jQuery lightbox
3 * Version 1.7.14-UMD - http://noelboss.github.io/featherlight/
4 *
5 * Copyright 2019, Noël Raoul Bossart (http://www.noelboss.com)
6 * MIT Licensed.
7**/
8(function (factory) {
9	if (typeof define === 'function' && define.amd) {
10		// AMD. Register as an anonymous module.
11		define(['jquery'], factory);
12	} else if (typeof module === 'object' && module.exports) {
13		// Node/CommonJS
14		module.exports = function (root, jQuery) {
15			if (jQuery === undefined) {
16				// require('jQuery') returns a factory that requires window to
17				// build a jQuery instance, we normalize how we use modules
18				// that require this pattern but the window provided is a noop
19				// if it's defined (how jquery works)
20				if (typeof window !== 'undefined') {
21					jQuery = require('jquery');
22				} else {
23					jQuery = require('jquery')(root);
24				}
25			}
26			factory(jQuery);
27			return jQuery;
28		};
29	} else {
30		// Browser globals
31		factory(jQuery);
32	}
33})(function($) {
34	"use strict";
35
36	if('undefined' === typeof $) {
37		if('console' in window){ window.console.info('Too much lightness, Featherlight needs jQuery.'); }
38		return;
39	}
40	if($.fn.jquery.match(/-ajax/)) {
41		if('console' in window){ window.console.info('Featherlight needs regular jQuery, not the slim version.'); }
42		return;
43	}
44	/* Featherlight is exported as $.featherlight.
45	   It is a function used to open a featherlight lightbox.
46
47	   [tech]
48	   Featherlight uses prototype inheritance.
49	   Each opened lightbox will have a corresponding object.
50	   That object may have some attributes that override the
51	   prototype's.
52	   Extensions created with Featherlight.extend will have their
53	   own prototype that inherits from Featherlight's prototype,
54	   thus attributes can be overriden either at the object level,
55	   or at the extension level.
56	   To create callbacks that chain themselves instead of overriding,
57	   use chainCallbacks.
58	   For those familiar with CoffeeScript, this correspond to
59	   Featherlight being a class and the Gallery being a class
60	   extending Featherlight.
61	   The chainCallbacks is used since we don't have access to
62	   CoffeeScript's `super`.
63	*/
64
65	function Featherlight($content, config) {
66		if(this instanceof Featherlight) {  /* called with new */
67			this.id = Featherlight.id++;
68			this.setup($content, config);
69			this.chainCallbacks(Featherlight._callbackChain);
70		} else {
71			var fl = new Featherlight($content, config);
72			fl.open();
73			return fl;
74		}
75	}
76
77	var opened = [],
78		pruneOpened = function(remove) {
79			opened = $.grep(opened, function(fl) {
80				return fl !== remove && fl.$instance.closest('body').length > 0;
81			} );
82			return opened;
83		};
84
85	// Removes keys of `set` from `obj` and returns the removed key/values.
86	function slice(obj, set) {
87		var r = {};
88		for (var key in obj) {
89			if (key in set) {
90				r[key] = obj[key];
91				delete obj[key];
92			}
93		}
94		return r;
95	}
96
97	// NOTE: List of available [iframe attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe).
98	var iFrameAttributeSet = {
99		allow: 1, allowfullscreen: 1, frameborder: 1, height: 1, longdesc: 1, marginheight: 1, marginwidth: 1,
100		mozallowfullscreen: 1, name: 1, referrerpolicy: 1, sandbox: 1, scrolling: 1, src: 1, srcdoc: 1, style: 1,
101		webkitallowfullscreen: 1, width: 1
102	};
103
104	// Converts camelCased attributes to dasherized versions for given prefix:
105	//   parseAttrs({hello: 1, hellFrozeOver: 2}, 'hell') => {froze-over: 2}
106	function parseAttrs(obj, prefix) {
107		var attrs = {},
108			regex = new RegExp('^' + prefix + '([A-Z])(.*)');
109		for (var key in obj) {
110			var match = key.match(regex);
111			if (match) {
112				var dasherized = (match[1] + match[2].replace(/([A-Z])/g, '-$1')).toLowerCase();
113				attrs[dasherized] = obj[key];
114			}
115		}
116		return attrs;
117	}
118
119	/* document wide key handler */
120	var eventMap = { keyup: 'onKeyUp', resize: 'onResize' };
121
122	var globalEventHandler = function(event) {
123		$.each(Featherlight.opened().reverse(), function() {
124			if (!event.isDefaultPrevented()) {
125				if (false === this[eventMap[event.type]](event)) {
126					event.preventDefault(); event.stopPropagation(); return false;
127			  }
128			}
129		});
130	};
131
132	var toggleGlobalEvents = function(set) {
133			if(set !== Featherlight._globalHandlerInstalled) {
134				Featherlight._globalHandlerInstalled = set;
135				var events = $.map(eventMap, function(_, name) { return name+'.'+Featherlight.prototype.namespace; } ).join(' ');
136				$(window)[set ? 'on' : 'off'](events, globalEventHandler);
137			}
138		};
139
140	Featherlight.prototype = {
141		constructor: Featherlight,
142		/*** defaults ***/
143		/* extend featherlight with defaults and methods */
144		namespace:      'featherlight',        /* Name of the events and css class prefix */
145		targetAttr:     'data-featherlight',   /* Attribute of the triggered element that contains the selector to the lightbox content */
146		variant:        null,                  /* Class that will be added to change look of the lightbox */
147		resetCss:       false,                 /* Reset all css */
148		background:     null,                  /* Custom DOM for the background, wrapper and the closebutton */
149		openTrigger:    'click',               /* Event that triggers the lightbox */
150		closeTrigger:   'click',               /* Event that triggers the closing of the lightbox */
151		filter:         null,                  /* Selector to filter events. Think $(...).on('click', filter, eventHandler) */
152		root:           'body',                /* Where to append featherlights */
153		openSpeed:      250,                   /* Duration of opening animation */
154		closeSpeed:     250,                   /* Duration of closing animation */
155		closeOnClick:   'background',          /* Close lightbox on click ('background', 'anywhere' or false) */
156		closeOnEsc:     true,                  /* Close lightbox when pressing esc */
157		closeIcon:      '✕',            /* Close icon */
158		loading:        '',                    /* Content to show while initial content is loading */
159		persist:        false,                 /* If set, the content will persist and will be shown again when opened again. 'shared' is a special value when binding multiple elements for them to share the same content */
160		otherClose:     null,                  /* Selector for alternate close buttons (e.g. "a.close") */
161		beforeOpen:     $.noop,                /* Called before open. can return false to prevent opening of lightbox. Gets event as parameter, this contains all data */
162		beforeContent:  $.noop,                /* Called when content is loaded. Gets event as parameter, this contains all data */
163		beforeClose:    $.noop,                /* Called before close. can return false to prevent closing of lightbox. Gets event as parameter, this contains all data */
164		afterOpen:      $.noop,                /* Called after open. Gets event as parameter, this contains all data */
165		afterContent:   $.noop,                /* Called after content is ready and has been set. Gets event as parameter, this contains all data */
166		afterClose:     $.noop,                /* Called after close. Gets event as parameter, this contains all data */
167		onKeyUp:        $.noop,                /* Called on key up for the frontmost featherlight */
168		onResize:       $.noop,                /* Called after new content and when a window is resized */
169		type:           null,                  /* Specify type of lightbox. If unset, it will check for the targetAttrs value. */
170		contentFilters: ['jquery', 'image', 'html', 'ajax', 'iframe', 'text'], /* List of content filters to use to determine the content */
171
172		/*** methods ***/
173		/* setup iterates over a single instance of featherlight and prepares the background and binds the events */
174		setup: function(target, config){
175			/* all arguments are optional */
176			if (typeof target === 'object' && target instanceof $ === false && !config) {
177				config = target;
178				target = undefined;
179			}
180
181			var self = $.extend(this, config, {target: target}),
182				css = !self.resetCss ? self.namespace : self.namespace+'-reset', /* by adding -reset to the classname, we reset all the default css */
183				$background = $(self.background || [
184					'<div class="'+css+'-loading '+css+'">',
185						'<div class="'+css+'-content">',
186							'<button class="'+css+'-close-icon '+ self.namespace + '-close" aria-label="Close">',
187								self.closeIcon,
188							'</button>',
189							'<div class="'+self.namespace+'-inner">' + self.loading + '</div>',
190						'</div>',
191					'</div>'].join('')),
192				closeButtonSelector = '.'+self.namespace+'-close' + (self.otherClose ? ',' + self.otherClose : '');
193
194			self.$instance = $background.clone().addClass(self.variant); /* clone DOM for the background, wrapper and the close button */
195
196			/* close when click on background/anywhere/null or closebox */
197			self.$instance.on(self.closeTrigger+'.'+self.namespace, function(event) {
198				if(event.isDefaultPrevented()) {
199					return;
200				}
201				var $target = $(event.target);
202				if( ('background' === self.closeOnClick  && $target.is('.'+self.namespace))
203					|| 'anywhere' === self.closeOnClick
204					|| $target.closest(closeButtonSelector).length ){
205					self.close(event);
206					event.preventDefault();
207				}
208			});
209
210			return this;
211		},
212
213		/* this method prepares the content and converts it into a jQuery object or a promise */
214		getContent: function(){
215			if(this.persist !== false && this.$content) {
216				return this.$content;
217			}
218			var self = this,
219				filters = this.constructor.contentFilters,
220				readTargetAttr = function(name){ return self.$currentTarget && self.$currentTarget.attr(name); },
221				targetValue = readTargetAttr(self.targetAttr),
222				data = self.target || targetValue || '';
223
224			/* Find which filter applies */
225			var filter = filters[self.type]; /* check explicit type like {type: 'image'} */
226
227			/* check explicit type like data-featherlight="image" */
228			if(!filter && data in filters) {
229				filter = filters[data];
230				data = self.target && targetValue;
231			}
232			data = data || readTargetAttr('href') || '';
233
234			/* check explicity type & content like {image: 'photo.jpg'} */
235			if(!filter) {
236				for(var filterName in filters) {
237					if(self[filterName]) {
238						filter = filters[filterName];
239						data = self[filterName];
240					}
241				}
242			}
243
244			/* otherwise it's implicit, run checks */
245			if(!filter) {
246				var target = data;
247				data = null;
248				$.each(self.contentFilters, function() {
249					filter = filters[this];
250					if(filter.test)  {
251						data = filter.test(target);
252					}
253					if(!data && filter.regex && target.match && target.match(filter.regex)) {
254						data = target;
255					}
256					return !data;
257				});
258				if(!data) {
259					if('console' in window){ window.console.error('Featherlight: no content filter found ' + (target ? ' for "' + target + '"' : ' (no target specified)')); }
260					return false;
261				}
262			}
263			/* Process it */
264			return filter.process.call(self, data);
265		},
266
267		/* sets the content of $instance to $content */
268		setContent: function($content){
269      this.$instance.removeClass(this.namespace+'-loading');
270
271      /* we need a special class for the iframe */
272      this.$instance.toggleClass(this.namespace+'-iframe', $content.is('iframe'));
273
274      /* replace content by appending to existing one before it is removed
275         this insures that featherlight-inner remain at the same relative
276         position to any other items added to featherlight-content */
277      this.$instance.find('.'+this.namespace+'-inner')
278        .not($content)                /* excluded new content, important if persisted */
279        .slice(1).remove().end()      /* In the unexpected event where there are many inner elements, remove all but the first one */
280        .replaceWith($.contains(this.$instance[0], $content[0]) ? '' : $content);
281
282      this.$content = $content.addClass(this.namespace+'-inner');
283
284      return this;
285		},
286
287		/* opens the lightbox. "this" contains $instance with the lightbox, and with the config.
288			Returns a promise that is resolved after is successfully opened. */
289		open: function(event){
290			var self = this;
291			self.$instance.hide().appendTo(self.root);
292			if((!event || !event.isDefaultPrevented())
293				&& self.beforeOpen(event) !== false) {
294
295				if(event){
296					event.preventDefault();
297				}
298				var $content = self.getContent();
299
300				if($content) {
301					opened.push(self);
302
303					toggleGlobalEvents(true);
304
305					self.$instance.fadeIn(self.openSpeed);
306					self.beforeContent(event);
307
308					/* Set content and show */
309					return $.when($content)
310						.always(function($openendContent){
311							if($openendContent) {
312								self.setContent($openendContent);
313								self.afterContent(event);
314							}
315						})
316						.then(self.$instance.promise())
317						/* Call afterOpen after fadeIn is done */
318						.done(function(){ self.afterOpen(event); });
319				}
320			}
321			self.$instance.detach();
322			return $.Deferred().reject().promise();
323		},
324
325		/* closes the lightbox. "this" contains $instance with the lightbox, and with the config
326			returns a promise, resolved after the lightbox is successfully closed. */
327		close: function(event){
328			var self = this,
329				deferred = $.Deferred();
330
331			if(self.beforeClose(event) === false) {
332				deferred.reject();
333			} else {
334
335				if (0 === pruneOpened(self).length) {
336					toggleGlobalEvents(false);
337				}
338
339				self.$instance.fadeOut(self.closeSpeed,function(){
340					self.$instance.detach();
341					self.afterClose(event);
342					deferred.resolve();
343				});
344			}
345			return deferred.promise();
346		},
347
348		/* resizes the content so it fits in visible area and keeps the same aspect ratio.
349				Does nothing if either the width or the height is not specified.
350				Called automatically on window resize.
351				Override if you want different behavior. */
352		resize: function(w, h) {
353			if (w && h) {
354				/* Reset apparent image size first so container grows */
355				this.$content.css('width', '').css('height', '');
356				/* Calculate the worst ratio so that dimensions fit */
357				 /* Note: -1 to avoid rounding errors */
358				var ratio = Math.max(
359					w  / (this.$content.parent().width()-1),
360					h / (this.$content.parent().height()-1));
361				/* Resize content */
362				if (ratio > 1) {
363					ratio = h / Math.floor(h / ratio); /* Round ratio down so height calc works */
364					this.$content.css('width', '' + w / ratio + 'px').css('height', '' + h / ratio + 'px');
365				}
366			}
367		},
368
369		/* Utility function to chain callbacks
370		   [Warning: guru-level]
371		   Used be extensions that want to let users specify callbacks but
372		   also need themselves to use the callbacks.
373		   The argument 'chain' has callback names as keys and function(super, event)
374		   as values. That function is meant to call `super` at some point.
375		*/
376		chainCallbacks: function(chain) {
377			for (var name in chain) {
378				this[name] = $.proxy(chain[name], this, $.proxy(this[name], this));
379			}
380		}
381	};
382
383	$.extend(Featherlight, {
384		id: 0,                                    /* Used to id single featherlight instances */
385		autoBind:       '[data-featherlight]',    /* Will automatically bind elements matching this selector. Clear or set before onReady */
386		defaults:       Featherlight.prototype,   /* You can access and override all defaults using $.featherlight.defaults, which is just a synonym for $.featherlight.prototype */
387		/* Contains the logic to determine content */
388		contentFilters: {
389			jquery: {
390				regex: /^[#.]\w/,         /* Anything that starts with a class name or identifiers */
391				test: function(elem)    { return elem instanceof $ && elem; },
392				process: function(elem) { return this.persist !== false ? $(elem) : $(elem).clone(true); }
393			},
394			image: {
395				regex: /\.(png|jpg|jpeg|gif|tiff?|bmp|svg)(\?\S*)?$/i,
396				process: function(url)  {
397					var self = this,
398						deferred = $.Deferred(),
399						img = new Image(),
400						$img = $('<img src="'+url+'" alt="" class="'+self.namespace+'-image" />');
401					img.onload  = function() {
402						/* Store naturalWidth & height for IE8 */
403						$img.naturalWidth = img.width; $img.naturalHeight = img.height;
404						deferred.resolve( $img );
405					};
406					img.onerror = function() { deferred.reject($img); };
407					img.src = url;
408					return deferred.promise();
409				}
410			},
411			html: {
412				regex: /^\s*<[\w!][^<]*>/, /* Anything that starts with some kind of valid tag */
413				process: function(html) { return $(html); }
414			},
415			ajax: {
416				regex: /./,            /* At this point, any content is assumed to be an URL */
417				process: function(url)  {
418					var self = this,
419						deferred = $.Deferred();
420					/* we are using load so one can specify a target with: url.html #targetelement */
421					var $container = $('<div></div>').load(url, function(response, status){
422						if ( status !== "error" ) {
423							deferred.resolve($container.contents());
424						}
425						deferred.reject();
426					});
427					return deferred.promise();
428				}
429			},
430			iframe: {
431				process: function(url) {
432					var deferred = new $.Deferred();
433					var $content = $('<iframe/>');
434					var css = parseAttrs(this, 'iframe');
435					var attrs = slice(css, iFrameAttributeSet);
436					$content.hide()
437						.attr('src', url)
438						.attr(attrs)
439						.css(css)
440						.on('load', function() { deferred.resolve($content.show()); })
441						// We can't move an <iframe> and avoid reloading it,
442						// so let's put it in place ourselves right now:
443						.appendTo(this.$instance.find('.' + this.namespace + '-content'));
444					return deferred.promise();
445				}
446			},
447			text: {
448				process: function(text) { return $('<div>', {text: text}); }
449			}
450		},
451
452		functionAttributes: ['beforeOpen', 'afterOpen', 'beforeContent', 'afterContent', 'beforeClose', 'afterClose'],
453
454		/*** class methods ***/
455		/* read element's attributes starting with data-featherlight- */
456		readElementConfig: function(element, namespace) {
457			var Klass = this,
458				regexp = new RegExp('^data-' + namespace + '-(.*)'),
459				config = {};
460			if (element && element.attributes) {
461				$.each(element.attributes, function(){
462					var match = this.name.match(regexp);
463					if (match) {
464						var val = this.value,
465							name = $.camelCase(match[1]);
466						if ($.inArray(name, Klass.functionAttributes) >= 0) {  /* jshint -W054 */
467							val = new Function(val);                           /* jshint +W054 */
468						} else {
469							try { val = JSON.parse(val); }
470							catch(e) {}
471						}
472						config[name] = val;
473					}
474				});
475			}
476			return config;
477		},
478
479		/* Used to create a Featherlight extension
480		   [Warning: guru-level]
481		   Creates the extension's prototype that in turn
482		   inherits Featherlight's prototype.
483		   Could be used to extend an extension too...
484		   This is pretty high level wizardy, it comes pretty much straight
485		   from CoffeeScript and won't teach you anything about Featherlight
486		   as it's not really specific to this library.
487		   My suggestion: move along and keep your sanity.
488		*/
489		extend: function(child, defaults) {
490			/* Setup class hierarchy, adapted from CoffeeScript */
491			var Ctor = function(){ this.constructor = child; };
492			Ctor.prototype = this.prototype;
493			child.prototype = new Ctor();
494			child.__super__ = this.prototype;
495			/* Copy class methods & attributes */
496			$.extend(child, this, defaults);
497			child.defaults = child.prototype;
498			return child;
499		},
500
501		attach: function($source, $content, config) {
502			var Klass = this;
503			if (typeof $content === 'object' && $content instanceof $ === false && !config) {
504				config = $content;
505				$content = undefined;
506			}
507			/* make a copy */
508			config = $.extend({}, config);
509
510			/* Only for openTrigger, filter & namespace... */
511			var namespace = config.namespace || Klass.defaults.namespace,
512				tempConfig = $.extend({}, Klass.defaults, Klass.readElementConfig($source[0], namespace), config),
513				sharedPersist;
514			var handler = function(event) {
515				var $target = $(event.currentTarget);
516				/* ... since we might as well compute the config on the actual target */
517				var elemConfig = $.extend(
518					{$source: $source, $currentTarget: $target},
519					Klass.readElementConfig($source[0], tempConfig.namespace),
520					Klass.readElementConfig(event.currentTarget, tempConfig.namespace),
521					config);
522				var fl = sharedPersist || $target.data('featherlight-persisted') || new Klass($content, elemConfig);
523				if(fl.persist === 'shared') {
524					sharedPersist = fl;
525				} else if(fl.persist !== false) {
526					$target.data('featherlight-persisted', fl);
527				}
528				if (elemConfig.$currentTarget.blur) {
529					elemConfig.$currentTarget.blur(); // Otherwise 'enter' key might trigger the dialog again
530				}
531				fl.open(event);
532			};
533
534			$source.on(tempConfig.openTrigger+'.'+tempConfig.namespace, tempConfig.filter, handler);
535
536			return {filter: tempConfig.filter, handler: handler};
537		},
538
539		current: function() {
540			var all = this.opened();
541			return all[all.length - 1] || null;
542		},
543
544		opened: function() {
545			var klass = this;
546			pruneOpened();
547			return $.grep(opened, function(fl) { return fl instanceof klass; } );
548		},
549
550		close: function(event) {
551			var cur = this.current();
552			if(cur) { return cur.close(event); }
553		},
554
555		/* Does the auto binding on startup.
556		   Meant only to be used by Featherlight and its extensions
557		*/
558		_onReady: function() {
559			var Klass = this;
560			if(Klass.autoBind){
561				var $autobound = $(Klass.autoBind);
562				/* Bind existing elements */
563				$autobound.each(function(){
564					Klass.attach($(this));
565				});
566				/* If a click propagates to the document level, then we have an item that was added later on */
567				$(document).on('click', Klass.autoBind, function(evt) {
568					if (evt.isDefaultPrevented()) {
569						return;
570					}
571					var $cur = $(evt.currentTarget);
572					var len = $autobound.length;
573					$autobound = $autobound.add($cur);
574					if(len === $autobound.length) {
575						return; /* already bound */
576					}
577					/* Bind featherlight */
578					var data = Klass.attach($cur);
579					/* Dispatch event directly */
580					if (!data.filter || $(evt.target).parentsUntil($cur, data.filter).length > 0) {
581						data.handler(evt);
582					}
583				});
584			}
585		},
586
587		/* Featherlight uses the onKeyUp callback to intercept the escape key.
588		   Private to Featherlight.
589		*/
590		_callbackChain: {
591			onKeyUp: function(_super, event){
592				if(27 === event.keyCode) {
593					if (this.closeOnEsc) {
594						$.featherlight.close(event);
595					}
596					return false;
597				} else {
598					return _super(event);
599				}
600			},
601
602			beforeOpen: function(_super, event) {
603				// Used to disable scrolling
604				$(document.documentElement).addClass('with-featherlight');
605
606				// Remember focus:
607				this._previouslyActive = document.activeElement;
608
609				// Disable tabbing:
610				// See http://stackoverflow.com/questions/1599660/which-html-elements-can-receive-focus
611				this._$previouslyTabbable = $("a, input, select, textarea, iframe, button, iframe, [contentEditable=true]")
612					.not('[tabindex]')
613					.not(this.$instance.find('button'));
614
615				this._$previouslyWithTabIndex = $('[tabindex]').not('[tabindex="-1"]');
616				this._previousWithTabIndices = this._$previouslyWithTabIndex.map(function(_i, elem) {
617					return $(elem).attr('tabindex');
618				});
619
620				this._$previouslyWithTabIndex.add(this._$previouslyTabbable).attr('tabindex', -1);
621
622				if (document.activeElement.blur) {
623					document.activeElement.blur();
624				}
625				return _super(event);
626			},
627
628			afterClose: function(_super, event) {
629				var r = _super(event);
630				// Restore focus
631				var self = this;
632				this._$previouslyTabbable.removeAttr('tabindex');
633				this._$previouslyWithTabIndex.each(function(i, elem) {
634					$(elem).attr('tabindex', self._previousWithTabIndices[i]);
635				});
636				this._previouslyActive.focus();
637				// Restore scroll
638				if(Featherlight.opened().length === 0) {
639					$(document.documentElement).removeClass('with-featherlight');
640				}
641				return r;
642			},
643
644			onResize: function(_super, event){
645				this.resize(this.$content.naturalWidth, this.$content.naturalHeight);
646				return _super(event);
647			},
648
649			afterContent: function(_super, event){
650				var r = _super(event);
651				this.$instance.find('[autofocus]:not([disabled])').focus();
652				this.onResize(event);
653				return r;
654			}
655		}
656	});
657
658	$.featherlight = Featherlight;
659
660	/* bind jQuery elements to trigger featherlight */
661	$.fn.featherlight = function($content, config) {
662		Featherlight.attach(this, $content, config);
663		return this;
664	};
665
666	/* bind featherlight on ready if config autoBind is set */
667	$(document).ready(function(){ Featherlight._onReady(); });
668});

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.