| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 /* |  | 
| 2  * Copyright (C) 2011-2016 Mathias Bynens <https://mathiasbynens.be/> |  | 
| 3  * Copyright (C) 2016-present eyeo GmbH (Minor modifications for compatibility.) |  | 
| 4  * |  | 
| 5  * Permission is hereby granted, free of charge, to any person obtaining |  | 
| 6  * a copy of this software and associated documentation files (the |  | 
| 7  * "Software"), to deal in the Software without restriction, including |  | 
| 8  * without limitation the rights to use, copy, modify, merge, publish, |  | 
| 9  * distribute, sublicense, and/or sell copies of the Software, and to |  | 
| 10  * permit persons to whom the Software is furnished to do so, subject to |  | 
| 11  * the following conditions: |  | 
| 12  * |  | 
| 13  * The above copyright notice and this permission notice shall be |  | 
| 14  * included in all copies or substantial portions of the Software. |  | 
| 15  * |  | 
| 16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |  | 
| 17  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |  | 
| 18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |  | 
| 19  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE |  | 
| 20  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION |  | 
| 21  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |  | 
| 22  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |  | 
| 23  */ |  | 
| 24 |  | 
| 25 'use strict'; |  | 
| 26 |  | 
| 27 /** Highest positive signed 32-bit float value */ |  | 
| 28 const maxInt = 2147483647; // aka. 0x7FFFFFFF or 2^31-1 |  | 
| 29 |  | 
| 30 /** Bootstring parameters */ |  | 
| 31 const base = 36; |  | 
| 32 const tMin = 1; |  | 
| 33 const tMax = 26; |  | 
| 34 const skew = 38; |  | 
| 35 const damp = 700; |  | 
| 36 const initialBias = 72; |  | 
| 37 const initialN = 128; // 0x80 |  | 
| 38 const delimiter = '-'; // '\x2D' |  | 
| 39 |  | 
| 40 /** Regular expressions */ |  | 
| 41 const regexPunycode = /^xn--/; |  | 
| 42 const regexNonASCII = /[^\x20-\x7E]/; // unprintable ASCII chars + non-ASCII cha
     rs |  | 
