PageSourceSearch

https://www.autorskecteni.cz/front/_starter/node_modules/nette-for…?v=c13cd2110d6fa47dedccc0089f5272dc

js autorskecteni.cz collected 2026-09-24 10:01:47 UTC 21,251 bytes, 785 lines download raw bytes

1/**
2 * NetteForms - simple form validation.
3 *
4 * This file is part of the Nette Framework (https://nette.org)
5 * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6 */
7
8(function(global, factory) {
9	if (!global.JSON) {
10		return;
11	}
12
13	if (typeof define === 'function' && define.amd) {
14		define(function() {
15			return factory(global);
16		});
17	} else if (typeof module === 'object' && typeof module.exports === 'object') {
18		module.exports = factory(global);
19	} else {
20		var init = !global.Nette || !global.Nette.noInit;
21		global.Nette = factory(global);
22		if (init) {
23			global.Nette.initOnLoad();
24		}
25	}
26
27}(typeof window !== 'undefined' ? window : this, function(window) {
28
29	'use strict';
30
31	var Nette = {};
32	var preventFiltering = {};
33	var formToggles = {};
34	var toggleListeners = new window.WeakMap();
35
36	Nette.formErrors = [];
37	Nette.version = '3.0';
38	Nette.invalidNumberMessage = 'Please enter a valid value.';
39
40
41	/**
42	 * Function to execute when the DOM is fully loaded.
43	 * @private
44	 */
45	Nette.onDocumentReady = function(callback) {
46		if (document.readyState !== 'loading') {
47			callback.call(this);
48		} else {
49			document.addEventListener('DOMContentLoaded', callback);
50		}
51	};
52
53
54	/**
55	 * Returns the value of form element.
56	 */
57	Nette.getValue = function(elem) {
58		var i;
59		if (!elem) {
60			return null;
61
62		} else if (!elem.tagName) { // RadioNodeList, HTMLCollection, array
63			return elem[0] ? Nette.getValue(elem[0]) : null;
64
65		} else if (elem.type === 'radio') {
66			var elements = elem.form.elements; // prevents problem with name 'item' or 'namedItem'
67			for (i = 0; i < elements.length; i++) {
68				if (elements[i].name === elem.name && elements[i].checked) {
69					return elements[i].value;
70				}
71			}
72			return null;
73
74		} else if (elem.type === 'file') {
75			return elem.files || elem.value;
76
77		} else if (elem.tagName.toLowerCase() === 'select') {
78			var index = elem.selectedIndex,
79				options = elem.options,
80				values = [];
81
82			if (elem.type === 'select-one') {
83				return index < 0 ? null : options[index].value;
84			}
85
86			for (i = 0; i < options.length; i++) {
87				if (options[i].selected) {
88					values.push(options[i].value);
89				}
90			}
91			return values;
92
93		} else if (elem.name && elem.name.substr(-2) === '[]') { // multiple elements []
94			elements = elem.form.elements[elem.name].tagName ? [elem] : elem.form.elements[elem.name];
95			values = [];
96
97			for (i = 0; i < elements.length; i++) {
98				if (elements[i].type !== 'checkbox' || elements[i].checked) {
99					values.push(elements[i].value);
100				}
101			}
102			return values;
103
104		} else if (elem.type === 'checkbox') {
105			return elem.checked;
106
107		} else if (elem.tagName.toLowerCase() === 'textarea') {
108			return elem.value.replace('\r', '');
109
110		} else {
111			return elem.value.replace('\r', '').replace(/^\s+|\s+$/g, '');
112		}
113	};
114
115
116	/**
117	 * Returns the effective value of form element.
118	 */
119	Nette.getEffectiveValue = function(elem, filter) {
120		var val = Nette.getValue(elem);
121		if (elem.getAttribute) {
122			if (val === elem.getAttribute('data-nette-empty-value')) {
123				val = '';
124			}
125		}
126		if (filter && preventFiltering[elem.name] === undefined) {
127			preventFiltering[elem.name] = true;
128			var ref = {value: val};
129			Nette.validateControl(elem, null, true, ref);
130			val = ref.value;
131			delete preventFiltering[elem.name];
132		}
133		return val;
134	};
135
136
137	/**
138	 * Validates form element against given rules.
139	 */
140	Nette.validateControl = function(elem, rules, onlyCheck, value, emptyOptional) {
141		var top = !rules;
142		elem = elem.tagName ? elem : elem[0]; // RadioNodeList
143		rules = rules || JSON.parse(elem.getAttribute('data-nette-rules') || '[]');
144		value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
145		emptyOptional = emptyOptional === undefined ? !Nette.validateRule(elem, ':filled', null, value) : emptyOptional;
146
147		for (var id = 0, len = rules.length; id < len; id++) {
148			var rule = rules[id],
149				op = rule.op.match(/(~)?([^?]+)/),
150				curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem;
151
152			rule.neg = op[1];
153			rule.op = op[2];
154			rule.condition = !!rule.rules;
155
156			if (!curElem) {
157				continue;
158			} else if (emptyOptional && !rule.condition && rule.op !== ':filled') {
159				continue;
160			}
161
162			curElem = curElem.tagName ? curElem : curElem[0]; // RadioNodeList
163			var success = Nette.validateRule(curElem, rule.op, rule.arg, elem === curElem ? value : undefined);
164
165			if (success === null) {
166				continue;
167			} else if (rule.neg) {
168				success = !success;
169			}
170
171			if (rule.condition && success) {
172				if (!Nette.validateControl(elem, rule.rules, onlyCheck, value, rule.op === ':blank' ? false : emptyOptional)) {
173					return false;
174				}
175			} else if (!rule.condition && !success) {
176				if (Nette.isDisabled(curElem)) {
177					continue;
178				}
179				if (!onlyCheck) {
180					var arr = Array.isArray(rule.arg) ? rule.arg : [rule.arg],
181						message = rule.msg.replace(/%(value|\d+)/g, function(foo, m) {
182							return Nette.getValue(m === 'value' ? curElem : elem.form.elements.namedItem(arr[m].control));
183						});
184					Nette.addError(curElem, message);
185				}
186				return false;
187			}
188		}
189
190		if (elem.type === 'number' && !elem.validity.valid) {
191			if (top && !onlyCheck) {
192				Nette.addError(elem, Nette.invalidNumberMessage);
193			}
194			return false;
195		}
196
197		return true;
198	};
199
200
201	/**
202	 * Validates whole form.
203	 */
204	Nette.validateForm = function(sender, onlyCheck) {
205		var form = sender.form || sender,
206			scope = false;
207
208		Nette.formErrors = [];
209
210		if (form['nette-submittedBy'] && form['nette-submittedBy'].getAttribute('formnovalidate') !== null) {
211			var scopeArr = JSON.parse(form['nette-submittedBy'].getAttribute('data-nette-validation-scope') || '[]');
212			if (scopeArr.length) {
213				scope = new RegExp('^(' + scopeArr.join('-|') + '-)');
214			} else {
215				Nette.showFormErrors(form, []);
216				return true;
217			}
218		}
219
220		var radios = {}, i, elem;
221
222		for (i = 0; i < form.elements.length; i++) {
223			elem = form.elements[i];
224
225			if (elem.tagName && !(elem.tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1})) {
226				continue;
227
228			} else if (elem.type === 'radio') {
229				if (radios[elem.name]) {
230					continue;
231				}
232				radios[elem.name] = true;
233			}
234
235			if ((scope && !elem.name.replace(/]\[|\[|]|$/g, '-').match(scope)) || Nette.isDisabled(elem)) {
236				continue;
237			}
238
239			if (!Nette.validateControl(elem, null, onlyCheck) && !Nette.formErrors.length) {
240				return false;
241			}
242		}
243		var success = !Nette.formErrors.length;
244		Nette.showFormErrors(form, Nette.formErrors);
245		return success;
246	};
247
248
249	/**
250	 * Check if input is disabled.
251	 */
252	Nette.isDisabled = function(elem) {
253		if (elem.type === 'radio') {
254			for (var i = 0, elements = elem.form.elements; i < elements.length; i++) {
255				if (elements[i].name === elem.name && !elements[i].disabled) {
256					return false;
257				}
258			}
259			return true;
260		}
261		return elem.disabled;
262	};
263
264
265	/**
266	 * Adds error message to the queue.
267	 */
268	Nette.addError = function(elem, message) {
269		Nette.formErrors.push({
270			element: elem,
271			message: message
272		});
273	};
274
275
276	/**
277	 * Display error messages.
278	 */
279	Nette.showFormErrors = function(form, errors) {
280		var messages = [],
281			focusElem;
282
283		for (var i = 0; i < errors.length; i++) {
284			var elem = errors[i].element,
285				message = errors[i].message;
286
287			if (messages.indexOf(message) < 0) {
288				messages.push(message);
289
290				if (!focusElem && elem.focus) {
291					focusElem = elem;
292				}
293			}
294		}
295
296		if (messages.length) {
297			alert(messages.join('\n'));
298
299			if (focusElem) {
300				focusElem.focus();
301			}
302		}
303	};
304
305
306	/**
307	 * Validates single rule.
308	 */
309	Nette.validateRule = function(elem, op, arg, value) {
310		value = value === undefined ? {value: Nette.getEffectiveValue(elem, true)} : value;
311
312		if (op.charAt(0) === ':') {
313			op = op.substr(1);
314		}
315		op = op.replace('::', '_');
316		op = op.replace(/\\/g, '');
317
318		var arr = Array.isArray(arg) ? arg.slice(0) : [arg];
319		for (var i = 0, len = arr.length; i < len; i++) {
320			if (arr[i] && arr[i].control) {
321				var control = elem.form.elements.namedItem(arr[i].control);
322				arr[i] = control === elem ? value.value : Nette.getEffectiveValue(control, true);
323			}
324		}
325
326		return Nette.validators[op]
327			? Nette.validators[op](elem, Array.isArray(arg) ? arr : arr[0], value.value, value)
328			: null;
329	};
330
331
332	Nette.validators = {
333		filled: function(elem, arg, val) {
334			if (elem.type === 'number' && elem.validity.badInput) {
335				return true;
336			}
337			return val !== '' && val !== false && val !== null
338				&& (!Array.isArray(val) || !!val.length)
339				&& (!window.FileList || !(val instanceof window.FileList) || val.length);
340		},
341
342		blank: function(elem, arg, val) {
343			return !Nette.validators.filled(elem, arg, val);
344		},
345
346		valid: function(elem) {
347			return Nette.validateControl(elem, null, true);
348		},
349
350		equal: function(elem, arg, val) {
351			if (arg === undefined) {
352				return null;
353			}
354
355			function toString(val) {
356				if (typeof val === 'number' || typeof val === 'string') {
357					return '' + val;
358				} else {
359					return val === true ? '1' : '';
360				}
361			}
362
363			val = Array.isArray(val) ? val : [val];
364			arg = Array.isArray(arg) ? arg : [arg];
365			loop:
366			for (var i1 = 0, len1 = val.length; i1 < len1; i1++) {
367				for (var i2 = 0, len2 = arg.length; i2 < len2; i2++) {
368					if (toString(val[i1]) === toString(arg[i2])) {
369						continue loop;
370					}
371				}
372				return false;
373			}
374			return true;
375		},
376
377		notEqual: function(elem, arg, val) {
378			return arg === undefined ? null : !Nette.validators.equal(elem, arg, val);
379		},
380
381		minLength: function(elem, arg, val) {
382			if (elem.type === 'number') {
383				if (elem.validity.tooShort) {
384					return false;
385				} else if (elem.validity.badInput) {
386					return null;
387				}
388			}
389			return val.length >= arg;
390		},
391
392		maxLength: function(elem, arg, val) {
393			if (elem.type === 'number') {
394				if (elem.validity.tooLong) {
395					return false;
396				} else if (elem.validity.badInput) {
397					return null;
398				}
399			}
400			return val.length <= arg;
401		},
402
403		length: function(elem, arg, val) {
404			if (elem.type === 'number') {
405				if (elem.validity.tooShort || elem.validity.tooLong) {
406					return false;
407				} else if (elem.validity.badInput) {
408					return null;
409				}
410			}
411			arg = Array.isArray(arg) ? arg : [arg, arg];
412			return (arg[0] === null || val.length >= arg[0]) && (arg[1] === null || val.length <= arg[1]);
413		},
414
415		email: function(elem, arg, val) {
416			return (/^("([ !#-[\]-~]|\\[ -~])+"|[-a-z0-9!#$%&'*+/=?^_`{|}~]+(\.[-a-z0-9!#$%&'*+/=?^_`{|}~]+)*)@([0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)+[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?$/i).test(val);
417		},
418
419		url: function(elem, arg, val, value) {
420			if (!(/^[a-z\d+.-]+:/).test(val)) {
421				val = 'http://' + val;
422			}
423			if ((/^https?:\/\/((([-_0-9a-z\u00C0-\u02FF\u0370-\u1EFF]+\.)*[0-9a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,61}[0-9a-z\u00C0-\u02FF\u0370-\u1EFF])?\.)?[a-z\u00C0-\u02FF\u0370-\u1EFF]([-0-9a-z\u00C0-\u02FF\u0370-\u1EFF]{0,17}[a-z\u00C0-\u02FF\u0370-\u1EFF])?|\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}|\[[0-9a-f:]{3,39}\])(:\d{1,5})?(\/\S*)?$/i).test(val)) {
424				value.value = val;
425				return true;
426			}
427			return false;
428		},
429
430		regexp: function(elem, arg, val) {
431			var parts = typeof arg === 'string' ? arg.match(/^\/(.*)\/([imu]*)$/) : false;
432			try {
433				return parts && (new RegExp(parts[1], parts[2].replace('u', ''))).test(val);
434			} catch (e) {} // eslint-disable-line no-empty
435		},
436
437		pattern: function(elem, arg, val, value, caseInsensitive) {
438			if (typeof arg !== 'string') {
439				return null;
440			}
441
442			try {
443				try {
444					var regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'ui' : 'u');
445				} catch (e) {
446					regExp = new RegExp('^(?:' + arg + ')$', caseInsensitive ? 'i' : '');
447				}
448
449				if (window.FileList && val instanceof FileList) {
450					for (var i = 0; i < val.length; i++) {
451						if (!regExp.test(val[i].name)) {
452							return false;
453						}
454					}
455
456					return true;
457				}
458
459				return regExp.test(val);
460			} catch (e) {} // eslint-disable-line no-empty
461		},
462
463		patternCaseInsensitive: function(elem, arg, val) {
464			return Nette.validators.pattern(elem, arg, val, null, true);
465		},
466
467		numeric: function(elem, arg, val) {
468			if (elem.type === 'number' && elem.validity.badInput) {
469				return false;
470			}
471			return (/^[0-9]+$/).test(val);
472		},
473
474		integer: function(elem, arg, val) {
475			if (elem.type === 'number' && elem.validity.badInput) {
476				return false;
477			}
478			return (/^-?[0-9]+$/).test(val);
479		},
480
481		'float': function(elem, arg, val, value) {
482			if (elem.type === 'number' && elem.validity.badInput) {
483				return false;
484			}
485			val = val.replace(/ +/g, '').replace(/,/g, '.');
486			if ((/^-?[0-9]*\.?[0-9]+$/).test(val)) {
487				value.value = val;
488				return true;
489			}
490			return false;
491		},
492
493		min: function(elem, arg, val) {
494			if (elem.type === 'number') {
495				if (elem.validity.rangeUnderflow) {
496					return false;
497				} else if (elem.validity.badInput) {
498					return null;
499				}
500			}
501			return arg === null || parseFloat(val) >= arg;
502		},
503
504		max: function(elem, arg, val) {
505			if (elem.type === 'number') {
506				if (elem.validity.rangeOverflow) {
507					return false;
508				} else if (elem.validity.badInput) {
509					return null;
510				}
511			}
512			return arg === null || parseFloat(val) <= arg;
513		},
514
515		range: function(elem, arg, val) {
516			if (elem.type === 'number') {
517				if (elem.validity.rangeUnderflow || elem.validity.rangeOverflow) {
518					return false;
519				} else if (elem.validity.badInput) {
520					return null;
521				}
522			}
523			return Array.isArray(arg) ?
524				((arg[0] === null || parseFloat(val) >= arg[0]) && (arg[1] === null || parseFloat(val) <= arg[1])) : null;
525		},
526
527		submitted: function(elem) {
528			return elem.form['nette-submittedBy'] === elem;
529		},
530
531		fileSize: function(elem, arg, val) {
532			if (window.FileList) {
533				for (var i = 0; i < val.length; i++) {
534					if (val[i].size > arg) {
535						return false;
536					}
537				}
538			}
539			return true;
540		},
541
542		mimeType: function (elem, arg, val) {
543			arg = Array.isArray(arg) ? arg : [arg];
544			for (var i = 0, len = arg.length, re = []; i < len; i++) {
545				re.push('^' + arg[i].replace(/([^\w])/g, '\\$1').replace('\\*', '.*') + '$');
546			}
547			re = new RegExp(re.join('|'));
548
549			if (window.FileList && val instanceof FileList) {
550				for (i = 0; i < val.length; i++) {
551					if (val[i].type && !re.test(val[i].type)) {
552						return false;
553					} else if (elem.validity.badInput) {
554						return null;
555					}
556				}
557			}
558			return true;
559		},
560
561		image: function (elem, arg, val) {
562			return Nette.validators.mimeType(elem, ['image/gif', 'image/png', 'image/jpeg', 'image/webp'], val);
563		},
564
565		'static': function (elem, arg) {
566			return arg;
567		}
568	};
569
570
571	/**
572	 * Process all toggles in form.
573	 */
574	Nette.toggleForm = function(form, event) {
575		var i;
576		formToggles = {};
577		for (i = 0; i < form.elements.length; i++) {
578			if (form.elements[i].tagName.toLowerCase() in {input: 1, select: 1, textarea: 1, button: 1}) {
579				Nette.toggleControl(form.elements[i], null, null, !event);
580			}
581		}
582
583		for (i in formToggles) {
584			Nette.toggle(i, formToggles[i].state, formToggles[i].elem, event);
585		}
586	};
587
588
589	/**
590	 * Process toggles on form element.
591	 */
592	Nette.toggleControl = function(elem, rules, success, firsttime, value, emptyOptional) {
593		rules = rules || JSON.parse(elem.getAttribute('data-nette-rules') || '[]');
594		value = value === undefined ? {value: Nette.getEffectiveValue(elem)} : value;
595		emptyOptional = emptyOptional === undefined ? !Nette.validateRule(elem, ':filled', null, value) : emptyOptional;
596
597		var has = false,
598			handler = function (e) {
599				Nette.toggleForm(elem.form, e);
600			},
601			curSuccess;
602
603		for (var id = 0, len = rules.length; id < len; id++) {
604			var rule = rules[id],
605				op = rule.op.match(/(~)?([^?]+)/),
606				curElem = rule.control ? elem.form.elements.namedItem(rule.control) : elem;
607
608			rule.neg = op[1];
609			rule.op = op[2];
610			rule.condition = !!rule.rules;
611
612			if (!curElem) {
613				continue;
614			} else if (emptyOptional && !rule.condition && rule.op !== ':filled') {
615				continue;
616			}
617
618			curSuccess = success;
619			if (success !== false) {
620				curSuccess = Nette.validateRule(curElem, rule.op, rule.arg, elem === curElem ? value : undefined);
621				if (curSuccess === null) {
622					continue;
623
624				} else if (rule.neg) {
625					curSuccess = !curSuccess;
626				}
627				if (!rule.condition) {
628					success = curSuccess;
629				}
630			}
631
632			if ((rule.condition && Nette.toggleControl(elem, rule.rules, curSuccess, firsttime, value, rule.op === ':blank' ? false : emptyOptional)) || rule.toggle) {
633				has = true;
634				if (firsttime) {
635					var name = curElem.tagName ? curElem.name : curElem[0].name,
636						els = curElem.tagName ? curElem.form.elements : curElem;
637
638					for (var i = 0; i < els.length; i++) {
639						if (els[i].name === name && !toggleListeners.has(els[i])) {
640							els[i].addEventListener('change', handler);
641							toggleListeners.set(els[i], null);
642						}
643					}
644				}
645				for (var toggleId in rule.toggle || []) {
646					formToggles[toggleId] = formToggles[toggleId] || {elem: elem};
647					formToggles[toggleId].state = formToggles[toggleId].state || (rule.toggle[toggleId] ? curSuccess : !curSuccess);
648				}
649			}
650		}
651		return has;
652	};
653
654
655	/**
656	 * Displays or hides HTML element.
657	 */
658	Nette.toggle = function(selector, visible, srcElement, event) { // eslint-disable-line no-unused-vars
659		if (/^\w[\w.:-]*$/.test(selector)) { // id
660			selector = '#' + selector;
661		}
662		var elems = document.querySelectorAll(selector);
663		for (var i = 0; i < elems.length; i++) {
664			elems[i].hidden = !visible;
665		}
666	};
667
668
669	/**
670	 * Compact checkboxes
671	 */
672	Nette.compactCheckboxes = function(form) {
673		var name, i, elem, values = {};
674
675		for (i = 0; i < form.elements.length; i++) {
676			elem = form.elements[i];
677			if (elem.tagName
678				&& elem.tagName.toLowerCase() === 'input'
679				&& elem.type === 'checkbox'
680			) {
681				if (elem.name
682					&& elem.name.substr(-2) === '[]'
683				) {
684					name = elem.name.substr(0, elem.name.length - 2);
685					elem.removeAttribute('name');
686					elem.setAttribute('data-nette-name', name);
687				}
688
689				if (name = elem.getAttribute('data-nette-name')) { // eslint-disable-line no-cond-assign
690					values[name] = values[name] || [];
691					if (elem.checked && !elem.disabled) {
692						values[name].push(elem.value);
693					}
694				}
695			}
696		}
697
698		for (name in values) {
699			if (form.elements[name] === undefined) {
700				elem = document.createElement('input');
701				elem.setAttribute('name', name);
702				elem.setAttribute('type', 'hidden');
703				form.appendChild(elem);
704			}
705			form.elements[name].value = values[name].join(',');
706			form.elements[name].disabled = values[name].length === 0;
707		}
708	};
709
710
711	/**
712	 * Setup handlers.
713	 */
714	Nette.initForm = function(form) {
715		if (form.method === 'get' && form.hasAttribute('data-nette-compact')) {
716			form.addEventListener('submit', function() {
717				Nette.compactCheckboxes(form);
718			});
719		}
720
721		check: {
722			for (var i = 0; i < form.elements.length; i++) {
723				if (form.elements[i].getAttribute('data-nette-rules')) {
724					break check;
725				}
726			}
727			return;
728		}
729
730		Nette.toggleForm(form);
731
732		if (form.noValidate) {
733			return;
734		}
735		form.noValidate = true;
736
737		form.addEventListener('submit', function(e) {
738			if (!Nette.validateForm(form)) {
739				e.stopPropagation();
740				e.preventDefault();
741			}
742		});
743	};
744
745
746	/**
747	 * @private
748	 */
749	Nette.initOnLoad = function() {
750		Nette.onDocumentReady(function() {
751			for (var i = 0; i < document.forms.length; i++) {
752				Nette.initForm(document.forms[i]);
753			}
754
755			document.body.addEventListener('click', function(e) {
756				var target = e.target;
757				while (target) {
758					if (target.form && target.type in {submit: 1, image: 1}) {
759						target.form['nette-submittedBy'] = target;
760						break;
761					}
762					target = target.parentNode;
763				}
764			});
765		});
766	};
767
768
769	/**
770	 * Converts string to web safe characters [a-z0-9-] text.
771	 */
772	Nette.webalize = function(s) {
773		s = s.toLowerCase();
774		var res = '', i, ch;
775		for (i = 0; i < s.length; i++) {
776			ch = Nette.webalizeTable[s.charAt(i)];
777			res += ch ? ch : s.charAt(i);
778		}
779		return res.replace(/[^a-z0-9]+/g, '-').replace(/^-|-$/g, '');
780	};
781
782	Nette.webalizeTable = {\u00e1: 'a', \u00e4: 'a', \u010d: 'c', \u010f: 'd', \u00e9: 'e', \u011b: 'e', \u00ed: 'i', \u013e: 'l', \u0148: 'n', \u00f3: 'o', \u00f4: 'o', \u0159: 'r', \u0161: 's', \u0165: 't', \u00fa: 'u', \u016f: 'u', \u00fd: 'y', \u017e: 'z'};
783
784	return Nette;
785}));

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.