PageSourceSearch

https://somersetnlv.org/apps-shared/js/keyboard/mmAccess.js?20190322

js somersetnlv.org collected 2026-10-06 06:46:17 UTC 22,303 bytes, 652 lines download raw bytes

1/* Educational Networks Main Menu Keyboard Access
2 *
3 * FOCUS STYLING
4 * It is important to add styling for the :focus event as is done for the :hover event.
5 * - Top level items:
6 *
7 *		#nav_items_0 li a:focus, #nav_items_0 li.over a { ... top level hover styling }
8 *		 	- in order to maintain top level hover effect the 'over' class is added to the top level li when
9 *			  a user is within a sub menu.
10 *
11 * - Sub level items:
12 * 		#nav_items_0 li ul li a:focus { ...sub level item styling }
13 *
14 */
15
16function MainMenu() {
17
18	var mm = this;
19	var current_focus, current_elem, previous_focus, latest_menu, disabled_id, disabled_item, focus_fired = null;
20	var keys_down = new Array(),
21		open_menus = new Array();
22
23	var browser = {
24		isChrome 	: navigator.userAgent.toLowerCase().indexOf('chrome') > -1,
25		isFirefox 	: navigator.userAgent.toLowerCase().indexOf('firefox') > -1,
26		isMac 		: navigator.platform.toUpperCase().indexOf('MAC') > -1
27	}
28
29	var keys = {
30		TAB: 	9,
31		ENTER: 	13,
32		SPACE: 	32,
33		ESCAPE: 27,
34		UP: 	38,
35		DOWN: 	40,
36		LEFT: 	37,
37		RIGHT: 	39
38	}
39
40	this.setFocus 		= function( obj, elem ) { current_focus = obj; current_elem = elem; }
41	this.setPrevFocus 	= function( obj ) { previous_focus = obj; }
42	this.setLatestMenu 	= function( menu ) { latest_menu = menu; }
43
44	this.getFocus 		= function() { return current_focus; }
45	this.getElement 	= function() { return current_elem; }
46	this.getBrowser 	= function() { return browser; }
47	this.getKeys 		= function() { return keys; }
48	this.getKeysDown 	= function() { return keys_down; }
49	this.getOpenMenus 	= function() { return open_menus; }
50	this.getLatestMenu 	= function() { return latest_menu; }
51	this.getPrevFocus	= function() { return previous_focus; }
52
53	/* init runs the setup function and sets all needed event listeners
54	 * assumes id="menu" */
55	this.init = function() {
56
57		jAria("#menu").delegate( "a", "focusin", function(e) {
58			e.stopImmediatePropagation();
59			/* - Parent Items With Links
60			 * 	 - disables the link by replacing href with javascript:;
61			 * 	 - original href is stored in another attribute [ data-href="*" ]
62			 * 	 - menu correction detects and closes menus that should have closed
63			 *     but didn't because the focus left undetected.  Voiceover problem.
64			 *   - 5/6/2020 menus now open on focusin
65			 * - Parents With No Link, Normal Links
66			 *	 - does nothing */
67			mm.unsetParentHref(this);
68			mm.menuCorrection( jAria(this).closest("ul").attr("id") );
69			mm.setFocus( jAria(this), document.activeElement );
70			//mm.openMenu();
71		});
72
73		jAria("#menu > ul ul a").delegate( "a", "focus focusin", function(e) {
74			/* ensures top level li maintains '.over' class while within sub menu */
75			e.stopImmediatePropagation();
76			mm.unsetParentHref(this);
77			jAria( this ).closest('ul').addClass('over');
78		});
79
80		jAria("#menu > ul ul a").delegate( "a", "blur", function(e) {
81			/* removes '.over' class top the top level each time a sub link blurs
82			 * it will be added again if the next focusable item is within the same menu
83			 * maintaining the hover effect for the top level item. */
84			e.stopImmediatePropagation();
85			mm.setParentHref(this);
86			jAria(this).closest('ul').removeClass('over');
87		});
88
89		jAria("#menu").delegate( "a", "blur", function() {
90			/* - Parent Items With Links
91			 * 	 - re-enables the link by replacing href with data-href attribute
92			 * 	 - data-href="*"  attribute is removed
93			 * - Parents With No Link, and Normal Links
94			 *	 - does nothing */
95			mm.setPrevFocus(jAria(this));
96			mm.setParentHref(this);
97		});
98
99		jAria("#menu").delegate( "a", "mouseenter", function() {
100			/* - Parent Items With Links
101			 *   - sets the *made up* en-mouseover attribute on the item preventing the link from being disabled as we would do for a keyboard user
102			 * - Parents With No Link, and Normal Links
103			 *	 - does nothing */
104			mm.setParentHref(this);
105			jAria(this).attr("en-mouseover", "yes");
106		});
107
108		jAria("#menu").delegate( "a", "mouseleave", function() {
109			/* - Parent Items With Links
110			 * 	 - clears the *made up* en-mouseover attribute on the item preventing the link from being disabled as we would do for a keyboard user
111			 * - Parents With No Link, and Normal Links
112			 *	 - does nothing */
113			jAria(this).attr("en-mouseover", "no");
114		});
115
116		jAria("#menu").delegate( "a", "click", function() {
117			/* - Parent Items:  TODO - redo notes
118			 *   - ignore links on first press, open the sub level
119			 *   - keep focus on the parent item
120			 *   	-* THIS SHOULD MAYBE CHANGE TO FOCUS THE FIRST ITEM FOR PARENTS WHICH ARE NON LINKS *-
121			 *   - link will become active, a following press will open the link
122			 * - Normal Links:
123			 *   - activates href */
124			mm.openMenu();
125		});
126
127		jAria("#menu").bind("keyup", function(e) {
128			/*  when a key is released, remove it from the keys_down array
129			 *  keys_down keeps track of any key pressed which allows us
130			 *  to avoid multiple events from firing if a key is held down. */
131			var key = e.keyCode ? e.keyCode : e.which;
132			if(key != keys.SPACE && key != keys.ENTER) e.preventDefault();
133			var key_index = jAria.inArray( key, keys_down );
134			if(key_index != -1) {
135				keys_down.splice(key_index, 1);
136			}
137		});
138
139		jAria("#menu").bind('keydown', function(e) {
140			/*  when a key is pressed, log it in the keys_down.
141			 *  keys_down array keeps track of any key pressed which allows us
142			 *  to avoid multiple events from firing if a key is held down.
143			 *  if a key is already down return immediately
144			 *  else continue to the main key switch */
145			var key = e.keyCode ? e.keyCode : e.which;
146			
147			// Allow select elements to handle their own keyboard events
148			if (e.target && e.target.tagName === 'SELECT') {
149				return;
150			}
151			
152			if( key == keys.UP || key == keys.DOWN  || key == keys.LEFT || key == keys.RIGHT || key == keys.SPACE )
153				e.preventDefault();
154
155			// the following prevents multiple event fires when a key is held down
156			if(jAria.inArray( key, keys_down ) > -1) {
157				return;
158			}
159
160			// logs a key to prevent multiple event fires
161			keys_down.push(key);
162
163			var active_elem = document.activeElement;
164			mm.setFocus( jAria(this), active_elem );
165
166			// main menu switch
167			switch(key) {
168				case keys.SPACE:
169				case keys.ENTER:
170					/* - Parent Items:
171					 *   - if parent item contains href the value is changed to javascript:; and a new menu item is created at the first position of the menu
172					 *   - focus moves to the first child menu item
173					 * - Normal Links:
174					 *   - activates href */
175					if( mm.isParent() ) {
176						e.preventDefault();
177						mm.openMenu();
178					} else if (active_elem.onclick) {
179						e.preventDefault();
180						active_elem.click();
181					}
182					break;
183
184				case keys.ESCAPE:
185					/* - Top Level:
186					 *   - Exit menu, land in main content area
187					 * - Sub Level:
188					 *   - close current menu
189					 *   - focus on the parent item of the menu closed */
190					mm.close( key );
191					break;
192
193				case keys.TAB:
194					/*
195					 *  - Top Level:
196					 *    - go to next item or previous item if shift is held down
197					 *  - Sub Level:
198					 *    - close current menu simulating right press,
199					 *    - if shift is down simulate left press
200					 */
201					if(open_menus.length > 0) {
202						e.preventDefault();
203						if(e.shiftKey) {
204							mm.close( keys.LEFT );
205						} else {
206							mm.close( keys.RIGHT );
207						}
208					}
209					break;
210					case keys.UP:
211						/* - Top Level:
212                         *   - does nothing
213                         * - Sub Level:
214                         *   - go to prev item in current list
215                         *   - if at the bottom item jump back to the top item */
216						if(open_menus.length < 1) {
217							var top_level_item = jAria(document.activeElement);
218							if(top_level_item.parent().is(':first-child')) {
219								top_level_item = top_level_item.parent().parent().find('> li').last().children('a');
220							} else {
221								var prevItem = mm.searchPrevElement(top_level_item.parent().get(0));
222								top_level_item = jAria(prevItem).children('a');
223							}
224							top_level_item.focus();
225							if(mm.isParent(top_level_item)) {
226								mm.openMenu(top_level_item);
227								var lastMenu = open_menus[open_menus.length-1];
228								var lastItem = lastMenu.menu_elem.children('li').last().children('a');
229								lastItem.focus();
230								lastMenu.active_item = lastItem;
231								lastMenu.has_focus = true;
232							}
233						} else {
234							mm.closestItem( key );
235						}
236						break;
237				case keys.DOWN:
238					/* - Top Level:
239					 *   - if parent, open menu
240					 *   - else do nothing
241					 * - Sub Level:
242					 *   - go to next item in the current list
243					 *   - if at the bottom item jump back to the top item */
244					if(open_menus.length < 1) {
245						mm.openMenu();
246					} else {
247						mm.closestItem( key );
248					}
249					break;
250
251				case keys.LEFT:
252					/* - Top Level
253					 * 	 - go left to the closest item, parent or not
254					 * - Sub Level
255					 * 	 - close the current menu and:
256					 * 		- if parent level is top level focus the previous top level item
257					 * 		- else if parent level is a sub menu item focus on that parent item
258					 */
259					if(open_menus.length < 1) {
260						mm.closestItem( key );
261					} else {
262						//mm.closestMenu( keys.LEFT );
263						mm.close( key );
264					}
265					break;
266
267				case keys.RIGHT:
268					/* - Top Level
269					 * 	 - go right to the closest item, parent or not
270					 * - Sub Level
271					 * 	 - if current item is a parent open child menu
272					 * 	 - if current item is not a parent close all sub menu levels and focus on the next top level item */
273					if(open_menus.length < 1) {
274						mm.closestItem( key );
275					} else {
276						//mm.closestMenu( keys.RIGHT );
277						if( mm.isParent() ) {
278							mm.openMenu();
279						} else {
280							mm.close( key );
281						}
282					}
283					break;
284
285				default:
286					/* - Top Level
287					 *   - Does nothing
288					 * - Sub Level
289					 *   - increases the size of items beginning with any alphabetical key
290					 *   - case insensitive
291					 * 	 - toggle through items on following key presses of the same alphabetical key
292					 * 	 - next item, next menu, and close functions will reset the font size and list of items to toggle */
293					try {
294						mm.filterAlphabetKeys( key );
295					} catch (e) {
296						console.debug(e);
297					}
298
299					break;
300			}
301
302		});
303	}
304
305	this.clearFilterKey = function( current_menu ) {
306		if(current_menu.filter_key != null) {
307			current_menu.filter_key = null;
308			current_menu.menu_items.each(function(){
309				if(jAria(this).hasClass("at-focus")) {
310					jAria(this).removeClass("at-focus");
311				}
312			});
313		}
314	}
315
316	this.isParent = function ( active_elem ) {
317		var active_elem = (typeof active_elem !== typeof undefined) ? active_elem : mm.getElement();
318		var check = jAria( active_elem ).attr('aria-haspopup');
319		return typeof check !== typeof undefined && check !== false;
320	}
321
322	this.unsetParentHref = function( active_elem ) {
323		if(jAria(active_elem).attr('en-mouseover') == "yes") return;
324		if(mm.isParent(active_elem)) {
325			jAria(active_elem).attr("data-href", jAria(active_elem).attr("href"));
326			jAria(active_elem).attr("href", "javascript:;");
327			if (!jAria("#menu").hasClass("en-mobnav-show") || (active_elem && active_elem.href && active_elem.href.contains("http"))) {
328				mm.prependParentLink(active_elem);
329			}
330		}
331	}
332
333	this.setParentHref = function( active_elem ) {
334		if(mm.isParent(active_elem)) {
335			jAria(active_elem).attr("href", jAria(active_elem).attr("data-href"));
336		}
337	}
338
339	this.prependParentLink = function( active_elem ) {
340		if(jAria(active_elem).attr("en-header-appended") !== "yes") {
341			jAria(active_elem).attr("en-header-appended", "yes");
342			var dataHref = jAria(active_elem).attr("data-href");
343			var sub_ul = jAria("#" + jAria(active_elem).attr("aria-controls"));
344			var newAnchor = jAria("<a/>", {
345				"href": dataHref,
346				"text": jAria(active_elem).text().replace("\u2192", "")
347			});
348			jAria("<li/>", {
349				"style":"display:none;",
350				"class": "nav_item_first keyboard-only"
351			}).prepend(newAnchor).prependTo(sub_ul);
352		}
353	}
354
355	this.openMenu = function ( active_elem ) {
356		var active_elem = (typeof active_elem !== typeof undefined) ? active_elem : mm.getElement();
357		var active_obj = jAria( active_elem );
358		var is_parent = mm.isParent( active_elem );
359		var is_link = (active_obj.attr('href') != "javascript:;" && active_obj.attr("href") != "#");
360		var mouse_over = active_obj.attr("en-mouseover") == "yes";
361		if ( is_parent ) {
362			open_menus.push({
363				locked_in 	: true,
364				has_focus	: false,
365				menu_id		: jAria("#" + active_obj.attr('aria-controls')).attr("id"),
366				menu_parent	: jAria(active_elem),
367				menu_elem	: jAria("#" + active_obj.attr('aria-controls')),
368				menu_items 	: null,
369				filtered_items: [],
370				filter_iter : 0,
371				filter_key 	: null,
372				active_item : null,
373				active_item_id: null,
374				sub_level: open_menus.length
375			});
376
377			var menu_index = open_menus.length-1;
378			open_menus[menu_index].menu_items = open_menus[menu_index].menu_elem.children('li').children('a');
379			open_menus[menu_index].menu_parent.parent().addClass('over');
380			open_menus[menu_index].menu_parent.attr('aria-expanded', 'true');
381			open_menus[menu_index].menu_elem.attr('aria-expanded', 'true');
382			open_menus[menu_index].menu_elem.attr('aria-hidden', 'false');
383			open_menus[menu_index].menu_elem.css('opacity', '1');
384			open_menus[menu_index].menu_elem.css('visibility', 'visible');
385			open_menus[menu_index].menu_elem.css('display', 'block');
386
387			if(!mouse_over) {
388				jAria(open_menus[menu_index].menu_items[0]).parent().show();
389			}
390
391			mm.setLatestMenu( open_menus[menu_index].menu_elem );
392			mm.closestItem( keys.DOWN );
393		}
394	}
395
396	this.closestItem = function ( key ) {
397		var current_menu = open_menus[open_menus.length-1];
398		var top_level_item = null;
399		if(current_menu != null) {
400			mm.clearFilterKey( current_menu );
401			if(key == keys.DOWN ) {
402				if(!current_menu.has_focus) {
403					current_menu.active_item = current_menu.menu_elem.children('li').first().children('a');
404					current_menu.active_item.focus();
405					current_menu.has_focus = true;
406				} else {
407					if(current_menu.active_item.parent().is(':last-child')) {
408						// Check if there's a next menu by looking at the parent's next sibling
409						var parentLi = current_menu.menu_parent.parent();
410						if (!parentLi.is(':last-child')) {
411							mm.close(keys.RIGHT); // Move right only if there's a next menu
412						}
413					} else {
414						current_menu.active_item = current_menu.active_item.parent().next().children('a');
415						current_menu.active_item.focus();
416					}
417				}
418			} else if ( key == keys.UP) {
419				if(current_menu.active_item.parent().is(':first-child')) {
420					mm.close(keys.UP);
421				} else {
422					current_menu.active_item = current_menu.active_item.parent().prev().children('a');
423					current_menu.active_item.focus();
424				}
425			}
426		} else {
427			top_level_item = jAria(document.activeElement);
428			if( key == keys.RIGHT ) {
429				if(top_level_item.parent().is(':last-child')) {
430					top_level_item = top_level_item.parent().parent().find('> li').first().children('a')
431				} else {
432					var nextItem = mm.searchNextElement(top_level_item.parent().get(0));
433					top_level_item = nextItem.getElementsByTagName('a')[0];
434				}
435				top_level_item.focus();
436			} else if ( key == keys.LEFT ) {
437				if(top_level_item.parent().is(':first-child')) {
438					top_level_item = top_level_item.parent().parent().find('> li').last().children('a');
439				} else {
440					var prevItem = mm.searchPrevElement(top_level_item.parent().get(0));
441					top_level_item = prevItem.getElementsByTagName('a')[0];
442				}
443				top_level_item.focus();
444			}
445		}
446	}
447
448	this.searchNextElement = function(startingPoint) {
449		var foundNode = false;
450		var nextNode = null;
451		var maxAttempts = 25;
452		var attempts = 0;
453		while(!foundNode) {
454			attempts++;
455			nextNode = (nextNode == null) ? startingPoint.nextSibling : nextNode.nextSibling;
456			try {
457				if(nextNode.hasAttribute("en-replacable")) {
458					continue;
459				}
460			} catch(e) {}
461			if(attempts > maxAttempts) {
462				break;
463			}
464			return nextNode;
465		}
466	}
467
468	this.searchPrevElement = function(startingPoint) {
469		var foundNode = false;
470		var nextNode = null;
471		var maxAttempts = 25;
472		var attempts = 0;
473		while(!foundNode) {
474			attempts++;
475			nextNode = (nextNode == null) ? startingPoint.previousSibling : nextNode.previousSibling;
476			try {
477				if(nextNode.hasAttribute("en-replacable")) {
478					continue
479				}
480			} catch(e) { }
481			if(attempts > maxAttempts) {
482				break;
483			}
484			return nextNode;
485		}
486	}
487
488	this.closestMenu = function ( key ) {
489		var current_menu = open_menus[open_menus.length-1];
490		mm.clearFilterKey( current_menu );
491		var item_check = null;
492		var menu_length = current_menu.menu_elem.children('li').length-1;
493		for(var i = 0; i <= menu_length; i++) {
494			if(key == keys.RIGHT) {
495				if(document.activeElement == current_menu.menu_elem.children('li').last().children('a').get(0)) {
496					if(current_menu.active_item.parent().is(':last-child')) {
497						item_check = current_menu.active_item;
498					}
499				} else {
500					item_check = (item_check == null)
501						? 	((!current_menu.has_focus)
502							? current_menu.menu_elem.children('li').first().children('a')
503							: current_menu.active_item.parent().next().children('a'))
504						: item_check.parent().next().children('a');
505				}
506			} else if(key == keys.LEFT) {
507				if(document.activeElement == current_menu.menu_elem.children('li').first().children('a').get(0)) {
508					if(current_menu.active_item.parent().is(':first-child')) {
509						item_check = current_menu.active_item;
510						mm.close( keys.LEFT );
511						break;
512					}
513				} else {
514					item_check = (item_check == null)
515						? 	((!current_menu.has_focus)
516							? current_menu.menu_elem.children('li').last().children('a')
517							: current_menu.active_item.parent().prev().children('a'))
518						: item_check.parent().prev().children('a');
519				}
520			}
521			current_menu.has_focus = true;
522			if(item_check.attr('aria-haspopup')) {
523				current_menu.active_item = item_check;
524				current_menu.active_item.focus();
525				break;
526			}
527			if( item_check.parent().is(':last-child') && key == keys.RIGHT ) {
528				mm.close( key );
529				break;
530			} else if ( item_check.parent().is(':first-child') && key == keys.LEFT ) {
531				mm.close( key );
532				break;
533			}
534		}
535	}
536
537	this.closeMenu = function( menu_id ) {
538		var menu = open_menus[ menu_id ];
539		var parent_li = menu.menu_parent.parent();
540		parent_li.removeClass('over');
541		menu.menu_parent.attr('aria-expanded', 'false');
542		menu.menu_elem.attr('aria-expanded', 'false');
543		menu.menu_elem.attr('aria-hidden', 'true');
544		menu.menu_elem.css("visibility", "");
545		menu.menu_elem.css("display", "");
546
547		menu.menu_elem.find(".keyboard-only").hide();
548		mm.setParentHref(menu.menu_parent);
549		if(menu.menu_items != null) {
550			menu.menu_items.each(function() {
551				if(jAria(this).hasClass("at-focus")) {
552					jAria(this).removeClass('at-focus');
553				}
554			});
555		}
556
557		open_menus.pop();
558	}
559
560	this.close = function( key ) {
561		if(open_menus.length < 1) {
562			var next = jAria("#content-shortcut-target");
563			next.attr("tabindex", "-1").focus().attr("tabindex", "0");
564			return;
565		}
566		var key = (typeof key === "undefined") ? null : key;
567		var num_to_close = (key == keys.ESCAPE || key == keys.LEFT) ? 1 : open_menus.length;
568		var top_level = open_menus[0].menu_parent;
569		var prev_level = open_menus[open_menus.length - 1].menu_parent;
570		for ( var i = open_menus.length; i > 0; --i ) {
571			mm.closeMenu(i-1);
572			num_to_close--;
573			if( num_to_close < 1 ) break;
574		}
575		if( open_menus.length < 1 ) {
576			if( key == keys.LEFT) {
577				if(prev_level == top_level) {
578					var isFirstTopLevel = top_level.parent().is(':first-child');
579					var parentElement = top_level.parent().get(0);
580					top_level = (isFirstTopLevel) ? parentElement : mm.searchPrevElement(parentElement);
581					top_level_item = top_level.getElementsByTagName('a')[0];
582					top_level_item.focus();
583				} else {
584					prev_level.focus();
585				}
586			} else if( key == keys.RIGHT ) {
587				var isLastTopLevel = top_level.parent().is(':last-child');
588				var parentElement = top_level.parent().get(0);
589				top_level = (isLastTopLevel) ? parentElement : mm.searchNextElement(parentElement);
590				top_level_item = top_level.getElementsByTagName('a')[0];
591				top_level_item.focus();
592			} else {
593				top_level.focus();
594			}
595		} else {
596			prev_level.focus();
597		}
598	}
599
600	this.menuCorrection = function ( menu_id ) {
601		if(open_menus.length < 1) return;
602		var num_to_close = open_menus.length;
603		var corrected = false;
604		for ( var i = open_menus.length; i > 0; --i ) {
605			if(open_menus[i-1].menu_id != menu_id) {
606				mm.closeMenu(i-1);
607				num_to_close--;
608				corrected = true;
609			} else if ( (num_to_close < 1) || (open_menus[i-1].menu_id == menu_id) ) {
610				if(corrected || open_menus[open_menus.length-1].active_item != jAria(document.activeElement)) {
611					open_menus[open_menus.length-1].has_focus = true;
612					open_menus[open_menus.length-1].active_item = jAria(document.activeElement);
613					open_menus[open_menus.length-1].active_item.focus();
614				}
615				break;
616			}
617		}
618	}
619
620	this.filterAlphabetKeys = function ( key ) {
621		if (( key >= 48 && key <= 57 )
622			|| ( key >= 65 && key <= 90 )
623			|| ( key >= 97 && key <= 122 ) ) {
624			var current_menu = open_menus[open_menus.length-1];
625			if(current_menu.menu_items != null) {
626				if(current_menu.filter_key != key) {
627					current_menu.filtered_items = [];
628					current_menu.filter_key = key;
629					current_menu.filter_iter = 0;
630					current_menu.menu_items.each(function() {
631						if(jAria(this).text().charCodeAt(0) == key || jAria(this).text().charCodeAt(0) == key+32) {
632							jAria(this).addClass("at-focus");
633							current_menu.filtered_items.push(jAria(this));
634						} else if(jAria(this).hasClass("at-focus")) {
635							jAria(this).removeClass("at-focus");
636						}
637					});
638					if(menu.filtered_items.length > 0) {
639						current_menu.active_item = menu.filtered_items[0];
640						current_menu.filtered_items[0].focus();
641					} else {
642						menu.filter_key = null;
643					}
644				} else {
645					current_menu.filter_iter = (current_menu.filter_iter + 1) >= current_menu.filtered_items.length ? 0 : current_menu.filter_iter + 1;
646					current_menu.filtered_items[current_menu.filter_iter].focus();
647					current_menu.active_item = current_menu.filtered_items[current_menu.filter_iter];
648				}
649			}
650		}
651	}
652}

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.