| 43 const regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g; // RFC 3490 separators |  | 
| 44 |  | 
| 45 /** Error messages */ |  | 
| 46 const errors = { |  | 
| 47         'overflow': 'Overflow: input needs wider integers to process', |  | 
| 48         'not-basic': 'Illegal input >= 0x80 (not a basic code point)', |  | 
| 49         'invalid-input': 'Invalid input' |  | 
| 50 }; |  | 
| 51 |  | 
| 52 /** Convenience shortcuts */ |  | 
| 53 const baseMinusTMin = base - tMin; |  | 
| 54 const floor = Math.floor; |  | 
| 55 const stringFromCharCode = String.fromCharCode; |  | 
| 56 |  | 
| 57 /*--------------------------------------------------------------------------*/ |  | 
| 58 |  | 
| 59 /** |  | 
| 60  * A generic error utility function. |  | 
| 61  * @private |  | 
| 62  * @param {String} type The error type. |  | 
| 63  * @returns {Error} Throws a `RangeError` with the applicable error message. |  | 
| 64  */ |  | 
| 65 function error(type) { |  | 
| 66         throw new RangeError(errors[type]); |  | 
| 67 } |  | 
| 68 |  | 
| 69 /** |  | 
| 70  * A generic `Array#map` utility function. |  | 
| 71  * @private |  | 
| 72  * @param {Array} array The array to iterate over. |  | 
| 73  * @param {Function} callback The function that gets called for every array |  | 
| 74  * item. |  | 
| 75  * @returns {Array} A new array of values returned by the callback function. |  | 
| 76  */ |  | 
| 77 function map(array, fn) { |  | 
| 78         const result = []; |  | 
| 79         let length = array.length; |  | 
| 80         while (length--) { |  | 
| 81                 result[length] = fn(array[length]); |  | 
| 82         } |  | 
| 83         return result; |  | 
| 84 } |  | 
| 85 |  | 
| 86 /** |  | 
| 87  * A simple `Array#map`-like wrapper to work with domain name strings or email |  | 
| 88  * addresses. |  | 
| 89  * @private |  | 
| 90  * @param {String} domain The domain name or email address. |  | 
| 91  * @param {Function} callback The function that gets called for every |  | 
| 92  * character. |  | 
| 93  * @returns {Array} A new string of characters returned by the callback |  | 
| 94  * function. |  | 
| 95  */ |  | 
| 96 function mapDomain(string, fn) { |  | 
| 97         const parts = string.split('@'); |  | 
| 98         let result = ''; |  | 
| 99         if (parts.length > 1) { |  | 
| 100                 // In email addresses, only the domain name should be punycoded.
      Leave |  | 
| 101                 // the local part (i.e. everything up to `@`) intact. |  | 
| 102                 result = parts[0] + '@'; |  | 
| 103                 string = parts[1]; |  | 
| 104         } |  | 
| 105         // Avoid `split(regex)` for IE8 compatibility. See #17. |  | 
| 106         string = string.replace(regexSeparators, '\x2E'); |  | 
| 107         const labels = string.split('.'); |  | 
| 108         const encoded = map(labels, fn).join('.'); |  | 
| 109         return result + encoded; |  | 
| 110 } |  | 
| 111 |  | 
| 112 /** |  | 
| 113  * Creates an array containing the numeric code points of each Unicode |  | 
| 114  * character in the string. While JavaScript uses UCS-2 internally, |  | 
| 115  * this function will convert a pair of surrogate halves (each of which |  | 
| 116  * UCS-2 exposes as separate characters) into a single code point, |  | 
| 117  * matching UTF-16. |  | 
| 118  * @see `punycode.ucs2.encode` |  | 
| 119  * @see <https://mathiasbynens.be/notes/javascript-encoding> |  | 
| 120  * @memberOf punycode.ucs2 |  | 
| 121  * @name decode |  | 
| 122  * @param {String} string The Unicode input string (UCS-2). |  | 
| 123  * @returns {Array} The new array of code points. |  | 
| 124  */ |  | 
| 125 function ucs2decode(string) { |  | 
| 126         const output = []; |  | 
| 127         let counter = 0; |  | 
| 128         const length = string.length; |  | 
| 129         while (counter < length) { |  | 
| 130                 const value = string.charCodeAt(counter++); |  | 
| 131                 if (value >= 0xD800 && value <= 0xDBFF && counter < length) { |  | 
| 132                         // It's a high surrogate, and there is a next character. |  | 
| 133                         const extra = string.charCodeAt(counter++); |  | 
| 134                         if ((extra & 0xFC00) == 0xDC00) { // Low surrogate. |  | 
| 135                                 output.push(((value & 0x3FF) << 10) + (extra & 0
     x3FF) + 0x10000); |  | 
| 136                         } else { |  | 
| 137                                 // It's an unmatched surrogate; only append this
      code unit, in case the |  | 
| 138                                 // next code unit is the high surrogate of a sur
     rogate pair. |  | 
| 139                                 output.push(value); |  | 
| 140                                 counter--; |  | 
| 141                         } |  | 
| 142                 } else { |  | 
| 143                         output.push(value); |  | 
| 144                 } |  | 
| 145         } |  | 
| 146         return output; |  | 
| 147 } |  | 
| 148 |  | 
| 149 /** |  | 
| 150  * Creates a string based on an array of numeric code points. |  | 
| 151  * @see `punycode.ucs2.decode` |  | 
| 152  * @memberOf punycode.ucs2 |  | 
| 153  * @name encode |  | 
| 154  * @param {Array} codePoints The array of numeric code points. |  | 
| 155  * @returns {String} The new Unicode string (UCS-2). |  | 
| 156  */ |  | 
| 157 const ucs2encode = array => String.fromCodePoint.apply(null, array); |  | 
| 158 |  | 
| 159 /** |  | 
| 160  * Converts a basic code point into a digit/integer. |  | 
| 161  * @see `digitToBasic()` |  | 
| 162  * @private |  | 
| 163  * @param {Number} codePoint The basic numeric code point value. |  | 
| 164  * @returns {Number} The numeric value of a basic code point (for use in |  | 
| 165  * representing integers) in the range `0` to `base - 1`, or `base` if |  | 
| 166  * the code point does not represent a value. |  | 
| 167  */ |  | 
| 168 const basicToDigit = function(codePoint) { |  | 
| 169         if (codePoint - 0x30 < 0x0A) { |  | 
| 170                 return codePoint - 0x16; |  | 
| 171         } |  | 
| 172         if (codePoint - 0x41 < 0x1A) { |  | 
| 173                 return codePoint - 0x41; |  | 
| 174         } |  | 
| 175         if (codePoint - 0x61 < 0x1A) { |  | 
| 176                 return codePoint - 0x61; |  | 
| 177         } |  | 
| 178         return base; |  | 
| 179 }; |  | 
| 180 |  | 
| 181 /** |  | 
| 182  * Converts a digit/integer into a basic code point. |  | 
| 183  * @see `basicToDigit()` |  | 
| 184  * @private |  | 
| 185  * @param {Number} digit The numeric value of a basic code point. |  | 
| 186  * @returns {Number} The basic code point whose value (when used for |  | 
| 187  * representing integers) is `digit`, which needs to be in the range |  | 
| 188  * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is |  | 
| 189  * used; else, the lowercase form is used. The behavior is undefined |  | 
| 190  * if `flag` is non-zero and `digit` has no uppercase form. |  | 
| 191  */ |  | 
| 192 const digitToBasic = function(digit, flag) { |  | 
| 193         //  0..25 map to ASCII a..z or A..Z |  | 
| 194         // 26..35 map to ASCII 0..9 |  | 
| 195         return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); |  | 
| 196 }; |  | 
| 197 |  | 
| 198 /** |  | 
| 199  * Bias adaptation function as per section 3.4 of RFC 3492. |  | 
| 200  * https://tools.ietf.org/html/rfc3492#section-3.4 |  | 
| 201  * @private |  | 
| 202  */ |  | 
| 203 const adapt = function(delta, numPoints, firstTime) { |  | 
| 204         let k = 0; |  | 
| 205         delta = firstTime ? floor(delta / damp) : delta >> 1; |  | 
| 206         delta += floor(delta / numPoints); |  | 
| 207         for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += ba
     se) { |  | 
| 208                 delta = floor(delta / baseMinusTMin); |  | 
| 209         } |  | 
| 210         return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); |  | 
| 211 }; |  | 
| 212 |  | 
| 213 /** |  | 
| 214  * Converts a Punycode string of ASCII-only symbols to a string of Unicode |  | 
| 215  * symbols. |  | 
| 216  * @memberOf punycode |  | 
| 217  * @param {String} input The Punycode string of ASCII-only symbols. |  | 
| 218  * @returns {String} The resulting string of Unicode symbols. |  | 
| 219  */ |  | 
| 220 const decode = function(input) { |  | 
| 221         // Don't use UCS-2. |  | 
| 222         const output = []; |  | 
| 223         const inputLength = input.length; |  | 
| 224         let i = 0; |  | 
| 225         let n = initialN; |  | 
| 226         let bias = initialBias; |  | 
| 227 |  | 
| 228         // Handle the basic code points: let `basic` be the number of input code |  | 
| 229         // points before the last delimiter, or `0` if there is none, then copy |  | 
| 230         // the first basic code points to the output. |  | 
| 231 |  | 
| 232         let basic = input.lastIndexOf(delimiter); |  | 
| 233         if (basic < 0) { |  | 
| 234                 basic = 0; |  | 
| 235         } |  | 
| 236 |  | 
| 237         for (let j = 0; j < basic; ++j) { |  | 
| 238                 // if it's not a basic code point |  | 
| 239                 if (input.charCodeAt(j) >= 0x80) { |  | 
| 240                         error('not-basic'); |  | 
| 241                 } |  | 
| 242                 output.push(input.charCodeAt(j)); |  | 
| 243         } |  | 
| 244 |  | 
| 245         // Main decoding loop: start just after the last delimiter if any basic 
     code |  | 
| 246         // points were copied; start at the beginning otherwise. |  | 
| 247 |  | 
| 248         for (let index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no f
     inal expression */) { |  | 
| 249 |  | 
| 250                 // `index` is the index of the next character to be consumed. |  | 
| 251                 // Decode a generalized variable-length integer into `delta`, |  | 
| 252                 // which gets added to `i`. The overflow checking is easier |  | 
| 253                 // if we increase `i` as we go, then subtract off its starting |  | 
| 254                 // value at the end to obtain `delta`. |  | 
| 255                 let oldi = i; |  | 
| 256                 for (let w = 1, k = base; /* no condition */; k += base) { |  | 
| 257 |  | 
| 258                         if (index >= inputLength) { |  | 
| 259                                 error('invalid-input'); |  | 
| 260                         } |  | 
| 261 |  | 
| 262                         const digit = basicToDigit(input.charCodeAt(index++)); |  | 
| 263 |  | 
| 264                         if (digit >= base || digit > floor((maxInt - i) / w)) { |  | 
| 265                                 error('overflow'); |  | 
| 266                         } |  | 
| 267 |  | 
| 268                         i += digit * w; |  | 
| 269                         const t = k <= bias ? tMin : (k >= bias + tMax ? tMax : 
     k - bias); |  | 
| 270 |  | 
| 271                         if (digit < t) { |  | 
| 272                                 break; |  | 
| 273                         } |  | 
| 274 |  | 
| 275                         const baseMinusT = base - t; |  | 
| 276                         if (w > floor(maxInt / baseMinusT)) { |  | 
| 277                                 error('overflow'); |  | 
| 278                         } |  | 
| 279 |  | 
| 280                         w *= baseMinusT; |  | 
| 281 |  | 
| 282                 } |  | 
| 283 |  | 
| 284                 const out = output.length + 1; |  | 
| 285                 bias = adapt(i - oldi, out, oldi == 0); |  | 
| 286 |  | 
| 287                 // `i` was supposed to wrap around from `out` to `0`, |  | 
| 288                 // incrementing `n` each time, so we'll fix that now: |  | 
| 289                 if (floor(i / out) > maxInt - n) { |  | 
| 290                         error('overflow'); |  | 
| 291                 } |  | 
| 292 |  | 
| 293                 n += floor(i / out); |  | 
| 294                 i %= out; |  | 
| 295 |  | 
| 296                 // Insert `n` at position `i` of the output. |  | 
| 297                 output.splice(i++, 0, n); |  | 
| 298 |  | 
| 299         } |  | 
| 300 |  | 
| 301         return String.fromCodePoint.apply(null, output); |  | 
| 302 }; |  | 
| 303 |  | 
| 304 /** |  | 
| 305  * Converts a string of Unicode symbols (e.g. a domain name label) to a |  | 
| 306  * Punycode string of ASCII-only symbols. |  | 
| 307  * @memberOf punycode |  | 
| 308  * @param {String} input The string of Unicode symbols. |  | 
| 309  * @returns {String} The resulting Punycode string of ASCII-only symbols. |  | 
| 310  */ |  | 
| 311 const encode = function(input) { |  | 
| 312         const output = []; |  | 
| 313 |  | 
| 314         // Convert the input in UCS-2 to an array of Unicode code points. |  | 
| 315         input = ucs2decode(input); |  | 
| 316 |  | 
| 317         // Cache the length. |  | 
| 318         let inputLength = input.length; |  | 
| 319 |  | 
| 320         // Initialize the state. |  | 
| 321         let n = initialN; |  | 
| 322         let delta = 0; |  | 
| 323         let bias = initialBias; |  | 
| 324 |  | 
| 325         // Handle the basic code points. |  | 
| 326         for (let currentValue of input) { |  | 
| 327                 if (currentValue < 0x80) { |  | 
| 328                         output.push(stringFromCharCode(currentValue)); |  | 
| 329                 } |  | 
| 330         } |  | 
| 331 |  | 
| 332         let basicLength = output.length; |  | 
| 333         let handledCPCount = basicLength; |  | 
| 334 |  | 
| 335         // `handledCPCount` is the number of code points that have been handled; |  | 
| 336         // `basicLength` is the number of basic code points. |  | 
| 337 |  | 
| 338         // Finish the basic string with a delimiter unless it's empty. |  | 
| 339         if (basicLength) { |  | 
| 340                 output.push(delimiter); |  | 
| 341         } |  | 
| 342 |  | 
| 343         // Main encoding loop: |  | 
| 344         while (handledCPCount < inputLength) { |  | 
| 345 |  | 
| 346                 // All non-basic code points < n have been handled already. Find
      the next |  | 
| 347                 // larger one: |  | 
| 348                 let m = maxInt; |  | 
| 349                 for (let currentValue of input) { |  | 
| 350                         if (currentValue >= n && currentValue < m) { |  | 
| 351                                 m = currentValue; |  | 
| 352                         } |  | 
| 353                 } |  | 
| 354 |  | 
| 355                 // Increase `delta` enough to advance the decoder's <n,i> state 
     to <m,0>, |  | 
| 356                 // but guard against overflow. |  | 
| 357                 const handledCPCountPlusOne = handledCPCount + 1; |  | 
| 358                 if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { |  | 
| 359                         error('overflow'); |  | 
| 360                 } |  | 
| 361 |  | 
| 362                 delta += (m - n) * handledCPCountPlusOne; |  | 
| 363                 n = m; |  | 
| 364 |  | 
| 365                 for (let currentValue of input) { |  | 
| 366                         if (currentValue < n && ++delta > maxInt) { |  | 
| 367                                 error('overflow'); |  | 
| 368                         } |  | 
| 369                         if (currentValue == n) { |  | 
| 370                                 // Represent delta as a generalized variable-len
     gth integer. |  | 
| 371                                 let q = delta; |  | 
| 372                                 for (let k = base; /* no condition */; k += base
     ) { |  | 
| 373                                         const t = k <= bias ? tMin : (k >= bias 
     + tMax ? tMax : k - bias); |  | 
| 374                                         if (q < t) { |  | 
| 375                                                 break; |  | 
| 376                                         } |  | 
| 377                                         const qMinusT = q - t; |  | 
| 378                                         const baseMinusT = base - t; |  | 
| 379                                         output.push( |  | 
| 380                                                 stringFromCharCode(digitToBasic(
     t + qMinusT % baseMinusT, 0)) |  | 
| 381                                         ); |  | 
| 382                                         q = floor(qMinusT / baseMinusT); |  | 
| 383                                 } |  | 
| 384 |  | 
| 385                                 output.push(stringFromCharCode(digitToBasic(q, 0
     ))); |  | 
| 386                                 bias = adapt(delta, handledCPCountPlusOne, handl
     edCPCount == basicLength); |  | 
| 387                                 delta = 0; |  | 
| 388                                 ++handledCPCount; |  | 
| 389                         } |  | 
| 390                 } |  | 
| 391 |  | 
| 392                 ++delta; |  | 
| 393                 ++n; |  | 
| 394 |  | 
| 395         } |  | 
| 396         return output.join(''); |  | 
| 397 }; |  | 
| 398 |  | 
| 399 /** |  | 
| 400  * Converts a Punycode string representing a domain name or an email address |  | 
| 401  * to Unicode. Only the Punycoded parts of the input will be converted, i.e. |  | 
| 402  * it doesn't matter if you call it on a string that has already been |  | 
| 403  * converted to Unicode. |  | 
| 404  * @memberOf punycode |  | 
| 405  * @param {String} input The Punycoded domain name or email address to |  | 
| 406  * convert to Unicode. |  | 
| 407  * @returns {String} The Unicode representation of the given Punycode |  | 
| 408  * string. |  | 
| 409  */ |  | 
| 410 const toUnicode = function(input) { |  | 
| 411         return mapDomain(input, function(string) { |  | 
| 412                 return regexPunycode.test(string) |  | 
| 413                         ? decode(string.slice(4).toLowerCase()) |  | 
| 414                         : string; |  | 
| 415         }); |  | 
| 416 }; |  | 
| 417 |  | 
| 418 /** |  | 
| 419  * Converts a Unicode string representing a domain name or an email address to |  | 
| 420  * Punycode. Only the non-ASCII parts of the domain name will be converted, |  | 
| 421  * i.e. it doesn't matter if you call it with a domain that's already in |  | 
| 422  * ASCII. |  | 
| 423  * @memberOf punycode |  | 
| 424  * @param {String} input The domain name or email address to convert, as a |  | 
| 425  * Unicode string. |  | 
| 426  * @returns {String} The Punycode representation of the given domain name or |  | 
| 427  * email address. |  | 
| 428  */ |  | 
| 429 const toASCII = function(input) { |  | 
| 430         return mapDomain(input, function(string) { |  | 
| 431                 return regexNonASCII.test(string) |  | 
| 432                         ? 'xn--' + encode(string) |  | 
| 433                         : string; |  | 
| 434         }); |  | 
| 435 }; |  | 
| 436 |  | 
| 437 /*--------------------------------------------------------------------------*/ |  | 
| 438 |  | 
| 439 /** Define the public API */ |  | 
| 440 module.exports = { |  | 
| 441         /** |  | 
| 442          * A string representing the current Punycode.js version number. |  | 
| 443          * @memberOf punycode |  | 
| 444          * @type String |  | 
| 445          */ |  | 
| 446         'version': '2.0.0', |  | 
| 447         /** |  | 
| 448          * An object of methods to convert from JavaScript's internal character |  | 
| 449          * representation (UCS-2) to Unicode code points, and back. |  | 
| 450          * @see <https://mathiasbynens.be/notes/javascript-encoding> |  | 
| 451          * @memberOf punycode |  | 
| 452          * @type Object |  | 
| 453          */ |  | 
| 454         'ucs2': { |  | 
| 455                 'decode': ucs2decode, |  | 
| 456                 'encode': ucs2encode |  | 
| 457         }, |  | 
| 458         'decode': decode, |  | 
| 459         'encode': encode, |  | 
| 460         'toASCII': toASCII, |  | 
| 461         'toUnicode': toUnicode |  | 
| 462 }; |  | 
| OLD | NEW | 
|---|