tldts-icann
Version:
Library to work against complex domain names, subdomains and URIs. Only contains ICANN section.
566 lines (556 loc) • 131 kB
JavaScript
'use strict';
/**
* Check if `vhost` is a valid suffix of `hostname` (top-domain)
*
* It means that `vhost` needs to be a suffix of `hostname` and we then need to
* make sure that: either they are equal, or the character preceding `vhost` in
* `hostname` is a '.' (it should not be a partial label).
*
* * hostname = 'not.evil.com' and vhost = 'vil.com' => not ok
* * hostname = 'not.evil.com' and vhost = 'evil.com' => ok
* * hostname = 'not.evil.com' and vhost = 'not.evil.com' => ok
*/
function shareSameDomainSuffix(hostname, vhost) {
if (hostname.endsWith(vhost)) {
return (hostname.length === vhost.length ||
hostname[hostname.length - vhost.length - 1] === '.');
}
return false;
}
/**
* Given a hostname and its public suffix, extract the general domain.
*/
function extractDomainWithSuffix(hostname, publicSuffix) {
// Locate the index of the last '.' in the part of the `hostname` preceding
// the public suffix.
//
// examples:
// 1. not.evil.co.uk => evil.co.uk
// ^ ^
// | | start of public suffix
// | index of the last dot
//
// 2. example.co.uk => example.co.uk
// ^ ^
// | | start of public suffix
// |
// | (-1) no dot found before the public suffix
const publicSuffixIndex = hostname.length - publicSuffix.length - 2;
const lastDotBeforeSuffixIndex = hostname.lastIndexOf('.', publicSuffixIndex);
// No '.' found, then `hostname` is the general domain (no sub-domain)
if (lastDotBeforeSuffixIndex === -1) {
return hostname;
}
// Extract the part between the last '.'
return hostname.slice(lastDotBeforeSuffixIndex + 1);
}
/**
* Detects the domain based on rules and upon and a host string
*/
function getDomain$1(suffix, hostname, options) {
// Check if `hostname` ends with a member of `validHosts`.
if (options.validHosts !== null) {
const validHosts = options.validHosts;
for (const vhost of validHosts) {
if ( /*@__INLINE__*/shareSameDomainSuffix(hostname, vhost)) {
return vhost;
}
}
}
let numberOfLeadingDots = 0;
if (hostname.startsWith('.')) {
while (numberOfLeadingDots < hostname.length &&
hostname[numberOfLeadingDots] === '.') {
numberOfLeadingDots += 1;
}
}
// If `hostname` is a valid public suffix, then there is no domain to return.
// Since we already know that `getPublicSuffix` returns a suffix of `hostname`
// there is no need to perform a string comparison and we only compare the
// size.
if (suffix.length === hostname.length - numberOfLeadingDots) {
return null;
}
// To extract the general domain, we start by identifying the public suffix
// (if any), then consider the domain to be the public suffix with one added
// level of depth. (e.g.: if hostname is `not.evil.co.uk` and public suffix:
// `co.uk`, then we take one more level: `evil`, giving the final result:
// `evil.co.uk`).
return /*@__INLINE__*/ extractDomainWithSuffix(hostname, suffix);
}
/**
* Return the part of domain without suffix.
*
* Example: for domain 'foo.com', the result would be 'foo'.
*/
function getDomainWithoutSuffix$1(domain, suffix) {
// Note: here `domain` and `suffix` cannot have the same length because in
// this case we set `domain` to `null` instead. It is thus safe to assume
// that `suffix` is shorter than `domain`.
return domain.slice(0, -suffix.length - 1);
}
/**
* @param url - URL we want to extract a hostname from.
* @param urlIsValidHostname - hint from caller; true if `url` is already a valid hostname.
*/
function extractHostname(url, urlIsValidHostname) {
let start = 0;
let end = url.length;
let hasUpper = false;
// If url is not already a valid hostname, then try to extract hostname.
if (!urlIsValidHostname) {
// Special handling of data URLs
if (url.startsWith('data:')) {
return null;
}
// Trim leading spaces
while (start < url.length && url.charCodeAt(start) <= 32) {
start += 1;
}
// Trim trailing spaces
while (end > start + 1 && url.charCodeAt(end - 1) <= 32) {
end -= 1;
}
// Skip scheme.
if (url.charCodeAt(start) === 47 /* '/' */ &&
url.charCodeAt(start + 1) === 47 /* '/' */) {
start += 2;
}
else {
const indexOfProtocol = url.indexOf(':/', start);
if (indexOfProtocol !== -1) {
// Implement fast-path for common protocols. We expect most protocols
// should be one of these 4 and thus we will not need to perform the
// more expansive validity check most of the time.
const protocolSize = indexOfProtocol - start;
const c0 = url.charCodeAt(start);
const c1 = url.charCodeAt(start + 1);
const c2 = url.charCodeAt(start + 2);
const c3 = url.charCodeAt(start + 3);
const c4 = url.charCodeAt(start + 4);
if (protocolSize === 5 &&
c0 === 104 /* 'h' */ &&
c1 === 116 /* 't' */ &&
c2 === 116 /* 't' */ &&
c3 === 112 /* 'p' */ &&
c4 === 115 /* 's' */) ;
else if (protocolSize === 4 &&
c0 === 104 /* 'h' */ &&
c1 === 116 /* 't' */ &&
c2 === 116 /* 't' */ &&
c3 === 112 /* 'p' */) ;
else if (protocolSize === 3 &&
c0 === 119 /* 'w' */ &&
c1 === 115 /* 's' */ &&
c2 === 115 /* 's' */) ;
else if (protocolSize === 2 &&
c0 === 119 /* 'w' */ &&
c1 === 115 /* 's' */) ;
else {
// Check that scheme is valid
for (let i = start; i < indexOfProtocol; i += 1) {
const lowerCaseCode = url.charCodeAt(i) | 32;
if (!(((lowerCaseCode >= 97 && lowerCaseCode <= 122) || // [a, z]
(lowerCaseCode >= 48 && lowerCaseCode <= 57) || // [0, 9]
lowerCaseCode === 46 || // '.'
lowerCaseCode === 45 || // '-'
lowerCaseCode === 43) // '+'
)) {
return null;
}
}
}
// Skip 0, 1 or more '/' after ':/'
start = indexOfProtocol + 2;
while (url.charCodeAt(start) === 47 /* '/' */) {
start += 1;
}
}
}
// Detect first occurrence of '/', '?' or '#'. We also keep track of the
// last occurrence of '@', ']' or ':' to speed-up subsequent parsing of
// (respectively), identifier, ipv6 or port.
let indexOfIdentifier = -1;
let indexOfClosingBracket = -1;
let indexOfPort = -1;
for (let i = start; i < end; i += 1) {
const code = url.charCodeAt(i);
if (code === 35 || // '#'
code === 47 || // '/'
code === 63 // '?'
) {
end = i;
break;
}
else if (code === 64) {
// '@'
indexOfIdentifier = i;
}
else if (code === 93) {
// ']'
indexOfClosingBracket = i;
}
else if (code === 58) {
// ':'
indexOfPort = i;
}
else if (code >= 65 && code <= 90) {
hasUpper = true;
}
}
// Detect identifier: '@'
if (indexOfIdentifier !== -1 &&
indexOfIdentifier > start &&
indexOfIdentifier < end) {
start = indexOfIdentifier + 1;
}
// Handle ipv6 addresses
if (url.charCodeAt(start) === 91 /* '[' */) {
if (indexOfClosingBracket !== -1) {
return url.slice(start + 1, indexOfClosingBracket).toLowerCase();
}
return null;
}
else if (indexOfPort !== -1 && indexOfPort > start && indexOfPort < end) {
// Detect port: ':'
end = indexOfPort;
}
}
// Trim trailing dots
while (end > start + 1 && url.charCodeAt(end - 1) === 46 /* '.' */) {
end -= 1;
}
const hostname = start !== 0 || end !== url.length ? url.slice(start, end) : url;
if (hasUpper) {
return hostname.toLowerCase();
}
return hostname;
}
/**
* Check if a hostname is an IP. You should be aware that this only works
* because `hostname` is already garanteed to be a valid hostname!
*/
function isProbablyIpv4(hostname) {
// Cannot be shorted than 1.1.1.1
if (hostname.length < 7) {
return false;
}
// Cannot be longer than: 255.255.255.255
if (hostname.length > 15) {
return false;
}
let numberOfDots = 0;
for (let i = 0; i < hostname.length; i += 1) {
const code = hostname.charCodeAt(i);
if (code === 46 /* '.' */) {
numberOfDots += 1;
}
else if (code < 48 /* '0' */ || code > 57 /* '9' */) {
return false;
}
}
return (numberOfDots === 3 &&
hostname.charCodeAt(0) !== 46 /* '.' */ &&
hostname.charCodeAt(hostname.length - 1) !== 46 /* '.' */);
}
/**
* Similar to isProbablyIpv4.
*/
function isProbablyIpv6(hostname) {
if (hostname.length < 3) {
return false;
}
let start = hostname.startsWith('[') ? 1 : 0;
let end = hostname.length;
if (hostname[end - 1] === ']') {
end -= 1;
}
// We only consider the maximum size of a normal IPV6. Note that this will
// fail on so-called "IPv4 mapped IPv6 addresses" but this is a corner-case
// and a proper validation library should be used for these.
if (end - start > 39) {
return false;
}
let hasColon = false;
for (; start < end; start += 1) {
const code = hostname.charCodeAt(start);
if (code === 58 /* ':' */) {
hasColon = true;
}
else if (!(((code >= 48 && code <= 57) || // 0-9
(code >= 97 && code <= 102) || // a-f
(code >= 65 && code <= 90)) // A-F
)) {
return false;
}
}
return hasColon;
}
/**
* Check if `hostname` is *probably* a valid ip addr (either ipv6 or ipv4).
* This *will not* work on any string. We need `hostname` to be a valid
* hostname.
*/
function isIp(hostname) {
return isProbablyIpv6(hostname) || isProbablyIpv4(hostname);
}
/**
* Implements fast shallow verification of hostnames. This does not perform a
* struct check on the content of labels (classes of Unicode characters, etc.)
* but instead check that the structure is valid (number of labels, length of
* labels, etc.).
*
* If you need stricter validation, consider using an external library.
*/
function isValidAscii(code) {
return ((code >= 97 && code <= 122) || (code >= 48 && code <= 57) || code > 127);
}
/**
* Check if a hostname string is valid. It's usually a preliminary check before
* trying to use getDomain or anything else.
*
* Beware: it does not check if the TLD exists.
*/
function isValidHostname (hostname) {
if (hostname.length > 255) {
return false;
}
if (hostname.length === 0) {
return false;
}
if (
/*@__INLINE__*/ !isValidAscii(hostname.charCodeAt(0)) &&
hostname.charCodeAt(0) !== 46 && // '.' (dot)
hostname.charCodeAt(0) !== 95 // '_' (underscore)
) {
return false;
}
// Validate hostname according to RFC
let lastDotIndex = -1;
let lastCharCode = -1;
const len = hostname.length;
for (let i = 0; i < len; i += 1) {
const code = hostname.charCodeAt(i);
if (code === 46 /* '.' */) {
if (
// Check that previous label is < 63 bytes long (64 = 63 + '.')
i - lastDotIndex > 64 ||
// Check that previous character was not already a '.'
lastCharCode === 46 ||
// Check that the previous label does not end with '-' (RFC 1035 §2.3.1 LDH).
// '_' is intentionally NOT restricted: DNS allows any octet (RFC 2181 §11) and
// WHATWG URL does not treat '_' as a forbidden host code point.
lastCharCode === 45) {
return false;
}
lastDotIndex = i;
}
else if (!( /*@__INLINE__*/(isValidAscii(code) || code === 45 || code === 95))) {
// Check if there is a forbidden character in the label
return false;
}
lastCharCode = code;
}
return (
// Check that last label is shorter than 63 chars
len - lastDotIndex - 1 <= 63 &&
// Check that the last character is an allowed trailing label character.
// Since we already checked that the char is a valid hostname character,
// we only need to check that it's different from '-'.
lastCharCode !== 45);
}
function setDefaultsImpl({ allowIcannDomains = true, allowPrivateDomains = false, detectIp = true, extractHostname = true, mixedInputs = true, validHosts = null, validateHostname = true, }) {
return {
allowIcannDomains,
allowPrivateDomains,
detectIp,
extractHostname,
mixedInputs,
validHosts,
validateHostname,
};
}
const DEFAULT_OPTIONS = /*@__INLINE__*/ setDefaultsImpl({});
function setDefaults(options) {
if (options === undefined) {
return DEFAULT_OPTIONS;
}
return /*@__INLINE__*/ setDefaultsImpl(options);
}
/**
* Returns the subdomain of a hostname string
*/
function getSubdomain$1(hostname, domain) {
// If `hostname` and `domain` are the same, then there is no sub-domain
if (domain.length === hostname.length) {
return '';
}
return hostname.slice(0, -domain.length - 1);
}
/**
* Implement a factory allowing to plug different implementations of suffix
* lookup (e.g.: using a trie or the packed hashes datastructures). This is used
* and exposed in `tldts.ts` and `tldts-experimental.ts` bundle entrypoints.
*/
function getEmptyResult() {
return {
domain: null,
domainWithoutSuffix: null,
hostname: null,
isIcann: null,
isIp: null,
isPrivate: null,
publicSuffix: null,
subdomain: null,
};
}
function resetResult(result) {
result.domain = null;
result.domainWithoutSuffix = null;
result.hostname = null;
result.isIcann = null;
result.isIp = null;
result.isPrivate = null;
result.publicSuffix = null;
result.subdomain = null;
}
function parseImpl(url, step, suffixLookup, partialOptions, result) {
const options = /*@__INLINE__*/ setDefaults(partialOptions);
// Very fast approximate check to make sure `url` is a string. This is needed
// because the library will not necessarily be used in a typed setup and
// values of arbitrary types might be given as argument.
if (typeof url !== 'string') {
return result;
}
// Extract hostname from `url` only if needed. This can be made optional
// using `options.extractHostname`. This option will typically be used
// whenever we are sure the inputs to `parse` are already hostnames and not
// arbitrary URLs.
//
// `mixedInput` allows to specify if we expect a mix of URLs and hostnames
// as input. If only hostnames are expected then `extractHostname` can be
// set to `false` to speed-up parsing. If only URLs are expected then
// `mixedInputs` can be set to `false`. The `mixedInputs` is only a hint
// and will not change the behavior of the library.
if (!options.extractHostname) {
result.hostname = url;
}
else if (options.mixedInputs) {
result.hostname = extractHostname(url, isValidHostname(url));
}
else {
result.hostname = extractHostname(url, false);
}
// Check if `hostname` is a valid ip address
if (options.detectIp && result.hostname !== null) {
result.isIp = isIp(result.hostname);
if (result.isIp) {
return result;
}
}
// Perform hostname validation if enabled. If hostname is not valid, no need to
// go further as there will be no valid domain or sub-domain. This validation
// is applied before any early returns to ensure consistent behavior across
// all API methods including getHostname().
if (options.validateHostname &&
options.extractHostname &&
result.hostname !== null &&
!isValidHostname(result.hostname)) {
result.hostname = null;
return result;
}
if (step === 0 /* FLAG.HOSTNAME */ || result.hostname === null) {
return result;
}
// Extract public suffix
suffixLookup(result.hostname, options, result);
if (step === 2 /* FLAG.PUBLIC_SUFFIX */ || result.publicSuffix === null) {
return result;
}
// Extract domain
result.domain = getDomain$1(result.publicSuffix, result.hostname, options);
if (step === 3 /* FLAG.DOMAIN */ || result.domain === null) {
return result;
}
// Extract subdomain
result.subdomain = getSubdomain$1(result.hostname, result.domain);
if (step === 4 /* FLAG.SUB_DOMAIN */) {
return result;
}
// Extract domain without suffix
result.domainWithoutSuffix = getDomainWithoutSuffix$1(result.domain, result.publicSuffix);
return result;
}
function fastPathLookup (hostname, options, out) {
// Fast path for very popular suffixes; this allows to by-pass lookup
// completely as well as any extra allocation or string manipulation.
if (!options.allowPrivateDomains && hostname.length > 3) {
const last = hostname.length - 1;
const c3 = hostname.charCodeAt(last);
const c2 = hostname.charCodeAt(last - 1);
const c1 = hostname.charCodeAt(last - 2);
const c0 = hostname.charCodeAt(last - 3);
if (c3 === 109 /* 'm' */ &&
c2 === 111 /* 'o' */ &&
c1 === 99 /* 'c' */ &&
c0 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'com';
return true;
}
else if (c3 === 103 /* 'g' */ &&
c2 === 114 /* 'r' */ &&
c1 === 111 /* 'o' */ &&
c0 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'org';
return true;
}
else if (c3 === 117 /* 'u' */ &&
c2 === 100 /* 'd' */ &&
c1 === 101 /* 'e' */ &&
c0 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'edu';
return true;
}
else if (c3 === 118 /* 'v' */ &&
c2 === 111 /* 'o' */ &&
c1 === 103 /* 'g' */ &&
c0 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'gov';
return true;
}
else if (c3 === 116 /* 't' */ &&
c2 === 101 /* 'e' */ &&
c1 === 110 /* 'n' */ &&
c0 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'net';
return true;
}
else if (c3 === 101 /* 'e' */ &&
c2 === 100 /* 'd' */ &&
c1 === 46 /* '.' */) {
out.isIcann = true;
out.isPrivate = false;
out.publicSuffix = 'de';
return true;
}
}
return false;
}
const exceptions = (function () {
const _73 = [1, {}], _74 = [0, { "city": _73 }];
const exceptions = [0, { "ck": [0, { "www": _73 }], "jp": [0, { "kawasaki": _74, "kitakyushu": _74, "kobe": _74, "nagoya": _74, "sapporo": _74, "sendai": _74, "yokohama": _74 }] }];
return exceptions;
})();
const rules = (function () {
const _75 = [1, {}], _76 = [1, { "com": _75, "edu": _75, "gov": _75, "mil": _75, "net": _75, "org": _75 }], _77 = [1, { "com": _75, "edu": _75, "gov": _75, "net": _75, "org": _75 }], _78 = [1, { "gov": _75 }], _79 = [0, { "*": _75 }], _80 = [1, { "co": _75, "com": _75, "edu": _75, "gov": _75, "net": _75, "org": _75 }], _81 = [1, { "com": _75, "edu": _75, "net": _75, "org": _75 }], _82 = [1, { "co": _75, "net": _75, "org": _75 }], _83 = [1, { "co": _75, "com": _75, "edu": _75, "gov": _75, "mil": _75, "net": _75, "nom": _75, "org": _75 }], _84 = [1, { "biz": _75, "com": _75, "edu": _75, "gov": _75, "info": _75, "net": _75, "org": _75 }], _85 = [1, { "gs": _75 }], _86 = [0, { "nes": _75 }], _87 = [1, { "k12": _75, "cc": _75, "lib": _75 }], _88 = [1, { "cc": _75 }], _89 = [1, { "cc": _75, "lib": _75 }];
const rules = [0, { "ac": _76, "ad": _75, "ae": [1, { "ac": _75, "co": _75, "gov": _75, "mil": _75, "net": _75, "org": _75, "sch": _75 }], "aero": [1, { "airline": _75, "airport": _75, "accident-investigation": _75, "accident-prevention": _75, "aerobatic": _75, "aeroclub": _75, "aerodrome": _75, "agents": _75, "air-surveillance": _75, "air-traffic-control": _75, "aircraft": _75, "airtraffic": _75, "ambulance": _75, "association": _75, "author": _75, "ballooning": _75, "broker": _75, "caa": _75, "cargo": _75, "catering": _75, "certification": _75, "championship": _75, "charter": _75, "civilaviation": _75, "club": _75, "conference": _75, "consultant": _75, "consulting": _75, "control": _75, "council": _75, "crew": _75, "design": _75, "dgca": _75, "educator": _75, "emergency": _75, "engine": _75, "engineer": _75, "entertainment": _75, "equipment": _75, "exchange": _75, "express": _75, "federation": _75, "flight": _75, "freight": _75, "fuel": _75, "gliding": _75, "government": _75, "groundhandling": _75, "group": _75, "hanggliding": _75, "homebuilt": _75, "insurance": _75, "journal": _75, "journalist": _75, "leasing": _75, "logistics": _75, "magazine": _75, "maintenance": _75, "marketplace": _75, "media": _75, "microlight": _75, "modelling": _75, "navigation": _75, "parachuting": _75, "paragliding": _75, "passenger-association": _75, "pilot": _75, "press": _75, "production": _75, "recreation": _75, "repbody": _75, "res": _75, "research": _75, "rotorcraft": _75, "safety": _75, "scientist": _75, "services": _75, "show": _75, "skydiving": _75, "software": _75, "student": _75, "taxi": _75, "trader": _75, "trading": _75, "trainer": _75, "union": _75, "workinggroup": _75, "works": _75 }], "af": _77, "ag": [1, { "co": _75, "com": _75, "net": _75, "nom": _75, "org": _75 }], "ai": [1, { "com": _75, "net": _75, "off": _75, "org": _75 }], "al": _76, "am": [1, { "co": _75, "com": _75, "commune": _75, "net": _75, "org": _75 }], "ao": [1, { "co": _75, "ed": _75, "edu": _75, "gov": _75, "gv": _75, "it": _75, "og": _75, "org": _75, "pb": _75 }], "aq": _75, "ar": [1, { "bet": _75, "com": _75, "coop": _75, "edu": _75, "gob": _75, "gov": _75, "int": _75, "mil": _75, "musica": _75, "mutual": _75, "net": _75, "org": _75, "seg": _75, "senasa": _75, "tur": _75 }], "arpa": [1, { "e164": _75, "home": _75, "in-addr": _75, "ip6": _75, "iris": _75, "uri": _75, "urn": _75 }], "as": _78, "asia": _75, "at": [1, { "ac": [1, { "sth": _75 }], "co": _75, "gv": _75, "or": _75 }], "au": [1, { "asn": _75, "com": _75, "edu": [1, { "act": _75, "catholic": _75, "nsw": _75, "nt": _75, "qld": _75, "sa": _75, "tas": _75, "vic": _75, "wa": _75 }], "gov": [1, { "qld": _75, "sa": _75, "tas": _75, "vic": _75, "wa": _75 }], "id": _75, "net": _75, "org": _75, "conf": _75, "oz": _75, "act": _75, "nsw": _75, "nt": _75, "qld": _75, "sa": _75, "tas": _75, "vic": _75, "wa": _75 }], "aw": [1, { "com": _75 }], "ax": _75, "az": [1, { "biz": _75, "co": _75, "com": _75, "edu": _75, "gov": _75, "info": _75, "int": _75, "mil": _75, "name": _75, "net": _75, "org": _75, "pp": _75, "pro": _75 }], "ba": _76, "bb": [1, { "biz": _75, "co": _75, "com": _75, "edu": _75, "gov": _75, "info": _75, "net": _75, "org": _75, "store": _75, "tv": _75 }], "bd": [1, { "ac": _75, "ai": _75, "co": _75, "com": _75, "edu": _75, "gov": _75, "id": _75, "info": _75, "it": _75, "mil": _75, "net": _75, "org": _75, "sch": _75, "tv": _75 }], "be": [1, { "ac": _75 }], "bf": _78, "bg": [1, { "0": _75, "1": _75, "2": _75, "3": _75, "4": _75, "5": _75, "6": _75, "7": _75, "8": _75, "9": _75, "a": _75, "b": _75, "c": _75, "d": _75, "e": _75, "f": _75, "g": _75, "h": _75, "i": _75, "j": _75, "k": _75, "l": _75, "m": _75, "n": _75, "o": _75, "p": _75, "q": _75, "r": _75, "s": _75, "t": _75, "u": _75, "v": _75, "w": _75, "x": _75, "y": _75, "z": _75 }], "bh": _77, "bi": [1, { "co": _75, "com": _75, "edu": _75, "or": _75, "org": _75 }], "biz": _75, "bj": [1, { "africa": _75, "agro": _75, "architectes": _75, "assur": _75, "avocats": _75, "co": _75, "com": _75, "eco": _75, "econo": _75, "edu": _75, "info": _75, "loisirs": _75, "money": _75, "net": _75, "org": _75, "ote": _75, "restaurant": _75, "resto": _75, "tourism": _75, "univ": _75 }], "bm": _77, "bn": _77, "bo": [1, { "com": _75, "edu": _75, "gob": _75, "int": _75, "mil": _75, "net": _75, "org": _75, "tv": _75, "web": _75, "academia": _75, "agro": _75, "arte": _75, "blog": _75, "bolivia": _75, "ciencia": _75, "cooperativa": _75, "democracia": _75, "deporte": _75, "ecologia": _75, "economia": _75, "empresa": _75, "indigena": _75, "industria": _75, "info": _75, "medicina": _75, "movimiento": _75, "musica": _75, "natural": _75, "nombre": _75, "noticias": _75, "patria": _75, "plurinacional": _75, "politica": _75, "profesional": _75, "pueblo": _75, "revista": _75, "salud": _75, "tecnologia": _75, "tksat": _75, "transporte": _75, "wiki": _75 }], "br": [1, { "9guacu": _75, "abc": _75, "adm": _75, "adv": _75, "agr": _75, "aju": _75, "am": _75, "anani": _75, "aparecida": _75, "api": _75, "app": _75, "arq": _75, "art": _75, "ato": _75, "b": _75, "barueri": _75, "belem": _75, "bet": _75, "bhz": _75, "bib": _75, "bio": _75, "blog": _75, "bmd": _75, "boavista": _75, "bsb": _75, "campinagrande": _75, "campinas": _75, "caxias": _75, "cim": _75, "cng": _75, "cnt": _75, "com": _75, "contagem": _75, "coop": _75, "coz": _75, "cri": _75, "cuiaba": _75, "curitiba": _75, "def": _75, "des": _75, "det": _75, "dev": _75, "ecn": _75, "eco": _75, "edu": _75, "emp": _75, "enf": _75, "eng": _75, "esp": _75, "etc": _75, "eti": _75, "far": _75, "feira": _75, "flog": _75, "floripa": _75, "fm": _75, "fnd": _75, "fortal": _75, "fot": _75, "foz": _75, "fst": _75, "g12": _75, "geo": _75, "ggf": _75, "goiania": _75, "gov": [1, { "ac": _75, "al": _75, "am": _75, "ap": _75, "ba": _75, "ce": _75, "df": _75, "es": _75, "go": _75, "ma": _75, "mg": _75, "ms": _75, "mt": _75, "pa": _75, "pb": _75, "pe": _75, "pi": _75, "pr": _75, "rj": _75, "rn": _75, "ro": _75, "rr": _75, "rs": _75, "sc": _75, "se": _75, "sp": _75, "to": _75 }], "gru": _75, "ia": _75, "imb": _75, "ind": _75, "inf": _75, "jab": _75, "jampa": _75, "jdf": _75, "joinville": _75, "jor": _75, "jus": _75, "leg": _75, "leilao": _75, "lel": _75, "log": _75, "londrina": _75, "macapa": _75, "maceio": _75, "manaus": _75, "maringa": _75, "mat": _75, "med": _75, "mil": _75, "morena": _75, "mp": _75, "mus": _75, "natal": _75, "net": _75, "niteroi": _75, "nom": _79, "not": _75, "ntr": _75, "odo": _75, "ong": _75, "org": _75, "osasco": _75, "palmas": _75, "poa": _75, "ppg": _75, "pro": _75, "psc": _75, "psi": _75, "pvh": _75, "qsl": _75, "radio": _75, "rec": _75, "recife": _75, "rep": _75, "ribeirao": _75, "rio": _75, "riobranco": _75, "riopreto": _75, "salvador": _75, "sampa": _75, "santamaria": _75, "santoandre": _75, "saobernardo": _75, "saogonca": _75, "seg": _75, "sjc": _75, "slg": _75, "slz": _75, "social": _75, "sorocaba": _75, "srv": _75, "taxi": _75, "tc": _75, "tec": _75, "teo": _75, "the": _75, "tmp": _75, "trd": _75, "tur": _75, "tv": _75, "udi": _75, "vet": _75, "vix": _75, "vlog": _75, "wiki": _75, "xyz": _75, "zlg": _75 }], "bs": _77, "bt": _77, "bv": _75, "bw": [1, { "ac": _75, "co": _75, "gov": _75, "net": _75, "org": _75 }], "by": [1, { "gov": _75, "mil": _75, "com": _75, "of": _75 }], "bz": _80, "ca": [1, { "ab": _75, "bc": _75, "mb": _75, "nb": _75, "nf": _75, "nl": _75, "ns": _75, "nt": _75, "nu": _75, "on": _75, "pe": _75, "qc": _75, "sk": _75, "yk": _75, "gc": _75 }], "cat": _75, "cc": _75, "cd": _78, "cf": _75, "cg": _75, "ch": _75, "ci": [1, { "ac": _75, "xn--aroport-bya": _75, "aéroport": _75, "asso": _75, "co": _75, "com": _75, "ed": _75, "edu": _75, "go": _75, "gouv": _75, "int": _75, "net": _75, "or": _75, "org": _75 }], "ck": _79, "cl": [1, { "co": _75, "gob": _75, "gov": _75, "mil": _75 }], "cm": [1, { "co": _75, "com": _75, "gov": _75, "net": _75 }], "cn": [1, { "ac": _75, "com": _75, "edu": _75, "gov": _75, "mil": _75, "net": _75, "org": _75, "xn--55qx5d": _75, "公司": _75, "xn--od0alg": _75, "網絡": _75, "xn--io0a7i": _75, "网络": _75, "ah": _75, "bj": _75, "cq": _75, "fj": _75, "gd": _75, "gs": _75, "gx": _75, "gz": _75, "ha": _75, "hb": _75, "he": _75, "hi": _75, "hk": _75, "hl": _75, "hn": _75, "jl": _75, "js": _75, "jx": _75, "ln": _75, "mo": _75, "nm": _75, "nx": _75, "qh": _75, "sc": _75, "sd": _75, "sh": _75, "sn": _75, "sx": _75, "tj": _75, "tw": _75, "xj": _75, "xz": _75, "yn": _75, "zj": _75 }], "co": [1, { "com": _75, "edu": _75, "gov": _75, "mil": _75, "net": _75, "nom": _75, "org": _75 }], "com": _75, "coop": _75, "cr": [1, { "ac": _75, "co": _75, "ed": _75, "fi": _75, "go": _75, "or": _75, "sa": _75 }], "cu": [1, { "com": _75, "edu": _75, "gob": _75, "inf": _75, "nat": _75, "net": _75, "org": _75 }], "cv": [1, { "com": _75, "edu": _75, "id": _75, "int": _75, "net": _75, "nome": _75, "org": _75, "publ": _75 }], "cw": _81, "cx": _78, "cy": [1, { "ac": _75, "biz": _75, "com": _75, "ekloges": _75, "gov": _75, "ltd": _75, "mil": _75, "net": _75, "org": _75, "press": _75, "pro": _75, "tm": _75 }], "cz": _78, "de": _75, "dj": _75, "dk": _75, "dm": _80, "do": [1, { "art": _75, "com": _75, "edu": _75, "gob": _75, "gov": _75, "mil": _75, "net": _75, "org": _75, "sld": _75, "web": _75 }], "dz": [1, { "art": _75, "asso": _75, "com": _75, "edu": _75, "gov": _75, "net": _75, "org": _75, "pol": _75, "soc": _75, "tm": _75 }], "ec": [1, { "abg": _75, "adm": _75, "agron": _75, "arqt": _75, "art": _75, "bar": _75, "chef": _75, "com": _75, "cont": _75, "cpa": _75, "cue": _75, "dent": _75, "dgn": _75, "disco": _75, "doc": _75, "edu": _75, "eng": _75, "esm": _75, "fin": _75, "fot": _75, "gal": _75, "gob": _75, "gov": _75, "gye": _75, "ibr": _75, "info": _75, "k12": _75, "lat": _75, "loj": _75, "med": _75, "mil": _75, "mktg": _75, "mon": _75, "net": _75, "ntr": _75, "odont": _75, "org": _75, "pro": _75, "prof": _75, "psic": _75, "psiq": _75, "pub": _75, "rio": _75, "rrpp": _75, "sal": _75, "tech": _75, "tul": _75, "tur": _75, "uio": _75, "vet": _75, "xxx": _75 }], "edu": _75, "ee": [1, { "aip": _75, "com": _75, "edu": _75, "fie": _75, "gov": _75, "lib": _75, "med": _75, "org": _75, "pri": _75, "riik": _75 }], "eg": [1, { "ac": _75, "com": _75, "edu": _75, "eun": _75, "gov": _75, "info": _75, "me": _75, "mil": _75, "name": _75, "net": _75, "org": _75, "sci": _75, "sport": _75, "tv": _75 }], "er": _79, "es": [1, { "com": _75, "edu": _75, "gob": _75, "nom": _75, "org": _75 }], "et": [1, { "biz": _75, "com": _75, "edu": _75, "gov": _75, "info": _75, "name": _75, "net": _75, "org": _75 }], "eu": _75, "fi": [1, { "aland": _75 }], "fj": [1, { "ac": _75, "biz": _75, "com": _75, "edu": _75, "gov": _75, "id": _75, "info": _75, "mil": _75, "name": _75, "net": _75, "org": _75, "pro": _75 }], "fk": _79, "fm": _81, "fo": _75, "fr": [1, { "asso": _75, "com": _75, "gouv": _75, "nom": _75, "prd": _75, "tm": _75, "avoues": _75, "cci": _75, "greta": _75, "huissier-justice": _75 }], "ga": _75, "gb": _75, "gd": [1, { "edu": _75, "gov": _75 }], "ge": [1, { "com": _75, "edu": _75, "gov": _75, "net": _75, "org": _75, "pvt": _75, "school": _75 }], "gf": _75, "gg": _82, "gh": [1, { "biz": _75, "com": _75, "edu": _75, "gov": _75, "mil": _75, "net": _75, "org": _75 }], "gi": [1, { "com": _75, "edu": _75, "gov": _75, "ltd": _75, "mod": _75, "org": _75 }], "gl": [1, { "co": _75, "com": _75, "edu": _75, "net": _75, "org": _75 }], "gm": _75, "gn": [1, { "ac": _75, "com": _75, "edu": _75, "gov": _75, "net": _75, "org": _75 }], "gov": _75, "gp": [1, { "asso": _75, "com": _75, "edu": _75, "mobi": _75, "net": _75, "org": _75 }], "gq": _75, "gr": _77, "gs": _75, "gt": [1, { "com": _75, "edu": _75, "gob": _75, "ind": _75, "mil": _75, "net": _75, "org": _75 }], "gu": [1, { "com": _75, "edu": _75, "gov": _75, "guam": _75, "info": _75, "net": _75, "org": _75, "web": _75 }], "gw": _75, "gy": _80, "hk": [1, { "com": _75, "edu": _75, "gov": _75, "idv": _75, "net": _75, "org": _75, "xn--ciqpn": _75, "个人": _75, "xn--gmqw5a": _75, "個人": _75, "xn--55qx5d": _75, "公司": _75, "xn--mxtq1m": _75, "政府": _75, "xn--lcvr32d": _75, "敎育": _75, "xn--wcvs22d": _75, "教育": _75, "xn--gmq050i": _75, "箇人": _75, "xn--uc0atv": _75, "組織": _75, "xn--uc0ay4a": _75, "組织": _75, "xn--od0alg": _75, "網絡": _75, "xn--zf0avx": _75, "網络": _75, "xn--mk0axi": _75, "组織": _75, "xn--tn0ag": _75, "组织": _75, "xn--od0aq3b": _75, "网絡": _75, "xn--io0a7i": _75, "网络": _75 }], "hm": _75, "hn": [1, { "com": _75, "edu": _75, "gob": _75, "mil": _75, "net": _75, "org": _75 }], "hr": [1, { "com": _75, "from": _75, "iz": _75, "name": _75 }], "ht": [1, { "adult": _75, "art": _75, "asso": _75, "com": _75, "coop": _75, "edu": _75, "firm": _75, "gouv": _75, "info": _75, "med": _75, "net": _75, "org": _75, "perso": _75, "pol": _75, "pro": _75, "rel": _75, "shop": _75 }], "hu": [1, { "2000": _75, "agrar": _75, "bolt": _75, "casino": _75, "city": _75, "co": _75, "erotica": _75, "erotika": _75, "film": _75, "forum": _75, "games": _75, "hotel": _75, "info": _75, "ingatlan": _75, "jogasz": _75, "konyvelo": _75, "lakas": _75, "media": _75, "news": _75, "org": _75, "priv": _75, "reklam": _75, "sex": _75, "shop": _75, "sport": _75, "suli": _75, "szex": _75, "tm": _75, "tozsde": _75, "utazas": _75, "video": _75 }], "id": [1, { "ac": _75, "biz": _75, "co": _75, "desa": _75, "go": _75, "kop": _75, "mil": _75, "my": _75, "net": _75, "or": _75, "ponpes": _75, "sch": _75, "web": _75, "xn--9tfky": _75, "ᬩᬮᬶ": _75 }], "ie": _78, "il": [1, { "ac": _75, "co": _75, "gov": _75, "idf": _75, "k12": _75, "muni": _75, "net": _75, "org": _75 }], "xn--4dbrk0ce": [1, { "xn--4dbgdty6c": _75, "xn--5dbhl8d": _75, "xn--8dbq2a": _75, "xn--hebda8b": _75 }], "ישראל": [1, { "אקדמיה": _75, "ישוב": _75, "צהל": _75, "ממשל": _75 }], "im": [1, { "ac": _75, "co": [1, { "ltd": _75, "plc": _75 }], "com": _75, "net": _75, "org": _75, "tt": _75, "tv": _75 }], "in": [1, { "5g": _75, "6g": _75, "ac": _75, "ai": _75, "am": _75, "bank": _75, "bihar": _75, "biz": _75, "business": _75, "ca": _75, "cn": _75, "co": _75, "com": _75, "coop": _75, "cs": _75, "delhi": _75, "dr": _75, "edu": _75, "er": _75, "fin": _75, "firm": _75, "gen": _75, "gov": _75, "gujarat": _75, "ind": _75, "info": _75, "int": _75, "internet": _75, "io": _75, "me": _75, "mil": _75, "net": _75, "nic": _75, "org": _75, "pg": _75, "post": _75, "pro": _75, "res": _75, "travel": _75, "tv": _75, "uk": _75, "up": _75, "us": _75 }], "info": _75, "int": [1, { "eu": _75 }], "io": _83, "iq": _76, "ir": [1, { "ac": _75, "co": _75, "gov": _75, "id": _75, "net": _75, "org": _75, "sch": _75, "xn--mgba3a4f16a": _75, "ایران": _75, "xn--mgba3a4fra": _75, "ايران": _75 }], "is": _75, "it": [1, { "edu": _75, "gov": _75, "abr": _75, "abruzzo": _75, "aosta-valley": _75, "aostavalley": _75, "bas": _75, "basilicata": _75, "cal": _75, "calabria": _75, "cam": _75, "campania": _75, "emilia-romagna": _75, "emiliaromagna": _75, "emr": _75, "friuli-v-giulia": _75, "friuli-ve-giulia": _75, "friuli-vegiulia": _75, "friuli-venezia-giulia": _75, "friuli-veneziagiulia": _75, "friuli-vgiulia": _75, "friuliv-giulia": _75, "friulive-giulia": _75, "friulivegiulia": _75, "friulivenezia-giulia": _75, "friuliveneziagiulia": _75, "friulivgiulia": _75, "fvg": _75, "laz": _75, "lazio": _75, "lig": _75, "liguria": _75, "lom": _75, "lombardia": _75, "lombardy": _75, "lucania": _75, "mar": _75, "marche": _75, "mol": _75, "molise": _75, "piedmont": _75, "piemonte": _75, "pmn": _75, "pug": _75, "puglia": _75, "sar": _75, "sardegna": _75, "sardinia": _75, "sic": _75, "sicilia": _75, "sicily": _75, "taa": _75, "tos": _75, "toscana": _75, "trentin-sud-tirol": _75, "xn--trentin-sd-tirol-rzb": _75, "trentin-süd-tirol": _75, "trentin-sudtirol": _75, "xn--trentin-sdtirol-7vb": _75, "trentin-südtirol": _75, "trentin-sued-tirol": _75, "trentin-suedtirol": _75, "trentino": _75, "trentino-a-adige": _75, "trentino-aadige": _75, "trentino-alto-adige": _75, "trentino-altoadige": _75, "trentino-s-tirol": _75, "trentino-stirol": _75, "trentino-sud-tirol": _75, "xn--trentino-sd-tirol-c3b": _75, "trentino-süd-tirol": _75, "trentino-sudtirol": _75, "xn--trentino-sdtirol-szb": _75, "trentino-südtirol": _75, "trentino-sued-tirol": _75, "trentino-suedtirol": _75, "trentinoa-adige": _75, "trentinoaadige": _75, "trentinoalto-adige": _75, "trentinoaltoadige": _75, "trentinos-tirol": _75, "trentinostirol": _75, "trentinosud-tirol": _75, "xn--trentinosd-tirol-rzb": _75, "trentinosüd-tirol": _75, "trentinosudtirol": _75, "xn--trentinosdtirol-7vb": _75, "trentinosüdtirol": _75, "trentinosued-tirol": _75, "trentinosuedtirol": _75, "trentinsud-tirol": _75, "xn--trentinsd-tirol-6vb": _75, "trentinsüd-tirol": _75, "trentinsudtirol": _75, "xn--trentinsdtirol-nsb": _75, "trentinsüdtirol": _75, "trentinsued-tirol": _75, "trentinsuedtirol": _75, "tuscany": _75, "umb": _75, "umbria": _75, "val-d-aosta": _75, "val-daosta": _75, "vald-aosta": _75, "valdaosta": _75, "valle-aosta": _75, "valle-d-aosta": _75, "valle-daosta": _75, "valleaosta": _75, "valled-aosta": _75, "valledaosta": _75, "vallee-aoste": _75, "xn--valle-aoste-ebb": _75, "vallée-aoste": _75, "vallee-d-aoste": _75, "xn--valle-d-aoste-ehb": _75, "vallée-d-aoste": _75, "valleeaoste": _75, "xn--valleaoste-e7a": _75, "valléeaoste": _75, "valleedaoste": _75, "xn--valledaoste-ebb": _75, "valléedaoste": _75, "vao": _75, "vda": _75, "ven": _75, "veneto": _75, "ag": _75, "agrigento": _75, "al": _75, "alessandria": _75, "alto-adige": _75, "altoadige": _75, "an": _75, "ancona": _75, "andria-barletta-trani": _75, "andria-trani-barletta": _75, "andriabarlettatrani": _75, "andriatranibarletta": _75, "ao": _75, "aosta": _75, "aoste": _75, "ap": _75, "aq": _75, "aquila": _75, "ar": _75, "arezzo": _75, "ascoli-piceno": _75, "ascolipiceno": _75, "asti": _75, "at": _75, "av": _75, "avellino": _75, "ba": _75, "balsan": _75, "balsan-sudtirol": _75, "xn--balsan-sdtirol-nsb": _75, "balsan-südtirol": _75, "balsan-suedtirol": _75, "bari": _75, "barletta-trani-andria": _75, "barlettatraniandria": _75, "belluno": _75, "benevento": _75, "bergamo": _75, "bg": _75, "bi": _75, "biella": _75, "bl": _75, "bn": _75, "bo": _75, "bologna": _75, "bolzano": _75, "bolzano-altoadige": _75, "bozen": _75, "bozen-sudtirol": _75, "xn--bozen-sdtirol-2ob": _75, "bozen-südtirol": _75, "bozen-suedtirol": _75, "br": _75, "brescia": _75, "brindisi": _75, "bs": _75, "bt": _75, "bulsan": _75, "bulsan-sudtirol": _75, "xn--bulsan-sdtirol-nsb": _75, "bulsan-südtirol": _75, "bulsan-suedtirol": _75, "bz": _75, "ca": _75, "cagliari": _75, "caltanissetta": _75, "campidano-medio": _75, "campidanomedio": _75, "campobasso": _75, "carbonia-iglesias": _75, "carboniaiglesias": _75, "carrara-massa": _75, "carraramassa": _75, "caserta": _75, "catania": _75, "catanzaro": _75, "cb": _75, "ce": _75, "cesena-forli": _75, "xn--cesena-forl-mcb": _75, "cesena-forlì": _75, "cesenaforli": _75, "xn--cesenaforl-i8a": _75, "cesenaforlì": _75, "ch": _75, "chieti": _75, "ci": _75, "cl": _75, "cn": _75, "co": _75, "como": _75, "cosenza": _75, "cr": _75, "cremona": _75, "crotone": _75, "cs": _75, "ct": _75, "cuneo": _75, "cz": _75, "dell-ogliastra": _75, "dellogliastra": _75, "en": _75, "enna": _75, "fc": _75, "fe": _75, "fermo": _75, "ferrara": _75, "fg": _75, "fi": _75, "firenze": _75, "florence": _75, "fm": _75, "foggia": _75, "forli-cesena": _75, "xn--forl-cesena-fcb": _75, "forlì-cesena": _75, "forlicesena": _75, "xn--forlcesena-c8a": _75, "forlìcesena": _75, "fr": _75, "frosinone": _75, "ge": _75, "genoa": _75, "genova": _75, "go": _75, "gorizia": _75, "gr": _75, "grosseto": _75, "iglesias-carbonia": _75, "iglesiascarbonia": _75, "im": _75, "imperia": _75, "is": _75, "isernia": _75, "kr": _75, "la-spezia": _75, "laquila": _75, "laspezia": _75, "latina": _75, "lc": _75, "le": _75, "lecce": _75, "lecco": _75, "li": _75, "livorno": _75, "lo": _75, "lodi": _75, "lt": _75, "lu": _75, "lucca": _75, "macerata": _75, "mantova": _75, "massa-carrara": _75, "massacarrara": _75, "matera": _75, "mb": _75, "mc": _75, "me": _75, "medio-campidano": _75, "mediocampidano": _75, "messina": _75, "mi": _75, "milan": _75, "milano": _75, "mn": _75, "mo": _75, "modena": _75, "monza": _75, "monza-brianza": _75, "monza-e-della-brianza": _75, "monzabrianza": _75, "monzaebrianza": _75, "monzaedellabrianza": _75, "ms": _75, "mt": _75, "na": _75, "naples": _75, "napoli": _75, "no": _75, "novara": _75, "nu": _75, "nuoro": _75, "og": _75, "ogliastra": _75, "olbia-tempio": _75, "olbiatempio": _75, "or": _75, "oristano": _75, "ot": _75, "pa": _75, "padova": _75, "padua": _75, "palermo": _75, "parma": _75, "pavia": _75, "pc": _75, "pd": _75, "pe": _75, "perugia": _75, "pesaro-urbino": _75, "pesarourbino": _75, "pescara": _75, "pg": _75, "pi": _75, "piacenza": _75, "pisa": _75, "pistoia": _75, "pn": _75, "po": _75, "pordenone": _75, "potenza": _75, "pr": _75, "prato": _75, "pt": _75, "pu": _75, "pv": _75, "pz": _75, "ra": _75, "ragusa": _75, "ravenna": _75, "rc": _75, "re": _75, "reggio-calabria": _75, "reggio-emilia": _75, "reggiocalabria": _75, "reggioemilia": _75, "rg": _75, "ri": _75, "rieti": _75, "rimini": _75, "rm": _75, "rn": _75, "ro": _75, "roma": _75, "rome": _75, "rovigo": _75, "sa": _75, "salerno": _75, "sassari": _75, "savona": _75, "si": _75, "siena": _75, "siracusa": _75, "so": _75, "sondrio": _75, "sp": _75, "sr": _75, "ss": _75, "xn--sdtirol-n2a": _75, "südtirol": _75, "suedtirol": _75, "sv": _75, "ta": _75, "taranto": _75, "te": _75, "tempio-olbia": _75, "tempioolbia": _75, "teramo": _75, "terni": _75, "tn": _75, "to": _75, "torino": _75, "tp": _75, "tr": _75, "trani-andria-barletta": _75, "trani-barletta-andria": _75, "traniandriabarletta": _75, "tranibarlettaandria": _75, "trapani": _75, "trento": _75, "treviso": _75, "trieste": _75, "ts": _75, "turin": _75, "tv": _75, "ud": _75, "udine": _75, "urbino-pesaro": _75, "urbinopesaro": _75, "va": _75, "varese": _75, "vb": _75, "vc": _75, "ve": _75, "venezia": _75, "venice": _75, "verbania": _75, "vercelli": _75, "verona": _75, "vi": _75, "vibo-valentia": _75, "vibovalentia": _75, "vicenza": _75, "viterbo": _75, "vr": _75, "vs": _75, "vt": _75, "vv": _75 }], "je": _82, "jm": _79, "jo": [1, { "agri": _75, "ai": _75, "com": _75, "edu": _75, "eng": _75, "fm": _75, "gov": _75, "mil": _75, "net": _75, "org": _75, "per": _75, "phd": _75, "sch": _75, "tv": _75 }], "jobs": _75, "jp": [1, { "ac": _75, "ad": _75, "co": _75, "ed": _75, "go": _75, "gr": _75, "lg": _75, "ne": _75, "or": _75, "aichi": [1, { "aisai": _75, "ama": _75, "anjo": _75, "asuke": _75, "chiryu": _75, "chita": _75, "fuso": _75, "gamagori": _75, "handa": _75, "hazu": _75, "hekinan": _75, "higashiura": _75, "ichinomiya": _75, "inazawa": _75, "inuyama": _75, "isshiki": _75, "iwakura": _75, "kanie": _75, "kariya": _75, "kasugai": _75, "kira": _75, "kiyosu": _75, "komaki": _75, "konan": _75, "kota": _75, "mihama": _75, "miyoshi": _75, "nishio": _75, "nisshin": _75, "obu": _75, "oguchi": _75, "oharu": _75, "okazaki": _75, "owariasahi": _75, "seto": _75, "shikatsu": _75, "shinshiro": _75, "shitara": _75, "tahara": _75, "takahama": _75, "tobishima": _75, "toei": _75, "togo": _75, "tokai": _75, "tokoname": _75, "toyoake": _75, "toyohashi": _75, "toyokawa": _75, "toyone": _75, "toyota": _75, "tsushima": _75, "yatomi": _75 }], "akita": [1, { "akita": _75, "daisen": _75, "fujisato": _75, "gojome": _75, "hachirogata": _75, "happou": _75, "higashinaruse": _75, "honjo": _75, "honjyo": _75, "ikawa": _75, "kamikoani": _75, "kamioka": _75, "katagami": _75, "kazuno": _75, "kitaakita": _75, "kosaka": _75, "kyowa": _75, "misato": _75, "mitane": _75, "moriyoshi": _75, "nikaho": _75, "noshiro": _75, "odate": _75, "oga": _75, "ogata": _75, "semboku": _75, "yokote": _75, "yurihonjo": _75 }], "aomori": [1, { "aomori": _75, "gonohe": _75, "hachinohe": _75, "hashikami": _75, "hiranai": _75, "hirosaki": _75, "itayanagi": _75, "kuroishi": _75, "misawa": _75, "mutsu": _75, "nakadomari": _75, "noheji": _75, "oirase": _75, "owani": _75, "rokunohe": _75, "sannohe": _75, "shichinohe": _75, "shingo": _75, "takko": _75, "towada": _75, "tsugaru": _75, "tsuruta": _75 }], "chiba": [1, { "abiko": _75, "asahi": _75, "chonan": _75, "chosei": _75, "choshi": _75, "chuo": _75, "funabashi": _75, "futtsu": _75, "hanamigawa": _75, "ichihara": _75, "ichikawa": _75, "ichinomiya": _75, "inzai": _75, "isumi": _75, "kamagaya": _75, "kamogawa": _75, "kashiwa": _75, "katori": _75, "katsuura": _75, "kimitsu": _75, "kisarazu": _75, "kozaki": _75, "kujukuri": _75, "kyonan": _75, "matsudo": _75, "midori": _75, "mihama": _75, "minamiboso": _75, "mobara": _75, "mutsuzawa": _75, "nagara": _75, "nagareyama": _75, "narashino": _75, "narita": _75, "noda": _75, "oamishirasato": _75, "omigawa": _75, "onjuku": _75, "otaki": _75, "sakae": _75, "sakura": _75, "shimofusa": _75, "shirako": _75, "shiroi": _75, "shisui": _75, "sodegaura": _75, "sosa": _75, "tako": _75, "tateyama": _75, "togane": _75, "tohnosho": _75, "tomisato": _75, "urayasu": _75, "yachimata": _75, "yachiyo": _75, "yokaichiba": _75, "yokoshibahikari": _75, "yotsukaido": _75 }], "ehime": [1, { "ainan": _75, "honai": _75, "ikata": _75, "imabari": _75, "iyo": _75, "kamijima": _75, "kihoku": _75, "kumakogen": _75, "masaki": _75, "matsuno": _75, "matsuyama": _75, "namikata": _75, "niihama": _75, "ozu": _75, "saijo": _75, "seiyo": _75, "shikokuchuo": _75, "tobe": _75, "toon": _75, "uchiko": _75, "uwajima": _75, "yawatahama": _75 }], "fukui": [1, { "echizen": _75, "eiheiji": _75, "fukui": _75, "ikeda": _75, "katsuyama": _75, "mihama": _75, "minamiechizen": _75, "obama": _75, "ohi": _75, "ono": _75, "sabae": _75, "sakai": _75, "takahama": _75, "tsuruga": _75, "wakasa": _75 }], "fukuoka": [1, { "ashiya": _75, "buzen": _75, "chikugo": _75, "chikuho": _75, "chikujo": _75, "chikushino": _75, "chikuzen": _75, "chuo": _75, "dazaifu": _75, "fukuchi": _75, "hakata": _75, "higashi": _75, "hirokawa": _75, "hisayama": _75, "iizuka": _75, "inatsuki": _75, "kaho": _75, "kasuga": _75, "kasuya": _75, "kawara": _75, "keisen": _75, "koga": _75, "kurate": _75, "kurogi": _75, "kurume": _75, "minami": _75, "miyako": _75, "miyama": _75, "miyawaka": _75, "mizumaki": _75, "munakata": _75, "nakagawa": _75, "nakama": _75, "nishi": _75, "nogata": _75, "ogori": _75, "okagaki": _75, "okawa": _75, "oki": _75, "omuta": _75, "onga": _75, "onojo": _75, "oto": _75, "saigawa": _75, "sasaguri": _75, "shingu": _75, "shinyoshitomi": _75, "shonai": _75, "soeda": _75, "sue": _75, "tachiarai": _75, "tagawa": _75, "takata": _75, "toho": _75, "toyotsu": _75, "tsuiki": _75, "ukiha": _75, "umi": _75, "usui": _75, "yamada": _75, "yame": _75, "yanagawa": _75, "yukuhashi": _75 }], "fukushima": [1, { "aizubange": _75, "aizumisato": _75, "aizuwakamatsu": _75, "asakawa": _75, "bandai": _75, "date": _75, "fukushima": _75, "furudono": _75, "futaba": _75, "hanawa": _75, "higashi": _75, "hirata": _75, "hirono": _75, "iitate": _75, "inawashiro": _75, "ishikawa": _75, "iwaki": _75, "izumizaki": _75, "kagamiishi": _75, "kaneyama": _75, "kawamata": _75, "kitakata": _75, "kitashiobara": _75, "koori": _75, "koriyama": _75, "kunimi": _75, "miharu": _75, "mishima": _75, "namie": _75, "nango": _75, "nishiaizu": _75, "nishigo": _75, "okuma": _75, "omotego": _75, "ono": _75, "otama": _75, "samegawa": _75, "shimogo": _75, "shirakawa": _75, "showa": _75, "soma": _75, "sukagawa": _75, "taishin": _75, "tamakawa": _75, "tanagura": _75, "tenei": _75, "yabuki": _75, "yamato": _75, "yamatsuri": _75, "yanaizu": _75, "yugawa": _75 }], "gifu": [1, { "anpachi": _75, "ena": _75, "gifu": _75, "ginan": _75, "godo": _75, "gujo": _75, "hashima": _75, "hichiso": _75, "hida": _75, "higashishirakawa": _75, "ibigawa": _75, "ikeda": _75, "kakamigahara": _75, "kani": _75, "kasahara": _75, "kasamatsu": _75, "kawaue": _75, "kitagata": _75, "mino": _75, "minokamo": _75, "mitake": _75, "mizunami": _75, "motosu": _75, "nakatsugawa": _75, "ogaki": _75, "sakahogi": _75, "seki": _75, "sekigahara": _75, "shirakawa": _75, "tajimi": _75, "takayama": _75, "tarui": _75, "toki": _75, "tomika": _75, "wanouchi": _75, "yamagata": _75, "yaotsu": _75, "yoro": _75 }], "gunma": [1, { "annaka": _75, "chiyoda": _75, "fujioka": _75, "higashiagatsuma": _75, "isesaki": _75, "itakura": _75, "kanna": _75, "kanra": _75, "katashina": _75, "kawaba": _75, "kiryu": _75, "kusatsu": _75, "maebashi": _75, "meiwa": _75, "midori": _75, "minakami": _75, "naganohara": _75, "nakanojo": _75, "nanmoku": _75, "numata": _75, "oizumi": _75, "ora": _75, "ota": _75, "shibukawa": _75, "shimonita": _75, "shinto": _75, "showa": _75, "takasaki": _75, "takayama": _75, "tamamura": _75, "tatebayashi": _75, "tomioka": _75, "tsukiyono":