You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							168 lines
						
					
					
						
							5.1 KiB
						
					
					
				
			
		
		
	
	
							168 lines
						
					
					
						
							5.1 KiB
						
					
					
				'use strict'; | 
						|
// based on https://github.com/bestiejs/punycode.js/blob/master/punycode.js | 
						|
var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 | 
						|
var base = 36; | 
						|
var tMin = 1; | 
						|
var tMax = 26; | 
						|
var skew = 38; | 
						|
var damp = 700; | 
						|
var initialBias = 72; | 
						|
var initialN = 128; // 0x80 | 
						|
var delimiter = '-'; // '\x2D' | 
						|
var regexNonASCII = /[^\0-\u007E]/; // non-ASCII chars | 
						|
var regexSeparators = /[.\u3002\uFF0E\uFF61]/g; // RFC 3490 separators | 
						|
var OVERFLOW_ERROR = 'Overflow: input needs wider integers to process'; | 
						|
var baseMinusTMin = base - tMin; | 
						|
var floor = Math.floor; | 
						|
var stringFromCharCode = String.fromCharCode; | 
						|
 | 
						|
/** | 
						|
 * Creates an array containing the numeric code points of each Unicode | 
						|
 * character in the string. While JavaScript uses UCS-2 internally, | 
						|
 * this function will convert a pair of surrogate halves (each of which | 
						|
 * UCS-2 exposes as separate characters) into a single code point, | 
						|
 * matching UTF-16. | 
						|
 */ | 
						|
var ucs2decode = function (string) { | 
						|
  var output = []; | 
						|
  var counter = 0; | 
						|
  var length = string.length; | 
						|
  while (counter < length) { | 
						|
    var value = string.charCodeAt(counter++); | 
						|
    if (value >= 0xD800 && value <= 0xDBFF && counter < length) { | 
						|
      // It's a high surrogate, and there is a next character. | 
						|
      var extra = string.charCodeAt(counter++); | 
						|
      if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. | 
						|
        output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); | 
						|
      } else { | 
						|
        // It's an unmatched surrogate; only append this code unit, in case the | 
						|
        // next code unit is the high surrogate of a surrogate pair. | 
						|
        output.push(value); | 
						|
        counter--; | 
						|
      } | 
						|
    } else { | 
						|
      output.push(value); | 
						|
    } | 
						|
  } | 
						|
  return output; | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * Converts a digit/integer into a basic code point. | 
						|
 */ | 
						|
var digitToBasic = function (digit) { | 
						|
  //  0..25 map to ASCII a..z or A..Z | 
						|
  // 26..35 map to ASCII 0..9 | 
						|
  return digit + 22 + 75 * (digit < 26); | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * Bias adaptation function as per section 3.4 of RFC 3492. | 
						|
 * https://tools.ietf.org/html/rfc3492#section-3.4 | 
						|
 */ | 
						|
var adapt = function (delta, numPoints, firstTime) { | 
						|
  var k = 0; | 
						|
  delta = firstTime ? floor(delta / damp) : delta >> 1; | 
						|
  delta += floor(delta / numPoints); | 
						|
  for (; delta > baseMinusTMin * tMax >> 1; k += base) { | 
						|
    delta = floor(delta / baseMinusTMin); | 
						|
  } | 
						|
  return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); | 
						|
}; | 
						|
 | 
						|
/** | 
						|
 * Converts a string of Unicode symbols (e.g. a domain name label) to a | 
						|
 * Punycode string of ASCII-only symbols. | 
						|
 */ | 
						|
// eslint-disable-next-line  max-statements | 
						|
var encode = function (input) { | 
						|
  var output = []; | 
						|
 | 
						|
  // Convert the input in UCS-2 to an array of Unicode code points. | 
						|
  input = ucs2decode(input); | 
						|
 | 
						|
  // Cache the length. | 
						|
  var inputLength = input.length; | 
						|
 | 
						|
  // Initialize the state. | 
						|
  var n = initialN; | 
						|
  var delta = 0; | 
						|
  var bias = initialBias; | 
						|
  var i, currentValue; | 
						|
 | 
						|
  // Handle the basic code points. | 
						|
  for (i = 0; i < input.length; i++) { | 
						|
    currentValue = input[i]; | 
						|
    if (currentValue < 0x80) { | 
						|
      output.push(stringFromCharCode(currentValue)); | 
						|
    } | 
						|
  } | 
						|
 | 
						|
  var basicLength = output.length; // number of basic code points. | 
						|
  var handledCPCount = basicLength; // number of code points that have been handled; | 
						|
 | 
						|
  // Finish the basic string with a delimiter unless it's empty. | 
						|
  if (basicLength) { | 
						|
    output.push(delimiter); | 
						|
  } | 
						|
 | 
						|
  // Main encoding loop: | 
						|
  while (handledCPCount < inputLength) { | 
						|
    // All non-basic code points < n have been handled already. Find the next larger one: | 
						|
    var m = maxInt; | 
						|
    for (i = 0; i < input.length; i++) { | 
						|
      currentValue = input[i]; | 
						|
      if (currentValue >= n && currentValue < m) { | 
						|
        m = currentValue; | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    // Increase `delta` enough to advance the decoder's <n,i> state to <m,0>, but guard against overflow. | 
						|
    var handledCPCountPlusOne = handledCPCount + 1; | 
						|
    if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { | 
						|
      throw RangeError(OVERFLOW_ERROR); | 
						|
    } | 
						|
 | 
						|
    delta += (m - n) * handledCPCountPlusOne; | 
						|
    n = m; | 
						|
 | 
						|
    for (i = 0; i < input.length; i++) { | 
						|
      currentValue = input[i]; | 
						|
      if (currentValue < n && ++delta > maxInt) { | 
						|
        throw RangeError(OVERFLOW_ERROR); | 
						|
      } | 
						|
      if (currentValue == n) { | 
						|
        // Represent delta as a generalized variable-length integer. | 
						|
        var q = delta; | 
						|
        for (var k = base; /* no condition */; k += base) { | 
						|
          var t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); | 
						|
          if (q < t) break; | 
						|
          var qMinusT = q - t; | 
						|
          var baseMinusT = base - t; | 
						|
          output.push(stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT))); | 
						|
          q = floor(qMinusT / baseMinusT); | 
						|
        } | 
						|
 | 
						|
        output.push(stringFromCharCode(digitToBasic(q))); | 
						|
        bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); | 
						|
        delta = 0; | 
						|
        ++handledCPCount; | 
						|
      } | 
						|
    } | 
						|
 | 
						|
    ++delta; | 
						|
    ++n; | 
						|
  } | 
						|
  return output.join(''); | 
						|
}; | 
						|
 | 
						|
module.exports = function (input) { | 
						|
  var encoded = []; | 
						|
  var labels = input.toLowerCase().replace(regexSeparators, '\u002E').split('.'); | 
						|
  var i, label; | 
						|
  for (i = 0; i < labels.length; i++) { | 
						|
    label = labels[i]; | 
						|
    encoded.push(regexNonASCII.test(label) ? 'xn--' + encode(label) : label); | 
						|
  } | 
						|
  return encoded.join('.'); | 
						|
};
 | 
						|
 |