JS update corresponding to r67 (java). Contributed by tronikos.
authorlararennie@google.com <lararennie@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Tue, 1 Feb 2011 14:49:13 +0000 (14:49 +0000)
committerlararennie@google.com <lararennie@google.com@ee073f10-1060-11df-b6a4-87a95322a99c>
Tue, 1 Feb 2011 14:49:13 +0000 (14:49 +0000)
git-svn-id: http://libphonenumber.googlecode.com/svn/trunk@71 ee073f10-1060-11df-b6a4-87a95322a99c

javascript/README
javascript/i18n/phonenumbers/asyoutypeformatter.js
javascript/i18n/phonenumbers/asyoutypeformatter_test.js
javascript/i18n/phonenumbers/demo.html
javascript/i18n/phonenumbers/metadata.js
javascript/i18n/phonenumbers/metadatalite.js
javascript/i18n/phonenumbers/phonenumberutil.js
javascript/i18n/phonenumbers/phonenumberutil_test.js

index 20fc4d5..b6ee5c0 100644 (file)
@@ -25,7 +25,7 @@ pages with your web browser:
 
 How to update:
 ==============
-The JavaScript library is ported from the Java implementation (revision 62).
+The JavaScript library is ported from the Java implementation (revision 67).
 When the Java project gets updated follow these steps to update the JavaScript
 project:
 
index 248e945..a4ab839 100644 (file)
@@ -44,6 +44,8 @@ goog.require('i18n.phonenumbers.PhoneNumberDesc');
 goog.require('i18n.phonenumbers.PhoneNumberUtil');
 goog.require('i18n.phonenumbers.metadata');
 
+
+
 /**
  * Constructs a light-weight formatter which does no formatting, but outputs
  * exactly what is fed into the inputDigit method.
@@ -95,7 +97,6 @@ i18n.phonenumbers.AsYouTypeFormatter = function(regionCode) {
    * @private
    */
   this.digitPattern_ = new RegExp(this.digitPlaceholder_);
-
   /**
    * @type {string}
    * @private
@@ -179,9 +180,8 @@ i18n.phonenumbers.AsYouTypeFormatter = function(regionCode) {
    * @private
    */
   this.possibleFormats_ = [];
-
   /**
-   *  @type {string}
+   * @type {string}
    * @private
    */
   this.defaultCountry_ = regionCode;
@@ -193,12 +193,13 @@ i18n.phonenumbers.AsYouTypeFormatter = function(regionCode) {
   this.defaultMetaData_ = this.currentMetaData_;
 };
 
+
 /**
  * @param {string} regionCode
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.initializeCountrySpecificInfo_ =
-  function(regionCode) {
+    function(regionCode) {
 
   /** @type {i18n.phonenumbers.PhoneMetadata} */
   this.currentMetaData_ = this.phoneUtil_.getMetadataForRegion(regionCode);
@@ -210,13 +211,14 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.initializeCountrySpecificInfo_ =
       this.currentMetaData_.getInternationalPrefix() + ')');
 };
 
+
 /**
  * @return {boolean} true if a new template is created as opposed to reusing the
  *     existing template.
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.maybeCreateNewTemplate_ =
-  function() {
+    function() {
 
   // When there are multiple available formats, the formatter uses the first
   // format where a formatting template could be created.
@@ -239,12 +241,13 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.maybeCreateNewTemplate_ =
   return false;
 };
 
+
 /**
  * @param {string} leadingThreeDigits
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.getAvailableFormats_ =
-  function(leadingThreeDigits) {
+    function(leadingThreeDigits) {
 
   /** @type {Array.<i18n.phonenumbers.NumberFormat>} */
   var formatList = (this.isInternationalFormatting_ && this.currentMetaData_
@@ -254,12 +257,13 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.getAvailableFormats_ =
   this.narrowDownPossibleFormats_(leadingThreeDigits);
 };
 
+
 /**
  * @param {string} leadingDigits
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.narrowDownPossibleFormats_ =
-  function(leadingDigits) {
+    function(leadingDigits) {
 
   /** @type {Array.<i18n.phonenumbers.NumberFormat>} */
   var possibleFormats = [];
@@ -289,13 +293,14 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.narrowDownPossibleFormats_ =
   this.possibleFormats_ = possibleFormats;
 };
 
+
 /**
  * @param {i18n.phonenumbers.NumberFormat} format
  * @return {boolean}
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.createFormattingTemplate_ =
-  function(format) {
+    function(format) {
 
   /** @type {string} */
   var numberFormat = format.getFormatOrDefault();
@@ -319,6 +324,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.createFormattingTemplate_ =
   return true;
 };
 
+
 /**
  * Gets a formatting template which could be used to efficiently format a
  * partial number where digits are added one by one.
@@ -329,7 +335,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.createFormattingTemplate_ =
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.getFormattingTemplate_ =
-  function(numberPattern, numberFormat) {
+    function(numberPattern, numberFormat) {
 
   // Creates a phone number consisting only of the digit 9 that matches the
   // numberPattern by applying the pattern to the longestPhoneNumber string.
@@ -349,6 +355,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.getFormattingTemplate_ =
   return template;
 };
 
+
 /**
  * Clears the internal state of the formatter, so it could be reused.
  */
@@ -372,6 +379,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.clear = function() {
   }
 };
 
+
 /**
  * Formats a phone number on-the-fly as each digit is entered.
  *
@@ -385,6 +393,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigit = function(nextChar) {
   return this.currentOutput_;
 };
 
+
 /**
  * Same as inputDigit, but remembers the position where nextChar is inserted, so
  * that it could be retrieved later by using getRememberedPosition(). The
@@ -395,13 +404,14 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigit = function(nextChar) {
  * @return {string}
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitAndRememberPosition =
-  function(nextChar) {
+    function(nextChar) {
 
   this.currentOutput_ =
       this.inputDigitWithOptionToRememberPosition_(nextChar, true);
   return this.currentOutput_;
 };
 
+
 /**
  * @param {string} nextChar
  * @param {boolean} rememberPosition
@@ -433,67 +443,68 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
   // digits (the plus sign is counted as a digit as well for this purpose) have
   // been entered.
   switch (this.accruedInputWithoutFormatting_.getLength()) {
-  case 0: // this is the case where the first few inputs are neither digits nor
-          // the plus sign.
-  case 1:
-  case 2:
-    return this.accruedInput_.toString();
-  case 3:
-    if (this.attemptToExtractIdd_()) {
-      this.isExpectingCountryCode_ = true;
-    } else {
-      // No IDD or plus sign is found, must be entering in national format.
-      this.removeNationalPrefixFromNationalNumber_();
-      return this.attemptToChooseFormattingPattern_();
-    }
-  case 4:
-  case 5:
-    if (this.isExpectingCountryCode_) {
-      if (this.attemptToExtractCountryCode_()) {
-        this.isExpectingCountryCode_ = false;
-      }
-      return this.prefixBeforeNationalNumber_.toString() +
-          this.nationalNumber_.toString();
-    }
-  // We make a last attempt to extract a country code at the 6th digit because
-  // the maximum length of IDD and country code are both 3.
-  case 6:
-    if (this.isExpectingCountryCode_ && !this.attemptToExtractCountryCode_()) {
-      this.ableToFormat_ = false;
+    case 0: // when the first few inputs are neither digits nor the plus sign.
+    case 1:
+    case 2:
       return this.accruedInput_.toString();
-    }
-  default:
-    if (this.possibleFormats_.length > 0) {
-      // The formatting pattern is already chosen.
-      /** @type {string} */
-      var tempNationalNumber = this.inputDigitHelper_(nextChar);
-      // See if the accrued digits can be formatted properly already. If not,
-      // use the results from inputDigitHelper, which does formatting based on
-      // the formatting pattern chosen.
-      /** @type {string} */
-      var formattedNumber = this.attemptToFormatAccruedDigits_();
-      if (formattedNumber.length > 0) {
-        return formattedNumber;
+    case 3:
+      if (this.attemptToExtractIdd_()) {
+        this.isExpectingCountryCode_ = true;
+      } else {
+        // No IDD or plus sign is found, must be entering in national format.
+        this.removeNationalPrefixFromNationalNumber_();
+        return this.attemptToChooseFormattingPattern_();
       }
-      this.narrowDownPossibleFormats_(this.nationalNumber_.toString());
-      if (this.maybeCreateNewTemplate_()) {
-        return this.inputAccruedNationalNumber_();
+    case 4:
+    case 5:
+      if (this.isExpectingCountryCode_) {
+        if (this.attemptToExtractCountryCode_()) {
+          this.isExpectingCountryCode_ = false;
+        }
+        return this.prefixBeforeNationalNumber_.toString() +
+            this.nationalNumber_.toString();
+      }
+    // We make a last attempt to extract a country code at the 6th digit because
+    // the maximum length of IDD and country code are both 3.
+    case 6:
+      if (this.isExpectingCountryCode_ &&
+          !this.attemptToExtractCountryCode_()) {
+        this.ableToFormat_ = false;
+        return this.accruedInput_.toString();
+      }
+    default:
+      if (this.possibleFormats_.length > 0) {
+        // The formatting pattern is already chosen.
+        /** @type {string} */
+        var tempNationalNumber = this.inputDigitHelper_(nextChar);
+        // See if the accrued digits can be formatted properly already. If not,
+        // use the results from inputDigitHelper, which does formatting based on
+        // the formatting pattern chosen.
+        /** @type {string} */
+        var formattedNumber = this.attemptToFormatAccruedDigits_();
+        if (formattedNumber.length > 0) {
+          return formattedNumber;
+        }
+        this.narrowDownPossibleFormats_(this.nationalNumber_.toString());
+        if (this.maybeCreateNewTemplate_()) {
+          return this.inputAccruedNationalNumber_();
+        }
+        return this.ableToFormat_ ?
+            this.prefixBeforeNationalNumber_.toString() + tempNationalNumber :
+            tempNationalNumber;
+      } else {
+        return this.attemptToChooseFormattingPattern_();
       }
-      return this.ableToFormat_ ?
-          this.prefixBeforeNationalNumber_.toString() + tempNationalNumber :
-          tempNationalNumber;
-    } else {
-      return this.attemptToChooseFormattingPattern_();
-    }
   }
 };
 
+
 /**
  * @return {string}
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToFormatAccruedDigits_ =
-  function() {
+    function() {
 
   /** @type {string} */
   var nationalNumber = this.nationalNumber_.toString();
@@ -516,6 +527,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToFormatAccruedDigits_ =
   return '';
 };
 
+
 /**
  * Returns the current position in the partially formatted phone number of the
  * character which was previously passed in as the parameter of
@@ -524,7 +536,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToFormatAccruedDigits_ =
  * @return {number}
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.getRememberedPosition =
-  function() {
+    function() {
 
   if (!this.ableToFormat_) {
     return this.originalPosition_;
@@ -553,6 +565,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.getRememberedPosition =
   return currentOutputIndex;
 };
 
+
 /**
  * Attempts to set the formatting template and returns a string which contains
  * the formatted version of the digits entered so far.
@@ -577,6 +590,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
   }
 };
 
+
 /**
  * Invokes inputDigitHelper on each digit of the national number accrued, and
  * returns a formatted string in the end.
@@ -585,7 +599,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.inputAccruedNationalNumber_ =
-  function() {
+    function() {
 
   /** @type {string} */
   var nationalNumber = this.nationalNumber_.toString();
@@ -606,11 +620,12 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.inputAccruedNationalNumber_ =
   }
 };
 
+
 /**
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.
-      removeNationalPrefixFromNationalNumber_ = function() {
+    removeNationalPrefixFromNationalNumber_ = function() {
 
   /** @type {string} */
   var nationalNumber = this.nationalNumber_.toString();
@@ -638,6 +653,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
   this.nationalNumber_.append(nationalNumber.substring(startOfNationalNumber));
 };
 
+
 /**
  * Extracts IDD and plus sign to prefixBeforeNationalNumber when they are
  * available, and places the remaining input into nationalNumber.
@@ -647,7 +663,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToExtractIdd_ =
-  function() {
+    function() {
 
   /** @type {string} */
   var accruedInputWithoutFormatting =
@@ -672,6 +688,7 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToExtractIdd_ =
   return false;
 };
 
+
 /**
  * Extracts country code from the beginning of nationalNumber to
  * prefixBeforeNationalNumber when they are available, and places the remaining
@@ -681,34 +698,35 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToExtractIdd_ =
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.attemptToExtractCountryCode_ =
-  function() {
+    function() {
 
-    if (this.nationalNumber_.getLength() == 0) {
-      return false;
-    }
-    /** @type {!goog.string.StringBuffer} */
-    var numberWithoutCountryCode = new goog.string.StringBuffer();
-    /** @type {number} */
-    var countryCode = this.phoneUtil_.extractCountryCode(
-        this.nationalNumber_, numberWithoutCountryCode);
-    if (countryCode == 0) {
-      return false;
-    } else {
-      this.nationalNumber_.clear();
-      this.nationalNumber_.append(numberWithoutCountryCode.toString());
-      /** @type {string} */
-      var newRegionCode =
-          this.phoneUtil_.getRegionCodeForCountryCode(countryCode);
-      if (newRegionCode != this.defaultCountry_) {
-        this.initializeCountrySpecificInfo_(newRegionCode);
-      }
-      /** @type {string} */
-      var countryCodeString = '' + countryCode;
-      this.prefixBeforeNationalNumber_.append(countryCodeString).append(' ');
+  if (this.nationalNumber_.getLength() == 0) {
+    return false;
+  }
+  /** @type {!goog.string.StringBuffer} */
+  var numberWithoutCountryCode = new goog.string.StringBuffer();
+  /** @type {number} */
+  var countryCode = this.phoneUtil_.extractCountryCode(
+      this.nationalNumber_, numberWithoutCountryCode);
+  if (countryCode == 0) {
+    return false;
+  } else {
+    this.nationalNumber_.clear();
+    this.nationalNumber_.append(numberWithoutCountryCode.toString());
+    /** @type {string} */
+    var newRegionCode =
+        this.phoneUtil_.getRegionCodeForCountryCode(countryCode);
+    if (newRegionCode != this.defaultCountry_) {
+      this.initializeCountrySpecificInfo_(newRegionCode);
     }
+    /** @type {string} */
+    var countryCodeString = '' + countryCode;
+    this.prefixBeforeNationalNumber_.append(countryCodeString).append(' ');
+  }
   return true;
 };
 
+
 /**
  * Accrues digits and the plus sign to accruedInputWithoutFormatting for later
  * use. If nextChar contains a digit in non-ASCII format (e.g. the full-width
@@ -739,13 +757,14 @@ i18n.phonenumbers.AsYouTypeFormatter.prototype.
   return nextChar;
 };
 
+
 /**
  * @param {string} nextChar
  * @return {string}
  * @private
  */
 i18n.phonenumbers.AsYouTypeFormatter.prototype.inputDigitHelper_ =
