var proxy = __PROXY__; var direct = 'DIRECT'; var directDomains = __DIRECT_DOMAINS__; var domainsUsingProxy = __DOMAINS__; var localTlds = __LOCAL_TLDS__; var cnips = __CN_IPS__; var hasOwnProperty = Object.hasOwnProperty; var ipRegExp = new RegExp(/^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/); function isIPv6(ip) { // Split the IP address into groups of hexadecimal digits const groups = ip.split(':'); // An IPv6 address must have at least one group and at most 8 groups if (groups.length < 1 || groups.length > 8) { return false; } // Check that each group is a valid hexadecimal number for (const group of groups) { // Check that the group is not null, undefined, or an empty string before calling parseInt() if (group === null || group === undefined || group === '') { continue; } // Use parseInt() to check if the group is a valid hexadecimal number const value = parseInt(group, 16); if (isNaN(value) || value < 0 || value > 0xFFFF) { return false; } } // If the address contains a double colon, ensure that it appears only once if (ip.includes('::')) { if (ip.indexOf('::') !== ip.lastIndexOf('::')) { return false; } } // The address is valid if it passes all the checks return true; } function convertAddress(ipchars) { var bytes = ipchars.split('.'); var result = ((bytes[0] & 0xff) << 24) | ((bytes[1] & 0xff) << 16) | ((bytes[2] & 0xff) << 8) | (bytes[3] & 0xff); return result; } function match(ip) { var left = 0, right = cnips.length; do { var mid = Math.floor((left + right) / 2), ipf = (ip & cnips[mid][1]) >>> 0, m = (cnips[mid][0] & cnips[mid][1]) >>> 0; if (ipf == m) { return true; } else if (ipf > m) { left = mid + 1; } else { right = mid; } } while (left + 1 <= right) return false; } function isInDirectDomain(host) { if (hasOwnProperty.call(directDomains, host)) { return true; } for (var domain in directDomains) { if (host.endsWith('.' + domain)) { return true; } } return false; } function isInProxyDomain(host) { if (hasOwnProperty.call(domainsUsingProxy, host)) { return true; } for (var domain in domainsUsingProxy) { if (host.endsWith('.' + domain)) { return true; } } return false; } function isLocalTestDomain(domain) { // Chrome uses .test as testing gTLD. var tld = domain.substring(domain.lastIndexOf('.')); if (tld === domain) { return false; } return Object.hasOwnProperty.call(localTlds, tld); } /* https://github.com/frenchbread/private-ip */ function isPrivateIp(ip) { return /^(::f{4}:)?10\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^(::f{4}:)?192\.168\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^(::f{4}:)?172\.(1[6-9]|2\d|30|31)\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^(::f{4}:)?127\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^(::f{4}:)?169\.254\.([0-9]{1,3})\.([0-9]{1,3})$/i.test(ip) || /^f[cd][0-9a-f]{2}:/i.test(ip) || /^fe80:/i.test(ip) || /^::1$/.test(ip) || /^::$/.test(ip); } function FindProxyForURL(url, host) { if (isPlainHostName(host) || isPrivateIp(host) || isLocalTestDomain(host) || host === 'localhost') { return direct; } if (shExpMatch(url, "http:*")) { return direct; } if (!ipRegExp.test(host)) { if (isInDirectDomain(host)) { return direct } if (isInProxyDomain(host)) { return proxy; } strIp = dnsResolve(host); } else { strIp = host } if (!strIp) { return proxy; } intIp = convertAddress(strIp); if (match(intIp)) { return direct; } return proxy; }