| | |
| | | 'use strict'; |
| | | // based on https://github.com/bestiejs/punycode.js/blob/master/punycode.js |
| | | var global = require('../internals/global'); |
| | | var uncurryThis = require('../internals/function-uncurry-this'); |
| | | |
| | | var maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 |
| | | var base = 36; |
| | | var tMin = 1; |
| | |
| | | var regexSeparators = /[.\u3002\uFF0E\uFF61]/g; // RFC 3490 separators |
| | | var OVERFLOW_ERROR = 'Overflow: input needs wider integers to process'; |
| | | var baseMinusTMin = base - tMin; |
| | | |
| | | var RangeError = global.RangeError; |
| | | var exec = uncurryThis(regexSeparators.exec); |
| | | var floor = Math.floor; |
| | | var stringFromCharCode = String.fromCharCode; |
| | | var fromCharCode = String.fromCharCode; |
| | | var charCodeAt = uncurryThis(''.charCodeAt); |
| | | var join = uncurryThis([].join); |
| | | var push = uncurryThis([].push); |
| | | var replace = uncurryThis(''.replace); |
| | | var split = uncurryThis(''.split); |
| | | var toLowerCase = uncurryThis(''.toLowerCase); |
| | | |
| | | /** |
| | | * Creates an array containing the numeric code points of each Unicode |
| | |
| | | var counter = 0; |
| | | var length = string.length; |
| | | while (counter < length) { |
| | | var value = string.charCodeAt(counter++); |
| | | var value = charCodeAt(string, counter++); |
| | | if (value >= 0xD800 && value <= 0xDBFF && counter < length) { |
| | | // It's a high surrogate, and there is a next character. |
| | | var extra = string.charCodeAt(counter++); |
| | | var extra = charCodeAt(string, counter++); |
| | | if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. |
| | | output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000); |
| | | push(output, ((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); |
| | | push(output, value); |
| | | counter--; |
| | | } |
| | | } else { |
| | | output.push(value); |
| | | push(output, value); |
| | | } |
| | | } |
| | | return output; |
| | |
| | | var k = 0; |
| | | delta = firstTime ? floor(delta / damp) : delta >> 1; |
| | | delta += floor(delta / numPoints); |
| | | for (; delta > baseMinusTMin * tMax >> 1; k += base) { |
| | | while (delta > baseMinusTMin * tMax >> 1) { |
| | | delta = floor(delta / baseMinusTMin); |
| | | k += base; |
| | | } |
| | | 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 -- TODO |
| | | var encode = function (input) { |
| | | var output = []; |
| | | |
| | |
| | | for (i = 0; i < input.length; i++) { |
| | | currentValue = input[i]; |
| | | if (currentValue < 0x80) { |
| | | output.push(stringFromCharCode(currentValue)); |
| | | push(output, fromCharCode(currentValue)); |
| | | } |
| | | } |
| | | |
| | |
| | | |
| | | // Finish the basic string with a delimiter unless it's empty. |
| | | if (basicLength) { |
| | | output.push(delimiter); |
| | | push(output, delimiter); |
| | | } |
| | | |
| | | // Main encoding loop: |
| | |
| | | if (currentValue == n) { |
| | | // Represent delta as a generalized variable-length integer. |
| | | var q = delta; |
| | | for (var k = base; /* no condition */; k += base) { |
| | | var k = base; |
| | | while (true) { |
| | | 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))); |
| | | push(output, fromCharCode(digitToBasic(t + qMinusT % baseMinusT))); |
| | | q = floor(qMinusT / baseMinusT); |
| | | k += base; |
| | | } |
| | | |
| | | output.push(stringFromCharCode(digitToBasic(q))); |
| | | push(output, fromCharCode(digitToBasic(q))); |
| | | bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); |
| | | delta = 0; |
| | | ++handledCPCount; |
| | | handledCPCount++; |
| | | } |
| | | } |
| | | |
| | | ++delta; |
| | | ++n; |
| | | delta++; |
| | | n++; |
| | | } |
| | | return output.join(''); |
| | | return join(output, ''); |
| | | }; |
| | | |
| | | module.exports = function (input) { |
| | | var encoded = []; |
| | | var labels = input.toLowerCase().replace(regexSeparators, '\u002E').split('.'); |
| | | var labels = split(replace(toLowerCase(input), regexSeparators, '\u002E'), '.'); |
| | | var i, label; |
| | | for (i = 0; i < labels.length; i++) { |
| | | label = labels[i]; |
| | | encoded.push(regexNonASCII.test(label) ? 'xn--' + encode(label) : label); |
| | | push(encoded, exec(regexNonASCII, label) ? 'xn--' + encode(label) : label); |
| | | } |
| | | return encoded.join('.'); |
| | | return join(encoded, '.'); |
| | | }; |