-  function(nextChar) {
+    function(nextChar) {
 
   /** @type {string} */
   var formattingTemplate = this.formattingTemplate_.toString();
index 04f9b20..3f2dd8c 100644 (file)
@@ -317,7 +317,7 @@ function testAYTFGBFixedLine() {
 }
 
 function testAYTFGBTollFree() {
-   /** @type {i18n.phonenumbers.AsYouTypeFormatter} */
+  /** @type {i18n.phonenumbers.AsYouTypeFormatter} */
   var f = new i18n.phonenumbers.AsYouTypeFormatter('gb');
   assertEquals('0', f.inputDigit('0'));
   assertEquals('08', f.inputDigit('8'));
index dde5b20..5198569 100644 (file)
@@ -58,7 +58,7 @@ function phoneNumberParser() {
         .append(phoneUtil.isPossibleNumber(number));
     output.append('\nResult from getNumberType(): ');
     var PNT = i18n.phonenumbers.PhoneNumberType;
-    switch(phoneUtil.getNumberType(number)) {
+    switch (phoneUtil.getNumberType(number)) {
       case PNT.FIXED_LINE:
         output.append('FIXED_LINE');
         break;
index 1b47077..6d841d8 100644 (file)
@@ -329,13 +329,13 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"AM":[,[,,"[1-37-9]\\d{7}","\\d{5,8}"]
 ,[,,"(?:10\\d|2(?:2[2-46]|3[1-8]|4[2-69]|5[2-7]|6[1-9]|8[1-7])|3[12]2)\\d{5}","\\d{5,8}",,,"10123456"]
-,[,,"(?:77|9[1-49])\\d{6}","\\d{8}",,,"77123456"]
+,[,,"(?:77|9[1-469])\\d{6}","\\d{8}",,,"77123456"]
 ,[,,"800\\d{5}","\\d{8}",,,"80012345"]
 ,[,,"90[016]\\d{5}","\\d{8}",,,"90012345"]
 ,[,,"80[1-4]\\d{5}","\\d{8}",,,"80112345"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",["[17]|9[1-49]"]
+,"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",["[17]|9[1-469]"]
 ,"(0$1)",""]
 ,[,"(\\d{3})(\\d{5})","$1 $2",["[23]"]
 ,"(0$1)",""]
@@ -583,12 +583,12 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"BH":[,[,,"[1367]\\d{7}","\\d{8}"]
+,"BH":[,[,,"[136-9]\\d{7}","\\d{8}"]
 ,[,,"(?:1(?:3[3-6]|6[0156]|7\\d)|6(?:1[16]|6[03469]|9[69])|77\\d)\\d{5}","\\d{8}",,,"17001234"]
 ,[,,"(?:3(?:[369]\\d|77|8[38])|6(?:1[16]|6[03469]|9[69])|77\\d)\\d{5}","\\d{8}",,,"36001234"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"80\\d{6}","\\d{8}",,,"80123456"]
+,[,,"(?:87|9[014578])\\d{6}","\\d{8}",,,"90123456"]
+,[,,"84\\d{6}","\\d{8}",,,"84123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"BH",973,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",,"",""]
@@ -738,15 +738,20 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"BZ":[,[]
-,[]
-,[]
+,"BZ":[,[,,"[2-8]\\d{6}|0\\d{10}","\\d{7}(?:\\d{4})?"]
+,[,,"[234578][02]\\d{5}","\\d{7}",,,"2221234"]
+,[,,"6(?:[01]\\d|2[0-5]|[67][01])\\d{4}","\\d{7}",,,"6221234"]
+,[,,"0800\\d{7}","\\d{11}",,,"08001234123"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"BZ",501,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"BZ",501,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[2-8]"]
+,"",""]
+,[,"(0)(800)(\\d{4})(\\d{3})","$1-$2-$3-$4",["0"]
+,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"CA":[,[,,"[2-9]\\d{9}|3\\d{6}","\\d{7,10}"]
 ,[,,"(?:2(?:04|26|50|89)|306|4(?:03|16|18|38|50|56)|5(?:00|06|14|19|81|87)|6(?:00|04|13|47)|7(?:00|05|09|10|78|80)|8(?:07|19|67))[2-9]\\d{6}|310\\d{4}","\\d{7,10}",,,"2042345678"]
@@ -760,7 +765,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"CD":[,[,,"[89]\\d{8}|[1-6]\\d{6}","\\d{7,9}"]
 ,[,,"[1-6]\\d{6}","\\d{7}",,,"1234567"]
-,[,,"(?:8[0149]|9[7-9])\\d{7}","\\d{9}",,,"991234567"]
+,[,,"(?:8[0-2489]|9[7-9])\\d{7}","\\d{9}",,,"991234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -785,15 +790,18 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"CG":[,[,,"[24-68]\\d{6}","\\d{7}"]
-,[,,"(?:2[1-589]|8\\d)\\d{5}","\\d{7}",,,"2123456"]
-,[,,"[4-6]\\d{6}","\\d{7}",,,"5012345"]
-,[,,"NA","NA"]
+,"CG":[,[,,"[028]\\d{8}","\\d{9}"]
+,[,,"222[1-589]\\d{5}","\\d{9}",,,"222123456"]
+,[,,"0[14-6]\\d{7}","\\d{9}",,,"061234567"]
+,[,,"800\\d{6}","\\d{9}",,,"800123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CG",242,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]
+,"CG",242,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[02]"]
+,"",""]
+,[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["8"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -930,27 +938,37 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"CO",57,"(?:00[579]|#555|#999)","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"CR":[,[,,"[28]\\d{7}","\\d{8}"]
+,"CR":[,[,,"[289]\\d{7,9}","\\d{8,10}"]
 ,[,,"2[24-7]\\d{6}","\\d{8}",,,"22123456"]
-,[,,"8[38]\\d{6}","\\d{8}",,,"83123456"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"8[389]\\d{6}","\\d{8}",,,"83123456"]
+,[,,"800\\d{7}","\\d{10}",,,"8001234567"]
+,[,,"90[059]\\d{7}","\\d{10}",,,"9001234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CR",506,"00",,,,,,,,[[,"([28]\\d{3})(\\d{4})","$1 $2",,"",""]
+,"CR",506,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["2|8[389]"]
+,"",""]
+,[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["[89]0"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
-,"CU":[,[]
-,[]
-,[]
+,"CU":[,[,,"[2-57]\\d{5,7}","\\d{4,8}"]
+,[,,"(?:2[1-4]\\d{5,6}|3(?:1\\d{6}|[23]\\d{4,6})|4(?:[125]\\d{5,6}|[36]\\d{6}|[78]\\d{4,6})|7\\d{6,7})","\\d{4,8}",,,"71234567"]
+,[,,"5\\d{7}","\\d{8}",,,"51234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CU",53,"119","0",,,"0",,,1,,,[,,"NA","NA"]
+,"CU",53,"119","0",,,"0",,,,[[,"(\\d)(\\d{6,7})","$1 $2",["7"]
+,"(0$1)",""]
+,[,"(\\d{2})(\\d{4,6})","$1 $2",["[2-4]"]
+,"(0$1)",""]
+,[,"(\\d)(\\d{7})","$1 $2",["5"]
+,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"CV":[,[,,"[259]\\d{6}","\\d{7}"]
 ,[,,"2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\\d|7[1-3]|8[1-5])\\d{4}","\\d{7}",,,"2211234"]
@@ -988,9 +1006,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"DE":[,[,,"(?:4[0-8]|[1-35-9]\\d)\\d{4,12}|49(?:4[1-8]|[0-35-7]\\d)\\d{2,7}","\\d{2,14}"]
-,[,,"(?:[246]\\d{2}|3[02-9]\\d|5(?:0[2-8]|[38][0-8]|[124-6]\\d|[79][0-7])|[789](?:[1-9]\\d|0[2-9]))\\d{3,10}","\\d{2,14}",,,"30123456"]
-,[,,"1(?:5\\d{9}|7(?:[0-57-9]|6\\d)\\d{7}|6[02]\\d{7,8}|63\\d{7})","\\d{10,11}",,,"15123456789"]
+,"DE":[,[,,"[1-35-9]\\d{3,13}|4(?:[0-8]\\d{4,12}|9(?:4[1-8]|[0-35-7]\\d)\\d{2,7})","\\d{2,14}"]
+,[,,"[246]\\d{5,13}|3(?:[03-9]\\d{4,11}|2\\d{9})|5(?:0[2-8]|[38][0-8]|[124-6]\\d|[79][0-7])\\d{3,10}|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-9]\\d)\\d{3,10}|9(?:0[6-9]|[1-9]\\d)\\d{3,10}","\\d{2,14}",,,"30123456"]
+,[,,"1(?:5\\d{9}|7(?:[0-57-9]|6\\d)\\d{7}|6(?:[02]\\d{7,8}|3\\d{7}))","\\d{10,11}",,,"15123456789"]
 ,[,,"800\\d{7,9}","\\d{10,12}",,,"8001234567"]
 ,[,,"900(?:[135]\\d{6}|9\\d{7})","\\d{10,11}",,,"9001234567"]
 ,[,,"180\\d{5,11}","\\d{8,14}",,,"18012345"]
@@ -1011,17 +1029,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,"(700)(\\d{4})(\\d{4})","$1 $2 $3",["700"]
 ,"0$1",""]
 ]
-,,[,,"NA","NA"]
+,,[,,"16(?:4\\d{1,10}|[89]\\d{1,11})","\\d{4,14}",,,"16412345"]
 ]
-,"DJ":[,[,,"[2-8]\\d{5}","\\d{6}"]
-,[,,"(?:25|3[0-6]|42)\\d{4}","\\d{6}",,,"251234"]
-,[,,"(?:[5-7]\\d|8[0-7])\\d{4}","\\d{6}",,,"601234"]
+,"DJ":[,[,,"[1-8]\\d{5}","\\d{6}"]
+,[,,"(?:1[05]|[2-5]\\d)\\d{4}","\\d{6}",,,"251234"]
+,[,,"[6-8]\\d{5}","\\d{6}",,,"601234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"DJ",253,"00",,,,,,,,[[,"([2-8]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
+,"DJ",253,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -1074,29 +1092,45 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"EC":[,[]
-,[]
-,[]
+,"EC":[,[,,"[2-9]\\d{7}|1\\d{9,10}","\\d{7,11}"]
+,[,,"[2-7][2-7]\\d{6}","\\d{7,8}",,,"22123456"]
+,[,,"[89]\\d{7}","\\d{8}",,,"99123456"]
+,[,,"1800\\d{6,7}","\\d{10,11}",,,"18001234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
+,"EC",593,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2-$3",["[2-7]"]
+,"(0$1)",""]
+,[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[89]"]
+,"0$1",""]
+,[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"]
+,"$1",""]
+]
+,[[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[2-7]"]
+,,""]
+,[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[89]"]
+,,""]
+,[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"]
+,,""]
+]
 ,[,,"NA","NA"]
-,"EC",593,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
 ,"EE":[,[,,"[3-9]\\d{6,7}|800\\d{6,7}","\\d{6,10}"]
-,[,,"(?:3[23589]|4[3-8]|6\\d|7[1-9]|88)\\d{5}","\\d{7}",,,"3212345"]
+,[,,"(?:3[23589]|4(?:0\\d|[3-8])|6\\d|7[1-9]|88)\\d{5}","\\d{7,8}",,,"3212345"]
 ,[,,"(?:5\\d|8[1-5])\\d{6}|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])\\d{3}","\\d{7,8}",,,"51234567"]
 ,[,,"800(?:0\\d{3}|1\\d|[2-9])\\d{3}","\\d{7,10}",,,"80012345"]
 ,[,,"900\\d{4}","\\d{7}",,,"9001234"]
 ,[,,"NA","NA"]
-,[,,"70\\d{5}","\\d{7}",,,"7012345"]
+,[,,"70[0-2]?\\d{5}","\\d{7,8}",,,"70012345"]
 ,[,,"NA","NA"]
-,"EE",372,"00",,,,,,,,[[,"([34-79]\\d{2})(\\d{4})","$1 $2",["[34679]|5(?:[0-2]|5[0-478]|6[45])","[34679]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))"]
+,"EE",372,"00",,,,,,,,[[,"([34-79]\\d{2})(\\d{4})","$1 $2",["[3679]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])","[3679]|4[3-8]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))"]
+,"",""]
+,[,"(70)(\\d{2})(\\d{4})","$1 $2 $3",["70"]
 ,"",""]
 ,[,"(8000)(\\d{3})(\\d{3})","$1 $2 $3",["800","8000"]
 ,"",""]
-,[,"([58]\\d{3})(\\d{3,4})","$1 $2",["5|8(?:00|[1-5])","5|8(?:00[1-9]|[1-5])"]
+,[,"([458]\\d{3})(\\d{3,4})","$1 $2",["40|5|8(?:00|[1-5])","40|5|8(?:00[1-9]|[1-5])"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -1201,15 +1235,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"FM",691,"00",,,,,,,1,,,[,,"NA","NA"]
 ]
-,"FO":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"FO":[,[,,"[2-9]\\d{5}","\\d{6}"]
+,[,,"(?:20|[3-4]\\d|8[19])\\d{4}","\\d{6}",,,"201234"]
+,[,,"(?:2[1-9]|5\\d|7[1-79])\\d{4}","\\d{6}",,,"211234"]
+,[,,"80[257-9]\\d{3}","\\d{6}",,,"802123"]
+,[,,"90(?:[1345][15-7]|2[125-7]|99)\\d{2}","\\d{6}",,,"901123"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"FO",298,"00",,,,,,,1,,,[,,"NA","NA"]
+,[,,"(?:6[0-36]|88)\\d{4}","\\d{6}",,,"601234"]
+,"FO",298,"00",,,,"10(?:01|[12]0|88)",,,,,,[,,"NA","NA"]
 ]
 ,"FR":[,[,,"[1-9]\\d{8}","\\d{9}"]
 ,[,,"[1-5]\\d{8}","\\d{9}",,,"123456789"]
@@ -1242,7 +1276,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"GB":[,[,,"\\d{7,10}","\\d{4,10}"]
-,[,,"1(?:1[3-8]|[2-69]1)\\d{7}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-4789]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1235679]|9[24578])|4(?:0[03-9]|2[02-5789]|[37]\\d|4[02-69]|5[0-8]|[69][0-79]|8[02-5789])|5(?:0[1235-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-5789])|6(?:0[034689]|2[0-35689]|3[013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|8[013-9]|9[0124578])|7(?:0[0246-9]|2\\d|3[023678]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-5789]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-5789]|4[2-9]|5[0-579]|6[234789]|7[0124578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-4789]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[015789]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[234678]\\d{2}|16977[23]\\d{3}|2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[012])\\d{7}|(?:3[0347]|55)\\d{8}","\\d{4,10}",,,"1212345678"]
+,[,,"2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[012])\\d{7}|1(?:(?:1(?:3[0-48]|[46][0-4]|5[012789]|7[0-39]|8[01349])|21[0-7]|31[0-8]|[459]1\\d|61[01246-9]))\\d{6}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-4789]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1235679]|9[24578])|4(?:0[03-9]|[28][02-5789]|[37]\\d|4[02-69]|5[0-8]|[69][0-79])|5(?:0[1235-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-5789])|6(?:0[034689]|2[0-35689]|[38][013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|9[0124578])|7(?:0[0246-9]|2\\d|3[023678]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-5789]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-5789]|4[2-9]|5[0-579]|6[234789]|7[0124578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-4789]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[015789]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[234678]\\d{2}|16977[23]\\d{3}|(?:3[0347]|55)\\d{8}","\\d{4,10}",,,"1212345678"]
 ,[,,"7(?:[1-4]\\d\\d|5(?:0[0-8]|[13-9]\\d|2[0-35-9])|7(?:0[1-9]|[1-7]\\d|8[02-9]|9[0-689])|8(?:[014-9]\\d|[23][0-8])|9(?:[04-9]\\d|1[02-9]|2[0135-9]|3[0-689]))\\d{6}","\\d{10}",,,"7400123456"]
 ,[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}","\\d{7}(?:\\d{2,3})?",,,"8001234567"]
 ,[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}","\\d{10}",,,"9012345678"]
@@ -1335,15 +1369,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"GI":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"GI":[,[,,"[2568]\\d{7}","\\d{8}"]
+,[,,"2(?:00\\d|16[0-7]|22[2457])\\d{4}","\\d{8}",,,"20012345"]
+,[,,"(?:5[4-8]|60)\\d{6}","\\d{8}",,,"57123456"]
+,[,,"80\\d{6}","\\d{8}",,,"80123456"]
+,[,,"8[1-689]\\d{6}","\\d{8}",,,"88123456"]
+,[,,"87\\d{6}","\\d{8}",,,"87123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"GI",350,"00",,,,,,,1,,,[,,"NA","NA"]
+,"GI",350,"00",,,,,,,,,,[,,"NA","NA"]
 ]
 ,"GL":[,[,,"[1-689]\\d{5}","\\d{6}"]
 ,[,,"(?:19|3[1-6]|6[14689]|8[14-79]|9\\d)\\d{4}","\\d{6}",,,"321000"]
@@ -1371,7 +1405,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"GN":[,[,,"[3567]\\d{7}","\\d{8}"]
 ,[,,"30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\\d{4}","\\d{8}",,,"30241234"]
-,[,,"55\\d{6}|6(?:0(?:2\\d|3[3467]|5[2457-9])|[2457]\\d{2}|3(?:[14]0|35))\\d{4}","\\d{8}",,,"60201234"]
+,[,,"55\\d{6}|6(?:0(?:2\\d|3[3467]|5[2457-9])|[24578]\\d{2}|3(?:[14]0|35))\\d{4}","\\d{8}",,,"60201234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -1484,15 +1518,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"HN":[,[]
-,[]
-,[]
+,"HN":[,[,,"[237-9]\\d{7}","\\d{8}"]
+,[,,"2(?:2(?:0[019]|1[1-36]|[23]\\d|4[056]|5[57]|9[01])|4(?:2|3-59]|3[13-689]|4[0-68]|5[1-35])|5(?:4[3-5]|5\\d|6[56]|74)|6(?:4[0-378]|[56]\\d|[78][0-8]|9[01])|7(?:6[46-9]|7[02-9]|8[34])|8(?:79|8[0-35789]|9[1-57-9]))\\d{4}","\\d{8}",,,"22123456"]
+,[,,"[37-9]\\d{7}","\\d{8}",,,"91234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"HN",504,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"HN",504,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1-$2",,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"HR":[,[,,"[1-7]\\d{5,8}|[89]\\d{6,11}","\\d{6,12}"]
 ,[,,"(?:1|6[029])\\d{7}|(?:2[0-3]|3[1-5]|4[02-47-9]|5[1-3])\\d{6}","\\d{6,9}",,,"12345678"]
@@ -1523,19 +1559,21 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"HT":[,[]
-,[]
-,[]
+,"HT":[,[,,"[2-489]\\d{7}","\\d{8}"]
+,[,,"2(?:[24]\\d|5[1-5]|94)\\d{5}","\\d{8}",,,"22453300"]
+,[,,"(?:3[4-9]|4\\d)\\d{6}","\\d{8}",,,"34101234"]
+,[,,"8\\d{7}","\\d{8}",,,"80012345"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"HT",509,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,[,,"98[89]\\d{5}","\\d{8}",,,"98901234"]
+,"HT",509,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"HU":[,[,,"\\d{8,9}","\\d{6,9}"]
 ,[,,"(?:1\\d|2(?:1\\d|[2-9])|3[2-7]|4[24-9]|5[2-79]|6[23689]|7(?:1\\d|[2-9])|8[2-57-9]|9[2-69])\\d{6}","\\d{6,9}",,,"12345678"]
-,[,,"(?:[237]0|31)\\d{7}","\\d{9}",,,"201234567"]
+,[,,"(?:[27]0|3[01])\\d{7}","\\d{9}",,,"201234567"]
 ,[,,"80\\d{6}","\\d{8}",,,"80123456"]
 ,[,,"9[01]\\d{6}","\\d{8}",,,"90123456"]
 ,[,,"40\\d{6}","\\d{8}",,,"40123456"]
@@ -1572,8 +1610,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"IE":[,[,,"[124-9]\\d{6,9}","\\d{5,10}"]
-,[,,"1\\d{7,8}|(?:2[24-9]|4(?:0[24]|7)|5(?:0[45]|8)|6[237-9]|9[3-9])\\d{5}|(?:45|[569]1|818)\\d{6}|(?:4[12469]|5[3679]|6[56]|7[14]|9[04])\\d{7}|21\\d{6,7}|(?:23|4[34]|52|64)\\d{5,7}|48\\d{8}","\\d{5,10}",,,"2212345"]
-,[,,"8[35-9]\\d{7}","\\d{9}",,,"850123456"]
+,[,,"1\\d{7,8}|2(?:1\\d{6,7}|[24-9]\\d{5}|3\\d{5,7})|4(?:0[24]\\d{5}|[1269]\\d{7}|[34]\\d{5,7}|5\\d{6}|7\\d{5}|8[0-46-9]\\d{7})|5(?:0[45]\\d{5}|1\\d{6}|2\\d{5,7}|[3679]\\d{7}|8\\d{5})|6(?:1\\d{6}|4\\d{5,7}|[237-9]\\d{5}|[56]\\d{7})|7[14]\\d{7}|818\\d{6}|9(?:1\\d{6}|[04]\\d{7}|[3-9]\\d{5})","\\d{5,10}",,,"2212345"]
+,[,,"8(?:22\\d{6}|[35-9]\\d{7,8})","\\d{9,10}",,,"850123456"]
 ,[,,"1800\\d{6}","\\d{10}",,,"1800123456"]
 ,[,,"15(?:1[2-9]|[2-8]0|59|9[089])\\d{6}","\\d{10}",,,"1520123456"]
 ,[,,"18[59]0\\d{6}","\\d{10}",,,"1850123456"]
@@ -1591,7 +1629,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"(0$1)",""]
 ,[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[24-69]|7[14]"]
 ,"(0$1)",""]
-,[,"([78]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["76|8[35-9]"]
+,[,"([78]\\d)(\\d{3,4})(\\d{4})","$1 $2 $3",["76|8[35-9]"]
 ,"0$1",""]
 ,[,"(700)(\\d{3})(\\d{3})","$1 $2 $3",["70"]
 ,"0$1",""]
@@ -1759,9 +1797,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"JE":[,[,,"[15789]\\d{6,9}","\\d{6,10}"]
 ,[,,"1534\\d{6}","\\d{6,10}",,,"1534456789"]
 ,[,,"7(?:509|7(?:00|97)|829|937)\\d{6}","\\d{10}",,,"7797123456"]
-,[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}","\\d{7}(?:\\d{2,3})?",,,"8001234567"]
-,[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}","\\d{10}",,,"9012345678"]
-,[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})","\\d{7}(?:\\d{3})?",,,"8431234567"]
+,[,,"80(?:07(?:35|81)|8901)\\d{4}","\\d{10}",,,"8007354567"]
+,[,,"(?:871206|90(?:066[59]|1810|71(?:07|55)))\\d{4}","\\d{10}",,,"9018105678"]
+,[,,"8(?:4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|70002)\\d{4}","\\d{10}",,,"8447034567"]
 ,[,,"701511\\d{4}","\\d{10}",,,"7015115678"]
 ,[,,"56\\d{8}","\\d{10}",,,"5612345678"]
 ,"JE",44,"00","0"," x",,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}","\\d{10}",,,"7640123456"]
@@ -1776,15 +1814,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"JM",1,"011","1",,,"1",,,,,,[,,"NA","NA"]
 ,,"876"]
-,"JO":[,[,,"[235-9]\\d{7,8}","\\d{7,9}"]
-,[,,"[2356][2-8]\\d{6}","\\d{7,8}",,,"62345678"]
-,[,,"7(?:4[5-7]|55|7[5-79]|8[5-8]|9[05-9])\\d{6}","\\d{9}",,,"790123456"]
+,"JO":[,[,,"[235-9]\\d{7,8}","\\d{8,9}"]
+,[,,"[2356][2-8]\\d{6}","\\d{7,8}",,,"62001234"]
+,[,,"7(?:[1-8]\\d|9[02-9])\\d{6}","\\d{9}",,,"790123456"]
 ,[,,"80\\d{6}","\\d{8}",,,"80012345"]
-,[,,"90\\d{6}","\\d{8}",,,"90012345"]
-,[,,"(?:8[57]\\d|810)\\d{5}","\\d{8}",,,"85012345"]
+,[,,"900\\d{5}","\\d{8}",,,"90012345"]
+,[,,"8(?:10\\d|5\\d{2}|7(?:[02]0|7[08]|9[09]))\\d{4}","\\d{8}",,,"85012345"]
 ,[,,"70\\d{7}","\\d{9}",,,"700123456"]
 ,[,,"NA","NA"]
-,"JO",962,"00","0",,,"0",,,,[[,"([2356])(\\d{3})(\\d{4})","$1 $2 $3",["[2356]"]
+,"JO",962,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2356]"]
 ,"(0$1)",""]
 ,[,"(7)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["7[457-9]"]
 ,"0$1",""]
@@ -1794,7 +1832,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"JP":[,[,,"\\d{9,10}","\\d{9,10}"]
-,[,,"(?:1[1-9][1-9]|9(?:[3-9][1-9]|2\\d)|(?:[36][1-9]|[24578][2-9])\\d)\\d{6}","\\d{9}",,,"312345678"]
+,[,,"(?:1(?:2[3-6]|3[3-9]|4[2-6]|[58][2-8]|6[2-7]|7[2-9]|9[1-578])|2[2-9]\\d|[36][1-9]\\d|4(?:6[0235-8]|[2-578]\\d|9[2-59])|5(?:6[1-9]|7[2-8]|[2-589]\\d)|7(?:3[4-9]|4[02-9]|[25-9]\\d)|8(?:3[2-9]|4[5-9]|5[1-9]|8[03-9]|[2679]\\d)|9(?:[679][1-9]|[2-58]\\d))\\d{6}","\\d{9}",,,"312345678"]
 ,[,,"[7-9]0\\d{8}","\\d{10}",,,"7012345678"]
 ,[,,"120\\d{6}","\\d{9}",,,"120123456"]
 ,[,,"990\\d{6}","\\d{9}",,,"990123456"]
@@ -1993,18 +2031,16 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"LB":[,[,,"[13-9]\\d{6,7}","\\d{7,8}"]
-,[,,"(?:[14-6]\\d|[7-9][2-9])\\d{5}","\\d{7}",,,"1123456"]
-,[,,"(?:3\\d|7(?:0\\d|1[167]))\\d{5}","\\d{7,8}",,,"71123456"]
+,[,,"(?:[14-6]\\d{2}|7(?:[2-57-9]\\d|62)|[89][2-9]\\d)\\d{4}","\\d{7}",,,"1123456"]
+,[,,"(?:3\\d|7(?:[01]\\d|66))\\d{5}","\\d{7,8}",,,"71123456"]
 ,[,,"NA","NA"]
 ,[,,"8[01]\\d{6}","\\d{8}",,,"80123456"]
 ,[,,"9[01]\\d{6}","\\d{8}",,,"90123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LB",961,"00","0",,,"0",,,,[[,"([13-6])(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]"]
-,"0$1",""]
-,[,"([7-9][01])(\\d{3})(\\d{3})","$1 $2 $3",["[7-9][01]"]
+,"LB",961,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]|7(?:[2-57-9]|62)|[89][2-9]"]
 ,"0$1",""]
-,[,"([7-9][2-9])(\\d{2})(\\d{3})","$1 $2 $3",["[7-9][2-9]"]
+,[,"([7-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[89][01]|7(?:[01]|66)"]
 ,"0$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -2038,25 +2074,30 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"LK":[,[]
-,[]
-,[]
+,"LK":[,[,,"[1-9]\\d{8}","\\d{7,9}"]
+,[,,"(?:[189]1|2[13-7]|3[1-8]|4[157]|5[12457]|6[35-7])[2-57]\\d{6}","\\d{7,9}",,,"112345678"]
+,[,,"7[12578]\\d{7}","\\d{9}",,,"712345678"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LK",94,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"LK",94,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{1})(\\d{6})","$1 $2 $3",["[1-689]"]
+,"0$1",""]
+,[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"]
+,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
-,"LR":[,[,,"(?:[27]\\d|[4-6])\\d{6}","\\d{7,8}"]
+,"LR":[,[,,"(?:[279]\\d|[4-6])\\d{6}","\\d{7,8}"]
 ,[,,"2\\d{7}","\\d{8}",,,"21234567"]
-,[,,"(?:4[67]|5\\d|7\\d{2}|6[4-8])\\d{5}","\\d{7,8}",,,"4612345"]
-,[,,"NA","NA"]
+,[,,"(?:4[67]|5\\d|6[4-8]|7\\d{2})\\d{5}","\\d{7,8}",,,"4612345"]
 ,[,,"NA","NA"]
+,[,,"90\\d{6}","\\d{8}",,,"90123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LR",231,"00","0",,,"0",,,,[[,"([27]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[27]"]
+,"LR",231,"00","0",,,"0",,,,[[,"([279]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[279]"]
 ,"0$1",""]
 ,[,"([4-6])(\\d{3})(\\d{3})","$1 $2 $3",["[4-6]"]
 ,"0$1",""]
@@ -2125,8 +2166,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"LY",218,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
 ,"MA":[,[,,"[5689]\\d{8}","\\d{9}"]
-,[,,"5(?:2(?:[015-7]\\d{2}|(?:[28][2-9]|3[2-7]|4[2-8])\\d|9(?:0\\d|[89]0))|3(?:[0-4]\\d{2}|(?:[57][2-9]|6[2-8]|9[3-9])\\d|8(?:0\\d|[89]0)))\\d{4}","\\d{9}",,,"520123456"]
-,[,,"6(?:00|33|[15-7]\\d|4[0-8]|99)\\d{6}","\\d{9}",,,"650123456"]
+,[,,"5(?:2(?:(?:[015-7]\\d|2[2-9]|3[2-57]|4[2-8]|8[235-9]|)\\d|9(?:0\\d|[89]0))|3(?:(?:[0-4]\\d|[57][2-9]|6[235-8]|9[3-9])\\d|8(?:0\\d|[89]0)))\\d{4}","\\d{9}",,,"520123456"]
+,[,,"6(?:0[06]|[14-7]\\d|2[236]|33|99)\\d{6}","\\d{9}",,,"650123456"]
 ,[,,"80\\d{7}","\\d{9}",,,"801234567"]
 ,[,,"89\\d{7}","\\d{9}",,,"891234567"]
 ,[,,"NA","NA"]
@@ -2213,8 +2254,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"MH",692,"011","1",,,"1",,,1,,,[,,"NA","NA"]
 ]
 ,"MK":[,[,,"[2-578]\\d{7}","\\d{8}"]
-,[,,"(?:2\\d|3[1-4]|4[2-8])\\d{6}","\\d{6,8}",,,"22212345"]
-,[,,"7\\d{7}","\\d{8}",,,"72345678"]
+,[,,"(?:2(?:[23]\\d|5[125]|61)|3(?:1[3-6]|2[2-6]|3[2-5]|4[235])|4(?:[23][2-6]|4[3-6]|5[25]|6[25-8]|7[24-6]|8[4-6]))\\d{5}","\\d{6,8}",,,"22212345"]
+,[,,"7[0-25-8]\\d{6}","\\d{8}",,,"72345678"]
 ,[,,"800\\d{5}","\\d{8}",,,"80012345"]
 ,[,,"5[02-9]\\d{6}","\\d{8}",,,"50012345"]
 ,[,,"8(?:0[1-9]|[1-9]\\d)\\d{5}","\\d{8}",,,"80123456"]
@@ -2264,21 +2305,23 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"MN":[,[,,"[127-9]\\d{7}","\\d{8}"]
-,[,,"(?:[12](?:1\\d|2[1-37]|3[2-8]|4[2-68]|5[1-4689])|70)\\d{6}","\\d{8}",,,"70123456"]
-,[,,"(?:88|9[1569])\\d{6}","\\d{8}",,,"88123456"]
-,[,,"NA","NA"]
+,"MN":[,[,,"[12]\\d{7,9}|[57-9]\\d{7}","\\d{8,10}"]
+,[,,"[12](?:1\\d|2(?:[1-3]\\d?|7\\d)|3[2-8]\\d{1,2}|4[2-68]\\d{1,2}|5[1-4689]\\d{1,2})\\d{5}|(?:5[0568]|70)\\d{6}","\\d{8,10}",,,"70123456"]
+,[,,"(?:8[89]|9[15689])\\d{6}","\\d{8}",,,"88123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MN",976,"001","0",,,"0",,,,[[,"([127-9]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1|[7-9]"]
+,[,,"7[569]\\d{6}","\\d{8}",,,"75123456"]
+,"MN",976,"001","0",,,"0",,,,[[,"([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1"]
 ,"0$1",""]
-,[,"([12]2\\d)(\\d{5})","$1 $2",["[12]2[1-3]"]
+,[,"([12]2\\d)(\\d{5,6})","$1 $2",["[12]2[1-3]"]
 ,"0$1",""]
-,[,"([12]\\d{3})(\\d{4})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"]
+,[,"([12]\\d{3})(\\d{5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"]
 ,"0$1",""]
-,[,"([12]\\d{4})(\\d{3})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"]
+,[,"(\\d{4})(\\d{4})","$1 $2",["[57-9]"]
+,"$1",""]
+,[,"([12]\\d{4})(\\d{4,5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"]
 ,"0$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -2315,15 +2358,18 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"MQ",596,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"MR":[,[,,"[2-7]\\d{6}","\\d{7}"]
-,[,,"5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\\d{4}","\\d{7}",,,"5131234"]
-,[,,"(?:[23][0-4]|4[3-5]|6\\d|7[0-7])\\d{5}","\\d{7}",,,"3123456"]
-,[,,"NA","NA"]
+,"MR":[,[,,"[2-4]\\d{6,7}|[5-7]\\d{6}|8\\d{7}","\\d{7,8}"]
+,[,,"5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\\d{4}|[2-4]5\\d{6}","\\d{7,8}",,,"35123456"]
+,[,,"(?:[23][0-4]|4[3-5]|6\\d|7[0-7])\\d{5}|(?:2[27]|3[367]|4[467])\\d{6}","\\d{7,8}",,,"22123456"]
+,[,,"800\\d{5}","\\d{8}",,,"80012345"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MR",222,"00",,,,,,,,[[,"([2-7]\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
+,"MR",222,"00",,,,,,,,[[,"([2-48]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-48]"]
+,"",""]
+,[,"([2-7]\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["[2-7]"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -2337,15 +2383,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"MS",1,"011","1",,,"1",,,,,,[,,"NA","NA"]
 ,,"664"]
-,"MT":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
+,"MT":[,[,,"[2579]\\d{7}","\\d{8}"]
+,[,,"2(?:0(?:1[0-6]|[69]\\d)|[1-357]\\d{2})\\d{4}","\\d{8}",,,"21001234"]
+,[,,"(?:7(?:210|[79]\\d{2}|)|9(?:2[13]\\d|696|8(?:1[1-3]|89|97)|9\\d{2}))\\d{4}","\\d{8}",,,"96961234"]
 ,[,,"NA","NA"]
+,[,,"50(?:0(?:3[1679]|4\\d)|[169]\\d{2}|7[06]\\d)\\d{3}","\\d{8}",,,"50031234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MT",356,"00","21",,,"21",,,1,,,[,,"NA","NA"]
+,"MT",356,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",,"",""]
+]
+,,[,,"7117\\d{4}","\\d{8}",,,"71171234"]
 ]
 ,"MU":[,[,,"[2-9]\\d{6}","\\d{7}"]
 ,[,,"(?:2(?:[034789]\\d|1[0-8]|2[0-79])|4(?:[013-8]\\d|2[4-7])|[56]\\d{2}|8(?:14|3[129]))\\d{4}","\\d{7}",,,"2012345"]
@@ -2359,15 +2407,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"MV":[,[]
-,[]
-,[]
+,"MV":[,[,,"[3679]\\d{6}","\\d{7}"]
+,[,,"(?:3(?:00|3[0-59]|)|6(?:[567][02468]|8[024689]))\\d{4}","\\d{7}",,,"6701234"]
+,[,,"(?:7(?:[679]\\d|8[02-9])|9[6-9]\\d)\\d{4}","\\d{7}",,,"7712345"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MV",960,"020","0",,,"0",,,1,,,[,,"NA","NA"]
+,"MV",960,"0(?:0|19)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1-$2",,"",""]
+]
+,,[,,"781\\d{4}","\\d{7}",,,"7812345"]
 ]
 ,"MW":[,[,,"(?:[13-5]|[27]\\d{2}|[89](?:\\d{2})?)\\d{6}","\\d{7,9}"]
 ,[,,"(?:1[2-9]|21\\d{2})\\d{5}","\\d{7,9}",,,"1234567"]
@@ -2452,28 +2502,22 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"NA":[,[,,"[68]\\d{5,9}","\\d{4,10}"]
-,[,,"6(?:1(?:[136]|2\\d?)\\d|2(?:[25]\\d?|[134678])\\d|3(?:2\\d{0,3}|4\\d{1,2}|[135-8]\\d?)|4(?:[13-8]\\d|2\\d{1,2})|(?:5(?:[16-7]\\d|[3-58]\\d?|2\\d{1,2}))|6\\d{0,4}|7\\d{0,3})\\d{4}","\\d{4,10}",,,"612012345"]
-,[,,"8(?:1(?:1[0-24]|[2-4]\\d|50|6[0-2])|5\\d{2})\\d{5}","\\d{9}",,,"811012345"]
+,"NA":[,[,,"[68]\\d{7,8}","\\d{8,9}"]
+,[,,"6(?:1(?:17|2(?:[0189]\\d|[23-6]|7\\d?)|3(?:2\\d|3[378])|4[01]|69|7[014])|2(?:17|25|5(?:[0-36-8]|4\\d?)|69|70)|3(?:17|2(?:[0237]\\d?|[14-689])|34|6[29]|7[01]|81)|4(?:17|2(?:[012]|7?)|4(?:[06]|1\\d)|5(?:[01357]|[25]\\d?)|69|7[01])|5(?:17|2(?:[0459]|[23678]\\d?)|69|7[01])|6(?:17|2(?:5|6\\d?)|38|42|69|7[01])|7(?:17|2(?:[569]|[234]\\d?)|3(?:0\\d?|[13])|69|7[01]))\\d{4}","\\d{8,9}",,,"612012345"]
+,[,,"(?:60|8[125])\\d{7}","\\d{9}",,,"811234567"]
 ,[,,"NA","NA"]
+,[,,"8701\\d{5}","\\d{9}",,,"870123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"88\\d{6}","\\d{8}",,,"88123456"]
-,"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[15]"]
-,"0$1",""]
-,[,"(632532)(\\d{2,4})","$1 $2",["632","6325","63253","632532"]
-,"0$1",""]
-,[,"(6\\d)(\\d{2,3})(\\d{4})","$1 $2 $3",["6(?:1|[245][1-7]|3[125-7]|6[1256]|7[1236])"]
+,[,,"886\\d{5}","\\d{8}",,,"88612345"]
+,"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[125]"]
 ,"0$1",""]
-,[,"(6\\d)(\\d{4,5})","$1 $2",["6(?:3[12567]|5[3-5]|6[1256]|7[1236])"]
-,"0$1",""]
-,[,"(6\\d{2})(\\d{4,6})","$1 $2",["6[2356]8"]
-,"0$1",""]
-,[,"(6\\d{3})(\\d{4,5})","$1 $2",["6(?:34|6[34]|75)","6(?:342|6[34]|751)"]
+,[,"(6\\d)(\\d{2,3})(\\d{4})","$1 $2 $3",["6"]
 ,"0$1",""]
 ,[,"(88)(\\d{3})(\\d{3})","$1 $2 $3",["88"]
 ,"0$1",""]
+,[,"(870)(\\d{3})(\\d{3})","$1 $2 $3",["870"]
+,"0$1",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -2608,15 +2652,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"NR",674,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"NU":[,[]
-,[]
-,[]
+,"NU":[,[,,"[1-5]\\d{3}","\\d{4}"]
+,[,,"[34]\\d{3}","\\d{4}",,,"4002"]
+,[,,"[125]\\d{3}","\\d{4}",,,"1234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"NU",683,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"NU",683,"00",,,,,,,,,,[,,"NA","NA"]
 ]
 ,"NZ":[,[,,"[2-9]\\d{7,9}","\\d{7,10}"]
 ,[,,"(?:3[2-79]|[479][2-689]|6[235-9])\\d{6}|24099\\d{3}","\\d{7,8}",,,"32345678"]
@@ -2695,7 +2739,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"PG":[,[,,"[1-9]\\d{6,7}","\\d{7,8}"]
 ,[,,"(?:3\\d{2}|4[257]\\d|5[34]\\d|6(?:29|4[1-9])|85[02-46-9]|9[78]\\d)\\d{4}","\\d{7}",,,"3123456"]
-,[,,"(?:68|7(?:[126]\\d|3[34689]))\\d{5}","\\d{7,8}",,,"6812345"]
+,[,,"(?:68|7(?:[126]\\d|3[1-9]))\\d{5}","\\d{7,8}",,,"6812345"]
 ,[,,"180\\d{4}","\\d{7}",,,"1801234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -2795,15 +2839,22 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"PR",1,"011","1",,,"1",,,1,,,[,,"NA","NA"]
 ,,"787|939"]
-,"PS":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"PS":[,[,,"(?:[24589]\\d{7,9}|1(?:[78]\\d{8}|[49]\\d{2,3}))","\\d{4,10}"]
+,[,,"(?:22[2379]|42[45]|82[01458]|92[369])\\d{5}","\\d{7,8}",,,"22234567"]
+,[,,"5[69]\\d{7}","\\d{9}",,,"599123456"]
+,[,,"1800\\d{6}","\\d{10}",,,"1800123456"]
+,[,,"1(?:4|9\\d)\\d{2}","\\d{4,5}",,,"19123"]
+,[,,"1700\\d{6}","\\d{10}",,,"1700123456"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"PS",970,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"PS",970,"00","0",,,"0",,,,[[,"([2489])(2\\d{2})(\\d{4})","$1 $2 $3",["[2489]"]
+,"0$1",""]
+,[,"(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["5"]
+,"0$1",""]
+,[,"(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3",["1[78]"]
+,"$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"PT":[,[,,"[2-46-9]\\d{8}","\\d{9}"]
 ,[,,"2(?:[12]\\d|[35][1-689]|4[1-59]|6[1-35689]|7[1-9]|8[1-69]|9[1256])\\d{6}","\\d{9}",,,"212345678"]
@@ -2959,27 +3010,32 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"SB",677,"00",,,,,,,1,,,[,,"NA","NA"]
 ]
-,"SC":[,[,,"[2-8]\\d{5}","\\d{6}"]
+,"SC":[,[,,"[2-8]\\d{5,6}","\\d{6,7}"]
 ,[,,"(?:2(?:1[78]|2[14-69]|3[2-4]|4[1-36-8]|6[167]|[89]\\d)|3(?:2[1-6]|4[4-6]|55|6[016]|7\\d|8[0-589]|9[0-5])|5(?:5\\d|6[0-2])|6(?:0[0-27-9]|1[0-478]|2[145]|3[02-4]|4[124]|6[015]|7\\d|8[1-3])|78[0138])\\d{3}","\\d{6}",,,"217123"]
 ,[,,"(?:5(?:[1247-9]\\d|6[3-9])|7(?:[14679]\\d|2[1-9]|8[24-79]))\\d{3}","\\d{6}",,,"510123"]
 ,[,,"8000\\d{2}","\\d{6}",,,"800000"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"4[1-37]\\d{4}","\\d{6}",,,"410123"]
-,"SC",248,"0[0-2]",,,,,,"00",,[[,"(\\d{3})(\\d{3})","$1 $2",,"",""]
+,[,,"(?:4?4[1-3]|6?47)\\d{4}","\\d{6,7}",,,"4410123"]
+,"SC",248,"0[0-2]",,,,,,"00",,[[,"(\\d{3})(\\d{3})","$1 $2",["[23578]|[46][0-35-9]"]
+,"",""]
+,[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[46]4"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
-,"SD":[,[]
-,[]
-,[]
+,"SD":[,[,,"[19]\\d{8}","\\d{9}"]
+,[,,"1(?:[25]\\d|8[3567])\\d{6}","\\d{9}",,,"121231234"]
+,[,,"9[1259]\\d{7}","\\d{9}",,,"911231234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"SD",249,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"SD",249,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"SE":[,[,,"\\d{7,10}","\\d{5,10}"]
 ,[,,"1(?:0[1-8]\\d{6}|[136]\\d{5,7}|(?:2[0-35]|4[0-4]|5[0-25-9]|7[13-6]|[89]\\d)\\d{5,6})|2(?:[136]\\d{5,7}|(?:2[0-7]|4[0136-8]|5[0-38]|7[018]|8[01]|9[0-57])\\d{5,6})|3(?:[356]\\d{5,7}|(?:0[0-4]|1\\d|2[0-25]|4[056]|7[0-2]|8[0-3]|9[023])\\d{5,6})|4(?:[0246]\\d{5,7}|(?:1[01-8]|3[0135]|5[14-79]|7[0-246-9]|8[0156]|9[0-689])\\d{5,6})|5(?:0[0-6]|1[1-5]|2[0-68]|3[0-4]|4\\d|5[0-5]|6[03-5]|7[013]|8[0-79]|9[01])\\d{5,6}|6(?:[03]\\d{5,7}|(?:1[1-3]|2[0-4]|4[02-57]|5[0-37]|6[0-3]|7[0-2]|8[0247]|9[0-356])\\d{5,6})|8\\d{6,8}|9(?:0\\d{5,7}|(?:1[0-68]|2\\d|3[02-59]|4[0-4]|5[0-4]|6[01]|7[0135-8]|8[01])\\d{5,6})","\\d{5,9}",,,"8123456"]
@@ -3008,18 +3064,20 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"SG":[,[,,"[13689]\\d{7,10}","\\d{8,11}"]
-,[,,"[36]\\d{7}","\\d{8}",,,"31234567"]
-,[,,"[89]\\d{7}","\\d{8}",,,"81234567"]
+,"SG":[,[,,"[36]\\d{7}|[17-9]\\d{7,10}","\\d{8,11}"]
+,[,,"6[1-8]\\d{6}|7000\\d{7}","\\d{8,11}",,,"61234567"]
+,[,,"(?:8[1-5]|9[0-8])\\d{6}","\\d{8}",,,"81234567"]
 ,[,,"1?800\\d{7}","\\d{10,11}",,,"18001234567"]
 ,[,,"1900\\d{7}","\\d{11}",,,"19001234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"3[0-2]\\d{6}","\\d{8}",,,"31234567"]
 ,"SG",65,"0[0-3][0-9]",,,,,,,,[[,"([3689]\\d{3})(\\d{4})","$1 $2",["[369]|8[1-9]"]
 ,"",""]
 ,[,"(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3",["1[89]"]
 ,"",""]
+,[,"(7000)(\\d{4})(\\d{3})","$1 $2 $3",["70"]
+,"",""]
 ,[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"]
 ,"",""]
 ]
@@ -3115,7 +3173,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"SO",252,"00",,,,,,,,[[,"([13-5])(\\d{6})","$1 $2",["[13-5]"]
 ,"",""]
-,[,"([19]\\d)(\\d{6})","$1 $2",["[19]"]
+,[,"([19]\\d)(\\d{6})","$1 $2",["15|9"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -3167,17 +3225,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"SZ":[,[,,"[2-7]\\d{6,7}","\\d{7,8}"]
+,"SZ":[,[,,"[02-7]\\d{6,7}","\\d{7,8}"]
 ,[,,"2?(?:2(?:0[07]|[13]7|2[57])|3(?:0[34]|[1278]3|3[23]|[46][34])|(?:40[4-69]|16|2[12]|3[57]|[4578]2|67)|5(?:0[5-7]|1[6-9]|[23][78]|48|5[01]))\\d{4}","\\d{7,8}",,,"2171234"]
-,[,,"(?:6|7[67])\\d{6}","\\d{7,8}",,,"76123456"]
-,[,,"NA","NA"]
+,[,,"(?:6|7[6-8])\\d{6}","\\d{7,8}",,,"76123456"]
+,[,,"0800\\d{4}","\\d{8}",,,"08001234"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"SZ",268,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-6]"]
 ,"",""]
-,[,"(\\d{4})(\\d{4})","$1 $2",["7"]
+,[,"(\\d{4})(\\d{4})","$1 $2",["[027]"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -3511,7 +3569,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,"340"]
 ,"VN":[,[,,"8\\d{5,8}|[1-79]\\d{7,9}","\\d{7,10}"]
 ,[,,"(?:2(?:[025-79]|1[0189]|[348][01])|3(?:[0136-9]|[25][01])|[48]\\d|5(?:[01][01]|[2-9])|6(?:[0-46-8]|5[01])|7(?:[02-79]|[18][01]))\\d{7}|69\\d{5,6}|80\\d{5}","\\d{7,10}",,,"2101234567"]
-,[,,"(?:9\\d|1(?:2[1-35-9]|6[3-9]|99))\\d{7}","\\d{9,10}",,,"912345678"]
+,[,,"(?:9\\d|1(?:2\\d|6[3-9]|88|99))\\d{7}","\\d{9,10}",,,"912345678"]
 ,[,,"1800\\d{4,6}","\\d{8,10}",,,"1800123456"]
 ,[,,"1900\\d{4,6}","\\d{8,10}",,,"1900123456"]
 ,[,,"NA","NA"]
@@ -3529,9 +3587,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"0$1",""]
 ,[,"(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"]
 ,"0$1",""]
-,[,"(1[269]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|99)"]
+,[,"(1[2689]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|88|99)"]
 ,"0$1",""]
-,[,"(1[89]00)(\\d{4,6})","$1 $2",["1(?:8|90)"]
+,[,"(1[89]00)(\\d{4,6})","$1 $2",["1[89]0"]
 ,"$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -3600,11 +3658,14 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"(?:1[0-8]|2[1-478]|3[1-69]|4\\d|5[1346-8])\\d{7}","\\d{8,9}",,,"101234567"]
 ,[,,"(?:7[1-4689]|8[1-5789])\\d{7}","\\d{9}",,,"711234567"]
 ,[,,"80\\d{7}","\\d{9}",,,"801234567"]
-,[,,"86\\d{7}","\\d{9}",,,"861234567"]
-,[,,"NA","NA"]
+,[,,"86[1-9]\\d{6}","\\d{9}",,,"861234567"]
+,[,,"860\\d{6}","\\d{9}",,,"860123456"]
 ,[,,"NA","NA"]
 ,[,,"87\\d{7}","\\d{9}",,,"871234567"]
-,"ZA",27,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]
+,"ZA",27,"00","0",,,"0",,,,[[,"(860)(\\d{3})(\\d{3})","$1 $2 $3",["860"]
+,"0$1",""]
+,[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[1-57]|8(?:[0-57-9]|6[1-9])"]
+,"0$1",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -3625,7 +3686,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"ZW":[,[,,"2(?:[012457-9]\\d{3,8}|6\\d{3,6})|[13-79]\\d{4,8}|86\\d{8}","\\d{3,10}"]
 ,[,,"(?:1[3-9]|2(?:0[45]|[16]|2[28]|[49]8?|58[23]|7[246]|8[1346-9])|3(?:08?|17?|3[78]|[2456]|7[1569]|8[379])|5(?:[07-9]|1[78]|483|5(?:7?|8))|6(?:0|28|37?|[45][68][78]|98?)|848)\\d{3,6}|(?:2(?:27|5|7[135789]|8[25])|3[39]|5[1-46]|6[126-8])\\d{4,6}|2(?:0|70)\\d{5,6}|(?:4\\d|9[2-8])\\d{4,7}","\\d{3,10}",,,"1312345"]
-,[,,"(?:[19]1|7[13])\\d{6,7}","\\d{8,9}",,,"911234567"]
+,[,,"7[137]\\d{7}","\\d{9}",,,"711234567"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
index 45fce42..e121e67 100644 (file)
@@ -329,13 +329,13 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"AM":[,[,,"[1-37-9]\\d{7}","\\d{5,8}"]
 ,[,,"(?:10\\d|2(?:2[2-46]|3[1-8]|4[2-69]|5[2-7]|6[1-9]|8[1-7])|3[12]2)\\d{5}","\\d{5,8}"]
-,[,,"(?:77|9[1-49])\\d{6}","\\d{8}"]
+,[,,"(?:77|9[1-469])\\d{6}","\\d{8}"]
 ,[,,"800\\d{5}","\\d{8}"]
 ,[,,"90[016]\\d{5}","\\d{8}"]
 ,[,,"80[1-4]\\d{5}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",["[17]|9[1-49]"]
+,"AM",374,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{6})","$1 $2",["[17]|9[1-469]"]
 ,"(0$1)",""]
 ,[,"(\\d{3})(\\d{5})","$1 $2",["[23]"]
 ,"(0$1)",""]
@@ -583,12 +583,12 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"BH":[,[,,"[1367]\\d{7}","\\d{8}"]
+,"BH":[,[,,"[136-9]\\d{7}","\\d{8}"]
 ,[,,"(?:1(?:3[3-6]|6[0156]|7\\d)|6(?:1[16]|6[03469]|9[69])|77\\d)\\d{5}","\\d{8}"]
 ,[,,"(?:3(?:[369]\\d|77|8[38])|6(?:1[16]|6[03469]|9[69])|77\\d)\\d{5}","\\d{8}"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"80\\d{6}","\\d{8}"]
+,[,,"(?:87|9[014578])\\d{6}","\\d{8}"]
+,[,,"84\\d{6}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"BH",973,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",,"",""]
@@ -738,15 +738,20 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"BZ":[,[]
-,[]
-,[]
+,"BZ":[,[,,"[2-8]\\d{6}|0\\d{10}","\\d{7}(?:\\d{4})?"]
+,[,,"[234578][02]\\d{5}","\\d{7}"]
+,[,,"6(?:[01]\\d|2[0-5]|[67][01])\\d{4}","\\d{7}"]
+,[,,"0800\\d{7}","\\d{11}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"BZ",501,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"BZ",501,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1-$2",["[2-8]"]
+,"",""]
+,[,"(0)(800)(\\d{4})(\\d{3})","$1-$2-$3-$4",["0"]
+,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"CA":[,[,,"[2-9]\\d{9}|3\\d{6}","\\d{7,10}"]
 ,[,,"(?:2(?:04|26|50|89)|306|4(?:03|16|18|38|50|56)|5(?:00|06|14|19|81|87)|6(?:00|04|13|47)|7(?:00|05|09|10|78|80)|8(?:07|19|67))[2-9]\\d{6}|310\\d{4}","\\d{7,10}"]
@@ -760,7 +765,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"CD":[,[,,"[89]\\d{8}|[1-6]\\d{6}","\\d{7,9}"]
 ,[,,"[1-6]\\d{6}","\\d{7}"]
-,[,,"(?:8[0149]|9[7-9])\\d{7}","\\d{9}"]
+,[,,"(?:8[0-2489]|9[7-9])\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -785,15 +790,18 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"CG":[,[,,"[24-68]\\d{6}","\\d{7}"]
-,[,,"(?:2[1-589]|8\\d)\\d{5}","\\d{7}"]
-,[,,"[4-6]\\d{6}","\\d{7}"]
-,[,,"NA","NA"]
+,"CG":[,[,,"[028]\\d{8}","\\d{9}"]
+,[,,"222[1-589]\\d{5}","\\d{9}"]
+,[,,"0[14-6]\\d{7}","\\d{9}"]
+,[,,"800\\d{6}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CG",242,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",,"",""]
+,"CG",242,"00",,,,,,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["[02]"]
+,"",""]
+,[,"(\\d)(\\d{4})(\\d{4})","$1 $2 $3",["8"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -930,27 +938,37 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"CO",57,"(?:00[579]|#555|#999)","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"CR":[,[,,"[28]\\d{7}","\\d{8}"]
+,"CR":[,[,,"[289]\\d{7,9}","\\d{8,10}"]
 ,[,,"2[24-7]\\d{6}","\\d{8}"]
-,[,,"8[38]\\d{6}","\\d{8}"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"8[389]\\d{6}","\\d{8}"]
+,[,,"800\\d{7}","\\d{10}"]
+,[,,"90[059]\\d{7}","\\d{10}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CR",506,"00",,,,,,,,[[,"([28]\\d{3})(\\d{4})","$1 $2",,"",""]
+,"CR",506,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",["2|8[389]"]
+,"",""]
+,[,"(\\d{3})(\\d{3})(\\d{4})","$1-$2-$3",["[89]0"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
-,"CU":[,[]
-,[]
-,[]
+,"CU":[,[,,"[2-57]\\d{5,7}","\\d{4,8}"]
+,[,,"(?:2[1-4]\\d{5,6}|3(?:1\\d{6}|[23]\\d{4,6})|4(?:[125]\\d{5,6}|[36]\\d{6}|[78]\\d{4,6})|7\\d{6,7})","\\d{4,8}"]
+,[,,"5\\d{7}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"CU",53,"119","0",,,"0",,,1,,,[,,"NA","NA"]
+,"CU",53,"119","0",,,"0",,,,[[,"(\\d)(\\d{6,7})","$1 $2",["7"]
+,"(0$1)",""]
+,[,"(\\d{2})(\\d{4,6})","$1 $2",["[2-4]"]
+,"(0$1)",""]
+,[,"(\\d)(\\d{7})","$1 $2",["5"]
+,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"CV":[,[,,"[259]\\d{6}","\\d{7}"]
 ,[,,"2(?:2[1-7]|3[0-8]|4[12]|5[1256]|6\\d|7[1-3]|8[1-5])\\d{4}","\\d{7}"]
@@ -988,9 +1006,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"DE":[,[,,"(?:4[0-8]|[1-35-9]\\d)\\d{4,12}|49(?:4[1-8]|[0-35-7]\\d)\\d{2,7}","\\d{2,14}"]
-,[,,"(?:[246]\\d{2}|3[02-9]\\d|5(?:0[2-8]|[38][0-8]|[124-6]\\d|[79][0-7])|[789](?:[1-9]\\d|0[2-9]))\\d{3,10}","\\d{2,14}"]
-,[,,"1(?:5\\d{9}|7(?:[0-57-9]|6\\d)\\d{7}|6[02]\\d{7,8}|63\\d{7})","\\d{10,11}"]
+,"DE":[,[,,"[1-35-9]\\d{3,13}|4(?:[0-8]\\d{4,12}|9(?:4[1-8]|[0-35-7]\\d)\\d{2,7})","\\d{2,14}"]
+,[,,"[246]\\d{5,13}|3(?:[03-9]\\d{4,11}|2\\d{9})|5(?:0[2-8]|[38][0-8]|[124-6]\\d|[79][0-7])\\d{3,10}|7(?:0[2-8]|[1-9]\\d)\\d{3,10}|8(?:0[2-9]|[1-9]\\d)\\d{3,10}|9(?:0[6-9]|[1-9]\\d)\\d{3,10}","\\d{2,14}"]
+,[,,"1(?:5\\d{9}|7(?:[0-57-9]|6\\d)\\d{7}|6(?:[02]\\d{7,8}|3\\d{7}))","\\d{10,11}"]
 ,[,,"800\\d{7,9}","\\d{10,12}"]
 ,[,,"900(?:[135]\\d{6}|9\\d{7})","\\d{10,11}"]
 ,[,,"180\\d{5,11}","\\d{8,14}"]
@@ -1011,17 +1029,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,"(700)(\\d{4})(\\d{4})","$1 $2 $3",["700"]
 ,"0$1",""]
 ]
-,,[,,"NA","NA"]
+,,[,,"16(?:4\\d{1,10}|[89]\\d{1,11})","\\d{4,14}"]
 ]
-,"DJ":[,[,,"[2-8]\\d{5}","\\d{6}"]
-,[,,"(?:25|3[0-6]|42)\\d{4}","\\d{6}"]
-,[,,"(?:[5-7]\\d|8[0-7])\\d{4}","\\d{6}"]
+,"DJ":[,[,,"[1-8]\\d{5}","\\d{6}"]
+,[,,"(?:1[05]|[2-5]\\d)\\d{4}","\\d{6}"]
+,[,,"[6-8]\\d{5}","\\d{6}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"DJ",253,"00",,,,,,,,[[,"([2-8]\\d)(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
+,"DJ",253,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -1074,29 +1092,45 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"EC":[,[]
-,[]
-,[]
+,"EC":[,[,,"[2-9]\\d{7}|1\\d{9,10}","\\d{7,11}"]
+,[,,"[2-7][2-7]\\d{6}","\\d{7,8}"]
+,[,,"[89]\\d{7}","\\d{8}"]
+,[,,"1800\\d{6,7}","\\d{10,11}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
+,"EC",593,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2-$3",["[2-7]"]
+,"(0$1)",""]
+,[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[89]"]
+,"0$1",""]
+,[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"]
+,"$1",""]
+]
+,[[,"(\\d)(\\d{3})(\\d{4})","$1-$2-$3",["[2-7]"]
+,,""]
+,[,"(\\d{2})(\\d{3})(\\d{3})","$1 $2 $3",["[89]"]
+,,""]
+,[,"(1800)(\\d{3})(\\d{3,4})","$1 $2 $3",["1"]
+,,""]
+]
 ,[,,"NA","NA"]
-,"EC",593,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
 ,"EE":[,[,,"[3-9]\\d{6,7}|800\\d{6,7}","\\d{6,10}"]
-,[,,"(?:3[23589]|4[3-8]|6\\d|7[1-9]|88)\\d{5}","\\d{7}"]
+,[,,"(?:3[23589]|4(?:0\\d|[3-8])|6\\d|7[1-9]|88)\\d{5}","\\d{7,8}"]
 ,[,,"(?:5\\d|8[1-5])\\d{6}|5(?:[02]\\d{2}|1(?:[0-8]\\d|95)|5[0-478]\\d|64[0-4]|65[1-589])\\d{3}","\\d{7,8}"]
 ,[,,"800(?:0\\d{3}|1\\d|[2-9])\\d{3}","\\d{7,10}"]
 ,[,,"900\\d{4}","\\d{7}"]
 ,[,,"NA","NA"]
-,[,,"70\\d{5}","\\d{7}"]
+,[,,"70[0-2]?\\d{5}","\\d{7,8}"]
 ,[,,"NA","NA"]
-,"EE",372,"00",,,,,,,,[[,"([34-79]\\d{2})(\\d{4})","$1 $2",["[34679]|5(?:[0-2]|5[0-478]|6[45])","[34679]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))"]
+,"EE",372,"00",,,,,,,,[[,"([34-79]\\d{2})(\\d{4})","$1 $2",["[3679]|4[3-8]|5(?:[0-2]|5[0-478]|6[45])","[3679]|4[3-8]|5(?:[02]|1(?:[0-8]|95)|5[0-478]|6(?:4[0-4]|5[1-589]))"]
+,"",""]
+,[,"(70)(\\d{2})(\\d{4})","$1 $2 $3",["70"]
 ,"",""]
 ,[,"(8000)(\\d{3})(\\d{3})","$1 $2 $3",["800","8000"]
 ,"",""]
-,[,"([58]\\d{3})(\\d{3,4})","$1 $2",["5|8(?:00|[1-5])","5|8(?:00[1-9]|[1-5])"]
+,[,"([458]\\d{3})(\\d{3,4})","$1 $2",["40|5|8(?:00|[1-5])","40|5|8(?:00[1-9]|[1-5])"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -1201,15 +1235,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"FM",691,"00",,,,,,,1,,,[,,"NA","NA"]
 ]
-,"FO":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
+,"FO":[,[,,"[2-9]\\d{5}","\\d{6}"]
+,[,,"(?:20|[3-4]\\d|8[19])\\d{4}","\\d{6}"]
+,[,,"(?:2[1-9]|5\\d|7[1-79])\\d{4}","\\d{6}"]
+,[,,"80[257-9]\\d{3}","\\d{6}"]
+,[,,"90(?:[1345][15-7]|2[125-7]|99)\\d{2}","\\d{6}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"FO",298,"00",,,,,,,1,,,[,,"NA","NA"]
+,[,,"(?:6[0-36]|88)\\d{4}","\\d{6}"]
+,"FO",298,"00",,,,"10(?:01|[12]0|88)",,,,,,[,,"NA","NA"]
 ]
 ,"FR":[,[,,"[1-9]\\d{8}","\\d{9}"]
 ,[,,"[1-5]\\d{8}","\\d{9}"]
@@ -1242,7 +1276,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"GB":[,[,,"\\d{7,10}","\\d{4,10}"]
-,[,,"1(?:1[3-8]|[2-69]1)\\d{7}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-4789]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1235679]|9[24578])|4(?:0[03-9]|2[02-5789]|[37]\\d|4[02-69]|5[0-8]|[69][0-79]|8[02-5789])|5(?:0[1235-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-5789])|6(?:0[034689]|2[0-35689]|3[013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|8[013-9]|9[0124578])|7(?:0[0246-9]|2\\d|3[023678]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-5789]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-5789]|4[2-9]|5[0-579]|6[234789]|7[0124578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-4789]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[015789]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[234678]\\d{2}|16977[23]\\d{3}|2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[012])\\d{7}|(?:3[0347]|55)\\d{8}","\\d{4,10}"]
+,[,,"2(?:0[01378]|3[0189]|4[017]|8[0-46-9]|9[012])\\d{7}|1(?:(?:1(?:3[0-48]|[46][0-4]|5[012789]|7[0-39]|8[01349])|21[0-7]|31[0-8]|[459]1\\d|61[01246-9]))\\d{6}|1(?:2(?:0[024-9]|2[3-9]|3[3-79]|4[1-689]|[58][02-9]|6[0-4789]|7[013-9]|9\\d)|3(?:0\\d|[25][02-9]|3[02-579]|[468][0-46-9]|7[1235679]|9[24578])|4(?:0[03-9]|[28][02-5789]|[37]\\d|4[02-69]|5[0-8]|[69][0-79])|5(?:0[1235-9]|2[024-9]|3[015689]|4[02-9]|5[03-9]|6\\d|7[0-35-9]|8[0-468]|9[0-5789])|6(?:0[034689]|2[0-35689]|[38][013-9]|4[1-467]|5[0-69]|6[13-9]|7[0-8]|9[0124578])|7(?:0[0246-9]|2\\d|3[023678]|4[03-9]|5[0-46-9]|6[013-9]|7[0-35-9]|8[024-9]|9[02-9])|8(?:0[35-9]|2[1-5789]|3[02-578]|4[0-578]|5[124-9]|6[2-69]|7\\d|8[02-9]|9[02569])|9(?:0[02-589]|2[02-689]|3[1-5789]|4[2-9]|5[0-579]|6[234789]|7[0124578]|8\\d|9[2-57]))\\d{6}|1(?:2(?:0(?:46[1-4]|87[2-9])|545[1-79]|76(?:2\\d|3[1-8]|6[1-6])|9(?:7(?:2[0-4]|3[2-5])|8(?:2[2-8]|7[0-4789]|8[345])))|3(?:638[2-5]|647[23]|8(?:47[04-9]|64[015789]))|4(?:044[1-7]|20(?:2[23]|8\\d)|6(?:0(?:30|5[2-57]|6[1-8]|7[2-8])|140)|8(?:052|87[123]))|5(?:24(?:3[2-79]|6\\d)|276\\d|6(?:26[06-9]|686))|6(?:06(?:4\\d|7[4-79])|295[567]|35[34]\\d|47(?:24|61)|59(?:5[08]|6[67]|74)|955[0-4])|7(?:26(?:6[13-9]|7[0-7])|442\\d|50(?:2[0-3]|[3-68]2|76))|8(?:27[56]\\d|37(?:5[2-5]|8[239])|84(?:3[2-58]))|9(?:0(?:0(?:6[1-8]|85)|52\\d)|3583|4(?:66[1-8]|9(?:2[01]|81))|63(?:23|3[1-4])|9561))\\d{3}|176888[234678]\\d{2}|16977[23]\\d{3}|(?:3[0347]|55)\\d{8}","\\d{4,10}"]
 ,[,,"7(?:[1-4]\\d\\d|5(?:0[0-8]|[13-9]\\d|2[0-35-9])|7(?:0[1-9]|[1-7]\\d|8[02-9]|9[0-689])|8(?:[014-9]\\d|[23][0-8])|9(?:[04-9]\\d|1[02-9]|2[0135-9]|3[0-689]))\\d{6}","\\d{10}"]
 ,[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}","\\d{7}(?:\\d{2,3})?"]
 ,[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}","\\d{10}"]
@@ -1335,15 +1369,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"GI":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"GI":[,[,,"[2568]\\d{7}","\\d{8}"]
+,[,,"2(?:00\\d|16[0-7]|22[2457])\\d{4}","\\d{8}"]
+,[,,"(?:5[4-8]|60)\\d{6}","\\d{8}"]
+,[,,"80\\d{6}","\\d{8}"]
+,[,,"8[1-689]\\d{6}","\\d{8}"]
+,[,,"87\\d{6}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"GI",350,"00",,,,,,,1,,,[,,"NA","NA"]
+,"GI",350,"00",,,,,,,,,,[,,"NA","NA"]
 ]
 ,"GL":[,[,,"[1-689]\\d{5}","\\d{6}"]
 ,[,,"(?:19|3[1-6]|6[14689]|8[14-79]|9\\d)\\d{4}","\\d{6}"]
@@ -1371,7 +1405,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"GN":[,[,,"[3567]\\d{7}","\\d{8}"]
 ,[,,"30(?:24|3[12]|4[1-35-7]|5[13]|6[189]|[78]1|9[1478])\\d{4}","\\d{8}"]
-,[,,"55\\d{6}|6(?:0(?:2\\d|3[3467]|5[2457-9])|[2457]\\d{2}|3(?:[14]0|35))\\d{4}","\\d{8}"]
+,[,,"55\\d{6}|6(?:0(?:2\\d|3[3467]|5[2457-9])|[24578]\\d{2}|3(?:[14]0|35))\\d{4}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -1484,15 +1518,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"HN":[,[]
-,[]
-,[]
+,"HN":[,[,,"[237-9]\\d{7}","\\d{8}"]
+,[,,"2(?:2(?:0[019]|1[1-36]|[23]\\d|4[056]|5[57]|9[01])|4(?:2|3-59]|3[13-689]|4[0-68]|5[1-35])|5(?:4[3-5]|5\\d|6[56]|74)|6(?:4[0-378]|[56]\\d|[78][0-8]|9[01])|7(?:6[46-9]|7[02-9]|8[34])|8(?:79|8[0-35789]|9[1-57-9]))\\d{4}","\\d{8}"]
+,[,,"[37-9]\\d{7}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"HN",504,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"HN",504,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1-$2",,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"HR":[,[,,"[1-7]\\d{5,8}|[89]\\d{6,11}","\\d{6,12}"]
 ,[,,"(?:1|6[029])\\d{7}|(?:2[0-3]|3[1-5]|4[02-47-9]|5[1-3])\\d{6}","\\d{6,9}"]
@@ -1523,19 +1559,21 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"HT":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"HT":[,[,,"[2-489]\\d{7}","\\d{8}"]
+,[,,"2(?:[24]\\d|5[1-5]|94)\\d{5}","\\d{8}"]
+,[,,"(?:3[4-9]|4\\d)\\d{6}","\\d{8}"]
+,[,,"8\\d{7}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"HT",509,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,[,,"98[89]\\d{5}","\\d{8}"]
+,"HT",509,"00",,,,,,,,[[,"(\\d{2})(\\d{2})(\\d{4})","$1 $2 $3",,"",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"HU":[,[,,"\\d{8,9}","\\d{6,9}"]
 ,[,,"(?:1\\d|2(?:1\\d|[2-9])|3[2-7]|4[24-9]|5[2-79]|6[23689]|7(?:1\\d|[2-9])|8[2-57-9]|9[2-69])\\d{6}","\\d{6,9}"]
-,[,,"(?:[237]0|31)\\d{7}","\\d{9}"]
+,[,,"(?:[27]0|3[01])\\d{7}","\\d{9}"]
 ,[,,"80\\d{6}","\\d{8}"]
 ,[,,"9[01]\\d{6}","\\d{8}"]
 ,[,,"40\\d{6}","\\d{8}"]
@@ -1572,8 +1610,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"IE":[,[,,"[124-9]\\d{6,9}","\\d{5,10}"]
-,[,,"1\\d{7,8}|(?:2[24-9]|4(?:0[24]|7)|5(?:0[45]|8)|6[237-9]|9[3-9])\\d{5}|(?:45|[569]1|818)\\d{6}|(?:4[12469]|5[3679]|6[56]|7[14]|9[04])\\d{7}|21\\d{6,7}|(?:23|4[34]|52|64)\\d{5,7}|48\\d{8}","\\d{5,10}"]
-,[,,"8[35-9]\\d{7}","\\d{9}"]
+,[,,"1\\d{7,8}|2(?:1\\d{6,7}|[24-9]\\d{5}|3\\d{5,7})|4(?:0[24]\\d{5}|[1269]\\d{7}|[34]\\d{5,7}|5\\d{6}|7\\d{5}|8[0-46-9]\\d{7})|5(?:0[45]\\d{5}|1\\d{6}|2\\d{5,7}|[3679]\\d{7}|8\\d{5})|6(?:1\\d{6}|4\\d{5,7}|[237-9]\\d{5}|[56]\\d{7})|7[14]\\d{7}|818\\d{6}|9(?:1\\d{6}|[04]\\d{7}|[3-9]\\d{5})","\\d{5,10}"]
+,[,,"8(?:22\\d{6}|[35-9]\\d{7,8})","\\d{9,10}"]
 ,[,,"1800\\d{6}","\\d{10}"]
 ,[,,"15(?:1[2-9]|[2-8]0|59|9[089])\\d{6}","\\d{10}"]
 ,[,,"18[59]0\\d{6}","\\d{10}"]
@@ -1591,7 +1629,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"(0$1)",""]
 ,[,"(\\d{2})(\\d{3})(\\d{3,4})","$1 $2 $3",["[24-69]|7[14]"]
 ,"(0$1)",""]
-,[,"([78]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["76|8[35-9]"]
+,[,"([78]\\d)(\\d{3,4})(\\d{4})","$1 $2 $3",["76|8[35-9]"]
 ,"0$1",""]
 ,[,"(700)(\\d{3})(\\d{3})","$1 $2 $3",["70"]
 ,"0$1",""]
@@ -1759,9 +1797,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"JE":[,[,,"[15789]\\d{6,9}","\\d{6,10}"]
 ,[,,"1534\\d{6}","\\d{6,10}"]
 ,[,,"7(?:509|7(?:00|97)|829|937)\\d{6}","\\d{10}"]
-,[,,"80(?:0(?:1111|\\d{6,7})|8\\d{7})|500\\d{6}","\\d{7}(?:\\d{2,3})?"]
-,[,,"(?:87[123]|9(?:[01]\\d|8[0-3]))\\d{7}","\\d{10}"]
-,[,,"8(?:4(?:5464\\d|[2-5]\\d{7})|70\\d{7})","\\d{7}(?:\\d{3})?"]
+,[,,"80(?:07(?:35|81)|8901)\\d{4}","\\d{10}"]
+,[,,"(?:871206|90(?:066[59]|1810|71(?:07|55)))\\d{4}","\\d{10}"]
+,[,,"8(?:4(?:4(?:4(?:05|42|69)|703)|5(?:041|800))|70002)\\d{4}","\\d{10}"]
 ,[,,"701511\\d{4}","\\d{10}"]
 ,[,,"56\\d{8}","\\d{10}"]
 ,"JE",44,"00","0"," x",,"0",,,,,,[,,"76(?:0[012]|2[356]|4[0134]|5[49]|6[0-369]|77|81|9[39])\\d{6}","\\d{10}"]
@@ -1776,15 +1814,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"JM",1,"011","1",,,"1",,,,,,[,,"NA","NA"]
 ,,"876"]
-,"JO":[,[,,"[235-9]\\d{7,8}","\\d{7,9}"]
+,"JO":[,[,,"[235-9]\\d{7,8}","\\d{8,9}"]
 ,[,,"[2356][2-8]\\d{6}","\\d{7,8}"]
-,[,,"7(?:4[5-7]|55|7[5-79]|8[5-8]|9[05-9])\\d{6}","\\d{9}"]
+,[,,"7(?:[1-8]\\d|9[02-9])\\d{6}","\\d{9}"]
 ,[,,"80\\d{6}","\\d{8}"]
-,[,,"90\\d{6}","\\d{8}"]
-,[,,"(?:8[57]\\d|810)\\d{5}","\\d{8}"]
+,[,,"900\\d{5}","\\d{8}"]
+,[,,"8(?:10\\d|5\\d{2}|7(?:[02]0|7[08]|9[09]))\\d{4}","\\d{8}"]
 ,[,,"70\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
-,"JO",962,"00","0",,,"0",,,,[[,"([2356])(\\d{3})(\\d{4})","$1 $2 $3",["[2356]"]
+,"JO",962,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[2356]"]
 ,"(0$1)",""]
 ,[,"(7)(\\d{2})(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4 $5",["7[457-9]"]
 ,"0$1",""]
@@ -1794,7 +1832,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"JP":[,[,,"\\d{9,10}","\\d{9,10}"]
-,[,,"(?:1[1-9][1-9]|9(?:[3-9][1-9]|2\\d)|(?:[36][1-9]|[24578][2-9])\\d)\\d{6}","\\d{9}"]
+,[,,"(?:1(?:2[3-6]|3[3-9]|4[2-6]|[58][2-8]|6[2-7]|7[2-9]|9[1-578])|2[2-9]\\d|[36][1-9]\\d|4(?:6[0235-8]|[2-578]\\d|9[2-59])|5(?:6[1-9]|7[2-8]|[2-589]\\d)|7(?:3[4-9]|4[02-9]|[25-9]\\d)|8(?:3[2-9]|4[5-9]|5[1-9]|8[03-9]|[2679]\\d)|9(?:[679][1-9]|[2-58]\\d))\\d{6}","\\d{9}"]
 ,[,,"[7-9]0\\d{8}","\\d{10}"]
 ,[,,"120\\d{6}","\\d{9}"]
 ,[,,"990\\d{6}","\\d{9}"]
@@ -1993,18 +2031,16 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,[,,"NA","NA"]
 ]
 ,"LB":[,[,,"[13-9]\\d{6,7}","\\d{7,8}"]
-,[,,"(?:[14-6]\\d|[7-9][2-9])\\d{5}","\\d{7}"]
-,[,,"(?:3\\d|7(?:0\\d|1[167]))\\d{5}","\\d{7,8}"]
+,[,,"(?:[14-6]\\d{2}|7(?:[2-57-9]\\d|62)|[89][2-9]\\d)\\d{4}","\\d{7}"]
+,[,,"(?:3\\d|7(?:[01]\\d|66))\\d{5}","\\d{7,8}"]
 ,[,,"NA","NA"]
 ,[,,"8[01]\\d{6}","\\d{8}"]
 ,[,,"9[01]\\d{6}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LB",961,"00","0",,,"0",,,,[[,"([13-6])(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]"]
+,"LB",961,"00","0",,,"0",,,,[[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[13-6]|7(?:[2-57-9]|62)|[89][2-9]"]
 ,"0$1",""]
-,[,"([7-9][01])(\\d{3})(\\d{3})","$1 $2 $3",["[7-9][01]"]
-,"0$1",""]
-,[,"([7-9][2-9])(\\d{2})(\\d{3})","$1 $2 $3",["[7-9][2-9]"]
+,[,"([7-9]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[89][01]|7(?:[01]|66)"]
 ,"0$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -2038,25 +2074,30 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"LK":[,[]
-,[]
-,[]
+,"LK":[,[,,"[1-9]\\d{8}","\\d{7,9}"]
+,[,,"(?:[189]1|2[13-7]|3[1-8]|4[157]|5[12457]|6[35-7])[2-57]\\d{6}","\\d{7,9}"]
+,[,,"7[12578]\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LK",94,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"LK",94,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{1})(\\d{6})","$1 $2 $3",["[1-689]"]
+,"0$1",""]
+,[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",["7"]
+,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
-,"LR":[,[,,"(?:[27]\\d|[4-6])\\d{6}","\\d{7,8}"]
+,"LR":[,[,,"(?:[279]\\d|[4-6])\\d{6}","\\d{7,8}"]
 ,[,,"2\\d{7}","\\d{8}"]
-,[,,"(?:4[67]|5\\d|7\\d{2}|6[4-8])\\d{5}","\\d{7,8}"]
-,[,,"NA","NA"]
+,[,,"(?:4[67]|5\\d|6[4-8]|7\\d{2})\\d{5}","\\d{7,8}"]
 ,[,,"NA","NA"]
+,[,,"90\\d{6}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"LR",231,"00","0",,,"0",,,,[[,"([27]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[27]"]
+,"LR",231,"00","0",,,"0",,,,[[,"([279]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[279]"]
 ,"0$1",""]
 ,[,"([4-6])(\\d{3})(\\d{3})","$1 $2 $3",["[4-6]"]
 ,"0$1",""]
@@ -2125,8 +2166,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"LY",218,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
 ,"MA":[,[,,"[5689]\\d{8}","\\d{9}"]
-,[,,"5(?:2(?:[015-7]\\d{2}|(?:[28][2-9]|3[2-7]|4[2-8])\\d|9(?:0\\d|[89]0))|3(?:[0-4]\\d{2}|(?:[57][2-9]|6[2-8]|9[3-9])\\d|8(?:0\\d|[89]0)))\\d{4}","\\d{9}"]
-,[,,"6(?:00|33|[15-7]\\d|4[0-8]|99)\\d{6}","\\d{9}"]
+,[,,"5(?:2(?:(?:[015-7]\\d|2[2-9]|3[2-57]|4[2-8]|8[235-9]|)\\d|9(?:0\\d|[89]0))|3(?:(?:[0-4]\\d|[57][2-9]|6[235-8]|9[3-9])\\d|8(?:0\\d|[89]0)))\\d{4}","\\d{9}"]
+,[,,"6(?:0[06]|[14-7]\\d|2[236]|33|99)\\d{6}","\\d{9}"]
 ,[,,"80\\d{7}","\\d{9}"]
 ,[,,"89\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
@@ -2213,8 +2254,8 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"MH",692,"011","1",,,"1",,,1,,,[,,"NA","NA"]
 ]
 ,"MK":[,[,,"[2-578]\\d{7}","\\d{8}"]
-,[,,"(?:2\\d|3[1-4]|4[2-8])\\d{6}","\\d{6,8}"]
-,[,,"7\\d{7}","\\d{8}"]
+,[,,"(?:2(?:[23]\\d|5[125]|61)|3(?:1[3-6]|2[2-6]|3[2-5]|4[235])|4(?:[23][2-6]|4[3-6]|5[25]|6[25-8]|7[24-6]|8[4-6]))\\d{5}","\\d{6,8}"]
+,[,,"7[0-25-8]\\d{6}","\\d{8}"]
 ,[,,"800\\d{5}","\\d{8}"]
 ,[,,"5[02-9]\\d{6}","\\d{8}"]
 ,[,,"8(?:0[1-9]|[1-9]\\d)\\d{5}","\\d{8}"]
@@ -2264,21 +2305,23 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"MN":[,[,,"[127-9]\\d{7}","\\d{8}"]
-,[,,"(?:[12](?:1\\d|2[1-37]|3[2-8]|4[2-68]|5[1-4689])|70)\\d{6}","\\d{8}"]
-,[,,"(?:88|9[1569])\\d{6}","\\d{8}"]
+,"MN":[,[,,"[12]\\d{7,9}|[57-9]\\d{7}","\\d{8,10}"]
+,[,,"[12](?:1\\d|2(?:[1-3]\\d?|7\\d)|3[2-8]\\d{1,2}|4[2-68]\\d{1,2}|5[1-4689]\\d{1,2})\\d{5}|(?:5[0568]|70)\\d{6}","\\d{8,10}"]
+,[,,"(?:8[89]|9[15689])\\d{6}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"MN",976,"001","0",,,"0",,,,[[,"([127-9]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1|[7-9]"]
+,[,,"7[569]\\d{6}","\\d{8}"]
+,"MN",976,"001","0",,,"0",,,,[[,"([12]\\d)(\\d{2})(\\d{4})","$1 $2 $3",["[12]1"]
 ,"0$1",""]
-,[,"([12]2\\d)(\\d{5})","$1 $2",["[12]2[1-3]"]
+,[,"([12]2\\d)(\\d{5,6})","$1 $2",["[12]2[1-3]"]
 ,"0$1",""]
-,[,"([12]\\d{3})(\\d{4})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"]
+,[,"([12]\\d{3})(\\d{5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)2"]
 ,"0$1",""]
-,[,"([12]\\d{4})(\\d{3})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"]
+,[,"(\\d{4})(\\d{4})","$1 $2",["[57-9]"]
+,"$1",""]
+,[,"([12]\\d{4})(\\d{4,5})","$1 $2",["[12](?:27|[3-5])","[12](?:27|[3-5]\\d)[4-9]"]
 ,"0$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -2315,15 +2358,18 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"MQ",596,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"MR":[,[,,"[2-7]\\d{6}","\\d{7}"]
-,[,,"5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\\d{4}","\\d{7}"]
-,[,,"(?:[23][0-4]|4[3-5]|6\\d|7[0-7])\\d{5}","\\d{7}"]
-,[,,"NA","NA"]
+,"MR":[,[,,"[2-4]\\d{6,7}|[5-7]\\d{6}|8\\d{7}","\\d{7,8}"]
+,[,,"5(?:1[035]|2[0-69]|3[0348]|4[468]|5[02-467]|6[39]|7[4-69])\\d{4}|[2-4]5\\d{6}","\\d{7,8}"]
+,[,,"(?:[23][0-4]|4[3-5]|6\\d|7[0-7])\\d{5}|(?:2[27]|3[367]|4[467])\\d{6}","\\d{7,8}"]
+,[,,"800\\d{5}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MR",222,"00",,,,,,,,[[,"([2-7]\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",,"",""]
+,"MR",222,"00",,,,,,,,[[,"([2-48]\\d)(\\d{2})(\\d{2})(\\d{2})","$1 $2 $3 $4",["[2-48]"]
+,"",""]
+,[,"([2-7]\\d{2})(\\d{2})(\\d{2})","$1 $2 $3",["[2-7]"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -2337,15 +2383,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"MS",1,"011","1",,,"1",,,,,,[,,"NA","NA"]
 ,,"664"]
-,"MT":[,[]
-,[]
-,[]
+,"MT":[,[,,"[2579]\\d{7}","\\d{8}"]
+,[,,"2(?:0(?:1[0-6]|[69]\\d)|[1-357]\\d{2})\\d{4}","\\d{8}"]
+,[,,"(?:7(?:210|[79]\\d{2}|)|9(?:2[13]\\d|696|8(?:1[1-3]|89|97)|9\\d{2}))\\d{4}","\\d{8}"]
 ,[,,"NA","NA"]
+,[,,"50(?:0(?:3[1679]|4\\d)|[169]\\d{2}|7[06]\\d)\\d{3}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
-,"MT",356,"00","21",,,"21",,,1,,,[,,"NA","NA"]
+,"MT",356,"00",,,,,,,,[[,"(\\d{4})(\\d{4})","$1 $2",,"",""]
+]
+,,[,,"7117\\d{4}","\\d{8}"]
 ]
 ,"MU":[,[,,"[2-9]\\d{6}","\\d{7}"]
 ,[,,"(?:2(?:[034789]\\d|1[0-8]|2[0-79])|4(?:[013-8]\\d|2[4-7])|[56]\\d{2}|8(?:14|3[129]))\\d{4}","\\d{7}"]
@@ -2359,15 +2407,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"MV":[,[]
-,[]
-,[]
+,"MV":[,[,,"[3679]\\d{6}","\\d{7}"]
+,[,,"(?:3(?:00|3[0-59]|)|6(?:[567][02468]|8[024689]))\\d{4}","\\d{7}"]
+,[,,"(?:7(?:[679]\\d|8[02-9])|9[6-9]\\d)\\d{4}","\\d{7}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"MV",960,"020","0",,,"0",,,1,,,[,,"NA","NA"]
+,"MV",960,"0(?:0|19)",,,,,,"00",,[[,"(\\d{3})(\\d{4})","$1-$2",,"",""]
+]
+,,[,,"781\\d{4}","\\d{7}"]
 ]
 ,"MW":[,[,,"(?:[13-5]|[27]\\d{2}|[89](?:\\d{2})?)\\d{6}","\\d{7,9}"]
 ,[,,"(?:1[2-9]|21\\d{2})\\d{5}","\\d{7,9}"]
@@ -2452,28 +2502,22 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"NA":[,[,,"[68]\\d{5,9}","\\d{4,10}"]
-,[,,"6(?:1(?:[136]|2\\d?)\\d|2(?:[25]\\d?|[134678])\\d|3(?:2\\d{0,3}|4\\d{1,2}|[135-8]\\d?)|4(?:[13-8]\\d|2\\d{1,2})|(?:5(?:[16-7]\\d|[3-58]\\d?|2\\d{1,2}))|6\\d{0,4}|7\\d{0,3})\\d{4}","\\d{4,10}"]
-,[,,"8(?:1(?:1[0-24]|[2-4]\\d|50|6[0-2])|5\\d{2})\\d{5}","\\d{9}"]
-,[,,"NA","NA"]
+,"NA":[,[,,"[68]\\d{7,8}","\\d{8,9}"]
+,[,,"6(?:1(?:17|2(?:[0189]\\d|[23-6]|7\\d?)|3(?:2\\d|3[378])|4[01]|69|7[014])|2(?:17|25|5(?:[0-36-8]|4\\d?)|69|70)|3(?:17|2(?:[0237]\\d?|[14-689])|34|6[29]|7[01]|81)|4(?:17|2(?:[012]|7?)|4(?:[06]|1\\d)|5(?:[01357]|[25]\\d?)|69|7[01])|5(?:17|2(?:[0459]|[23678]\\d?)|69|7[01])|6(?:17|2(?:5|6\\d?)|38|42|69|7[01])|7(?:17|2(?:[569]|[234]\\d?)|3(?:0\\d?|[13])|69|7[01]))\\d{4}","\\d{8,9}"]
+,[,,"(?:60|8[125])\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
+,[,,"8701\\d{5}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"88\\d{6}","\\d{8}"]
-,"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[15]"]
-,"0$1",""]
-,[,"(632532)(\\d{2,4})","$1 $2",["632","6325","63253","632532"]
-,"0$1",""]
-,[,"(6\\d)(\\d{2,3})(\\d{4})","$1 $2 $3",["6(?:1|[245][1-7]|3[125-7]|6[1256]|7[1236])"]
+,[,,"886\\d{5}","\\d{8}"]
+,"NA",264,"00","0",,,"0",,,,[[,"(8\\d)(\\d{3})(\\d{4})","$1 $2 $3",["8[125]"]
 ,"0$1",""]
-,[,"(6\\d)(\\d{4,5})","$1 $2",["6(?:3[12567]|5[3-5]|6[1256]|7[1236])"]
-,"0$1",""]
-,[,"(6\\d{2})(\\d{4,6})","$1 $2",["6[2356]8"]
-,"0$1",""]
-,[,"(6\\d{3})(\\d{4,5})","$1 $2",["6(?:34|6[34]|75)","6(?:342|6[34]|751)"]
+,[,"(6\\d)(\\d{2,3})(\\d{4})","$1 $2 $3",["6"]
 ,"0$1",""]
 ,[,"(88)(\\d{3})(\\d{3})","$1 $2 $3",["88"]
 ,"0$1",""]
+,[,"(870)(\\d{3})(\\d{3})","$1 $2 $3",["870"]
+,"0$1",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -2608,15 +2652,15 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"NR",674,"00","0",,,"0",,,1,,,[,,"NA","NA"]
 ]
-,"NU":[,[]
-,[]
-,[]
+,"NU":[,[,,"[1-5]\\d{3}","\\d{4}"]
+,[,,"[34]\\d{3}","\\d{4}"]
+,[,,"[125]\\d{3}","\\d{4}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"NU",683,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"NU",683,"00",,,,,,,,,,[,,"NA","NA"]
 ]
 ,"NZ":[,[,,"[2-9]\\d{7,9}","\\d{7,10}"]
 ,[,,"(?:3[2-79]|[479][2-689]|6[235-9])\\d{6}|24099\\d{3}","\\d{7,8}"]
@@ -2695,7 +2739,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"PG":[,[,,"[1-9]\\d{6,7}","\\d{7,8}"]
 ,[,,"(?:3\\d{2}|4[257]\\d|5[34]\\d|6(?:29|4[1-9])|85[02-46-9]|9[78]\\d)\\d{4}","\\d{7}"]
-,[,,"(?:68|7(?:[126]\\d|3[34689]))\\d{5}","\\d{7,8}"]
+,[,,"(?:68|7(?:[126]\\d|3[1-9]))\\d{5}","\\d{7,8}"]
 ,[,,"180\\d{4}","\\d{7}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
@@ -2795,15 +2839,22 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"PR",1,"011","1",,,"1",,,1,,,[,,"NA","NA"]
 ,,"787|939"]
-,"PS":[,[]
-,[]
-,[]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
-,[,,"NA","NA"]
+,"PS":[,[,,"(?:[24589]\\d{7,9}|1(?:[78]\\d{8}|[49]\\d{2,3}))","\\d{4,10}"]
+,[,,"(?:22[2379]|42[45]|82[01458]|92[369])\\d{5}","\\d{7,8}"]
+,[,,"5[69]\\d{7}","\\d{9}"]
+,[,,"1800\\d{6}","\\d{10}"]
+,[,,"1(?:4|9\\d)\\d{2}","\\d{4,5}"]
+,[,,"1700\\d{6}","\\d{10}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"PS",970,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"PS",970,"00","0",,,"0",,,,[[,"([2489])(2\\d{2})(\\d{4})","$1 $2 $3",["[2489]"]
+,"0$1",""]
+,[,"(5[69]\\d)(\\d{3})(\\d{3})","$1 $2 $3",["5"]
+,"0$1",""]
+,[,"(1[78]00)(\\d{3})(\\d{3})","$1 $2 $3",["1[78]"]
+,"$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"PT":[,[,,"[2-46-9]\\d{8}","\\d{9}"]
 ,[,,"2(?:[12]\\d|[35][1-689]|4[1-59]|6[1-35689]|7[1-9]|8[1-69]|9[1256])\\d{6}","\\d{9}"]
@@ -2959,27 +3010,32 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"SB",677,"00",,,,,,,1,,,[,,"NA","NA"]
 ]
-,"SC":[,[,,"[2-8]\\d{5}","\\d{6}"]
+,"SC":[,[,,"[2-8]\\d{5,6}","\\d{6,7}"]
 ,[,,"(?:2(?:1[78]|2[14-69]|3[2-4]|4[1-36-8]|6[167]|[89]\\d)|3(?:2[1-6]|4[4-6]|55|6[016]|7\\d|8[0-589]|9[0-5])|5(?:5\\d|6[0-2])|6(?:0[0-27-9]|1[0-478]|2[145]|3[02-4]|4[124]|6[015]|7\\d|8[1-3])|78[0138])\\d{3}","\\d{6}"]
 ,[,,"(?:5(?:[1247-9]\\d|6[3-9])|7(?:[14679]\\d|2[1-9]|8[24-79]))\\d{3}","\\d{6}"]
 ,[,,"8000\\d{2}","\\d{6}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"4[1-37]\\d{4}","\\d{6}"]
-,"SC",248,"0[0-2]",,,,,,"00",,[[,"(\\d{3})(\\d{3})","$1 $2",,"",""]
+,[,,"(?:4?4[1-3]|6?47)\\d{4}","\\d{6,7}"]
+,"SC",248,"0[0-2]",,,,,,"00",,[[,"(\\d{3})(\\d{3})","$1 $2",["[23578]|[46][0-35-9]"]
+,"",""]
+,[,"(\\d)(\\d{3})(\\d{3})","$1 $2 $3",["[46]4"]
+,"",""]
 ]
 ,,[,,"NA","NA"]
 ]
-,"SD":[,[]
-,[]
-,[]
+,"SD":[,[,,"[19]\\d{8}","\\d{9}"]
+,[,,"1(?:[25]\\d|8[3567])\\d{6}","\\d{9}"]
+,[,,"9[1259]\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,"SD",249,"00","0",,,"0",,,1,,,[,,"NA","NA"]
+,"SD",249,"00","0",,,"0",,,,[[,"(\\d{2})(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]
+]
+,,[,,"NA","NA"]
 ]
 ,"SE":[,[,,"\\d{7,10}","\\d{5,10}"]
 ,[,,"1(?:0[1-8]\\d{6}|[136]\\d{5,7}|(?:2[0-35]|4[0-4]|5[0-25-9]|7[13-6]|[89]\\d)\\d{5,6})|2(?:[136]\\d{5,7}|(?:2[0-7]|4[0136-8]|5[0-38]|7[018]|8[01]|9[0-57])\\d{5,6})|3(?:[356]\\d{5,7}|(?:0[0-4]|1\\d|2[0-25]|4[056]|7[0-2]|8[0-3]|9[023])\\d{5,6})|4(?:[0246]\\d{5,7}|(?:1[01-8]|3[0135]|5[14-79]|7[0-246-9]|8[0156]|9[0-689])\\d{5,6})|5(?:0[0-6]|1[1-5]|2[0-68]|3[0-4]|4\\d|5[0-5]|6[03-5]|7[013]|8[0-79]|9[01])\\d{5,6}|6(?:[03]\\d{5,7}|(?:1[1-3]|2[0-4]|4[02-57]|5[0-37]|6[0-3]|7[0-2]|8[0247]|9[0-356])\\d{5,6})|8\\d{6,8}|9(?:0\\d{5,7}|(?:1[0-68]|2\\d|3[02-59]|4[0-4]|5[0-4]|6[01]|7[0135-8]|8[01])\\d{5,6})","\\d{5,9}"]
@@ -3008,18 +3064,20 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"SG":[,[,,"[13689]\\d{7,10}","\\d{8,11}"]
-,[,,"[36]\\d{7}","\\d{8}"]
-,[,,"[89]\\d{7}","\\d{8}"]
+,"SG":[,[,,"[36]\\d{7}|[17-9]\\d{7,10}","\\d{8,11}"]
+,[,,"6[1-8]\\d{6}|7000\\d{7}","\\d{8,11}"]
+,[,,"(?:8[1-5]|9[0-8])\\d{6}","\\d{8}"]
 ,[,,"1?800\\d{7}","\\d{10,11}"]
 ,[,,"1900\\d{7}","\\d{11}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
-,[,,"NA","NA"]
+,[,,"3[0-2]\\d{6}","\\d{8}"]
 ,"SG",65,"0[0-3][0-9]",,,,,,,,[[,"([3689]\\d{3})(\\d{4})","$1 $2",["[369]|8[1-9]"]
 ,"",""]
 ,[,"(1[89]00)(\\d{3})(\\d{4})","$1 $2 $3",["1[89]"]
 ,"",""]
+,[,"(7000)(\\d{4})(\\d{3})","$1 $2 $3",["70"]
+,"",""]
 ,[,"(800)(\\d{3})(\\d{4})","$1 $2 $3",["80"]
 ,"",""]
 ]
@@ -3115,7 +3173,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"NA","NA"]
 ,"SO",252,"00",,,,,,,,[[,"([13-5])(\\d{6})","$1 $2",["[13-5]"]
 ,"",""]
-,[,"([19]\\d)(\\d{6})","$1 $2",["[19]"]
+,[,"([19]\\d)(\\d{6})","$1 $2",["15|9"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -3167,17 +3225,17 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,,[,,"NA","NA"]
 ]
-,"SZ":[,[,,"[2-7]\\d{6,7}","\\d{7,8}"]
+,"SZ":[,[,,"[02-7]\\d{6,7}","\\d{7,8}"]
 ,[,,"2?(?:2(?:0[07]|[13]7|2[57])|3(?:0[34]|[1278]3|3[23]|[46][34])|(?:40[4-69]|16|2[12]|3[57]|[4578]2|67)|5(?:0[5-7]|1[6-9]|[23][78]|48|5[01]))\\d{4}","\\d{7,8}"]
-,[,,"(?:6|7[67])\\d{6}","\\d{7,8}"]
-,[,,"NA","NA"]
+,[,,"(?:6|7[6-8])\\d{6}","\\d{7,8}"]
+,[,,"0800\\d{4}","\\d{8}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,"SZ",268,"00",,,,,,,,[[,"(\\d{3})(\\d{4})","$1 $2",["[2-6]"]
 ,"",""]
-,[,"(\\d{4})(\\d{4})","$1 $2",["7"]
+,[,"(\\d{4})(\\d{4})","$1 $2",["[027]"]
 ,"",""]
 ]
 ,,[,,"NA","NA"]
@@ -3511,7 +3569,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,,"340"]
 ,"VN":[,[,,"8\\d{5,8}|[1-79]\\d{7,9}","\\d{7,10}"]
 ,[,,"(?:2(?:[025-79]|1[0189]|[348][01])|3(?:[0136-9]|[25][01])|[48]\\d|5(?:[01][01]|[2-9])|6(?:[0-46-8]|5[01])|7(?:[02-79]|[18][01]))\\d{7}|69\\d{5,6}|80\\d{5}","\\d{7,10}"]
-,[,,"(?:9\\d|1(?:2[1-35-9]|6[3-9]|99))\\d{7}","\\d{9,10}"]
+,[,,"(?:9\\d|1(?:2\\d|6[3-9]|88|99))\\d{7}","\\d{9,10}"]
 ,[,,"1800\\d{4,6}","\\d{8,10}"]
 ,[,,"1900\\d{4,6}","\\d{8,10}"]
 ,[,,"NA","NA"]
@@ -3529,9 +3587,9 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,"0$1",""]
 ,[,"(9\\d)(\\d{3})(\\d{2})(\\d{2})","$1 $2 $3 $4",["9"]
 ,"0$1",""]
-,[,"(1[269]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|99)"]
+,[,"(1[2689]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["1(?:[26]|88|99)"]
 ,"0$1",""]
-,[,"(1[89]00)(\\d{4,6})","$1 $2",["1(?:8|90)"]
+,[,"(1[89]00)(\\d{4,6})","$1 $2",["1[89]0"]
 ,"$1",""]
 ]
 ,,[,,"NA","NA"]
@@ -3600,11 +3658,14 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ,[,,"(?:1[0-8]|2[1-478]|3[1-69]|4\\d|5[1346-8])\\d{7}","\\d{8,9}"]
 ,[,,"(?:7[1-4689]|8[1-5789])\\d{7}","\\d{9}"]
 ,[,,"80\\d{7}","\\d{9}"]
-,[,,"86\\d{7}","\\d{9}"]
-,[,,"NA","NA"]
+,[,,"86[1-9]\\d{6}","\\d{9}"]
+,[,,"860\\d{6}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"87\\d{7}","\\d{9}"]
-,"ZA",27,"00","0",,,"0",,,,[[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3",,"0$1",""]
+,"ZA",27,"00","0",,,"0",,,,[[,"(860)(\\d{3})(\\d{3})","$1 $2 $3",["860"]
+,"0$1",""]
+,[,"([1-578]\\d)(\\d{3})(\\d{4})","$1 $2 $3",["[1-57]|8(?:[0-57-9]|6[1-9])"]
+,"0$1",""]
 ]
 ,,[,,"NA","NA"]
 ]
@@ -3625,7 +3686,7 @@ i18n.phonenumbers.metadata.countryToMetadata = {
 ]
 ,"ZW":[,[,,"2(?:[012457-9]\\d{3,8}|6\\d{3,6})|[13-79]\\d{4,8}|86\\d{8}","\\d{3,10}"]
 ,[,,"(?:1[3-9]|2(?:0[45]|[16]|2[28]|[49]8?|58[23]|7[246]|8[1346-9])|3(?:08?|17?|3[78]|[2456]|7[1569]|8[379])|5(?:[07-9]|1[78]|483|5(?:7?|8))|6(?:0|28|37?|[45][68][78]|98?)|848)\\d{3,6}|(?:2(?:27|5|7[135789]|8[25])|3[39]|5[1-46]|6[126-8])\\d{4,6}|2(?:0|70)\\d{5,6}|(?:4\\d|9[2-8])\\d{4,7}","\\d{3,10}"]
-,[,,"(?:[19]1|7[13])\\d{6,7}","\\d{8,9}"]
+,[,,"7[137]\\d{7}","\\d{9}"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
 ,[,,"NA","NA"]
index 91cc767..a81c9a2 100644 (file)
@@ -37,6 +37,8 @@ goog.require('i18n.phonenumbers.PhoneNumber.CountryCodeSource');
 goog.require('i18n.phonenumbers.PhoneNumberDesc');
 goog.require('i18n.phonenumbers.metadata');
 
+
+
 /**
  * @constructor
  * @private
@@ -50,6 +52,7 @@ i18n.phonenumbers.PhoneNumberUtil = function() {
 };
 goog.addSingletonGetter(i18n.phonenumbers.PhoneNumberUtil);
 
+
 /**
  * Errors encountered when parsing phone numbers.
  *
@@ -72,7 +75,8 @@ i18n.phonenumbers.Error = {
   // This indicates the string had more digits than any valid phone number could
   // have.
   TOO_LONG: 'The string supplied is too long to be a phone number'
-}
+};
+
 
 /**
  * @const
@@ -81,6 +85,7 @@ i18n.phonenumbers.Error = {
  */
 i18n.phonenumbers.PhoneNumberUtil.NANPA_COUNTRY_CODE_ = 1;
 
+
 /**
  * The minimum length of the national significant number.
  *
@@ -90,6 +95,7 @@ i18n.phonenumbers.PhoneNumberUtil.NANPA_COUNTRY_CODE_ = 1;
  */
 i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ = 3;
 
+
 /**
  * The maximum length of the national significant number.
  *
@@ -99,6 +105,7 @@ i18n.phonenumbers.PhoneNumberUtil.MIN_LENGTH_FOR_NSN_ = 3;
  */
 i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_ = 15;
 
+
 /**
  * The PLUS_SIGN signifies the international prefix.
  *
@@ -107,6 +114,7 @@ i18n.phonenumbers.PhoneNumberUtil.MAX_LENGTH_FOR_NSN_ = 15;
  */
 i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN = '+';
 
+
 /**
  * These mappings map a character (key) to a specific digit that should replace
  * it for normalization purposes. Non-European digits that may be used in phone
@@ -147,6 +155,7 @@ i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS = {
   '\u0669': '9'  // Arabic-indic digit 9
 };
 
+
 /**
  * Only upper-case variants of alpha characters are stored.
  *
@@ -182,6 +191,7 @@ i18n.phonenumbers.PhoneNumberUtil.ALPHA_MAPPINGS_ = {
   'Z': '9'
 };
 
+
 /**
  * For performance reasons, amalgamate both into one map.
  *
@@ -247,6 +257,7 @@ i18n.phonenumbers.PhoneNumberUtil.ALL_NORMALIZATION_MAPPINGS_ = {
   'Z': '9'
 };
 
+
 /**
  * A list of all country codes where national significant numbers (excluding any
  * national prefix) exist that start with a leading zero.
@@ -261,9 +272,13 @@ i18n.phonenumbers.PhoneNumberUtil.LEADING_ZERO_COUNTRIES_ = {
   227: 1,  // Niger
   228: 1,  // Togo
   241: 1,  // Gabon
-  379: 1   // Vatican City
+  242: 1,  // Congo (Rep. of the)
+  268: 1,  // Swaziland
+  379: 1,  // Vatican City
+  501: 1   // Belize
 };
 
+
 /**
  * Pattern that makes it easy to distinguish whether a country has a unique
  * international dialing prefix or not. If a country has a unique international
@@ -280,6 +295,7 @@ i18n.phonenumbers.PhoneNumberUtil.LEADING_ZERO_COUNTRIES_ = {
 i18n.phonenumbers.PhoneNumberUtil.UNIQUE_INTERNATIONAL_PREFIX_ =
     /[\d]+(?:[~\u2053\u223C\uFF5E][\d]+)?/;
 
+
 /**
  * Regular expression of acceptable punctuation found in phone numbers. This
  * excludes punctuation found as a leading character only. This consists of dash
@@ -292,9 +308,10 @@ i18n.phonenumbers.PhoneNumberUtil.UNIQUE_INTERNATIONAL_PREFIX_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ =
-    '-x\u2010-\u2015\u2212\uFF0D-\uFF0F \u00A0\u200B\u2060\u3000()' +
+    '-x\u2010-\u2015\u2212\u30FC\uFF0D-\uFF0F \u00A0\u200B\u2060\u3000()' +
     '\uFF08\uFF09\uFF3B\uFF3D.\\[\\]/~\u2053\u223C\uFF5E';
 
+
 /**
  * Digits accepted in phone numbers (ascii, fullwidth, and arabic-indic digits).
  *
@@ -305,6 +322,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ =
 i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ =
     '0-9\uFF10-\uFF19\u0660-\u0669';
 
+
 /**
  * We accept alpha characters in phone numbers, ASCII only, upper and lower
  * case.
@@ -315,6 +333,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ =
  */
 i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ = 'A-Za-z';
 
+
 /**
  * @const
  * @type {string}
@@ -322,6 +341,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ = 'A-Za-z';
  */
 i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ = '+\uFF0B';
 
+
 /**
  * @const
  * @type {RegExp}
@@ -330,6 +350,7 @@ i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ = '+\uFF0B';
 i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_PATTERN_ =
     new RegExp('^[' + i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ + ']+');
 
+
 /**
  * @const
  * @type {RegExp}
@@ -338,6 +359,7 @@ i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_PATTERN_ =
 i18n.phonenumbers.PhoneNumberUtil.CAPTURING_DIGIT_PATTERN_ =
     new RegExp('([' + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + '])');
 
+
 /**
  * Regular expression of acceptable characters that may start a phone number for
  * the purposes of parsing. This allows us to strip away meaningless prefixes to
@@ -355,6 +377,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_START_CHAR_PATTERN =
     new RegExp('[' + i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_ +
                i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']');
 
+
 /**
  * Regular expression of characters typically used to start a second phone
  * number for the purposes of parsing. This allows us to strip off parts of the
@@ -369,6 +392,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_START_CHAR_PATTERN =
  */
 i18n.phonenumbers.PhoneNumberUtil.SECOND_NUMBER_START_PATTERN_ = /[\\\/] *x/;
 
+
 /**
  * Regular expression of trailing characters that we want to remove. We remove
  * all characters that are not alpha or numerical characters. The hash character
@@ -382,6 +406,7 @@ i18n.phonenumbers.PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN_ =
     new RegExp('[^' + i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ +
                i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_ + '#]+$');
 
+
 /**
  * We use this pattern to check if the phone number has at least three letters
  * in it - if so, then we treat it as a number where some phone-number digits
@@ -394,6 +419,7 @@ i18n.phonenumbers.PhoneNumberUtil.UNWANTED_END_CHAR_PATTERN_ =
 i18n.phonenumbers.PhoneNumberUtil.VALID_ALPHA_PHONE_PATTERN_ =
     /(?:.*?[A-Za-z]){3}.*/;
 
+
 /**
  * Regular expression of viable phone numbers. This is location independent.
  * Checks we have at least three leading digits, and only valid punctuation,
@@ -416,6 +442,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_ =
     i18n.phonenumbers.PhoneNumberUtil.VALID_PUNCTUATION_ +
     i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']*';
 
+
 /**
  * Default extension prefix to use when formatting. This will be put in front of
  * any extension component of the number, after the main national number is
@@ -429,6 +456,7 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_ =
  */
 i18n.phonenumbers.PhoneNumberUtil.DEFAULT_EXTN_PREFIX_ = ' ext. ';
 
+
 /**
  * Regexp of all possible ways to write extensions, for use when parsing. This
  * will be run as a case-insensitive regexp match. Wide character versions are
@@ -438,19 +466,23 @@ i18n.phonenumbers.PhoneNumberUtil.DEFAULT_EXTN_PREFIX_ = ' ext. ';
  * numbers themselves. The other one covers the special case of American numbers
  * where the extension is written with a hash at the end, such as "- 503#". Note
  * that the only capturing groups should be around the digits that you want to
- * capture as part of the extension, or else parsing will fail!
+ * capture as part of the extension, or else parsing will fail! We allow two
+ * options for representing the accented o - the character itself, and one in
+ * the unicode decomposed form with the combining acute accent.
  *
  * @const
  * @type {string}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ =
-    '[ \u00A0\\t,]*' + '(?:ext(?:ensio)?n?|\uFF45\uFF58\uFF54\uFF4E?|' +
+    '[ \u00A0\\t,]*' +
+    '(?:ext(?:ensi(?:o\u0301?|\u00F3))?n?|\uFF45\uFF58\uFF54\uFF4E?|' +
     '[,x\uFF58#\uFF03~\uFF5E]|int|anexo|\uFF49\uFF4E\uFF54)' +
     '[:\\.\uFF0E]?[ \u00A0\\t,-]*([' +
     i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']{1,7})#?|[- ]+([' +
     i18n.phonenumbers.PhoneNumberUtil.VALID_DIGITS_ + ']{1,5})#';
 
+
 /**
  * Regexp of all known extension prefixes used by different countries followed
  * by 1 or more valid digits, for use when parsing.
@@ -463,6 +495,7 @@ i18n.phonenumbers.PhoneNumberUtil.EXTN_PATTERN_ =
     new RegExp('(?:' + i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ +
                ')$', 'i');
 
+
 /**
  * We append optionally the extension pattern to the end here, as a valid phone
  * number may have an extension prefix appended, followed by 1 or more digits.
@@ -476,30 +509,39 @@ i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_PATTERN_ =
                '(?:' + i18n.phonenumbers.PhoneNumberUtil.KNOWN_EXTN_PATTERNS_ +
                ')?' + '$', 'i');
 
+
 /**
  * @const
  * @type {RegExp}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.NON_DIGITS_PATTERN_ = /\D+/;
+
+
 /**
  * @const
  * @type {RegExp}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.FIRST_GROUP_PATTERN_ = /(\$1)/;
+
+
 /**
  * @const
  * @type {RegExp}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.NP_PATTERN_ = /\$NP/;
+
+
 /**
  * @const
  * @type {RegExp}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.FG_PATTERN_ = /\$FG/;
+
+
 /**
  * @const
  * @type {RegExp}
@@ -507,6 +549,7 @@ i18n.phonenumbers.PhoneNumberUtil.FG_PATTERN_ = /\$FG/;
  */
 i18n.phonenumbers.PhoneNumberUtil.CC_PATTERN_ = /\$CC/;
 
+
 /**
  * INTERNATIONAL and NATIONAL formats are consistent with the definition in
  * ITU-T Recommendation E. 123. For example, the number of the Google Zurich
@@ -522,6 +565,7 @@ i18n.phonenumbers.PhoneNumberFormat = {
   NATIONAL: 2
 };
 
+
 /**
  * Type of phone numbers.
  *
@@ -552,6 +596,7 @@ i18n.phonenumbers.PhoneNumberType = {
   UNKNOWN: 9
 };
 
+
 /**
  * Types of phone number matches. See detailed description beside the
  * isNumberMatch() method.
@@ -565,6 +610,7 @@ i18n.phonenumbers.PhoneNumberUtil.MatchType = {
   EXACT_MATCH: 3
 };
 
+
 /**
  * Possible outcomes when testing if a PhoneNumber is possible.
  *
@@ -577,6 +623,7 @@ i18n.phonenumbers.PhoneNumberUtil.ValidationResult = {
   TOO_LONG: 3
 };
 
+
 /**
  * Attempts to extract a possible number from the string passed in. This
  * currently strips all leading characters that could not be used to start a
@@ -620,6 +667,7 @@ i18n.phonenumbers.PhoneNumberUtil.extractPossibleNumber = function(number) {
   return possibleNumber;
 };
 
+
 /**
  * Checks to see if the string of characters could possibly be a phone number at
  * all. At the moment, checks to see that the string begins with at least 3
@@ -640,6 +688,7 @@ i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber = function(number) {
       i18n.phonenumbers.PhoneNumberUtil.VALID_PHONE_NUMBER_PATTERN_, number);
 };
 
+
 /**
  * Normalizes a string of characters representing a phone number. This performs
  * the following conversions:
@@ -665,6 +714,7 @@ i18n.phonenumbers.PhoneNumberUtil.normalize = function(number) {
   }
 };
 
+
 /**
  * Normalizes a string of characters representing a phone number. This is a
  * wrapper for normalize(String number) but does in-place normalization of the
@@ -682,6 +732,7 @@ i18n.phonenumbers.PhoneNumberUtil.normalizeSB_ = function(number) {
   number.append(normalizedNumber);
 };
 
+
 /**
  * Normalizes a string of characters representing a phone number. This converts
  * wide-ascii and arabic-indic numerals to European numerals, and strips
@@ -695,6 +746,7 @@ i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly = function(number) {
       i18n.phonenumbers.PhoneNumberUtil.DIGIT_MAPPINGS, true);
 };
 
+
 /**
  * Converts all alpha characters in a number to their respective digits on a
  * keypad, but retains existing formatting. Also converts wide-ascii digits to
@@ -704,12 +756,13 @@ i18n.phonenumbers.PhoneNumberUtil.normalizeDigitsOnly = function(number) {
  * @return {string} the normalized string version of the phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.convertAlphaCharactersInNumber =
-  function(number) {
+    function(number) {
 
   return i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_(number,
       i18n.phonenumbers.PhoneNumberUtil.ALL_NORMALIZATION_MAPPINGS_, false);
 };
 
+
 /**
  * Gets the length of the geographical area code from the national_number field
  * of the PhoneNumber object passed in, so that clients could use it to split a
@@ -752,7 +805,7 @@ i18n.phonenumbers.PhoneNumberUtil.convertAlphaCharactersInNumber =
  * @return {number} the length of area code of the PhoneNumber object passed in.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode =
-  function(number) {
+    function(number) {
 
   if (number == null) {
     return 0;
@@ -764,10 +817,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode =
   }
   /** @type {i18n.phonenumbers.PhoneMetadata} */
   var metadata = this.getMetadataForRegion(regionCode);
-  // For NANPA countries, national prefix is the same as country code, but it
-  // is not stored in
-  // the metadata.
-  if (!metadata.hasNationalPrefix() && !this.isNANPACountry(regionCode)) {
+  if (!metadata.hasNationalPrefix()) {
     return 0;
   }
 
@@ -781,6 +831,47 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode =
     return 0;
   }
 
+  return this.getLengthOfNationalDestinationCode(number);
+};
+
+
+/**
+ * Gets the length of the national destination code (NDC) from the PhoneNumber
+ * object passed in, so that clients could use it to split a national
+ * significant number into NDC and subscriber number. The NDC of a phone number
+ * is normally the first group of digit(s) right after the country code when the
+ * number is formatted in the international format, if there is a subscriber
+ * number part that follows. An example of how this could be used:
+ *
+ * var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance();
+ * var number = phoneUtil.parse('18002530000', 'US');
+ * var nationalSignificantNumber =
+ *     i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber(number);
+ * var nationalDestinationCode;
+ * var subscriberNumber;
+ *
+ * var nationalDestinationCodeLength =
+ *     phoneUtil.getLengthOfNationalDestinationCode(number);
+ * if (nationalDestinationCodeLength > 0) {
+ *   nationalDestinationCode =
+ *       nationalSignificantNumber.substring(0, nationalDestinationCodeLength);
+ *   subscriberNumber =
+ *       nationalSignificantNumber.substring(nationalDestinationCodeLength);
+ * } else {
+ *   nationalDestinationCode = '';
+ *   subscriberNumber = nationalSignificantNumber;
+ * }
+ *
+ * Refer to the unittests to see the difference between this function and
+ * getLengthOfGeographicalAreaCode().
+ *
+ * @param {i18n.phonenumbers.PhoneNumber} number the PhoneNumber object for
+ *     which clients want to know the length of the NDC.
+ * @return {number} the length of NDC of the PhoneNumber object passed in.
+ */
+i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfNationalDestinationCode =
+    function(number) {
+
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var copiedProto;
   if (number.hasExtension()) {
@@ -812,9 +903,22 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode =
   if (numberGroups.length <= 2) {
     return 0;
   }
+
+  if (this.getRegionCodeForNumber(number) == 'AR' &&
+      this.getNumberType(number) == i18n.phonenumbers.PhoneNumberType.MOBILE) {
+    // Argentinian mobile numbers, when formatted in the international format,
+    // are in the form of +54 9 NDC XXXX.... As a result, we take the length of
+    // the third group (NDC) and add 1 for the digit 9, which also forms part of
+    // the national significant number.
+    //
+    // TODO: Investigate the possibility of better modeling the metadata to make
+    // it easier to obtain the NDC.
+    return numberGroups[2].length + 1;
+  }
   return numberGroups[1].length;
 };
 
+
 /**
  * Normalizes a string of characters representing a phone number by replacing
  * all characters found in the accompanying map with the values therein, and
@@ -830,7 +934,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getLengthOfGeographicalAreaCode =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_ =
-  function(number, normalizationReplacements, removeNonMatches) {
+    function(number, normalizationReplacements, removeNonMatches) {
 
   /** @type {!goog.string.StringBuffer} */
   var normalizedNumber = new goog.string.StringBuffer();
@@ -853,6 +957,7 @@ i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_ =
   return normalizedNumber.toString();
 };
 
+
 /**
  * Helper function to check region code is not unknown or null.
  *
@@ -862,12 +967,13 @@ i18n.phonenumbers.PhoneNumberUtil.normalizeHelper_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isValidRegionCode_ =
-  function(regionCode) {
+    function(regionCode) {
 
   return regionCode != null &&
       regionCode.toUpperCase() in i18n.phonenumbers.metadata.countryToMetadata;
 };
 
+
 /**
  * Formats a phone number in the specified format using default rules. Note that
  * this does not promise to produce a phone number that the user can dial from
@@ -886,7 +992,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isValidRegionCode_ =
  * @return {string} the formatted phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.format =
-  function(number, numberFormat) {
+    function(number, numberFormat) {
 
   /** @type {number} */
   var countryCode = number.getCountryCodeOrDefault();
@@ -923,6 +1029,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.format =
                                     formattedExtension);
 };
 
+
 /**
  * Formats a phone number in the specified format using client-defined
  * formatting rules. Note that if the phone number has a country code of zero or
@@ -939,7 +1046,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.format =
  * @return {string} the formatted phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatByPattern =
-  function(number, numberFormat, userDefinedFormats) {
+    function(number, numberFormat, userDefinedFormats) {
 
   /** @type {number} */
   var countryCode = number.getCountryCodeOrDefault();
@@ -1010,6 +1117,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatByPattern =
                                     formattedExtension);
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneNumber} number
  * @param {string} carrierCode
@@ -1046,6 +1154,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
       formattedNationalNumber, formattedExtension);
 };
 
+
 /**
  * Formats a phone number for out-of-country dialing purpose. If no
  * countryCallingFrom is supplied, we format the number in its INTERNATIONAL
@@ -1068,7 +1177,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
  * @return {string} the formatted phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatOutOfCountryCallingNumber =
-  function(number, countryCallingFrom) {
+    function(number, countryCallingFrom) {
 
   if (!this.isValidRegionCode_(countryCallingFrom)) {
     return this.format(number,
@@ -1092,13 +1201,14 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatOutOfCountryCallingNumber =
           this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL);
     }
   } else if (countryCode == this.getCountryCodeForRegion(countryCallingFrom)) {
-  // For countries that share a country calling code, the country code need not
-  // be dialled. This also applies when dialling within a country, so this if
-  // clause covers both these cases. Technically this is the case for dialling
-  // from la Reunion to other overseas departments of France (French Guiana,
-  // Martinique, Guadeloupe), but not vice versa - so we don't cover this edge
-  // case for now and for those cases return the version including country code.
-  // Details here: http://www.petitfute.com/voyage/225-info-pratiques-reunion
+    // For countries that share a country calling code, the country code need
+    // not be dialled. This also applies when dialling within a country, so this
+    // if clause covers both these cases. Technically this is the case for
+    // dialling from la Reunion to other overseas departments of France (French
+    // Guiana, Martinique, Guadeloupe), but not vice versa - so we don't cover
+    // this edge case for now and for those cases return the version including
+    // country code. Details here:
+    // http://www.petitfute.com/voyage/225-info-pratiques-reunion
     return this.format(number,
                        i18n.phonenumbers.PhoneNumberFormat.NATIONAL);
   }
@@ -1135,6 +1245,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatOutOfCountryCallingNumber =
           formattedNationalNumber, formattedExtension);
 };
 
+
 /**
  * Formats a phone number using the original phone number format that the number
  * is parsed from. The original format is embedded in the country_code_source
@@ -1148,28 +1259,29 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatOutOfCountryCallingNumber =
  * @return {string} the formatted phone number in its original number format.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatInOriginalFormat =
-  function(number, countryCallingFrom) {
+    function(number, countryCallingFrom) {
 
   if (!number.hasCountryCodeSource()) {
     return this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL);
   }
   switch (number.getCountryCodeSource()) {
-  case i18n.phonenumbers.PhoneNumber.CountryCodeSource
-      .FROM_NUMBER_WITH_PLUS_SIGN:
-    return this.format(number,
-        i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL);
-  case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD:
-    return this.formatOutOfCountryCallingNumber(number, countryCallingFrom);
-  case i18n.phonenumbers.PhoneNumber.CountryCodeSource
-      .FROM_NUMBER_WITHOUT_PLUS_SIGN:
-    return this.format(number,
-        i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL).substring(1);
-  case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY:
-  default:
-    return this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL);
+    case i18n.phonenumbers.PhoneNumber.CountryCodeSource
+        .FROM_NUMBER_WITH_PLUS_SIGN:
+      return this.format(number,
+          i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL);
+    case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_NUMBER_WITH_IDD:
+      return this.formatOutOfCountryCallingNumber(number, countryCallingFrom);
+    case i18n.phonenumbers.PhoneNumber.CountryCodeSource
+        .FROM_NUMBER_WITHOUT_PLUS_SIGN:
+      return this.format(number,
+          i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL).substring(1);
+    case i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY:
+    default:
+      return this.format(number, i18n.phonenumbers.PhoneNumberFormat.NATIONAL);
   }
 };
 
+
 /**
  * Gets the national significant number of the a phone number. Note a national
  * significant number doesn't contain a national prefix or any formatting.
@@ -1180,7 +1292,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatInOriginalFormat =
  *     passed in.
  */
 i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber =
-  function(number) {
+    function(number) {
 
   // The leading zero in the national (significant) number of an Italian phone
   // number has a special meaning. Unlike the rest of the world, it indicates
@@ -1199,6 +1311,7 @@ i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber =
   return nationalNumber;
 };
 
+
 /**
  * A helper function that is used by format and formatByPattern.
  *
@@ -1211,22 +1324,23 @@ i18n.phonenumbers.PhoneNumberUtil.getNationalSignificantNumber =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatNumberByFormat_ =
-  function(countryCode, numberFormat,
-           formattedNationalNumber, formattedExtension) {
+    function(countryCode, numberFormat,
+             formattedNationalNumber, formattedExtension) {
 
   switch (numberFormat) {
-  case i18n.phonenumbers.PhoneNumberFormat.E164:
-    return i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + countryCode +
-        formattedNationalNumber + formattedExtension;
-  case i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL:
-    return i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + countryCode + ' ' +
-        formattedNationalNumber + formattedExtension;
-  case i18n.phonenumbers.PhoneNumberFormat.NATIONAL:
-  default:
-    return formattedNationalNumber + formattedExtension;
+    case i18n.phonenumbers.PhoneNumberFormat.E164:
+      return i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + countryCode +
+          formattedNationalNumber + formattedExtension;
+    case i18n.phonenumbers.PhoneNumberFormat.INTERNATIONAL:
+      return i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN + countryCode + ' ' +
+          formattedNationalNumber + formattedExtension;
+    case i18n.phonenumbers.PhoneNumberFormat.NATIONAL:
+    default:
+      return formattedNationalNumber + formattedExtension;
   }
 };
 
+
 /**
  * Note in some countries, the national number can be written in two completely
  * different ways depending on whether it forms part of the NATIONAL format or
@@ -1243,7 +1357,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatNumberByFormat_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatNationalNumber_ =
-  function(number, regionCode, numberFormat, opt_carrierCode) {
+    function(number, regionCode, numberFormat, opt_carrierCode) {
 
   /** @type {i18n.phonenumbers.PhoneMetadata} */
   var metadata = this.getMetadataForRegion(regionCode);
@@ -1260,6 +1374,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatNationalNumber_ =
                                         opt_carrierCode);
 };
 
+
 /**
  * Note that carrierCode is optional - if NULL or an empty string, no carrier
  * code replacement will take place. Carrier code replacement occurs before
@@ -1276,7 +1391,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatNationalNumber_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatAccordingToFormats_ =
-  function(nationalNumber, availableFormats, numberFormat, opt_carrierCode) {
+    function(nationalNumber, availableFormats, numberFormat, opt_carrierCode) {
 
   /** @type {i18n.phonenumbers.NumberFormat} */
   var numFormat;
@@ -1335,6 +1450,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatAccordingToFormats_ =
   return nationalNumber;
 };
 
+
 /**
  * Gets a valid number for the specified country.
  *
@@ -1345,12 +1461,13 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatAccordingToFormats_ =
  *     information.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumber =
-  function(regionCode) {
+    function(regionCode) {
 
   return this.getExampleNumberForType(regionCode,
       i18n.phonenumbers.PhoneNumberType.FIXED_LINE);
 };
 
+
 /**
  * Gets a valid number, if any, for the specified country and number type.
  *
@@ -1363,7 +1480,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumber =
  *     information.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumberForType =
-  function(regionCode, type) {
+    function(regionCode, type) {
 
   /** @type {i18n.phonenumbers.PhoneNumberDesc} */
   var desc = this.getNumberDescByType_(
@@ -1377,6 +1494,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumberForType =
   return null;
 };
 
+
 /**
  * Gets the formatted extension of a phone number, if the phone number had an
  * extension specified. If not, it returns an empty string.
@@ -1388,7 +1506,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getExampleNumberForType =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.maybeGetFormattedExtension_ =
-  function(number, regionCode) {
+    function(number, regionCode) {
 
   if (!number.hasExtension()) {
     return '';
@@ -1397,6 +1515,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeGetFormattedExtension_ =
   }
 };
 
+
 /**
  * Formats the extension part of the phone number by prefixing it with the
  * appropriate extension prefix. This will be the default extension prefix,
@@ -1408,7 +1527,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeGetFormattedExtension_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.formatExtension_ =
-  function(extensionDigits, regionCode) {
+    function(extensionDigits, regionCode) {
 
   /** @type {i18n.phonenumbers.PhoneMetadata} */
   var metadata = this.getMetadataForRegion(regionCode);
@@ -1420,6 +1539,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatExtension_ =
   }
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneMetadata} metadata
  * @param {i18n.phonenumbers.PhoneNumberType} type
@@ -1427,31 +1547,32 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.formatExtension_ =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberDescByType_ =
-  function(metadata, type) {
+    function(metadata, type) {
 
   switch (type) {
-  case i18n.phonenumbers.PhoneNumberType.PREMIUM_RATE:
-    return metadata.getPremiumRate();
-  case i18n.phonenumbers.PhoneNumberType.TOLL_FREE:
-    return metadata.getTollFree();
-  case i18n.phonenumbers.PhoneNumberType.MOBILE:
-    return metadata.getMobile();
-  case i18n.phonenumbers.PhoneNumberType.FIXED_LINE:
-  case i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE:
-    return metadata.getFixedLine();
-  case i18n.phonenumbers.PhoneNumberType.SHARED_COST:
-    return metadata.getSharedCost();
-  case i18n.phonenumbers.PhoneNumberType.VOIP:
-    return metadata.getVoip();
-  case i18n.phonenumbers.PhoneNumberType.PERSONAL_NUMBER:
-    return metadata.getPersonalNumber();
-  case i18n.phonenumbers.PhoneNumberType.PAGER:
-    return metadata.getPager();
-  default:
-    return metadata.getGeneralDesc();
+    case i18n.phonenumbers.PhoneNumberType.PREMIUM_RATE:
+      return metadata.getPremiumRate();
+    case i18n.phonenumbers.PhoneNumberType.TOLL_FREE:
+      return metadata.getTollFree();
+    case i18n.phonenumbers.PhoneNumberType.MOBILE:
+      return metadata.getMobile();
+    case i18n.phonenumbers.PhoneNumberType.FIXED_LINE:
+    case i18n.phonenumbers.PhoneNumberType.FIXED_LINE_OR_MOBILE:
+      return metadata.getFixedLine();
+    case i18n.phonenumbers.PhoneNumberType.SHARED_COST:
+      return metadata.getSharedCost();
+    case i18n.phonenumbers.PhoneNumberType.VOIP:
+      return metadata.getVoip();
+    case i18n.phonenumbers.PhoneNumberType.PERSONAL_NUMBER:
+      return metadata.getPersonalNumber();
+    case i18n.phonenumbers.PhoneNumberType.PAGER:
+      return metadata.getPager();
+    default:
+      return metadata.getGeneralDesc();
   }
 };
 
+
 /**
  * Gets the type of a phone number.
  *
@@ -1460,7 +1581,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberDescByType_ =
  * @return {i18n.phonenumbers.PhoneNumberType} the type of the phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberType =
-  function(number) {
+    function(number) {
 
   /** @type {string} */
   var regionCode = /** @type {string} */ (this.getRegionCodeForNumber(number));
@@ -1474,6 +1595,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberType =
       this.getMetadataForRegion(regionCode));
 };
 
+
 /**
  * @param {string} nationalNumber
  * @param {i18n.phonenumbers.PhoneMetadata} metadata
@@ -1481,7 +1603,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberType =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberTypeHelper_ =
-  function(nationalNumber, metadata) {
+    function(nationalNumber, metadata) {
 
   /** @type {i18n.phonenumbers.PhoneNumberDesc} */
   var generalNumberDesc = metadata.getGeneralDesc();
@@ -1532,12 +1654,13 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNumberTypeHelper_ =
   return i18n.phonenumbers.PhoneNumberType.UNKNOWN;
 };
 
+
 /**
  * @param {?string} regionCode
  * @return {i18n.phonenumbers.PhoneMetadata}
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getMetadataForRegion =
-  function(regionCode) {
+    function(regionCode) {
 
   if (regionCode == null) {
     return null;
@@ -1562,6 +1685,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getMetadataForRegion =
   return metadata;
 };
 
+
 /**
  * @param {string} nationalNumber
  * @param {i18n.phonenumbers.PhoneNumberDesc} numberDesc
@@ -1569,14 +1693,15 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getMetadataForRegion =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatchingDesc_ =
-  function(nationalNumber, numberDesc) {
+    function(nationalNumber, numberDesc) {
 
   return i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_(
-             numberDesc.getPossibleNumberPattern(), nationalNumber) &&
-         i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_(
-             numberDesc.getNationalNumberPattern(), nationalNumber);
+      numberDesc.getPossibleNumberPattern(), nationalNumber) &&
+      i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_(
+          numberDesc.getNationalNumberPattern(), nationalNumber);
 };
 
+
 /**
  * Tests whether a phone number matches a valid pattern. Note this doesn't
  * verify the number is actually in use, which is impossible to tell by just
@@ -1594,6 +1719,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumber = function(number) {
       this.isValidNumberForRegion(number, regionCode);
 };
 
+
 /**
  * Tests whether a phone number is valid for a certain region. Note this doesn't
  * verify the number is actually in use, which is impossible to tell by just
@@ -1611,7 +1737,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumber = function(number) {
  *     pattern.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumberForRegion =
-  function(number, regionCode) {
+    function(number, regionCode) {
 
   if (number.getCountryCodeOrDefault() !=
       this.getCountryCodeForRegion(regionCode)) {
@@ -1640,6 +1766,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumberForRegion =
       i18n.phonenumbers.PhoneNumberType.UNKNOWN;
 };
 
+
 /**
  * Returns the country/region where a phone number is from. This could be used
  * for geo-coding in the country/region level.
@@ -1650,7 +1777,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isValidNumberForRegion =
  *     if no country matches this calling code.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForNumber =
-  function(number) {
+    function(number) {
 
   if (number == null) {
     return null;
@@ -1670,6 +1797,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForNumber =
   }
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneNumber} number
  * @param {Array.<string>} regionCodes
@@ -1695,13 +1823,14 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
         return regionCode;
       }
     } else if (this.getNumberTypeHelper_(nationalNumber, metadata) !=
-          i18n.phonenumbers.PhoneNumberType.UNKNOWN) {
+        i18n.phonenumbers.PhoneNumberType.UNKNOWN) {
       return regionCode;
     }
   }
   return null;
 };
 
+
 /**
  * Returns the region code that matches the specific country code. In the case
  * of no region code being found, ZZ will be returned. In the case of multiple
@@ -1712,7 +1841,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
  * @return {string}
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForCountryCode =
-  function(countryCode) {
+    function(countryCode) {
 
   /** @type {Array.<string>} */
   var regionCodes =
@@ -1720,6 +1849,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForCountryCode =
   return regionCodes == null ? 'ZZ' : regionCodes[0];
 };
 
+
 /**
  * Returns the country calling code for a specific region. For example, this
  * would be 1 for the United States, and 64 for New Zealand.
@@ -1730,7 +1860,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getRegionCodeForCountryCode =
  *     regionCode.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.getCountryCodeForRegion =
-  function(regionCode) {
+    function(regionCode) {
 
   if (!this.isValidRegionCode_(regionCode)) {
     return 0;
@@ -1743,6 +1873,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getCountryCodeForRegion =
   return metadata.getCountryCodeOrDefault();
 };
 
+
 /**
  * Returns the national dialling prefix for a specific region. For example, this
  * would be 1 for the United States, and 0 for New Zealand. Set stripNonDigits
@@ -1786,6 +1917,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNddPrefixForRegion = function(
   return nationalPrefix;
 };
 
+
 /**
  * Check if a country is one of the countries under the North American Numbering
  * Plan Administration (NANPA).
@@ -1794,7 +1926,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.getNddPrefixForRegion = function(
  * @return {boolean} true if regionCode is one of the countries under NANPA.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isNANPACountry =
-  function(regionCode) {
+    function(regionCode) {
 
   return goog.array.contains(
       i18n.phonenumbers.metadata.countryCodeToRegionCodeMap[
@@ -1802,6 +1934,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isNANPACountry =
       regionCode.toUpperCase());
 };
 
+
 /**
  * Check whether countryCode represents the country calling code from a country
  * whose national significant number could contain a leading zero. An example of
@@ -1815,6 +1948,7 @@ i18n.phonenumbers.PhoneNumberUtil.isLeadingZeroCountry = function(countryCode) {
       i18n.phonenumbers.PhoneNumberUtil.LEADING_ZERO_COUNTRIES_;
 };
 
+
 /**
  * Convenience wrapper around isPossibleNumberWithReason. Instead of returning
  * the reason for failure, this method returns a boolean value.
@@ -1824,12 +1958,13 @@ i18n.phonenumbers.PhoneNumberUtil.isLeadingZeroCountry = function(countryCode) {
  * @return {boolean} true if the number is possible.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumber =
-  function(number) {
+    function(number) {
 
   return this.isPossibleNumberWithReason(number) ==
       i18n.phonenumbers.PhoneNumberUtil.ValidationResult.IS_POSSIBLE;
 };
 
+
 /**
  * Check whether a phone number is a possible number. It provides a more lenient
  * check than isValidNumber in the following sense:
@@ -1857,7 +1992,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumber =
  *     ValidationResult object which indicates whether the number is possible.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberWithReason =
-  function(number) {
+    function(number) {
 
   /** @type {number} */
   var countryCode = number.getCountryCodeOrDefault();
@@ -1906,6 +2041,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberWithReason =
   }
 };
 
+
 /**
  * Check whether a phone number is a possible number given a number in the form
  * of a string, and the country where the number could be dialed from. It
@@ -1930,7 +2066,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberWithReason =
  * @return {boolean} true if the number is possible.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberString =
-  function(number, countryDialingFrom) {
+    function(number, countryDialingFrom) {
 
   try {
     return this.isPossibleNumber(this.parse(number, countryDialingFrom));
@@ -1939,6 +2075,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isPossibleNumberString =
   }
 };
 
+
 /**
  * Attempts to extract a valid number from a phone number that is too long to be
  * valid, and resets the PhoneNumber object passed in to that valid version. If
@@ -1972,6 +2109,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.truncateTooLongNumber =
   return true;
 };
 
+
 /**
  * Extracts country code from fullNumber, returns it and places the remaining
  * number in nationalNumber. It assumes that the leading plus sign or IDD has
@@ -1983,7 +2121,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.truncateTooLongNumber =
  * @return {number}
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.extractCountryCode =
-  function(fullNumber, nationalNumber) {
+    function(fullNumber, nationalNumber) {
 
   /** @type {string} */
   var fullNumberStr = fullNumber.toString();
@@ -2002,6 +2140,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.extractCountryCode =
   return 0;
 };
 
+
 /**
  * Tries to extract a country code from a number. This method will return zero
  * if no country code is considered to be present. Country codes are extracted
@@ -2039,8 +2178,8 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.extractCountryCode =
  * @throws {i18n.phonenumbers.Error}
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.maybeExtractCountryCode =
-  function(number, defaultRegionMetadata, nationalNumber,
-           storeCountryCodeSource, phoneNumber) {
+    function(number, defaultRegionMetadata, nationalNumber,
+             storeCountryCodeSource, phoneNumber) {
 
   if (number.length == 0) {
     return 0;
@@ -2137,6 +2276,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeExtractCountryCode =
   return 0;
 };
 
+
 /**
  * Strips the IDD from the start of the number if present. Helper function used
  * by maybeStripInternationalPrefixAndNormalize.
@@ -2149,7 +2289,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeExtractCountryCode =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.parsePrefixAsIdd_ =
-  function(iddPattern, number) {
+    function(iddPattern, number) {
 
   /** @type {string} */
   var numberStr = number.toString();
@@ -2176,6 +2316,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parsePrefixAsIdd_ =
   return false;
 };
 
+
 /**
  * Strips any international prefix (such as +, 00, 011) present in the number
  * provided, normalizes the resulting number, and indicates if an international
@@ -2225,6 +2366,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
       i18n.phonenumbers.PhoneNumber.CountryCodeSource.FROM_DEFAULT_COUNTRY;
 };
 
+
 /**
  * Strips any national prefix (such as 0, 1) present in the number provided.
  *
@@ -2240,7 +2382,8 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.
  *     prefix was stripped or transformed.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripNationalPrefix =
-  function(number, possibleNationalPrefix, transformRule, nationalNumberRule) {
+    function(number, possibleNationalPrefix, transformRule,
+             nationalNumberRule) {
 
   /** @type {string} */
   var numberStr = number.toString();
@@ -2278,6 +2421,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripNationalPrefix =
   }
 };
 
+
 /**
  * Strips any extension (as in, the part of the number dialled after the call is
  * connected, usually indicated with extn, ext, x or similar) from the end of
@@ -2288,7 +2432,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripNationalPrefix =
  * @return {string} the phone extension.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripExtension =
-  function(number) {
+    function(number) {
 
   /** @type {string} */
   var numberStr = number.toString();
@@ -2298,7 +2442,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripExtension =
   // If we find a potential extension, and the number preceding this is a viable
   // number, we assume it is an extension.
   if (mStart >= 0 && i18n.phonenumbers.PhoneNumberUtil.isViablePhoneNumber(
-        numberStr.substring(0, mStart))) {
+      numberStr.substring(0, mStart))) {
     // The numbers are captured into groups in the regular expression.
     /** @type {Array.<string>} */
     var matchedGroups =
@@ -2316,6 +2460,27 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripExtension =
   return '';
 };
 
+
+/**
+ * Checks to see that the region code used is valid, or if it is not valid, that
+ * the number to parse starts with a + symbol so that we can attempt to infer
+ * the country from the number.
+ * @param {string} numberToParse number that we are attempting to parse.
+ * @param {?string} defaultCountry the ISO 3166-1 two-letter country code that
+ *     denotes the country that we are expecting the number to be from.
+ * @return {boolean} false if it cannot use the region provided and the region
+ *     cannot be inferred.
+ * @private
+ */
+i18n.phonenumbers.PhoneNumberUtil.prototype.checkRegionForParsing_ = function(
+    numberToParse, defaultCountry) {
+  return this.isValidRegionCode_(defaultCountry) ||
+      (numberToParse != null && numberToParse.length > 0 &&
+          i18n.phonenumbers.PhoneNumberUtil.PLUS_CHARS_PATTERN_.test(
+              numberToParse));
+};
+
+
 /**
  * Parses a string and returns it in proto buffer format. This method will throw
  * a i18n.phonenumbers.Error if the number is not considered to be a possible
@@ -2341,15 +2506,10 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.maybeStripExtension =
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.parse = function(numberToParse,
                                                              defaultCountry) {
-  if (!this.isValidRegionCode_(defaultCountry)) {
-    if (numberToParse.length > 0 && numberToParse.charAt(0) !=
-        i18n.phonenumbers.PhoneNumberUtil.PLUS_SIGN) {
-      throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE;
-    }
-  }
-  return this.parseHelper_(numberToParse, defaultCountry, false);
+  return this.parseHelper_(numberToParse, defaultCountry, false, true);
 };
 
+
 /**
  * Parses a string and returns it in proto buffer format. This method differs
  * from parse() in that it always populates the raw_input field of the protocol
@@ -2370,7 +2530,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parse = function(numberToParse,
  *     is not in international format (does not start with +).
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.parseAndKeepRawInput =
-  function(numberToParse, defaultCountry) {
+    function(numberToParse, defaultCountry) {
 
   if (!this.isValidRegionCode_(defaultCountry)) {
     if (numberToParse.length > 0 && numberToParse.charAt(0) !=
@@ -2378,9 +2538,10 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parseAndKeepRawInput =
       throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE;
     }
   }
-  return this.parseHelper_(numberToParse, defaultCountry, true);
+  return this.parseHelper_(numberToParse, defaultCountry, true, true);
 };
 
+
 /**
  * Parses a string and returns it in proto buffer format. This method is the
  * same as the public parse() method, with the exception that it allows the
@@ -2396,14 +2557,19 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parseAndKeepRawInput =
  *     that of the default country supplied.
  * @param {boolean} keepRawInput whether to populate the raw_input field of the
  *     phoneNumber with numberToParse.
+ * @param {boolean} checkRegion should be set to false if it is permitted for
+ *     the default country to be null or unknown ('ZZ').
  * @return {i18n.phonenumbers.PhoneNumber} a phone number proto buffer filled
  *     with the parsed number.
  * @throws {i18n.phonenumbers.Error}
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.parseHelper_ =
-  function(numberToParse, defaultCountry, keepRawInput) {
+    function(numberToParse, defaultCountry, keepRawInput, checkRegion) {
 
+  if (numberToParse == null) {
+    throw i18n.phonenumbers.Error.NOT_A_NUMBER;
+  }
   // Extract a possible number from the string passed in (this strips leading
   // characters that could not be the start of a phone number.)
   /** @type {string} */
@@ -2413,6 +2579,12 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parseHelper_ =
     throw i18n.phonenumbers.Error.NOT_A_NUMBER;
   }
 
+  // Check the country supplied is valid, or that the extracted number starts
+  // with some sort of + sign so the number's region can be determined.
+  if (checkRegion && !this.checkRegionForParsing_(number, defaultCountry)) {
+    throw i18n.phonenumbers.Error.INVALID_COUNTRY_CODE;
+  }
+
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var phoneNumber = new i18n.phonenumbers.PhoneNumber();
   if (keepRawInput) {
@@ -2489,6 +2661,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parseHelper_ =
   return phoneNumber;
 };
 
+
 /**
  * Takes two phone numbers and compares them for equality.
  *
@@ -2515,7 +2688,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.parseHelper_ =
  *     a viable phone number.
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatch =
-  function(firstNumberIn, secondNumberIn) {
+    function(firstNumberIn, secondNumberIn) {
 
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var firstNumber;
@@ -2525,13 +2698,13 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatch =
   // Else make copies of the phone numbers so that the numbers passed in are not
   // edited.
   if (typeof firstNumberIn == 'string') {
-    firstNumber = this.parseHelper_(firstNumberIn, null, false);
+    firstNumber = this.parseHelper_(firstNumberIn, null, false, false);
   } else {
     firstNumber = new i18n.phonenumbers.PhoneNumber();
     firstNumber.mergeFrom(firstNumberIn);
   }
   if (typeof secondNumberIn == 'string') {
-    secondNumber = this.parseHelper_(secondNumberIn, null, false);
+    secondNumber = this.parseHelper_(secondNumberIn, null, false, false);
   } else {
     secondNumber = new i18n.phonenumbers.PhoneNumber();
     secondNumber.mergeFrom(secondNumberIn);
@@ -2588,6 +2761,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatch =
   return i18n.phonenumbers.PhoneNumberUtil.MatchType.NO_MATCH;
 };
 
+
 /**
  * Returns true when one national number is the suffix of the other or both are
  * the same.
@@ -2600,7 +2774,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isNumberMatch =
  * @private
  */
 i18n.phonenumbers.PhoneNumberUtil.prototype.isNationalNumberSuffixOfTheOther_ =
-  function(firstNumber, secondNumber) {
+    function(firstNumber, secondNumber) {
 
   /** @type {string} */
   var firstNumberNationalNumber = '' + firstNumber.getNationalNumber();
@@ -2613,6 +2787,7 @@ i18n.phonenumbers.PhoneNumberUtil.prototype.isNationalNumberSuffixOfTheOther_ =
                               firstNumberNationalNumber);
 };
 
+
 /**
  * Check whether the entire input sequence can be matched against the regular
  * expression.
@@ -2631,6 +2806,7 @@ i18n.phonenumbers.PhoneNumberUtil.matchesEntirely_ = function(regex, str) {
   return false;
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneNumber} other
  * @return {boolean}
@@ -2645,6 +2821,7 @@ i18n.phonenumbers.PhoneNumber.prototype.exactlySameAs = function(other) {
       this.getCountryCodeSource() == other.getCountryCodeSource();
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneNumberDesc} other
  * @return {boolean}
@@ -2656,6 +2833,7 @@ i18n.phonenumbers.PhoneNumberDesc.prototype.exactlySameAs = function(other) {
       this.getExampleNumber() == other.getExampleNumber();
 };
 
+
 /**
  * @param {i18n.phonenumbers.PhoneNumber} other
  * @return {i18n.phonenumbers.PhoneNumber}
@@ -2668,6 +2846,7 @@ i18n.phonenumbers.PhoneNumber.prototype.mergeFrom = function(other) {
   return this;
 };
 
+
 /**
  * @param {i18n.phonenumbers.NumberFormat} other
  * @return {i18n.phonenumbers.NumberFormat}
index 021b4db..016469e 100644 (file)
@@ -24,6 +24,7 @@
 goog.require('goog.testing.jsunit');
 goog.require('i18n.phonenumbers.PhoneNumberUtil');
 
+
 /** @type {i18n.phonenumbers.PhoneNumberUtil} */
 var phoneUtil = i18n.phonenumbers.PhoneNumberUtil.getInstance();
 
@@ -135,6 +136,61 @@ function testGetLengthOfGeographicalAreaCode() {
   assertEquals(0, phoneUtil.getLengthOfGeographicalAreaCode(number));
 }
 
+function testGetLengthOfNationalDestinationCode() {
+  /** @type {i18n.phonenumbers.PhoneNumber} */
+  var number = new i18n.phonenumbers.PhoneNumber();
+
+  // Google MTV, which has national destination code (NDC) "650".
+  number.setCountryCode(1);
+  number.setNationalNumber(6502530000);
+  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // A North America toll-free number, which has NDC "800".
+  number.setCountryCode(1);
+  number.setNationalNumber(8002530000);
+  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // Google London, which has NDC "20".
+  number.setCountryCode(44);
+  number.setNationalNumber(2070313000);
+  assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // A UK mobile phone, which has NDC "7123".
+  number.setCountryCode(44);
+  number.setNationalNumber(7123456789);
+  assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // Google Buenos Aires, which has NDC "11".
+  number.setCountryCode(54);
+  number.setNationalNumber(1155303000);
+  assertEquals(2, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // An Argentinian mobile which has NDC "911".
+  number.setCountryCode(54);
+  number.setNationalNumber(91155303001);
+  assertEquals(3, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // Google Sydney, which has NDC "2".
+  number.setCountryCode(61);
+  number.setNationalNumber(293744000);
+  assertEquals(1, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // Google Singapore, which has NDC "6521".
+  number.setCountryCode(65);
+  number.setNationalNumber(65218000);
+  assertEquals(4, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // An invalid US number (1 digit shorter), which has no NDC.
+  number.setCountryCode(1);
+  number.setNationalNumber(650253000);
+  assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
+
+  // A number containing an invalid country code, which shouldn't have any NDC.
+  number.setCountryCode(123);
+  number.setNationalNumber(6502530000);
+  assertEquals(0, phoneUtil.getLengthOfNationalDestinationCode(number));
+}
+
 function testGetNationalSignificantNumber() {
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var number = new i18n.phonenumbers.PhoneNumber();
@@ -1326,10 +1382,10 @@ function testMaybeStripInternationalPrefix() {
   numberToStrip = new goog.string.StringBuffer('0090112-3123');
   strippedNumber = new goog.string.StringBuffer('00901123123');
   assertEquals(CCS.FROM_DEFAULT_COUNTRY,
-      phoneUtil.maybeStripInternationalPrefixAndNormalize(numberToStrip,
-                                                          internationalPrefix));
+      phoneUtil.maybeStripInternationalPrefixAndNormalize(
+          numberToStrip, internationalPrefix));
   assertEquals('The number supplied had a 0 after the match so should not be ' +
-              'stripped.',
+               'stripped.',
                strippedNumber.toString(), numberToStrip.toString());
   // Here the 0 is separated by a space from the IDD.
   numberToStrip = new goog.string.StringBuffer('009 0-112-3123');
@@ -1392,9 +1448,9 @@ function testMaybeExtractCountryCode() {
                  0,
                  phoneUtil.maybeExtractCountryCode(phoneNumber, metadata,
                                                    numberToFill, true, number));
-  assertEquals('Did not figure out CountryCodeSource correctly',
-               CCS.FROM_DEFAULT_COUNTRY,
-               number.getCountryCodeSource());
+    assertEquals('Did not figure out CountryCodeSource correctly',
+                 CCS.FROM_DEFAULT_COUNTRY,
+                 number.getCountryCodeSource());
   } catch (e) {
     fail('Should not have thrown an exception: ' + e.toString());
   }
@@ -1517,7 +1573,7 @@ function testParseNationalNumber() {
   assertTrue(usNumber.exactlySameAs(phoneUtil.parse('123-456-7890', 'US')));
 }
 
- function testParseNumberWithAlphaCharacters() {
+function testParseNumberWithAlphaCharacters() {
   // Test case with alpha characters.
   /** @type {i18n.phonenumbers.PhoneNumber} */
   var tollfreeNumber = new i18n.phonenumbers.PhoneNumber();
@@ -1577,6 +1633,11 @@ function testParseWithInternationalPrefixes() {
       phoneUtil.parse('\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09' +
                       '\u3000\uFF13\uFF13\uFF13\uFF0D\uFF16\uFF10\uFF10\uFF10',
                       'SG')));
+  // Using U+30FC dash instead.
+  assertTrue(usNumber.exactlySameAs(
+      phoneUtil.parse('\uFF0B\uFF11\u3000\uFF08\uFF16\uFF15\uFF10\uFF09' +
+                      '\u3000\uFF13\uFF13\uFF13\u30FC\uFF16\uFF10\uFF10\uFF10',
+                      'SG')));
 }
 
 function testParseWithLeadingZero() {
@@ -1823,6 +1884,25 @@ function testFailedParseOnInvalidNumbers() {
                  i18n.phonenumbers.Error.NOT_A_NUMBER,
                  e);
   }
+  try {
+    // Invalid region.
+    phoneUtil.parse(null, 'ZZ');
+    fail('Null string - should fail.');
+  } catch (e) {
+    // Expected this exception.
+    assertEquals('Wrong error type stored in exception.',
+                 i18n.phonenumbers.Error.NOT_A_NUMBER,
+                 e);
+  }
+  try {
+    phoneUtil.parse(null, 'US');
+    fail('Null string - should fail.');
+  } catch (e) {
+    // Expected this exception.
+    assertEquals('Wrong error type stored in exception.',
+                 i18n.phonenumbers.Error.NOT_A_NUMBER,
+                 e);
+  }
 }
 
 function testParseNumbersWithPlusWithNoRegion() {
@@ -1833,6 +1913,12 @@ function testParseNumbersWithPlusWithNoRegion() {
   // 'ZZ' is allowed only if the number starts with a '+' - then the country
   // code can be calculated.
   assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('+64 3 331 6005', 'ZZ')));
+  // Test with full-width plus.
+  assertTrue(nzNumber.exactlySameAs(
+      phoneUtil.parse('\uFF0B64 3 331 6005', 'ZZ')));
+  // Test with normal plus but leading characters that need to be stripped.
+  assertTrue(nzNumber.exactlySameAs(
+      phoneUtil.parse('Tel: +64 3 331 6005', 'ZZ')));
   assertTrue(nzNumber.exactlySameAs(phoneUtil.parse('+64 3 331 6005', null)));
   nzNumber.setRawInput('+64 3 331 6005');
   nzNumber.setCountryCodeSource(i18n.phonenumbers.PhoneNumber
@@ -1919,6 +2005,12 @@ function testParseExtensions() {
   assertTrue(usWithExtension.exactlySameAs(
       phoneUtil.parse('(800) 901-3355 ,extension 7246433', 'US')));
   assertTrue(usWithExtension.exactlySameAs(
+      phoneUtil.parse('(800) 901-3355 ,extensi\u00F3n 7246433', 'US')));
+  // Repeat with the small letter o with acute accent created by combining
+  // characters.
+  assertTrue(usWithExtension.exactlySameAs(
+      phoneUtil.parse('(800) 901-3355 ,extensio\u0301n 7246433', 'US')));
+  assertTrue(usWithExtension.exactlySameAs(
       phoneUtil.parse('(800) 901-3355 , 7246433', 'US')));
   assertTrue(usWithExtension.exactlySameAs(
       phoneUtil.parse('(800) 901-3355 ext: 7246433', 'US')));