PageSourceSearch

https://stagesflight.com/Scripts/countrySelect.js

js stagesflight.com collected 2026-09-24 21:06:41 UTC 36,416 bytes, 1,361 lines download raw bytes

1//Internet explorer does not support "find". Workaround here.
2if (!Array.prototype.find) {
3    Object.defineProperty(Array.prototype, "find", {
4        value: function (predicate) {
5            if (this === null) {
6                throw new TypeError('Array.prototype.find called on null or undefined');
7            }
8            if (typeof predicate !== 'function') {
9                throw new TypeError('predicate must be a function');
10            }
11            var list = Object(this);
12            var length = list.length >>> 0;
13            var thisArg = arguments[1];
14            var value;
15
16            for (var i = 0; i < length; i++) {
17                value = list[i];
18                if (predicate.call(thisArg, value, i, list)) {
19                    return value;
20                }
21            }
22            return undefined;
23        }
24    });
25}
26
27// wrap in UMD - see https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
28(function(factory) {
29	if (typeof define === "function" && define.amd) {
30		define([ "jquery" ], function($) {
31			factory($, window, document);
32		});
33	} else {
34		factory(jQuery, window, document);
35	}
36})(function($, window, document, undefined) {
37	"use strict";
38	var pluginName = "countrySelect", id = 1, // give each instance its own ID for namespaced event handling
39	defaults = {
40		// Default country
41		defaultCountry: "",
42		// Position the selected flag inside or outside of the input
43		defaultStyling: "inside",
44		// Display only these countries
45		onlyCountries: [],
46		// The countries at the top of the list. Defaults to United States and United Kingdom
47		preferredCountries: [ "us", "gb" ]
48	}, keys = {
49		UP: 38,
50		DOWN: 40,
51		ENTER: 13,
52		ESC: 27,
53		PLUS: 43,
54		A: 65,
55		Z: 90
56	}, windowLoaded = false;
57	// keep track of if the window.load event has fired as impossible to check after the fact
58	$(window).on('load', function() {
59		windowLoaded = true;
60	});
61	function Plugin(element, options) {
62		this.element = element;
63		this.options = $.extend({}, defaults, options);
64		this._defaults = defaults;
65		// event namespace
66		this.ns = "." + pluginName + id++;
67		this._name = pluginName;
68		this.init();
69	}
70	Plugin.prototype = {
71		init: function() {
72			// Process all the data: onlyCountries, preferredCountries, defaultCountry etc
73			this._processCountryData();
74			// Generate the markup
75			this._generateMarkup();
76			// Set the initial state of the input value and the selected flag
77			this._setInitialState();
78			// Start all of the event listeners: input keyup, selectedFlag click
79			this._initListeners();
80			// Return this when the auto country is resolved.
81			this.autoCountryDeferred = new $.Deferred();
82			// Get auto country.
83			this._initAutoCountry();
84
85			return this.autoCountryDeferred;
86		},
87		/********************
88		 *  PRIVATE METHODS
89		 ********************/
90		// prepare all of the country data, including onlyCountries, preferredCountries and
91		// defaultCountry options
92		_processCountryData: function() {
93			// set the instances country data objects
94			this._setInstanceCountryData();
95			// set the preferredCountries property
96			this._setPreferredCountries();
97		},
98		// process onlyCountries array if present
99		_setInstanceCountryData: function() {
100			var that = this;
101			if (this.options.onlyCountries.length) {
102				var newCountries = [];
103				$.each(this.options.onlyCountries, function(i, countryCode) {
104					var countryData = that._getCountryData(countryCode, true);
105					if (countryData) {
106						newCountries.push(countryData);
107					}
108				});
109				this.countries = newCountries;
110			} else {
111				this.countries = allCountries;
112			}
113		},
114		// Process preferred countries - iterate through the preferences,
115		// fetching the country data for each one
116		_setPreferredCountries: function() {
117			var that = this;
118			this.preferredCountries = [];
119			$.each(this.options.preferredCountries, function(i, countryCode) {
120				var countryData = that._getCountryData(countryCode, false);
121				if (countryData) {
122					that.preferredCountries.push(countryData);
123				}
124			});
125		},
126		// generate all of the markup for the plugin: the selected flag overlay, and the dropdown
127		_generateMarkup: function() {
128			// Country input
129			this.countryInput = $(this.element);
130			// containers (mostly for positioning)
131			var mainClass = "country-select";
132			if (this.options.defaultStyling) {
133				mainClass += " " + this.options.defaultStyling;
134			}
135			this.countryInput.wrap($("<div>", {
136				"class": mainClass
137			}));
138			var flagsContainer = $("<div>", {
139				"class": "flag-dropdown"
140			}).insertAfter(this.countryInput);
141			// currently selected flag (displayed to left of input)
142			var selectedFlag = $("<div>", {
143				"class": "selected-flag"
144			}).appendTo(flagsContainer);
145			this.selectedFlagInner = $("<div>", {
146				"class": "flag"
147			}).appendTo(selectedFlag);
148			// CSS triangle
149			$("<div>", {
150				"class": "arrow"
151			}).appendTo(this.selectedFlagInner);
152			// country list contains: preferred countries, then divider, then all countries
153			this.countryList = $("<ul>", {
154				"class": "country-list v-hide"
155			}).appendTo(flagsContainer);
156			if (this.preferredCountries.length) {
157				this._appendListItems(this.preferredCountries, "preferred");
158				$("<li>", {
159					"class": "divider"
160				}).appendTo(this.countryList);
161			}
162			this._appendListItems(this.countries, "");
163			// Add the hidden input for the country code
164			this.countryCodeInput = $("#"+this.countryInput.attr("id")+"_code");
165			if (!this.countryCodeInput) {
166				this.countryCodeInput = $('<input type="hidden" id="'+this.countryInput.attr("id")+'_code" name="'+this.countryInput.attr("name")+'_code" value="" />');
167				this.countryCodeInput.insertAfter(this.countryInput);
168			}
169			// now we can grab the dropdown height, and hide it properly
170			this.dropdownHeight = this.countryList.outerHeight();
171			this.countryList.removeClass("v-hide").addClass("hide");
172			// this is useful in lots of places
173			this.countryListItems = this.countryList.children(".country");
174		},
175		// add a country <li> to the countryList <ul> container
176		_appendListItems: function(countries, className) {
177			// Generate DOM elements as a large temp string, so that there is only
178			// one DOM insert event
179			var tmp = "";
180			// for each country
181			$.each(countries, function(i, c) {
182				// open the list item
183				tmp += '<li class="country ' + className + '" data-country-code="' + c.iso2 + '">';
184				// add the flag
185				tmp += '<div class="flag ' + c.iso2 + '"></div>';
186                // and the country name
187                var cc = settings.countries_data.find(function (x) { return x.Abbr.toLowerCase() == c.iso2 }).PhoneCode;
188				tmp += '<span class="country-name">' + c.name + ' +' + cc + '</span>';
189				// close the list item
190				tmp += '</li>';
191			});
192			this.countryList.append(tmp);
193		},
194		// set the initial state of the input value and the selected flag
195		_setInitialState: function() {
196			var flagIsSet = false;
197			// If the input is pre-populated, then just update the selected flag
198			if (this.countryInput.val()) {
199				flagIsSet = this._updateFlagFromInputVal();
200			}
201			// If the country code input is pre-populated, update the name and the selected flag
202			var selectedCode = this.countryCodeInput.val();
203			if (selectedCode) {
204				this.selectCountry(selectedCode);
205			}
206			if (!flagIsSet) {
207				// flag is not set, so set to the default country
208				var defaultCountry;
209				// check the defaultCountry option, else fall back to the first in the list
210				if (this.options.defaultCountry) {
211					defaultCountry = this._getCountryData(this.options.defaultCountry, false);
212					// Did we not find the requested default country?
213					if (!defaultCountry) {
214						defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0];
215					}
216				} else {
217					defaultCountry = this.preferredCountries.length ? this.preferredCountries[0] : this.countries[0];
218				}
219				this.defaultCountry = defaultCountry.iso2;
220			}
221		},
222		// initialise the main event listeners: input keyup, and click selected flag
223		_initListeners: function() {
224			var that = this;
225			// Update flag on keyup.
226			// Use keyup instead of keypress because we want to update on backspace
227			// and instead of keydown because the value hasn't updated when that
228			// event is fired.
229			// NOTE: better to have this one listener all the time instead of
230			// starting it on focus and stopping it on blur, because then you've
231			// got two listeners (focus and blur)
232			this.countryInput.on("keyup" + this.ns, function() {
233				that._updateFlagFromInputVal();
234			});
235			// toggle country dropdown on click
236			var selectedFlag = this.selectedFlagInner.parent();
237			selectedFlag.on("click" + this.ns, function(e) {
238				// only intercept this event if we're opening the dropdown
239				// else let it bubble up to the top ("click-off-to-close" listener)
240				// we cannot just stopPropagation as it may be needed to close another instance
241				if (that.countryList.hasClass("hide") && !that.countryInput.prop("disabled")) {
242					that._showDropdown();
243				}
244			});
245			// Despite above note, added blur to ensure partially spelled country
246			// with correctly chosen flag is spelled out on blur. Also, correctly
247			// selects flag when field is autofilled
248			this.countryInput.on("blur" + this.ns, function() {
249				if (that.countryInput.val() != that.getSelectedCountryData().name) {
250					that.setCountry(that.countryInput.val());
251				}
252				that.countryInput.val(that.getSelectedCountryData().name);
253			});
254
255			$("div.flag-dropdown li").click(function () { set_code_phone_manager.set_item_b
vendor: 14,569 bytes, lines 255-607
255y_abbr($(this).attr('data-country-code')) });
256		},
257		_initAutoCountry: function() {
258			if (this.options.initialCountry === "auto") {
259				this._loadAutoCountry();
260			} else {
261				this.selectCountry(this.defaultCountry);
262				this.autoCountryDeferred.resolve();
263			}
264		},
265		// perform the geo ip lookup
266		_loadAutoCountry: function() {
267			var that = this;
268
269			// 3 options:
270			// 1) already loaded (we're done)
271			// 2) not already started loading (start)
272			// 3) already started loading (do nothing - just wait for loading callback to fire)
273			if ($.fn[pluginName].autoCountry) {
274				this.handleAutoCountry();
275			} else if (!$.fn[pluginName].startedLoadingAutoCountry) {
276				// don't do this twice!
277				$.fn[pluginName].startedLoadingAutoCountry = true;
278
279				if (typeof this.options.geoIpLookup === 'function') {
280					this.options.geoIpLookup(function(countryCode) {
281						$.fn[pluginName].autoCountry = countryCode.toLowerCase();
282						// tell all instances the auto country is ready
283						// TODO: this should just be the current instances
284						// UPDATE: use setTimeout in case their geoIpLookup function calls this callback straight away (e.g. if they have already done the geo ip lookup somewhere else). Using setTimeout means that the current thread of execution will finish before executing this, which allows the plugin to finish initialising.
285						setTimeout(function() {
286							$(".country-select input").countrySelect("handleAutoCountry");
287						});
288					});
289				}
290			}
291		},
292		// Focus input and put the cursor at the end
293		_focus: function() {
294			this.countryInput.focus();
295			var input = this.countryInput[0];
296			// works for Chrome, FF, Safari, IE9+
297			if (input.setSelectionRange) {
298				var len = this.countryInput.val().length;
299				input.setSelectionRange(len, len);
300			}
301		},
302		// Show the dropdown
303		_showDropdown: function() {
304			this._setDropdownPosition();
305			// update highlighting and scroll to active list item
306			var activeListItem = this.countryList.children(".active");
307			this._highlightListItem(activeListItem);
308			// show it
309			this.countryList.removeClass("hide");
310			this._scrollTo(activeListItem);
311			// bind all the dropdown-related listeners: mouseover, click, click-off, keydown
312			this._bindDropdownListeners();
313			// update the arrow
314			this.selectedFlagInner.children(".arrow").addClass("up");
315		},
316		// decide where to position dropdown (depends on position within viewport, and scroll)
317		_setDropdownPosition: function() {
318			var inputTop = this.countryInput.offset().top, windowTop = $(window).scrollTop(),
319			dropdownFitsBelow = inputTop + this.countryInput.outerHeight() + this.dropdownHeight < windowTop + $(window).height(), dropdownFitsAbove = inputTop - this.dropdownHeight > windowTop;
320			// dropdownHeight - 1 for border
321			var cssTop = !dropdownFitsBelow && dropdownFitsAbove ? "-" + (this.dropdownHeight - 1) + "px" : "";
322			this.countryList.css("top", cssTop);
323		},
324		// we only bind dropdown listeners when the dropdown is open
325		_bindDropdownListeners: function() {
326			var that = this;
327			// when mouse over a list item, just highlight that one
328			// we add the class "highlight", so if they hit "enter" we know which one to select
329			this.countryList.on("mouseover" + this.ns, ".country", function(e) {
330				that._highlightListItem($(this));
331			});
332			// listen for country selection
333			this.countryList.on("click" + this.ns, ".country", function(e) {
334				that._selectListItem($(this));
335			});
336			// click off to close
337			// (except when this initial opening click is bubbling up)
338			// we cannot just stopPropagation as it may be needed to close another instance
339			var isOpening = true;
340			$("html").on("click" + this.ns, function(e) {
341				if (!isOpening) {
342					that._closeDropdown();
343				}
344				isOpening = false;
345			});
346			// Listen for up/down scrolling, enter to select, or letters to jump to country name.
347			// Use keydown as keypress doesn't fire for non-char keys and we want to catch if they
348			// just hit down and hold it to scroll down (no keyup event).
349			// Listen on the document because that's where key events are triggered if no input has focus
350			$(document).on("keydown" + this.ns, function(e) {
351				// prevent down key from scrolling the whole page,
352				// and enter key from submitting a form etc
353				e.preventDefault();
354				if (e.which == keys.UP || e.which == keys.DOWN) {
355					// up and down to navigate
356					that._handleUpDownKey(e.which);
357				} else if (e.which == keys.ENTER) {
358					// enter to select
359					that._handleEnterKey();
360				} else if (e.which == keys.ESC) {
361					// esc to close
362					that._closeDropdown();
363				} else if (e.which >= keys.A && e.which <= keys.Z) {
364					// upper case letters (note: keyup/keydown only return upper case letters)
365					// cycle through countries beginning with that letter
366					that._handleLetterKey(e.which);
367				}
368			});
369		},
370		// Highlight the next/prev item in the list (and ensure it is visible)
371		_handleUpDownKey: function(key) {
372			var current = this.countryList.children(".highlight").first();
373			var next = key == keys.UP ? current.prev() : current.next();
374			if (next.length) {
375				// skip the divider
376				if (next.hasClass("divider")) {
377					next = key == keys.UP ? next.prev() : next.next();
378				}
379				this._highlightListItem(next);
380				this._scrollTo(next);
381			}
382		},
383		// select the currently highlighted item
384		_handleEnterKey: function() {
385			var currentCountry = this.countryList.children(".highlight").first();
386			if (currentCountry.length) {
387				this._selectListItem(currentCountry);
388			}
389		},
390		// Iterate through the countries starting with the given letter
391		_handleLetterKey: function(key) {
392			var letter = String.fromCharCode(key);
393			// filter out the countries beginning with that letter
394			var countries = this.countryListItems.filter(function() {
395				return $(this).text().charAt(0) == letter && !$(this).hasClass("preferred");
396			});
397			if (countries.length) {
398				// if one is already highlighted, then we want the next one
399				var highlightedCountry = countries.filter(".highlight").first(), listItem;
400				// if the next country in the list also starts with that letter
401				if (highlightedCountry && highlightedCountry.next() && highlightedCountry.next().text().charAt(0) == letter) {
402					listItem = highlightedCountry.next();
403				} else {
404					listItem = countries.first();
405				}
406				// update highlighting and scroll
407				this._highlightListItem(listItem);
408				this._scrollTo(listItem);
409			}
410		},
411		// Update the selected flag using the input's current value
412		_updateFlagFromInputVal: function() {
413			var that = this;
414			// try and extract valid country from input
415			var value = this.countryInput.val().replace(/(?=[() ])/g, '\\');
416			if (value) {
417				var countryCodes = [];
418				var matcher = new RegExp("^"+value, "i");
419				for (var i = 0; i < this.countries.length; i++) {
420					if (this.countries[i].name.match(matcher)) {
421						countryCodes.push(this.countries[i].iso2);
422					}
423				}
424				// Check if one of the matching countries is already selected
425				var alreadySelected = false;
426				$.each(countryCodes, function(i, c) {
427					if (that.selectedFlagInner.hasClass(c)) {
428						alreadySelected = true;
429					}
430				});
431				if (!alreadySelected) {
432					this._selectFlag(countryCodes[0]);
433					this.countryCodeInput.val(countryCodes[0]).trigger("change");
434				}
435				// Matching country found
436				return true;
437			}
438			// No match found
439			return false;
440		},
441		// remove highlighting from other list items and highlight the given item
442		_highlightListItem: function(listItem) {
443			this.countryListItems.removeClass("highlight");
444			listItem.addClass("highlight");
445		},
446		// find the country data for the given country code
447		// the ignoreOnlyCountriesOption is only used during init() while parsing the onlyCountries array
448		_getCountryData: function(countryCode, ignoreOnlyCountriesOption) {
449			var countryList = ignoreOnlyCountriesOption ? allCountries : this.countries;
450			for (var i = 0; i < countryList.length; i++) {
451				if (countryList[i].iso2 == countryCode) {
452					return countryList[i];
453				}
454			}
455			return null;
456		},
457		// update the selected flag and the active list item
458		_selectFlag: function(countryCode) {
459			if (! countryCode) {
460				return false;
461			}
462			this.selectedFlagInner.attr("class", "flag " + countryCode);
463			// update the title attribute
464			var countryData = this._getCountryData(countryCode);
465			this.selectedFlagInner.parent().attr("title", countryData.name);
466			// update the active list item
467			var listItem = this.countryListItems.children(".flag." + countryCode).first().parent();
468			this.countryListItems.removeClass("active");
469			listItem.addClass("active");
470		},
471		// called when the user selects a list item from the dropdown
472		_selectListItem: function(listItem) {
473			// update selected flag and active list item
474			var countryCode = listItem.attr("data-country-code");
475			this._selectFlag(countryCode);
476			this._closeDropdown();
477			// update input value
478			this._updateName(countryCode);
479			this.countryInput.trigger("change");
480			this.countryCodeInput.trigger("change");
481			// focus the input
482			this._focus();
483		},
484		// close the dropdown and unbind any listeners
485		_closeDropdown: function() {
486			this.countryList.addClass("hide");
487			// update the arrow
488			this.selectedFlagInner.children(".arrow").removeClass("up");
489			// unbind event listeners
490			$(document).off("keydown" + this.ns);
491			$("html").off("click" + this.ns);
492			// unbind both hover and click listeners
493			this.countryList.off(this.ns);
494		},
495		// check if an element is visible within its container, else scroll until it is
496		_scrollTo: function(element) {
497			if (!element || !element.offset()) {
498				return;
499			}
500			var container = this.countryList, containerHeight = container.height(), containerTop = container.offset().top, containerBottom = containerTop + containerHeight, elementHeight = element.outerHeight(), elementTop = element.offset().top, elementBottom = elementTop + elementHeight, newScrollTop = elementTop - containerTop + container.scrollTop();
501			if (elementTop < containerTop) {
502				// scroll up
503				container.scrollTop(newScrollTop);
504			} else if (elementBottom > containerBottom) {
505				// scroll down
506				var heightDifference = containerHeight - elementHeight;
507				container.scrollTop(newScrollTop - heightDifference);
508			}
509		},
510		// Replace any existing country name with the new one
511		_updateName: function(countryCode) {
512			this.countryCodeInput.val(countryCode).trigger("change");
513			this.countryInput.val(this._getCountryData(countryCode).name);
514		},
515		/********************
516		 *  PUBLIC METHODS
517		 ********************/
518		// this is called when the geoip call returns
519		handleAutoCountry: function() {
520			if (this.options.initialCountry === "auto") {
521				// we must set this even if there is an initial val in the input: in case the initial val is invalid and they delete it - they should see their auto country
522				this.defaultCountry = $.fn[pluginName].autoCountry;
523				// if there's no initial value in the input, then update the flag
524				if (!this.countryInput.val()) {
525					this.selectCountry(this.defaultCountry);
526				}
527				this.autoCountryDeferred.resolve();
528			}
529		},
530		// get the country data for the currently selected flag
531		getSelectedCountryData: function() {
532			// rely on the fact that we only set 2 classes on the selected flag element:
533			// the first is "flag" and the second is the 2-char country code
534			var countryCode = this.selectedFlagInner.attr("class").split(" ")[1];
535			return this._getCountryData(countryCode);
536		},
537		// update the selected flag
538		selectCountry: function(countryCode) {
539			countryCode = countryCode.toLowerCase();
540			// check if already selected
541			if (!this.selectedFlagInner.hasClass(countryCode)) {
542				this._selectFlag(countryCode);
543				this._updateName(countryCode);
544			}
545		},
546		// set the input value and update the flag
547		setCountry: function(country) {
548			this.countryInput.val(country);
549			this._updateFlagFromInputVal();
550		},
551		// remove plugin
552		destroy: function() {
553			// stop listeners
554			this.countryInput.off(this.ns);
555			this.selectedFlagInner.parent().off(this.ns);
556			// remove markup
557			var container = this.countryInput.parent();
558			container.before(this.countryInput).remove();
559		}
560	};
561	// adapted to allow public functions
562	// using https://github.com/jquery-boilerplate/jquery-boilerplate/wiki/Extending-jQuery-Boilerplate
563	$.fn[pluginName] = function(options) {
564		var args = arguments;
565		// Is the first parameter an object (options), or was omitted,
566		// instantiate a new instance of the plugin.
567		if (options === undefined || typeof options === "object") {
568			return this.each(function() {
569				if (!$.data(this, "plugin_" + pluginName)) {
570					$.data(this, "plugin_" + pluginName, new Plugin(this, options));
571				}
572			});
573		} else if (typeof options === "string" && options[0] !== "_" && options !== "init") {
574			// If the first parameter is a string and it doesn't start
575			// with an underscore or "contains" the `init`-function,
576			// treat this as a call to a public method.
577			// Cache the method call to make it possible to return a value
578			var returns;
579			this.each(function() {
580				var instance = $.data(this, "plugin_" + pluginName);
581				// Tests that there's already a plugin-instance
582				// and checks that the requested public method exists
583				if (instance instanceof Plugin && typeof instance[options] === "function") {
584					// Call the method of our plugin instance,
585					// and pass it the supplied arguments.
586					returns = instance[options].apply(instance, Array.prototype.slice.call(args, 1));
587				}
588				// Allow instances to be destroyed via the 'destroy' method
589				if (options === "destroy") {
590					$.data(this, "plugin_" + pluginName, null);
591				}
592			});
593			// If the earlier cached method gives a value back return the value,
594			// otherwise return this to preserve chainability.
595			return returns !== undefined ? returns : this;
596		}
597	};
598	/********************
599   *  STATIC METHODS
600   ********************/
601	// get the country data object
602	$.fn[pluginName].getCountryData = function() {
603		return allCountries;
604	};
605	// set the country data object
606	$.fn[pluginName].setCountryData = function(obj) {
607		allCountries = obj;
608	};
609	// Tell JSHint to ignore this warning: "character may get silently deleted by one or more browsers"
610	// jshint -W100
611	// Array of country objects for the flag dropdown.
612	// Each contains a name and country code (ISO 3166-1 alpha-2).
613	//
614	// Note: using single char property names to keep filesize down
615	// n = name
616	// i = iso2 (2-char country code)
617	var allCountries = $.each([ {
618		n: "Afghanistan (‫افغانستان‬‎)",
619		i: "af"
620	}, {
621		n: "Åland Islands (Åland)",
622		i: "ax"
623	}, {
624		n: "Albania (Shqipëri)",
625		i: "al"
626	}, {
627		n: "Algeria (‫الجزائر‬‎)",
628		i: "dz"
629	}, {
630		n: "American Samoa",
631		i: "as"
632	}, {
633		n: "Andorra",
634		i: "ad"
635	}, {
636		n: "Angola",
637		i: "ao"
638	}, {
639		n: "Anguilla",
640		i: "ai"
641	}, {
642		n: "Antigua and Barbuda",
643		i: "ag"
644	}, {
645		n: "Argentina",
646		i: "ar"
647	}, {
648		n: "Armenia (Հայաստան)",
649		i: "am"
650	}, {
651		n: "Aruba",
652		i: "aw"
653	}, {
654		n: "Australia",
655		i: "au"
656	}, {
657		n: "Austria (Österreich)",
658		i: "at"
659	}, {
660		n: "Azerbaijan (Azərbaycan)",
661		i: "az"
662	}, {
663		n: "Bahamas",
664		i: "bs"
665	}, {
666		n: "Bahrain (‫البحرين‬‎)",
667		i: "bh"
668	}, {
669		n: "Bangladesh (বাংলাদেশ)",
670		i: "bd"
671	}, {
672		n: "Barbados",
673		i: "bb"
674	}, {
675		n: "Belarus (Беларусь)",
676		i: "by"
677	}, {
678		n: "Belgium (België)",
679		i: "be"
680	}, {
681		n: "Belize",
682		i: "bz"
683	}, {
684		n: "Benin (Bénin)",
685		i: "bj"
686	}, {
687		n: "Bermuda",
688		i: "bm"
689	}, {
690		n: "Bhutan (འབྲུག)",
691		i: "bt"
692	}, {
693		n: "Bolivia",
694		i: "bo"
695	}, {
696		n: "Bosnia and Herzegovina (Босна и Херцеговина)",
697		i: "ba"
698	}, {
699		n: "Botswana",
700		i: "bw"
701	}, {
702		n: "Brazil (Brasil)",
703		i: "br"
704	}, {
705		n: "British Indian Ocean Territory",
706		i: "io"
707	}, {
708		n: "British Virgin Islands",
709		i: "vg"
710	}, {
711		n: "Brunei",
712		i: "bn"
713	}, {
714		n: "Bulgaria (България)",
715		i: "bg"
716	}, {
717		n: "Burkina Faso",
718		i: "bf"
719	}, {
720		n: "Burundi (Uburundi)",
721		i: "bi"
722	}, {
723		n: "Cambodia (កម្ពុជា)",
724		i: "kh"
725	}, {
726		n: "Cameroon (Cameroun)",
727		i: "cm"
728	}, {
729		n: "Canada",
730		i: "ca"
731	}, {
732		n: "Cape Verde (Kabu Verdi)",
733		i: "cv"
734	}, {
735		n: "Caribbean Netherlands",
736		i: "bq"
737	}, {
738		n: "Cayman Islands",
739		i: "ky"
740	}, {
741		n: "Central African Republic (République Centrafricaine)",
742		i: "cf"
743	}, {
744		n: "Chad (Tchad)",
745		i: "td"
746	}, {
747		n: "Chile",
748		i: "cl"
749	}, {
750		n: "China (中国)",
751		i: "cn"
752	}, {
753		n: "Christmas Island",
754		i: "cx"
755	}, {
756		n: "Cocos (Keeling) Islands (Kepulauan Cocos (Keeling))",
757		i: "cc"
758	}, {
759		n: "Colombia",
760		i: "co"
761	}, {
762		n: "Comoros (‫جزر القمر‬‎)",
763		i: "km"
764	}, {
765		n: "Congo (DRC) (Jamhuri ya Kidemokrasia ya Kongo)",
766		i: "cd"
767	}, {
768		n: "Congo (Republic) (Congo-Brazzaville)",
769		i: "cg"
770	}, {
771		n: "Cook Islands",
772		i: "ck"
773	}, {
774		n: "Costa Rica",
775		i: "cr"
776	}, {
777		n: "Côte d’Ivoire",
778		i: "ci"
779	}, {
780		n: "Croatia (Hrvatska)",
781		i: "hr"
782	}, {
783		n: "Cuba",
784		i: "cu"
785	}, {
786		n: "Curaçao",
787		i: "cw"
788	}, {
789		n: "Cyprus (Κύπρος)",
790		i: "cy"
791	}, {
792		n: "Czech Republic (Česká republika)",
793		i: "cz"
794	}, {
795		n: "Denmark (Danmark)",
796		i: "dk"
797	}, {
798		n: "Djibouti",
799		i: "dj"
800	}, {
801		n: "Dominica",
802		i: "dm"
803	}, {
804		n: "Dominican Republic (República Dominicana)",
805		i: "do"
806	}, {
807		n: "Ecuador",
808		i: "ec"
809	}, {
810		n: "Egypt (‫مصر‬‎)",
811		i: "eg"
812	}, {
813		n: "El Salvador",
814		i: "sv"
815	}, {
816		n: "Equatorial Guinea (Guinea Ecuatorial)",
817		i: "gq"
818	}, {
819		n: "Eritrea",
820		i: "er"
821	}, {
822		n: "Estonia (Eesti)",
823		i: "ee"
824	}, {
825		n: "Ethiopia",
826		i: "et"
827	}, {
828		n: "Falkland Islands (Islas Malvinas)",
829		i: "fk"
830	}, {
831		n: "Faroe Islands (Føroyar)",
832		i: "fo"
833	}, {
834		n: "Fiji",
835		i: "fj"
836	}, {
837		n: "Finland (Suomi)",
838		i: "fi"
839	}, {
840		n: "France",
841		i: "fr"
842	}, {
843		n: "French Guiana (Guyane française)",
844		i: "gf"
845	}, {
846		n: "French Polynesia (Polynésie française)",
847		i: "pf"
848	}, {
849		n: "Gabon",
850		i: "ga"
851	}, {
852		n: "Gambia",
853		i: "gm"
854	}, {
855		n: "Georgia (საქართველო)",
856		i: "ge"
857	}, {
858		n: "Germany (Deutschland)",
859		i: "de"
860	}, {
861		n: "Ghana (Gaana)",
862		i: "gh"
863	}, {
864		n: "Gibraltar",
865		i: "gi"
866	}, {
867		n: "Greece (Ελλάδα)",
868		i: "gr"
869	}, {
870		n: "Greenland (Kalaallit Nunaat)",
871		i: "gl"
872	}, {
873		n: "Grenada",
874		i: "gd"
875	}, {
876		n: "Guadeloupe",
877		i: "gp"
878	}, {
879		n: "Guam",
880		i: "gu"
881	}, {
882		n: "Guatemala",
883		i: "gt"
884	}, {
885		n: "Guernsey",
886		i: "gg"
887	}, {
888		n: "Guinea (Guinée)",
889		i: "gn"
890	}, {
891		n: "Guinea-Bissau (Guiné Bissau)",
892		i: "gw"
893	}, {
894		n: "Guyana",
895		i: "gy"
896	}, {
897		n: "Haiti",
898		i: "ht"
899	}, {
900		n: "Honduras",
901		i: "hn"
902	}, {
903		n: "Hong Kong (香港)",
904		i: "hk"
905	}, {
906		n: "Hungary (Magyarország)",
907		i: "hu"
908	}, {
909		n: "Iceland (Ísland)",
910		i: "is"
911	}, {
912		n: "India (भारत)",
913		i: "in"
914	}, {
915		n: "Indonesia",
916		i: "id"
917	}, {
918		n: "Iran (‫ایران‬‎)",
919		i: "ir"
920	}, {
921		n: "Iraq (‫العراق‬‎)",
922		i: "iq"
923	}, {
924		n: "Ireland",
925		i: "ie"
926	}, {
927		n: "Isle of Man",
928		i: "im"
929	}, {
930		n: "Israel (‫ישראל‬‎)",
931		i: "il"
932	}, {
933		n: "Italy (Italia)",
934		i: "it"
935	}, {
936		n: "Jamaica",
937		i: "jm"
938	}, {
939		n: "Japan (日本)",
940		i: "jp"
941	}, {
942		n: "Jersey",
943		i: "je"
944	}, {
945		n: "Jordan (‫الأردن‬‎)",
946		i: "jo"
947	}, {
948		n: "Kazakhstan (Казахстан)",
949		i: "kz"
950	}, {
951		n: "Kenya",
952		i: "ke"
953	}, {
954		n: "Kiribati",
955		i: "ki"
956	}, {
957		n: "Kosovo (Kosovë)",
958		i: "xk"
959	}, {
960		n: "Kuwait (‫الكويت‬‎)",
961		i: "kw"
962	}, {
963		n: "Kyrgyzstan (Кыргызстан)",
964		i: "kg"
965	}, {
966		n: "Laos (ລາວ)",
967		i: "la"
968	}, {
969		n: "Latvia (Latvija)",
970		i: "lv"
971	}, {
972		n: "Lebanon (‫لبنان‬‎)",
973		i: "lb"
974	}, {
975		n: "Lesotho",
976		i: "ls"
977	}, {
978		n: "Liberia",
979		i: "lr"
980	}, {
981		n: "Libya (‫ليبيا‬‎)",
982		i: "ly"
983	}, {
984		n: "Liechtenstein",
985		i: "li"
986	}, {
987		n: "Lithuania (Lietuva)",
988		i: "lt"
989	}, {
990		n: "Luxembourg",
991		i: "lu"
992	}, {
993		n: "Macau (澳門)",
994		i: "mo"
995	}, {
996		n: "Macedonia (FYROM) (Македонија)",
997		i: "mk"
998	}, {
999		n: "Madagascar (Madagasikara)",
1000		i: "mg"
1001	}, {
1002		n: "Malawi",
1003		i: "mw"
1004	}, {
1005		n: "Malaysia",
1006		i: "my"
1007	}, {
1008		n: "Maldives",
1009		i: "mv"
1010	}, {
1011		n: "Mali",
1012		i: "ml"
1013	}, {
1014		n: "Malta",
1015		i: "mt"
1016	}, {
1017		n: "Marshall Islands",
1018		i: "mh"
1019	}, {
1020		n: "Martinique",
1021		i: "mq"
1022	}, {
1023		n: "Mauritania (‫موريتانيا‬‎)",
1024		i: "mr"
1025	}, {
1026		n: "Mauritius (Moris)",
1027		i: "mu"
1028	}, {
1029		n: "Mayotte",
1030		i: "yt"
1031	}, {
1032		n: "Mexico (México)",
1033		i: "mx"
1034	}, {
1035		n: "Micronesia",
1036		i: "fm"
1037	}, {
1038		n: "Moldova (Republica Moldova)",
1039		i: "md"
1040	}, {
1041		n: "Monaco",
1042		i: "mc"
1043	}, {
1044		n: "Mongolia (Монгол)",
1045		i: "mn"
1046	}, {
1047		n: "Montenegro (Crna Gora)",
1048		i: "me"
1049	}, {
1050		n: "Montserrat",
1051		i: "ms"
1052	}, {
1053		n: "Morocco (‫المغرب‬‎)",
1054		i: "ma"
1055	}, {
1056		n: "Mozambique (Moçambique)",
1057		i: "mz"
1058	}, {
1059		n: "Myanmar (Burma) (မြန်မာ)",
1060		i: "mm"
1061	}, {
1062		n: "Namibia (Namibië)",
1063		i: "na"
1064	}, {
1065		n: "Nauru",
1066		i: "nr"
1067	}, {
1068		n: "Nepal (नेपाल)",
1069		i: "np"
1070	}, {
1071		n: "Netherlands (Nederland)",
1072		i: "nl"
1073	}, {
1074		n: "New Caledonia (Nouvelle-Calédonie)",
1075		i: "nc"
1076	}, {
1077		n: "New Zealand",
1078		i: "nz"
1079	}, {
1080		n: "Nicaragua",
1081		i: "ni"
1082	}, {
1083		n: "Niger (Nijar)",
1084		i: "ne"
1085	}, {
1086		n: "Nigeria",
1087		i: "ng"
1088	}, {
1089		n: "Niue",
1090		i: "nu"
1091	}, {
1092		n: "Norfolk Island",
1093		i: "nf"
1094	}, {
1095		n: "North Korea (조선 민주주의 인민 공화국)",
1096		i: "kp"
1097	}, {
1098		n: "Northern Mariana Islands",
1099		i: "mp"
1100	}, {
1101		n: "Norway (Norge)",
1102		i: "no"
1103	}, {
1104		n: "Oman (‫عُمان‬‎)",
1105		i: "om"
1106	}, {
1107		n: "Pakistan (‫پاکستان‬‎)",
1108		i: "pk"
1109	}, {
1110		n: "Palau",
1111		i: "pw"
1112	}, {
1113		n: "Palestine (‫فلسطين‬‎)",
1114		i: "ps"
1115	}, {
1116		n: "Panama (Panamá)",
1117		i: "pa"
1118	}, {
1119		n: "Papua New Guinea",
1120		i: "pg"
1121	}, {
1122		n: "Paraguay",
1123		i: "py"
1124	}, {
1125		n: "Peru (Perú)",
1126		i: "pe"
1127	}, {
1128		n: "Philippines",
1129		i: "ph"
1130	}, {
1131		n: "Pitcairn Islands",
1132		i: "pn"
1133	}, {
1134		n: "Poland (Polska)",
1135		i: "pl"
1136	}, {
1137		n: "Portugal",
1138		i: "pt"
1139	}, {
1140		n: "Puerto Rico",
1141		i: "pr"
1142	}, {
1143		n: "Qatar (‫قطر‬‎)",
1144		i: "qa"
1145	}, {
1146		n: "Réunion (La Réunion)",
1147		i: "re"
1148	}, {
1149		n: "Romania (România)",
1150		i: "ro"
1151	}, {
1152		n: "Russia (Россия)",
1153		i: "ru"
1154	}, {
1155		n: "Rwanda",
1156		i: "rw"
1157	}, {
1158		n: "Saint Barthélemy (Saint-Barthélemy)",
1159		i: "bl"
1160	}, {
1161		n: "Saint Helena",
1162		i: "sh"
1163	}, {
1164		n: "Saint Kitts and Nevis",
1165		i: "kn"
1166	}, {
1167		n: "Saint Lucia",
1168		i: "lc"
1169	}, {
1170		n: "Saint Martin (Saint-Martin (partie française))",
1171		i: "mf"
1172	}, {
1173		n: "Saint Pierre and Miquelon (Saint-Pierre-et-Miquelon)",
1174		i: "pm"
1175	}, {
1176		n: "Saint Vincent and the Grenadines",
1177		i: "vc"
1178	}, {
1179		n: "Samoa",
1180		i: "ws"
1181	}, {
1182		n: "San Marino",
1183		i: "sm"
1184	}, {
1185		n: "São Tomé and Príncipe (São Tomé e Príncipe)",
1186		i: "st"
1187	}, {
1188		n: "Saudi Arabia (‫المملكة العربية السعودية‬‎)",
1189		i: "sa"
1190	}, {
1191		n: "Senegal (Sénégal)",
1192		i: "sn"
1193	}, {
1194		n: "Serbia (Србија)",
1195		i: "rs"
1196	}, {
1197		n: "Seychelles",
1198		i: "sc"
1199	}, {
1200		n: "Sierra Leone",
1201		i: "sl"
1202	}, {
1203		n: "Singapore",
1204		i: "sg"
1205	}, {
1206		n: "Sint Maarten",
1207		i: "sx"
1208	}, {
1209		n: "Slovakia (Slovensko)",
1210		i: "sk"
1211	}, {
1212		n: "Slovenia (Slovenija)",
1213		i: "si"
1214	}, {
1215		n: "Solomon Islands",
1216		i: "sb"
1217	}, {
1218		n: "Somalia (Soomaaliya)",
1219		i: "so"
1220	}, {
1221		n: "South Africa",
1222		i: "za"
1223	}, {
1224		n: "South Georgia & South Sandwich Islands",
1225		i: "gs"
1226	}, {
1227		n: "South Korea (대한민국)",
1228		i: "kr"
1229	}, {
1230		n: "South Sudan (‫جنوب السودان‬‎)",
1231		i: "ss"
1232	}, {
1233		n: "Spain (España)",
1234		i: "es"
1235	}, {
1236		n: "Sri Lanka (ශ්‍රී ලංකාව)",
1237		i: "lk"
1238	}, {
1239		n: "Sudan (‫السودان‬‎)",
1240		i: "sd"
1241	}, {
1242		n: "Suriname",
1243		i: "sr"
1244	}, {
1245		n: "Svalbard and Jan Mayen (Svalbard og Jan Mayen)",
1246		i: "sj"
1247	}, {
1248		n: "Swaziland",
1249		i: "sz"
1250	}, {
1251		n: "Sweden (Sverige)",
1252		i: "se"
1253	}, {
1254		n: "Switzerland (Schweiz)",
1255		i: "ch"
1256	}, {
1257		n: "Syria (‫سوريا‬‎)",
1258		i: "sy"
1259	}, {
1260		n: "Taiwan (台灣)",
1261		i: "tw"
1262	}, {
1263		n: "Tajikistan",
1264		i: "tj"
1265	}, {
1266		n: "Tanzania",
1267		i: "tz"
1268	}, {
1269		n: "Thailand (ไทย)",
1270		i: "th"
1271	}, {
1272		n: "Timor-Leste",
1273		i: "tl"
1274	}, {
1275		n: "Togo",
1276		i: "tg"
1277	}, {
1278		n: "Tokelau",
1279		i: "tk"
1280	}, {
1281		n: "Tonga",
1282		i: "to"
1283	}, {
1284		n: "Trinidad and Tobago",
1285		i: "tt"
1286	}, {
1287		n: "Tunisia (‫تونس‬‎)",
1288		i: "tn"
1289	}, {
1290		n: "Turkey (Türkiye)",
1291		i: "tr"
1292	}, {
1293		n: "Turkmenistan",
1294		i: "tm"
1295	}, {
1296		n: "Turks and Caicos Islands",
1297		i: "tc"
1298	}, {
1299		n: "Tuvalu",
1300		i: "tv"
1301	}, {
1302		n: "Uganda",
1303		i: "ug"
1304	}, {
1305		n: "Ukraine (Україна)",
1306		i: "ua"
1307	}, {
1308		n: "United Arab Emirates (‫الإمارات العربية المتحدة‬‎)",
1309		i: "ae"
1310	}, {
1311		n: "United Kingdom",
1312		i: "gb"
1313	}, {
1314		n: "United States",
1315		i: "us"
1316	}, {
1317		n: "U.S. Minor Outlying Islands",
1318		i: "um"
1319	}, {
1320		n: "U.S. Virgin Islands",
1321		i: "vi"
1322	}, {
1323		n: "Uruguay",
1324		i: "uy"
1325	}, {
1326		n: "Uzbekistan (Oʻzbekiston)",
1327		i: "uz"
1328	}, {
1329		n: "Vanuatu",
1330		i: "vu"
1331	}, {
1332		n: "Vatican City (Città del Vaticano)",
1333		i: "va"
1334	}, {
1335		n: "Venezuela",
1336		i: "ve"
1337	}, {
1338		n: "Vietnam (Việt Nam)",
1339		i: "vn"
1340	}, {
1341		n: "Wallis and Futuna",
1342		i: "wf"
1343	}, {
1344		n: "Western Sahara (‫الصحراء الغربية‬‎)",
1345		i: "eh"
1346	}, {
1347		n: "Yemen (‫اليمن‬‎)",
1348		i: "ye"
1349	}, {
1350		n: "Zambia",
1351		i: "zm"
1352	}, {
1353		n: "Zimbabwe",
1354		i: "zw"
1355	} ], function(i, c) {
1356		c.name = c.n;
1357		c.iso2 = c.i;
1358		delete c.n;
1359		delete c.i;
1360	});
1361});

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.