From ada3e9e73ff924a1f64210052d99feda7389b35e Mon Sep 17 00:00:00 2001 From: Lara Scheidegger Date: Thu, 23 Oct 2014 11:34:31 +0000 Subject: [PATCH] CPP/JAVA: Introducing new public APIs in ShortNumberInfo/short_number_info. Deprecating old methods. Also includes a refactoring change introducing a matcher API. --- cpp/CMakeLists.txt | 3 + cpp/src/phonenumbers/matcher_api.h | 38 + cpp/src/phonenumbers/regex_based_matcher.cc | 52 + cpp/src/phonenumbers/regex_based_matcher.h | 45 + cpp/src/phonenumbers/shortnumberinfo.cc | 178 ++- cpp/src/phonenumbers/shortnumberinfo.h | 58 +- cpp/src/phonenumbers/test_metadata.cc | 1239 +++++++++-------- cpp/test/phonenumbers/shortnumberinfo_test.cc | 207 ++- cpp/test/phonenumbers/test_util.h | 12 + .../i18n/phonenumbers/ShortNumberInfo.java | 278 +++- .../phonenumbers/internal/MatcherApi.java | 22 + .../internal/RegexBasedMatcher.java | 36 + .../CountryCodeToRegionCodeMapForTesting.java | 4 +- .../i18n/phonenumbers/ExampleNumbersTest.java | 21 +- .../phonenumbers/ShortNumberInfoTest.java | 123 +- .../PhoneNumberMetadataProtoForTesting_BB | Bin 0 -> 165 bytes .../PhoneNumberMetadataProtoForTesting_CA | Bin 0 -> 165 bytes .../PhoneNumberMetadataProtoForTesting_CX | Bin 162 -> 164 bytes .../PhoneNumberMetadataProtoForTesting_FR | Bin 273 -> 275 bytes resources/PhoneNumberMetadataForTesting.xml | 13 +- 20 files changed, 1464 insertions(+), 865 deletions(-) create mode 100644 cpp/src/phonenumbers/matcher_api.h create mode 100644 cpp/src/phonenumbers/regex_based_matcher.cc create mode 100644 cpp/src/phonenumbers/regex_based_matcher.h create mode 100644 java/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java create mode 100644 java/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java create mode 100644 java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BB create mode 100644 java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_CA diff --git a/cpp/CMakeLists.txt b/cpp/CMakeLists.txt index a16887824..201af490d 100644 --- a/cpp/CMakeLists.txt +++ b/cpp/CMakeLists.txt @@ -192,6 +192,7 @@ set ( "src/phonenumbers/phonenumber.cc" "src/phonenumbers/phonenumber.pb.cc" # Generated by Protocol Buffers. "src/phonenumbers/phonenumberutil.cc" + "src/phonenumbers/regex_based_matcher.cc" "src/phonenumbers/regexp_cache.cc" "src/phonenumbers/shortnumberinfo.cc" "src/phonenumbers/string_byte_sink.cc" @@ -448,6 +449,7 @@ set (TEST_SOURCES "test/phonenumbers/regexp_adapter_test.cc" "test/phonenumbers/regexp_cache_test.cc" "test/phonenumbers/run_tests.cc" + "test/phonenumbers/shortnumberinfo_test.cc" "test/phonenumbers/stringutil_test.cc" "test/phonenumbers/test_util.cc" "test/phonenumbers/unicodestring_test.cc" @@ -502,6 +504,7 @@ install (FILES "src/phonenumbers/asyoutypeformatter.h" "src/phonenumbers/callback.h" "src/phonenumbers/logger.h" + "src/phonenumbers/matcher_api.h" "src/phonenumbers/phonenumber.pb.h" "src/phonenumbers/phonemetadata.pb.h" "src/phonenumbers/phonenumberutil.h" diff --git a/cpp/src/phonenumbers/matcher_api.h b/cpp/src/phonenumbers/matcher_api.h new file mode 100644 index 000000000..33536468d --- /dev/null +++ b/cpp/src/phonenumbers/matcher_api.h @@ -0,0 +1,38 @@ +#ifndef I18N_PHONENUMBERS_MATCHER_API_H_ +#define I18N_PHONENUMBERS_MATCHER_API_H_ + +#include + +namespace i18n { +namespace phonenumbers { + +using std::string; + +class PhoneNumberDesc; + +// Internal phonenumber matching API used to isolate the underlying +// implementation of the matcher and allow different implementations to be +// swapped in easily. +class MatcherApi { + public: + virtual ~MatcherApi() {} + + // Returns whether the given national number (a string containing only decimal + // digits) matches the national number pattern defined in the given + // PhoneNumberDesc message. + virtual bool MatchesNationalNumber(const string& national_number, + const PhoneNumberDesc& number_desc, + bool allow_prefix_match) const = 0; + + // Returns whether the given national number (a string containing only decimal + // digits) matches the possible number pattern defined in the given + // PhoneNumberDesc message. + virtual bool MatchesPossibleNumber( + const string& national_number, + const PhoneNumberDesc& number_desc) const = 0; +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_MATCHER_API_H_ diff --git a/cpp/src/phonenumbers/regex_based_matcher.cc b/cpp/src/phonenumbers/regex_based_matcher.cc new file mode 100644 index 000000000..71372a62c --- /dev/null +++ b/cpp/src/phonenumbers/regex_based_matcher.cc @@ -0,0 +1,52 @@ +#include "phonenumbers/regex_based_matcher.h" + +#include +#include + +#include "phonenumbers/base/memory/scoped_ptr.h" +#include "phonenumbers/phonemetadata.pb.h" +#include "phonenumbers/regexp_adapter.h" +#include "phonenumbers/regexp_cache.h" +#include "phonenumbers/regexp_factory.h" + +namespace i18n { +namespace phonenumbers { + +using std::string; + +// Same implementations of AbstractRegExpFactory and RegExpCache in +// PhoneNumberUtil (copy from phonenumberutil.cc). +RegexBasedMatcher::RegexBasedMatcher() + : regexp_factory_(new RegExpFactory()), + regexp_cache_(new RegExpCache(*regexp_factory_, 128)) {} + +RegexBasedMatcher::~RegexBasedMatcher() {} + +bool RegexBasedMatcher::MatchesNationalNumber( + const string& national_number, const PhoneNumberDesc& number_desc, + bool allow_prefix_match) const { + return Match(national_number, number_desc.national_number_pattern(), + allow_prefix_match); +} + +bool RegexBasedMatcher::MatchesPossibleNumber( + const string& national_number, const PhoneNumberDesc& number_desc) const { + return Match(national_number, number_desc.possible_number_pattern(), false); +} + +bool RegexBasedMatcher::Match(const string& national_number, + const string& number_pattern, + bool allow_prefix_match) const { + const RegExp& regexp(regexp_cache_->GetRegExp(number_pattern)); + + if (allow_prefix_match) { + const scoped_ptr normalized_number_input( + regexp_factory_->CreateInput(national_number)); + return regexp.Consume(normalized_number_input.get()); + } else { + return regexp.FullMatch(national_number); + } +} + +} // namespace phonenumbers +} // namespace i18n diff --git a/cpp/src/phonenumbers/regex_based_matcher.h b/cpp/src/phonenumbers/regex_based_matcher.h new file mode 100644 index 000000000..ce6982832 --- /dev/null +++ b/cpp/src/phonenumbers/regex_based_matcher.h @@ -0,0 +1,45 @@ +#ifndef I18N_PHONENUMBERS_REGEX_BASED_MATCHER_H_ +#define I18N_PHONENUMBERS_REGEX_BASED_MATCHER_H_ + +#include +#include + +#include "phonenumbers/base/basictypes.h" +#include "phonenumbers/base/memory/scoped_ptr.h" +#include "phonenumbers/matcher_api.h" + +namespace i18n { +namespace phonenumbers { + +class AbstractRegExpFactory; +class PhoneNumberDesc; +class RegExpCache; + +// Implementation of the matcher API using the regular expressions in the +// PhoneNumberDesc proto message to match numbers. +class RegexBasedMatcher : public MatcherApi { + public: + RegexBasedMatcher(); + ~RegexBasedMatcher(); + + bool MatchesNationalNumber(const string& national_number, + const PhoneNumberDesc& number_desc, + bool allow_prefix_match) const; + + bool MatchesPossibleNumber(const string& national_number, + const PhoneNumberDesc& number_desc) const; + + private: + bool Match(const string& national_number, const string& number_pattern, + bool allow_prefix_match) const; + + const scoped_ptr regexp_factory_; + const scoped_ptr regexp_cache_; + + DISALLOW_COPY_AND_ASSIGN(RegexBasedMatcher); +}; + +} // namespace phonenumbers +} // namespace i18n + +#endif // I18N_PHONENUMBERS_REGEX_BASED_MATCHER_H_ diff --git a/cpp/src/phonenumbers/shortnumberinfo.cc b/cpp/src/phonenumbers/shortnumberinfo.cc index 2b26df4c0..8e7efa8db 100644 --- a/cpp/src/phonenumbers/shortnumberinfo.cc +++ b/cpp/src/phonenumbers/shortnumberinfo.cc @@ -22,10 +22,10 @@ #include "phonenumbers/base/memory/scoped_ptr.h" #include "phonenumbers/default_logger.h" +#include "phonenumbers/matcher_api.h" #include "phonenumbers/phonemetadata.pb.h" #include "phonenumbers/phonenumberutil.h" -#include "phonenumbers/regexp_adapter.h" -#include "phonenumbers/regexp_factory.h" +#include "phonenumbers/regex_based_matcher.h" #include "phonenumbers/region_code.h" #include "phonenumbers/short_metadata.h" @@ -46,6 +46,7 @@ bool LoadCompiledInMetadata(PhoneMetadataCollection* metadata) { ShortNumberInfo::ShortNumberInfo() : phone_util_(*PhoneNumberUtil::GetInstance()), + matcher_api_(new RegexBasedMatcher()), region_to_short_metadata_map_(new map()), regions_where_emergency_numbers_must_be_exact_(new set()) { PhoneMetadataCollection metadata_collection; @@ -65,6 +66,8 @@ ShortNumberInfo::ShortNumberInfo() regions_where_emergency_numbers_must_be_exact_->insert("NI"); } +ShortNumberInfo::~ShortNumberInfo() {} + // Returns a pointer to the phone metadata for the appropriate region or NULL // if the region code is invalid or unknown. const PhoneMetadata* ShortNumberInfo::GetMetadataForRegion( @@ -77,74 +80,113 @@ const PhoneMetadata* ShortNumberInfo::GetMetadataForRegion( return NULL; } -bool ShortNumberInfo::IsPossibleShortNumberForRegion(const string& short_number, +namespace { +// Same as the matchesPossibleNumberAndNationalNumber method in +// java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java +// TODO: Once we have benchmarked ShortNumberInfo, consider if it is +// worth keeping this performance optimization, and if so move this into the +// matcher implementation. +bool MatchesPossibleNumberAndNationalNumber( + const MatcherApi& matcher_api, const string& number, + const PhoneNumberDesc& number_desc) { + return matcher_api.MatchesPossibleNumber(number, number_desc) && + matcher_api.MatchesNationalNumber(number, number_desc, false); +} +} // namespace + +bool ShortNumberInfo::IsPossibleShortNumberForRegion( + const string& short_number, const string& region_dialing_from) const { + const PhoneMetadata* phone_metadata = + GetMetadataForRegion(region_dialing_from); + if (!phone_metadata) { + return false; + } + const PhoneNumberDesc& general_desc = phone_metadata->general_desc(); + return matcher_api_->MatchesPossibleNumber(short_number, general_desc); +} + +bool ShortNumberInfo::IsPossibleShortNumberForRegion(const PhoneNumber& number, const string& region_dialing_from) const { const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { return false; } + string short_number; + phone_util_.GetNationalSignificantNumber(number, &short_number); const PhoneNumberDesc& general_desc = phone_metadata->general_desc(); - return phone_util_.IsNumberPossibleForDesc(short_number, general_desc); + return matcher_api_->MatchesPossibleNumber(short_number, general_desc); } bool ShortNumberInfo::IsPossibleShortNumber(const PhoneNumber& number) const { list region_codes; phone_util_.GetRegionCodesForCountryCallingCode(number.country_code(), - ®ion_codes); + ®ion_codes); string short_number; phone_util_.GetNationalSignificantNumber(number, &short_number); for (list::const_iterator it = region_codes.begin(); it != region_codes.end(); ++it) { const PhoneMetadata* phone_metadata = GetMetadataForRegion(*it); - if (phone_util_.IsNumberPossibleForDesc(short_number, - phone_metadata->general_desc())) { + if (matcher_api_->MatchesPossibleNumber(short_number, + phone_metadata->general_desc())) { return true; } } return false; } -bool ShortNumberInfo::IsValidShortNumberForRegion(const string& short_number, - const string& region_dialing_from) const { +bool ShortNumberInfo::IsValidShortNumberForRegion( + const string& short_number, const string& region_dialing_from) const { const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { return false; } const PhoneNumberDesc& general_desc = phone_metadata->general_desc(); - if (!general_desc.has_national_number_pattern() || - !phone_util_.IsNumberMatchingDesc(short_number, general_desc)) { + if (!MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + general_desc)) { return false; } const PhoneNumberDesc& short_number_desc = phone_metadata->short_code(); - if (!short_number_desc.has_national_number_pattern()) { - LOG(WARNING) << "No short code national number pattern found for region: " - << region_dialing_from; + return MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + short_number_desc); +} + +bool ShortNumberInfo::IsValidShortNumberForRegion( + const PhoneNumber& number, const string& region_dialing_from) const { + const PhoneMetadata* phone_metadata = + GetMetadataForRegion(region_dialing_from); + if (!phone_metadata) { return false; } - return phone_util_.IsNumberMatchingDesc(short_number, short_number_desc); + string short_number; + phone_util_.GetNationalSignificantNumber(number, &short_number); + const PhoneNumberDesc& general_desc = phone_metadata->general_desc(); + if (!MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + general_desc)) { + return false; + } + const PhoneNumberDesc& short_number_desc = phone_metadata->short_code(); + return MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + short_number_desc); } bool ShortNumberInfo::IsValidShortNumber(const PhoneNumber& number) const { list region_codes; phone_util_.GetRegionCodesForCountryCallingCode(number.country_code(), - ®ion_codes); - string short_number; - phone_util_.GetNationalSignificantNumber(number, &short_number); + ®ion_codes); string region_code; - GetRegionCodeForShortNumberFromRegionList(number, - region_codes, ®ion_code); + GetRegionCodeForShortNumberFromRegionList(number, region_codes, ®ion_code); if (region_codes.size() > 1 && region_code != RegionCode::GetUnknown()) { return true; } - return IsValidShortNumberForRegion(short_number, region_code); + return IsValidShortNumberForRegion(number, region_code); } ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCostForRegion( const string& short_number, const string& region_dialing_from) const { - const PhoneMetadata* phone_metadata = GetMetadataForRegion( - region_dialing_from); + const PhoneMetadata* phone_metadata = + GetMetadataForRegion(region_dialing_from); if (!phone_metadata) { return ShortNumberInfo::UNKNOWN_COST; } @@ -152,16 +194,48 @@ ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCostForRegion( // The cost categories are tested in order of decreasing expense, since if // for some reason the patterns overlap the most expensive matching cost // category should be returned. - if (phone_util_.IsNumberMatchingDesc(short_number, - phone_metadata->premium_rate())) { + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->premium_rate())) { return ShortNumberInfo::PREMIUM_RATE; } - if (phone_util_.IsNumberMatchingDesc(short_number, - phone_metadata->standard_rate())) { + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->standard_rate())) { return ShortNumberInfo::STANDARD_RATE; } - if (phone_util_.IsNumberMatchingDesc(short_number, - phone_metadata->toll_free())) { + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->toll_free())) { + return ShortNumberInfo::TOLL_FREE; + } + if (IsEmergencyNumber(short_number, region_dialing_from)) { + // Emergency numbers are implicitly toll-free. + return ShortNumberInfo::TOLL_FREE; + } + return ShortNumberInfo::UNKNOWN_COST; +} + +ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCostForRegion( + const PhoneNumber& number, const string& region_dialing_from) const { + const PhoneMetadata* phone_metadata = + GetMetadataForRegion(region_dialing_from); + if (!phone_metadata) { + return ShortNumberInfo::UNKNOWN_COST; + } + string short_number; + phone_util_.GetNationalSignificantNumber(number, &short_number); + + // The cost categories are tested in order of decreasing expense, since if + // for some reason the patterns overlap the most expensive matching cost + // category should be returned. + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->premium_rate())) { + return ShortNumberInfo::PREMIUM_RATE; + } + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->standard_rate())) { + return ShortNumberInfo::STANDARD_RATE; + } + if (MatchesPossibleNumberAndNationalNumber(*matcher_api_, short_number, + phone_metadata->toll_free())) { return ShortNumberInfo::TOLL_FREE; } if (IsEmergencyNumber(short_number, region_dialing_from)) { @@ -175,21 +249,18 @@ ShortNumberInfo::ShortNumberCost ShortNumberInfo::GetExpectedCost( const PhoneNumber& number) const { list region_codes; phone_util_.GetRegionCodesForCountryCallingCode(number.country_code(), - ®ion_codes); + ®ion_codes); if (region_codes.size() == 0) { return ShortNumberInfo::UNKNOWN_COST; } - string short_number; - phone_util_.GetNationalSignificantNumber(number, &short_number); if (region_codes.size() == 1) { - return GetExpectedCostForRegion(short_number, region_codes.front()); + return GetExpectedCostForRegion(number, region_codes.front()); } - ShortNumberInfo::ShortNumberCost cost = - ShortNumberInfo::TOLL_FREE; + ShortNumberInfo::ShortNumberCost cost = ShortNumberInfo::TOLL_FREE; for (list::const_iterator it = region_codes.begin(); it != region_codes.end(); ++it) { ShortNumberInfo::ShortNumberCost cost_for_region = - GetExpectedCostForRegion(short_number, *it); + GetExpectedCostForRegion(number, *it); switch (cost_for_region) { case ShortNumberInfo::PREMIUM_RATE: return ShortNumberInfo::PREMIUM_RATE; @@ -217,19 +288,22 @@ void ShortNumberInfo::GetRegionCodeForShortNumberFromRegionList( string* region_code) const { if (region_codes.size() == 0) { region_code->assign(RegionCode::GetUnknown()); + return; } else if (region_codes.size() == 1) { region_code->assign(region_codes.front()); + return; } string national_number; phone_util_.GetNationalSignificantNumber(number, &national_number); for (list::const_iterator it = region_codes.begin(); - it != region_codes.end(); ++it) { + it != region_codes.end(); ++it) { const PhoneMetadata* phone_metadata = GetMetadataForRegion(*it); if (phone_metadata != NULL && - phone_util_.IsNumberMatchingDesc(national_number, - phone_metadata->short_code())) { + MatchesPossibleNumberAndNationalNumber(*matcher_api_, national_number, + phone_metadata->short_code())) { // The number is valid for this region. region_code->assign(*it); + return; } } region_code->assign(RegionCode::GetUnknown()); @@ -302,34 +376,26 @@ bool ShortNumberInfo::MatchesEmergencyNumberHelper(const string& number, if (!metadata || !metadata->has_emergency()) { return false; } - const scoped_ptr regexp_factory( - new RegExpFactory()); - const scoped_ptr emergency_number_pattern( - regexp_factory->CreateRegExp( - metadata->emergency().national_number_pattern())); phone_util_.NormalizeDigitsOnly(&extracted_number); - const scoped_ptr normalized_number_input( - regexp_factory->CreateInput(extracted_number)); - - return (!allow_prefix_match || - regions_where_emergency_numbers_must_be_exact_->find(region_code) - != regions_where_emergency_numbers_must_be_exact_->end()) - ? emergency_number_pattern->FullMatch(extracted_number) - : emergency_number_pattern->Consume(normalized_number_input.get()); + bool allow_prefix_match_for_region = + allow_prefix_match && + regions_where_emergency_numbers_must_be_exact_->find(region_code) == + regions_where_emergency_numbers_must_be_exact_->end(); + return matcher_api_->MatchesNationalNumber( + extracted_number, metadata->emergency(), allow_prefix_match_for_region); } bool ShortNumberInfo::IsCarrierSpecific(const PhoneNumber& number) const { list region_codes; phone_util_.GetRegionCodesForCountryCallingCode(number.country_code(), - ®ion_codes); + ®ion_codes); string region_code; - GetRegionCodeForShortNumberFromRegionList(number, - region_codes, ®ion_code); + GetRegionCodeForShortNumberFromRegionList(number, region_codes, ®ion_code); string national_number; phone_util_.GetNationalSignificantNumber(number, &national_number); const PhoneMetadata* phone_metadata = GetMetadataForRegion(region_code); return phone_metadata && - phone_util_.IsNumberMatchingDesc(national_number, + MatchesPossibleNumberAndNationalNumber(*matcher_api_, national_number, phone_metadata->carrier_specific()); } diff --git a/cpp/src/phonenumbers/shortnumberinfo.h b/cpp/src/phonenumbers/shortnumberinfo.h index 9ca140b28..4a405f59a 100644 --- a/cpp/src/phonenumbers/shortnumberinfo.h +++ b/cpp/src/phonenumbers/shortnumberinfo.h @@ -26,7 +26,6 @@ #include "phonenumbers/base/basictypes.h" #include "phonenumbers/base/memory/scoped_ptr.h" -#include "phonenumbers/phonemetadata.pb.h" namespace i18n { namespace phonenumbers { @@ -36,12 +35,15 @@ using std::map; using std::set; using std::string; +class MatcherApi; +class PhoneMetadata; class PhoneNumber; class PhoneNumberUtil; class ShortNumberInfo { public: ShortNumberInfo(); + ~ShortNumberInfo(); // Cost categories of short numbers. enum ShortNumberCost { @@ -51,6 +53,12 @@ class ShortNumberInfo { UNKNOWN_COST }; + // DEPRECATED: Anyone who was using it and passing in a string with whitespace + // (or other formatting characters) would have been getting the wrong result. + // You should parse the string to PhoneNumber and use the method + // IsPossibleShortNumberForRegion(PhoneNumber, String). This method will be + // removed in the next release. + // // Check whether a short number is a possible number when dialled from a // region, given the number in the form of a string, and the region where the // number is dialed from. This provides a more lenient check than @@ -59,12 +67,26 @@ class ShortNumberInfo { const string& short_number, const string& region_dialing_from) const; + // Check whether a short number is a possible number when dialled from a + // region, given the number in the form of a string, and the region where the + // number is dialed from. This provides a more lenient check than + // IsValidShortNumberForRegion. + bool IsPossibleShortNumberForRegion( + const PhoneNumber& short_number, + const string& region_dialing_from) const; + // Check whether a short number is a possible number. If a country calling // code is shared by multiple regions, this returns true if it's possible in // any of them. This provides a more lenient check than IsValidShortNumber. // See IsPossibleShortNumberForRegion for details. bool IsPossibleShortNumber(const PhoneNumber& number) const; + // DEPRECATED: Anyone who was using it and passing in a string with whitespace + // (or other formatting characters) would have been getting the wrong result. + // You should parse the string to PhoneNumber and use the method + // IsValidShortNumberForRegion(PhoneNumber, String). This method will be + // removed in the next release. + // // Tests whether a short number matches a valid pattern in a region. Note // that this doesn't verify the number is actually in use, which is // impossible to tell by just looking at the number itself. @@ -72,6 +94,13 @@ class ShortNumberInfo { const string& short_number, const string& region_dialing_from) const; + // Tests whether a short number matches a valid pattern in a region. Note + // that this doesn't verify the number is actually in use, which is + // impossible to tell by just looking at the number itself. + bool IsValidShortNumberForRegion( + const PhoneNumber& short_number, + const string& region_dialing_from) const; + // Tests whether a short number matches a valid pattern. If a country calling // code is shared by multiple regions, this returns true if it's valid in any // of them. Note that this doesn't verify the number is actually in use, @@ -79,6 +108,12 @@ class ShortNumberInfo { // IsValidShortNumberForRegion for details. bool IsValidShortNumber(const PhoneNumber& number) const; + // DEPRECATED: Anyone who was using it and passing in a string with whitespace + // (or other formatting characters) would have been getting the wrong result. + // You should parse the string to PhoneNumber and use the method + // GetExpectedCostForRegion(PhoneNumber, String). This method will be + // removed in the next release. + // // Gets the expected cost category of a short number when dialled from a // region (however, nothing is implied about its validity). If it is // important that the number is valid, then its validity must first be @@ -97,6 +132,26 @@ class ShortNumberInfo { const string& short_number, const string& region_dialing_from) const; + // Gets the expected cost category of a short number when dialled from a + // region (however, nothing is implied about its validity). If it is + // important that the number is valid, then its validity must first be + // checked using IsValidShortNumberForRegion. Note that emergency numbers are + // always considered toll-free. Example usage: + // + // PhoneNumber number; + // phone_util.Parse("110", "US", &number); + // ... + // string region_code("CA"); + // ShortNumberInfo short_info; + // if (short_info.IsValidShortNumberForRegion(number, region_code)) { + // ShortNumberInfo::ShortNumberCost cost = + // short_info.GetExpectedCostForRegion(number, region_code); + // // Do something with the cost information here. + // } + ShortNumberCost GetExpectedCostForRegion( + const PhoneNumber& short_number, + const string& region_dialing_from) const; + // Gets the expected cost category of a short number (however, nothing is // implied about its validity). If the country calling code is unique to a // region, this method behaves exactly the same as GetExpectedCostForRegion. @@ -147,6 +202,7 @@ class ShortNumberInfo { private: const PhoneNumberUtil& phone_util_; + const scoped_ptr matcher_api_; // A mapping from a RegionCode to the PhoneMetadata for that region. scoped_ptr > diff --git a/cpp/src/phonenumbers/test_metadata.cc b/cpp/src/phonenumbers/test_metadata.cc index 6b8ee7cd0..92ccf9133 100644 --- a/cpp/src/phonenumbers/test_metadata.cc +++ b/cpp/src/phonenumbers/test_metadata.cc @@ -152,62 +152,12 @@ static const unsigned char data[] = { 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x0A, 0x6F, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, + 0x4E, 0x41, 0x0A, 0x72, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x42, 0x52, 0x50, - 0x37, 0x5A, 0x00, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xCF, - 0x02, 0x0A, 0x29, 0x12, 0x1D, 0x28, 0x32, 0x34, 0x32, 0x7C, 0x38, 0x28, 0x30, - 0x30, 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, 0x38, 0x38, 0x29, 0x7C, 0x39, - 0x30, 0x30, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, - 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x12, 0x6C, 0x12, 0x60, 0x32, 0x34, 0x32, 0x28, - 0x3F, 0x3A, 0x33, 0x28, 0x3F, 0x3A, 0x30, 0x32, 0x7C, 0x5B, 0x32, 0x33, 0x36, - 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x7C, 0x34, 0x5B, 0x30, 0x2D, 0x32, 0x34, - 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x36, 0x38, 0x5D, 0x7C, 0x37, - 0x5B, 0x33, 0x2D, 0x35, 0x37, 0x5D, 0x7C, 0x39, 0x5B, 0x32, 0x2D, 0x35, 0x5D, - 0x29, 0x7C, 0x34, 0x28, 0x3F, 0x3A, 0x32, 0x5B, 0x32, 0x33, 0x37, 0x5D, 0x7C, - 0x35, 0x31, 0x7C, 0x36, 0x34, 0x7C, 0x37, 0x37, 0x29, 0x7C, 0x35, 0x30, 0x32, - 0x7C, 0x36, 0x33, 0x36, 0x7C, 0x37, 0x30, 0x32, 0x29, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x23, - 0x12, 0x19, 0x32, 0x34, 0x32, 0x28, 0x33, 0x35, 0x37, 0x7C, 0x33, 0x35, 0x39, - 0x7C, 0x34, 0x35, 0x37, 0x7C, 0x35, 0x35, 0x37, 0x29, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x22, 0x1D, 0x12, 0x13, - 0x38, 0x28, 0x30, 0x30, 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, 0x38, 0x38, - 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, - 0x7D, 0x2A, 0x12, 0x12, 0x08, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, - 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, - 0x02, 0x42, 0x53, 0x50, 0x01, 0x5A, 0x03, 0x30, 0x31, 0x31, 0x62, 0x01, 0x31, - 0x7A, 0x01, 0x31, 0x90, 0x01, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xB8, - 0x02, 0x0A, 0x13, 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x35, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x12, 0x1B, 0x12, 0x0A, - 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, 0x1A, 0x05, 0x5C, - 0x64, 0x7B, 0x36, 0x7D, 0x32, 0x06, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x1A, - 0x13, 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, - 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x42, 0x59, 0x50, 0xF7, 0x02, 0x5A, - 0x03, 0x38, 0x31, 0x30, 0x62, 0x01, 0x38, 0x7A, 0x09, 0x38, 0x30, 0x3F, 0x7C, - 0x39, 0x39, 0x39, 0x39, 0x39, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x1E, 0x0A, 0x07, - 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x02, 0x24, 0x31, 0x1A, 0x05, - 0x5B, 0x31, 0x2D, 0x38, 0x5D, 0x22, 0x04, 0x38, 0x20, 0x24, 0x31, 0x2A, 0x00, - 0x30, 0x00, 0x9A, 0x01, 0x27, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, - 0x24, 0x32, 0x1A, 0x05, 0x5B, 0x31, 0x2D, 0x38, 0x5D, 0x22, 0x03, 0x38, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x28, 0x0A, 0x0E, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, - 0x24, 0x31, 0x20, 0x24, 0x32, 0x1A, 0x05, 0x5B, 0x31, 0x2D, 0x38, 0x5D, 0x22, - 0x04, 0x38, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x42, 0x42, 0x50, + 0x01, 0x5A, 0x03, 0x30, 0x31, 0x31, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, @@ -215,32 +165,100 @@ static const unsigned char data[] = { 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x43, 0x50, 0x3D, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x42, 0x52, 0x50, 0x37, 0x5A, 0x00, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xC5, 0x01, - 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xCF, 0x02, + 0x0A, 0x29, 0x12, 0x1D, 0x28, 0x32, 0x34, 0x32, 0x7C, 0x38, 0x28, 0x30, 0x30, + 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, 0x38, 0x38, 0x29, 0x7C, 0x39, 0x30, + 0x30, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x37, + 0x2C, 0x31, 0x30, 0x7D, 0x12, 0x6C, 0x12, 0x60, 0x32, 0x34, 0x32, 0x28, 0x3F, + 0x3A, 0x33, 0x28, 0x3F, 0x3A, 0x30, 0x32, 0x7C, 0x5B, 0x32, 0x33, 0x36, 0x5D, + 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x7C, 0x34, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x2D, + 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x36, 0x38, 0x5D, 0x7C, 0x37, 0x5B, + 0x33, 0x2D, 0x35, 0x37, 0x5D, 0x7C, 0x39, 0x5B, 0x32, 0x2D, 0x35, 0x5D, 0x29, + 0x7C, 0x34, 0x28, 0x3F, 0x3A, 0x32, 0x5B, 0x32, 0x33, 0x37, 0x5D, 0x7C, 0x35, + 0x31, 0x7C, 0x36, 0x34, 0x7C, 0x37, 0x37, 0x29, 0x7C, 0x35, 0x30, 0x32, 0x7C, + 0x36, 0x33, 0x36, 0x7C, 0x37, 0x30, 0x32, 0x29, 0x5C, 0x64, 0x7B, 0x34, 0x7D, + 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x23, 0x12, + 0x19, 0x32, 0x34, 0x32, 0x28, 0x33, 0x35, 0x37, 0x7C, 0x33, 0x35, 0x39, 0x7C, + 0x34, 0x35, 0x37, 0x7C, 0x35, 0x35, 0x37, 0x29, 0x5C, 0x64, 0x7B, 0x34, 0x7D, + 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x22, 0x1D, 0x12, 0x13, 0x38, + 0x28, 0x30, 0x30, 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, 0x38, 0x38, 0x29, + 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, + 0x2A, 0x12, 0x12, 0x08, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, + 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, + 0x42, 0x53, 0x50, 0x01, 0x5A, 0x03, 0x30, 0x31, 0x31, 0x62, 0x01, 0x31, 0x7A, + 0x01, 0x31, 0x90, 0x01, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xB8, 0x02, + 0x0A, 0x13, 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, + 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x12, 0x1B, 0x12, 0x0A, 0x5B, + 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, 0x1A, 0x05, 0x5C, 0x64, + 0x7B, 0x36, 0x7D, 0x32, 0x06, 0x31, 0x31, 0x32, 0x33, 0x34, 0x35, 0x1A, 0x13, + 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, 0x1A, + 0x05, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x4E, 0x50, 0x56, 0x5A, 0x00, 0x90, - 0x01, 0x01, 0x9A, 0x01, 0x53, 0x0A, 0x10, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x36, 0x7D, 0x29, 0x12, 0x05, 0x24, - 0x31, 0x20, 0x24, 0x32, 0x1A, 0x05, 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x1A, 0x0E, - 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x5B, 0x31, 0x39, - 0x5D, 0x1A, 0x13, 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, - 0x28, 0x3F, 0x3A, 0x31, 0x30, 0x7C, 0x39, 0x35, 0x29, 0x22, 0x02, 0x24, 0x31, - 0x2A, 0x06, 0x24, 0x43, 0x43, 0x20, 0x24, 0x31, 0x30, 0x00, 0xAA, 0x01, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x0A, 0x6F, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x58, 0x50, - 0x3D, 0x5A, 0x00, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x42, 0x59, 0x50, 0xF7, 0x02, 0x5A, 0x03, + 0x38, 0x31, 0x30, 0x62, 0x01, 0x38, 0x7A, 0x09, 0x38, 0x30, 0x3F, 0x7C, 0x39, + 0x39, 0x39, 0x39, 0x39, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x1E, 0x0A, 0x07, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x02, 0x24, 0x31, 0x1A, 0x05, 0x5B, + 0x31, 0x2D, 0x38, 0x5D, 0x22, 0x04, 0x38, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, + 0x00, 0x9A, 0x01, 0x27, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, + 0x32, 0x1A, 0x05, 0x5B, 0x31, 0x2D, 0x38, 0x5D, 0x22, 0x03, 0x38, 0x24, 0x31, + 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x28, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, + 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, 0x24, + 0x31, 0x20, 0x24, 0x32, 0x1A, 0x05, 0x5B, 0x31, 0x2D, 0x38, 0x5D, 0x22, 0x04, + 0x38, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0x0A, 0x72, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x41, 0x50, 0x01, 0x5A, + 0x03, 0x30, 0x31, 0x31, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, + 0x6F, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x43, 0x50, 0x3D, 0x5A, 0x00, + 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xC5, 0x01, 0x0A, 0x00, + 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x4E, 0x50, 0x56, 0x5A, 0x00, 0x90, 0x01, 0x01, + 0x9A, 0x01, 0x53, 0x0A, 0x10, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x36, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x1A, 0x05, 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x1A, 0x0E, 0x5B, 0x33, + 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x5B, 0x31, 0x39, 0x5D, 0x1A, + 0x13, 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x28, 0x3F, + 0x3A, 0x31, 0x30, 0x7C, 0x39, 0x35, 0x29, 0x22, 0x02, 0x24, 0x31, 0x2A, 0x06, + 0x24, 0x43, 0x43, 0x20, 0x24, 0x31, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0x0A, 0x71, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x43, 0x58, 0x50, 0x3D, 0x5A, + 0x02, 0x30, 0x30, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA3, @@ -296,7 +314,7 @@ static const unsigned char data[] = { 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x0A, 0xD9, 0x01, 0x0A, 0x0F, 0x12, 0x06, 0x33, 0x5C, 0x64, 0x7B, 0x36, 0x7D, + 0x0A, 0xDB, 0x01, 0x0A, 0x0F, 0x12, 0x06, 0x33, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x12, 0x0F, 0x12, 0x06, 0x33, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x0F, 0x12, 0x06, 0x33, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, @@ -304,556 +322,557 @@ static const unsigned char data[] = { 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x4A, 0x02, 0x46, 0x52, 0x50, 0x21, 0x5A, 0x00, 0x62, 0x01, 0x30, 0x7A, 0x01, - 0x30, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x34, 0x0A, 0x19, 0x28, 0x5C, 0x64, 0x29, - 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, - 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x01, 0x33, 0x22, 0x03, - 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, - 0xEA, 0x03, 0x0A, 0x12, 0x12, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x1A, - 0x08, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x31, 0x30, 0x7D, 0x12, 0x16, 0x12, 0x0A, - 0x5B, 0x31, 0x2D, 0x36, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x08, 0x5C, - 0x64, 0x7B, 0x36, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x18, 0x12, 0x0E, 0x37, 0x5B, - 0x31, 0x2D, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, - 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x22, 0x11, 0x12, 0x07, 0x38, 0x30, - 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, - 0x2A, 0x15, 0x12, 0x0B, 0x39, 0x5B, 0x30, 0x31, 0x38, 0x5D, 0x5C, 0x64, 0x7B, - 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x21, 0x12, - 0x17, 0x38, 0x28, 0x3F, 0x3A, 0x34, 0x5B, 0x33, 0x2D, 0x35, 0x5D, 0x7C, 0x37, - 0x5B, 0x30, 0x2D, 0x32, 0x5D, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, - 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x3A, 0x11, 0x12, 0x07, 0x37, 0x30, 0x5C, - 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x42, - 0x11, 0x12, 0x07, 0x35, 0x36, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, - 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x4A, 0x02, 0x47, 0x42, 0x50, 0x2C, 0x5A, 0x02, - 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, - 0x3A, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, - 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0C, 0x5B, 0x31, 0x2D, - 0x35, 0x39, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x30, 0x22, 0x05, 0x28, 0x30, - 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x36, 0x0A, 0x19, 0x28, - 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x0B, - 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x01, - 0x36, 0x22, 0x05, 0x28, 0x30, 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0x9A, - 0x01, 0x37, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, - 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x09, 0x37, 0x5B, - 0x31, 0x2D, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x22, 0x05, 0x28, 0x30, 0x24, 0x31, - 0x29, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, - 0x24, 0x33, 0x1A, 0x05, 0x38, 0x5B, 0x34, 0x37, 0x5D, 0x22, 0x05, 0x28, 0x30, - 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x11, 0x12, 0x07, 0x37, - 0x36, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, - 0x7D, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x80, 0x02, 0x01, 0x0A, 0x6F, - 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x47, 0x47, 0x50, 0x2C, 0x5A, 0x00, 0x90, - 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA7, 0x01, 0x0A, 0x10, 0x12, - 0x07, 0x33, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, - 0x39, 0x7D, 0x12, 0x10, 0x12, 0x07, 0x33, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, - 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x10, 0x12, 0x07, 0x33, 0x30, - 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x22, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x48, - 0x55, 0x50, 0x24, 0x5A, 0x00, 0x62, 0x02, 0x30, 0x36, 0x7A, 0x02, 0x30, 0x36, - 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA1, 0x03, 0x0A, 0x1A, - 0x12, 0x0E, 0x5B, 0x30, 0x33, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x2C, - 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x31, 0x31, 0x7D, - 0x12, 0x16, 0x12, 0x09, 0x30, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, - 0x1A, 0x09, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, 0x1A, 0x14, - 0x12, 0x08, 0x33, 0x5C, 0x64, 0x7B, 0x38, 0x2C, 0x39, 0x7D, 0x1A, 0x08, 0x5C, - 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x22, 0x1E, 0x12, 0x13, 0x38, 0x30, - 0x28, 0x3F, 0x3A, 0x30, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x7C, 0x33, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x1A, 0x07, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x39, 0x7D, - 0x2A, 0x1E, 0x12, 0x13, 0x38, 0x39, 0x28, 0x3F, 0x3A, 0x32, 0x5C, 0x64, 0x7B, - 0x33, 0x7D, 0x7C, 0x39, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x29, 0x1A, 0x07, 0x5C, - 0x64, 0x7B, 0x36, 0x2C, 0x39, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x49, - 0x54, 0x50, 0x27, 0x5A, 0x02, 0x30, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x2E, - 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, - 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x05, 0x30, 0x5B, 0x32, 0x36, - 0x5D, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x35, 0x0A, 0x17, 0x28, - 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, - 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, - 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0A, 0x30, 0x5B, 0x31, 0x33, 0x2D, - 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, - 0x2C, 0x0A, 0x17, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, 0x7D, 0x29, - 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x01, 0x33, - 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x22, 0x0A, 0x10, 0x28, 0x5C, - 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x36, 0x7D, - 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, 0x1A, 0x01, 0x38, 0x22, 0x00, - 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xD0, 0x01, - 0x01, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, - 0xB1, 0x05, 0x0A, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, 0x35, 0x7D, - 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, - 0x31, 0x7D, 0x12, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, 0x35, 0x7D, - 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, - 0x31, 0x7D, 0x1A, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, 0x35, 0x7D, - 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, - 0x31, 0x7D, 0x22, 0x1F, 0x12, 0x0D, 0x30, 0x37, 0x37, 0x37, 0x5B, 0x30, 0x31, - 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x37, 0x7D, - 0x32, 0x07, 0x30, 0x37, 0x37, 0x37, 0x30, 0x31, 0x32, 0x2A, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x4A, - 0x50, 0x50, 0x51, 0x5A, 0x03, 0x30, 0x31, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, - 0x30, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, - 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, - 0x33, 0x1A, 0x07, 0x5B, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x30, 0x22, 0x03, 0x30, - 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3D, 0x0A, 0x1C, 0x28, 0x5C, - 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x4A, 0x02, 0x46, 0x52, 0x50, 0x21, 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, + 0x7A, 0x01, 0x30, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x34, 0x0A, 0x19, 0x28, 0x5C, + 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, + 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x12, 0x0B, 0x24, + 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x01, 0x33, + 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x0A, 0xEA, 0x03, 0x0A, 0x12, 0x12, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, + 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x31, 0x30, 0x7D, 0x12, 0x16, + 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x36, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, + 0x08, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x18, 0x12, 0x0E, + 0x37, 0x5B, 0x31, 0x2D, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, + 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x22, 0x11, 0x12, 0x07, + 0x38, 0x30, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, + 0x30, 0x7D, 0x2A, 0x15, 0x12, 0x0B, 0x39, 0x5B, 0x30, 0x31, 0x38, 0x5D, 0x5C, + 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, + 0x21, 0x12, 0x17, 0x38, 0x28, 0x3F, 0x3A, 0x34, 0x5B, 0x33, 0x2D, 0x35, 0x5D, + 0x7C, 0x37, 0x5B, 0x30, 0x2D, 0x32, 0x5D, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, + 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x3A, 0x11, 0x12, 0x07, 0x37, + 0x30, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, + 0x7D, 0x42, 0x11, 0x12, 0x07, 0x35, 0x36, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, + 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x4A, 0x02, 0x47, 0x42, 0x50, 0x2C, + 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, + 0x9A, 0x01, 0x3A, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0C, 0x5B, + 0x31, 0x2D, 0x35, 0x39, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x30, 0x22, 0x05, + 0x28, 0x30, 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x36, 0x0A, + 0x19, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, - 0x1A, 0x07, 0x5B, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x30, 0x22, 0x03, 0x30, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x5C, 0x0A, 0x15, 0x28, 0x5C, 0x64, - 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, - 0x24, 0x33, 0x1A, 0x0B, 0x31, 0x31, 0x31, 0x7C, 0x32, 0x32, 0x32, 0x7C, 0x33, - 0x33, 0x33, 0x1A, 0x10, 0x28, 0x3F, 0x3A, 0x31, 0x31, 0x31, 0x7C, 0x32, 0x32, - 0x32, 0x7C, 0x33, 0x33, 0x33, 0x29, 0x31, 0x1A, 0x11, 0x28, 0x3F, 0x3A, 0x31, - 0x31, 0x31, 0x7C, 0x32, 0x32, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x29, 0x31, 0x31, - 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x54, 0x0A, - 0x12, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x29, 0x28, + 0x1A, 0x01, 0x36, 0x22, 0x05, 0x28, 0x30, 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, + 0x00, 0x9A, 0x01, 0x37, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x09, + 0x37, 0x5B, 0x31, 0x2D, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x22, 0x05, 0x28, 0x30, + 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, + 0x32, 0x20, 0x24, 0x33, 0x1A, 0x05, 0x38, 0x5B, 0x34, 0x37, 0x5D, 0x22, 0x05, + 0x28, 0x30, 0x24, 0x31, 0x29, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x11, 0x12, + 0x07, 0x37, 0x36, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, + 0x31, 0x30, 0x7D, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x80, 0x02, 0x01, + 0x0A, 0x6F, 0x0A, 0x00, 0x12, 0x00, 0x1A, 0x00, 0x22, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x47, 0x47, 0x50, 0x2C, 0x5A, + 0x00, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA7, 0x01, 0x0A, + 0x10, 0x12, 0x07, 0x33, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, + 0x64, 0x7B, 0x39, 0x7D, 0x12, 0x10, 0x12, 0x07, 0x33, 0x30, 0x5C, 0x64, 0x7B, + 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x10, 0x12, 0x07, + 0x33, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, + 0x7D, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, + 0x02, 0x48, 0x55, 0x50, 0x24, 0x5A, 0x00, 0x62, 0x02, 0x30, 0x36, 0x7A, 0x02, + 0x30, 0x36, 0x90, 0x01, 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA1, 0x03, + 0x0A, 0x1A, 0x12, 0x0E, 0x5B, 0x30, 0x33, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, + 0x35, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x31, + 0x31, 0x7D, 0x12, 0x16, 0x12, 0x09, 0x30, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, + 0x30, 0x7D, 0x1A, 0x09, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, + 0x1A, 0x14, 0x12, 0x08, 0x33, 0x5C, 0x64, 0x7B, 0x38, 0x2C, 0x39, 0x7D, 0x1A, + 0x08, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x22, 0x1E, 0x12, 0x13, + 0x38, 0x30, 0x28, 0x3F, 0x3A, 0x30, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x7C, 0x33, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x1A, 0x07, 0x5C, 0x64, 0x7B, 0x36, 0x2C, + 0x39, 0x7D, 0x2A, 0x1E, 0x12, 0x13, 0x38, 0x39, 0x28, 0x3F, 0x3A, 0x32, 0x5C, + 0x64, 0x7B, 0x33, 0x7D, 0x7C, 0x39, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x29, 0x1A, + 0x07, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x39, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, + 0x02, 0x49, 0x54, 0x50, 0x27, 0x5A, 0x02, 0x30, 0x30, 0x90, 0x01, 0x00, 0x9A, + 0x01, 0x2E, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, + 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x05, 0x30, 0x5B, + 0x32, 0x36, 0x5D, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x35, 0x0A, + 0x17, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, + 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, 0x7D, 0x29, 0x12, 0x08, + 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0A, 0x30, 0x5B, 0x31, + 0x33, 0x2D, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, + 0x9A, 0x01, 0x2C, 0x0A, 0x17, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, + 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, + 0x01, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x22, 0x0A, 0x10, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, + 0x36, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, 0x1A, 0x01, 0x38, + 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0xD0, 0x01, 0x01, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x0A, 0xB1, 0x05, 0x0A, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, + 0x35, 0x7D, 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, + 0x2C, 0x31, 0x31, 0x7D, 0x12, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, + 0x35, 0x7D, 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, + 0x2C, 0x31, 0x31, 0x7D, 0x1A, 0x25, 0x12, 0x19, 0x30, 0x37, 0x5C, 0x64, 0x7B, + 0x35, 0x7D, 0x7C, 0x5B, 0x31, 0x2D, 0x33, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x33, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, + 0x2C, 0x31, 0x31, 0x7D, 0x22, 0x1F, 0x12, 0x0D, 0x30, 0x37, 0x37, 0x37, 0x5B, + 0x30, 0x31, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, + 0x37, 0x7D, 0x32, 0x07, 0x30, 0x37, 0x37, 0x37, 0x30, 0x31, 0x32, 0x2A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, + 0x02, 0x4A, 0x50, 0x50, 0x51, 0x5A, 0x03, 0x30, 0x31, 0x30, 0x62, 0x01, 0x30, + 0x7A, 0x01, 0x30, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, 0x5C, + 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x1A, 0x07, 0x32, 0x32, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x1A, - 0x09, 0x32, 0x32, 0x32, 0x31, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x1A, 0x0A, 0x32, - 0x32, 0x32, 0x31, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x1A, 0x0B, 0x32, 0x32, - 0x32, 0x31, 0x32, 0x30, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x22, 0x03, 0x30, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x30, 0x0A, 0x15, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, - 0x24, 0x33, 0x1A, 0x04, 0x5B, 0x32, 0x33, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, - 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x25, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, - 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, - 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x03, 0x30, 0x37, 0x37, 0x22, 0x03, 0x30, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x1C, 0x0A, 0x07, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x03, 0x2A, 0x24, 0x31, 0x1A, 0x04, 0x5B, 0x32, - 0x33, 0x5D, 0x22, 0x02, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x12, 0x12, 0x09, - 0x5B, 0x32, 0x33, 0x5D, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x1A, 0x05, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xD0, 0x01, 0x01, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x0A, 0xE2, 0x0B, 0x0A, 0x1F, 0x12, 0x13, 0x5B, 0x31, 0x2D, 0x37, - 0x5D, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x39, 0x7D, 0x7C, 0x38, 0x5C, 0x64, 0x7B, - 0x38, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, 0x30, 0x7D, 0x12, - 0x4C, 0x12, 0x36, 0x28, 0x3F, 0x3A, 0x32, 0x7C, 0x5B, 0x33, 0x34, 0x5D, 0x5B, - 0x31, 0x2D, 0x33, 0x5D, 0x7C, 0x35, 0x5B, 0x31, 0x2D, 0x35, 0x5D, 0x7C, 0x36, - 0x5B, 0x31, 0x2D, 0x34, 0x5D, 0x29, 0x28, 0x3F, 0x3A, 0x31, 0x5C, 0x64, 0x7B, - 0x32, 0x2C, 0x33, 0x7D, 0x7C, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x36, 0x2C, 0x37, 0x7D, 0x29, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, - 0x30, 0x7D, 0x32, 0x08, 0x32, 0x32, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x1A, - 0x28, 0x12, 0x10, 0x31, 0x5B, 0x30, 0x2D, 0x32, 0x35, 0x2D, 0x39, 0x5D, 0x5C, - 0x64, 0x7B, 0x37, 0x2C, 0x38, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x39, 0x2C, - 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x22, 0x1B, 0x12, 0x07, 0x38, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, - 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x38, 0x30, 0x31, 0x32, - 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x20, 0x12, 0x0C, 0x36, 0x30, 0x5B, 0x32, - 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, - 0x39, 0x7D, 0x32, 0x09, 0x36, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x1D, 0x12, - 0x07, 0x35, 0x30, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, - 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x35, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x42, 0x1D, 0x12, 0x07, 0x37, 0x30, 0x5C, 0x64, 0x7B, 0x38, 0x7D, - 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x37, 0x30, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x4A, 0x02, 0x4B, 0x52, 0x50, 0x52, - 0x5A, 0x18, 0x30, 0x30, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x32, 0x34, 0x2D, 0x36, - 0x38, 0x5D, 0x7C, 0x5B, 0x33, 0x37, 0x5D, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, - 0x62, 0x01, 0x30, 0x7A, 0x15, 0x30, 0x28, 0x38, 0x5B, 0x31, 0x2D, 0x34, 0x36, - 0x2D, 0x38, 0x5D, 0x7C, 0x38, 0x35, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x3F, - 0x90, 0x01, 0x00, 0x9A, 0x01, 0x72, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, - 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, - 0x1A, 0x1F, 0x31, 0x28, 0x3F, 0x3A, 0x30, 0x7C, 0x31, 0x5B, 0x31, 0x39, 0x5D, - 0x7C, 0x5B, 0x36, 0x39, 0x5D, 0x39, 0x7C, 0x35, 0x5B, 0x34, 0x35, 0x38, 0x5D, - 0x29, 0x7C, 0x5B, 0x35, 0x37, 0x5D, 0x30, 0x1A, 0x25, 0x31, 0x28, 0x3F, 0x3A, - 0x30, 0x7C, 0x31, 0x5B, 0x31, 0x39, 0x5D, 0x7C, 0x5B, 0x36, 0x39, 0x5D, 0x39, - 0x7C, 0x35, 0x28, 0x3F, 0x3A, 0x34, 0x34, 0x7C, 0x35, 0x39, 0x7C, 0x38, 0x29, - 0x29, 0x7C, 0x5B, 0x35, 0x37, 0x5D, 0x30, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, - 0x00, 0x30, 0x00, 0x9A, 0x01, 0x9A, 0x01, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, - 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, - 0x33, 0x1A, 0x31, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x36, 0x39, 0x5D, 0x5B, - 0x32, 0x2D, 0x38, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x7C, 0x35, 0x5B, 0x31, - 0x2D, 0x34, 0x5D, 0x29, 0x7C, 0x5B, 0x36, 0x38, 0x5D, 0x30, 0x7C, 0x5B, 0x33, - 0x2D, 0x36, 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5B, 0x32, 0x2D, 0x39, 0x5D, - 0x1A, 0x3B, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x36, 0x39, 0x5D, 0x5B, 0x32, - 0x2D, 0x38, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x7C, 0x35, 0x28, 0x3F, 0x3A, - 0x5B, 0x31, 0x2D, 0x33, 0x5D, 0x7C, 0x34, 0x5B, 0x35, 0x36, 0x5D, 0x29, 0x29, - 0x7C, 0x5B, 0x36, 0x38, 0x5D, 0x30, 0x7C, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, - 0x31, 0x2D, 0x39, 0x5D, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x32, 0x0A, 0x12, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, 0x1A, - 0x03, 0x31, 0x33, 0x31, 0x1A, 0x04, 0x31, 0x33, 0x31, 0x32, 0x22, 0x03, 0x30, - 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3A, 0x0A, 0x15, 0x28, 0x5C, - 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, - 0x2D, 0x24, 0x33, 0x1A, 0x03, 0x31, 0x33, 0x31, 0x1A, 0x09, 0x31, 0x33, 0x31, - 0x5B, 0x31, 0x33, 0x2D, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, - 0x30, 0x00, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x20, 0x24, 0x33, 0x1A, 0x07, 0x5B, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x30, 0x22, + 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3D, 0x0A, 0x1C, + 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, 0x1A, - 0x07, 0x31, 0x33, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, - 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x38, 0x0A, 0x1C, 0x28, 0x5C, 0x64, 0x7B, - 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x0B, - 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, 0x2D, 0x24, 0x34, 0x1A, 0x02, - 0x33, 0x30, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, - 0x6E, 0x0A, 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, - 0x24, 0x32, 0x2D, 0x24, 0x33, 0x1A, 0x12, 0x32, 0x28, 0x3F, 0x3A, 0x5B, 0x32, - 0x36, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x37, 0x5D, 0x29, 0x1A, - 0x31, 0x32, 0x28, 0x3F, 0x3A, 0x5B, 0x32, 0x36, 0x5D, 0x7C, 0x33, 0x28, 0x3F, - 0x3A, 0x30, 0x31, 0x7C, 0x31, 0x5B, 0x34, 0x35, 0x5D, 0x7C, 0x32, 0x5B, 0x31, - 0x37, 0x2D, 0x39, 0x5D, 0x7C, 0x33, 0x39, 0x7C, 0x34, 0x7C, 0x36, 0x5B, 0x36, - 0x37, 0x5D, 0x7C, 0x37, 0x5B, 0x30, 0x37, 0x38, 0x5D, 0x29, 0x29, 0x22, 0x03, - 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x8A, 0x01, 0x0A, 0x12, - 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, + 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, + 0x24, 0x34, 0x1A, 0x07, 0x5B, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x30, 0x22, 0x03, + 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x5C, 0x0A, 0x15, 0x28, + 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, + 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0B, 0x31, 0x31, 0x31, 0x7C, 0x32, 0x32, 0x32, + 0x7C, 0x33, 0x33, 0x33, 0x1A, 0x10, 0x28, 0x3F, 0x3A, 0x31, 0x31, 0x31, 0x7C, + 0x32, 0x32, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x29, 0x31, 0x1A, 0x11, 0x28, 0x3F, + 0x3A, 0x31, 0x31, 0x31, 0x7C, 0x32, 0x32, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x29, + 0x31, 0x31, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, + 0x54, 0x0A, 0x12, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x07, 0x32, 0x32, 0x32, 0x7C, 0x33, 0x33, + 0x33, 0x1A, 0x09, 0x32, 0x32, 0x32, 0x31, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x1A, + 0x0A, 0x32, 0x32, 0x32, 0x31, 0x32, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x1A, 0x0B, + 0x32, 0x32, 0x32, 0x31, 0x32, 0x30, 0x7C, 0x33, 0x33, 0x33, 0x32, 0x22, 0x03, + 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x30, 0x0A, 0x15, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, + 0x32, 0x20, 0x24, 0x33, 0x1A, 0x04, 0x5B, 0x32, 0x33, 0x5D, 0x22, 0x03, 0x30, + 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x25, 0x0A, 0x0E, 0x28, 0x5C, + 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, + 0x05, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x03, 0x30, 0x37, 0x37, 0x22, 0x03, + 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x1C, 0x0A, 0x07, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x03, 0x2A, 0x24, 0x31, 0x1A, 0x04, + 0x5B, 0x32, 0x33, 0x5D, 0x22, 0x02, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x12, + 0x12, 0x09, 0x5B, 0x32, 0x33, 0x5D, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x1A, 0x05, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xD0, 0x01, 0x01, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xE2, 0x0B, 0x0A, 0x1F, 0x12, 0x13, 0x5B, 0x31, + 0x2D, 0x37, 0x5D, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x39, 0x7D, 0x7C, 0x38, 0x5C, + 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, 0x2C, 0x31, 0x30, + 0x7D, 0x12, 0x4C, 0x12, 0x36, 0x28, 0x3F, 0x3A, 0x32, 0x7C, 0x5B, 0x33, 0x34, + 0x5D, 0x5B, 0x31, 0x2D, 0x33, 0x5D, 0x7C, 0x35, 0x5B, 0x31, 0x2D, 0x35, 0x5D, + 0x7C, 0x36, 0x5B, 0x31, 0x2D, 0x34, 0x5D, 0x29, 0x28, 0x3F, 0x3A, 0x31, 0x5C, + 0x64, 0x7B, 0x32, 0x2C, 0x33, 0x7D, 0x7C, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x36, 0x2C, 0x37, 0x7D, 0x29, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x34, + 0x2C, 0x31, 0x30, 0x7D, 0x32, 0x08, 0x32, 0x32, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x1A, 0x28, 0x12, 0x10, 0x31, 0x5B, 0x30, 0x2D, 0x32, 0x35, 0x2D, 0x39, + 0x5D, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x38, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, + 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x30, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x22, 0x1B, 0x12, 0x07, 0x38, 0x30, 0x5C, 0x64, 0x7B, + 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x38, 0x30, + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x20, 0x12, 0x0C, 0x36, 0x30, + 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, + 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x36, 0x30, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, + 0x1D, 0x12, 0x07, 0x35, 0x30, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x06, 0x5C, + 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x35, 0x30, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x42, 0x1D, 0x12, 0x07, 0x37, 0x30, 0x5C, 0x64, 0x7B, + 0x38, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x37, + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x4A, 0x02, 0x4B, 0x52, + 0x50, 0x52, 0x5A, 0x18, 0x30, 0x30, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x32, 0x34, + 0x2D, 0x36, 0x38, 0x5D, 0x7C, 0x5B, 0x33, 0x37, 0x5D, 0x5C, 0x64, 0x7B, 0x32, + 0x7D, 0x29, 0x62, 0x01, 0x30, 0x7A, 0x15, 0x30, 0x28, 0x38, 0x5B, 0x31, 0x2D, + 0x34, 0x36, 0x2D, 0x38, 0x5D, 0x7C, 0x38, 0x35, 0x5C, 0x64, 0x7B, 0x32, 0x7D, + 0x29, 0x3F, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x72, 0x0A, 0x15, 0x28, 0x5C, 0x64, + 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, - 0x24, 0x33, 0x1A, 0x16, 0x32, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x30, 0x2D, 0x33, - 0x35, 0x2D, 0x39, 0x5D, 0x7C, 0x5B, 0x34, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x29, - 0x1A, 0x49, 0x32, 0x28, 0x3F, 0x3A, 0x33, 0x28, 0x3F, 0x3A, 0x30, 0x5B, 0x30, - 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x31, 0x5B, 0x30, 0x2D, 0x33, 0x36, 0x2D, 0x39, - 0x5D, 0x7C, 0x32, 0x5B, 0x30, 0x32, 0x2D, 0x36, 0x5D, 0x7C, 0x33, 0x5B, 0x30, - 0x2D, 0x38, 0x5D, 0x7C, 0x36, 0x5B, 0x30, 0x2D, 0x35, 0x38, 0x39, 0x5D, 0x7C, - 0x37, 0x5B, 0x31, 0x2D, 0x36, 0x39, 0x5D, 0x7C, 0x5B, 0x35, 0x38, 0x39, 0x5D, - 0x29, 0x7C, 0x5B, 0x34, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x29, 0x22, 0x03, 0x30, - 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x49, 0x0A, 0x0B, 0x28, 0x5C, - 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, - 0x2D, 0x24, 0x32, 0x1A, 0x0A, 0x32, 0x31, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, - 0x39, 0x5D, 0x1A, 0x1E, 0x32, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x2D, 0x32, + 0x24, 0x33, 0x1A, 0x1F, 0x31, 0x28, 0x3F, 0x3A, 0x30, 0x7C, 0x31, 0x5B, 0x31, + 0x39, 0x5D, 0x7C, 0x5B, 0x36, 0x39, 0x5D, 0x39, 0x7C, 0x35, 0x5B, 0x34, 0x35, + 0x38, 0x5D, 0x29, 0x7C, 0x5B, 0x35, 0x37, 0x5D, 0x30, 0x1A, 0x25, 0x31, 0x28, + 0x3F, 0x3A, 0x30, 0x7C, 0x31, 0x5B, 0x31, 0x39, 0x5D, 0x7C, 0x5B, 0x36, 0x39, + 0x5D, 0x39, 0x7C, 0x35, 0x28, 0x3F, 0x3A, 0x34, 0x34, 0x7C, 0x35, 0x39, 0x7C, + 0x38, 0x29, 0x29, 0x7C, 0x5B, 0x35, 0x37, 0x5D, 0x30, 0x22, 0x03, 0x30, 0x24, + 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x9A, 0x01, 0x0A, 0x15, 0x28, 0x5C, + 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, + 0x2D, 0x24, 0x33, 0x1A, 0x31, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x36, 0x39, + 0x5D, 0x5B, 0x32, 0x2D, 0x38, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x7C, 0x35, + 0x5B, 0x31, 0x2D, 0x34, 0x5D, 0x29, 0x7C, 0x5B, 0x36, 0x38, 0x5D, 0x30, 0x7C, + 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5B, 0x32, 0x2D, + 0x39, 0x5D, 0x1A, 0x3B, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x36, 0x39, 0x5D, + 0x5B, 0x32, 0x2D, 0x38, 0x5D, 0x7C, 0x5B, 0x37, 0x38, 0x5D, 0x7C, 0x35, 0x28, + 0x3F, 0x3A, 0x5B, 0x31, 0x2D, 0x33, 0x5D, 0x7C, 0x34, 0x5B, 0x35, 0x36, 0x5D, + 0x29, 0x29, 0x7C, 0x5B, 0x36, 0x38, 0x5D, 0x30, 0x7C, 0x5B, 0x33, 0x2D, 0x36, + 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x22, 0x03, + 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x32, 0x0A, 0x12, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, + 0x33, 0x1A, 0x03, 0x31, 0x33, 0x31, 0x1A, 0x04, 0x31, 0x33, 0x31, 0x32, 0x22, + 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3A, 0x0A, 0x15, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, + 0x24, 0x32, 0x2D, 0x24, 0x33, 0x1A, 0x03, 0x31, 0x33, 0x31, 0x1A, 0x09, 0x31, + 0x33, 0x31, 0x5B, 0x31, 0x33, 0x2D, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, + 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x33, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, + 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, + 0x33, 0x1A, 0x07, 0x31, 0x33, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x22, 0x03, 0x30, + 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x38, 0x0A, 0x1C, 0x28, 0x5C, + 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x12, 0x0B, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, 0x2D, 0x24, 0x34, + 0x1A, 0x02, 0x33, 0x30, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, + 0x9A, 0x01, 0x6E, 0x0A, 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, + 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, + 0x31, 0x2D, 0x24, 0x32, 0x2D, 0x24, 0x33, 0x1A, 0x12, 0x32, 0x28, 0x3F, 0x3A, + 0x5B, 0x32, 0x36, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x37, 0x5D, + 0x29, 0x1A, 0x31, 0x32, 0x28, 0x3F, 0x3A, 0x5B, 0x32, 0x36, 0x5D, 0x7C, 0x33, + 0x28, 0x3F, 0x3A, 0x30, 0x31, 0x7C, 0x31, 0x5B, 0x34, 0x35, 0x5D, 0x7C, 0x32, + 0x5B, 0x31, 0x37, 0x2D, 0x39, 0x5D, 0x7C, 0x33, 0x39, 0x7C, 0x34, 0x7C, 0x36, + 0x5B, 0x36, 0x37, 0x5D, 0x7C, 0x37, 0x5B, 0x30, 0x37, 0x38, 0x5D, 0x29, 0x29, + 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x8A, 0x01, + 0x0A, 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, + 0x32, 0x2D, 0x24, 0x33, 0x1A, 0x16, 0x32, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x30, + 0x2D, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x7C, 0x5B, 0x34, 0x35, 0x37, 0x2D, 0x39, + 0x5D, 0x29, 0x1A, 0x49, 0x32, 0x28, 0x3F, 0x3A, 0x33, 0x28, 0x3F, 0x3A, 0x30, + 0x5B, 0x30, 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x31, 0x5B, 0x30, 0x2D, 0x33, 0x36, + 0x2D, 0x39, 0x5D, 0x7C, 0x32, 0x5B, 0x30, 0x32, 0x2D, 0x36, 0x5D, 0x7C, 0x33, + 0x5B, 0x30, 0x2D, 0x38, 0x5D, 0x7C, 0x36, 0x5B, 0x30, 0x2D, 0x35, 0x38, 0x39, + 0x5D, 0x7C, 0x37, 0x5B, 0x31, 0x2D, 0x36, 0x39, 0x5D, 0x7C, 0x5B, 0x35, 0x38, + 0x39, 0x5D, 0x29, 0x7C, 0x5B, 0x34, 0x35, 0x37, 0x2D, 0x39, 0x5D, 0x29, 0x22, + 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x49, 0x0A, 0x0B, + 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, + 0x24, 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x0A, 0x32, 0x31, 0x5B, 0x30, 0x2D, 0x34, + 0x36, 0x2D, 0x39, 0x5D, 0x1A, 0x1E, 0x32, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, + 0x2D, 0x32, 0x34, 0x37, 0x2D, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x31, 0x32, 0x34, + 0x5D, 0x7C, 0x36, 0x5B, 0x31, 0x32, 0x36, 0x39, 0x5D, 0x29, 0x22, 0x03, 0x30, + 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3F, 0x0A, 0x0B, 0x28, 0x5C, + 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, + 0x2D, 0x24, 0x32, 0x1A, 0x06, 0x32, 0x31, 0x5B, 0x33, 0x36, 0x5D, 0x1A, 0x18, + 0x32, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x30, 0x33, 0x35, 0x2D, 0x39, 0x5D, + 0x7C, 0x36, 0x5B, 0x30, 0x33, 0x2D, 0x35, 0x37, 0x38, 0x5D, 0x29, 0x22, 0x03, + 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x6F, 0x0A, 0x0E, 0x28, + 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, + 0x12, 0x05, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x0B, 0x5B, 0x33, 0x2D, 0x36, + 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x1A, 0x17, 0x5B, 0x33, 0x2D, 0x36, + 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x2D, + 0x34, 0x36, 0x2D, 0x39, 0x5D, 0x29, 0x1A, 0x27, 0x5B, 0x33, 0x2D, 0x36, 0x5D, + 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x37, 0x2D, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x31, 0x32, 0x34, 0x5D, 0x7C, 0x36, 0x5B, 0x31, 0x32, 0x36, 0x39, 0x5D, 0x29, 0x22, 0x03, 0x30, 0x24, 0x31, - 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x3F, 0x0A, 0x0B, 0x28, 0x5C, 0x64, 0x29, - 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x2D, 0x24, - 0x32, 0x1A, 0x06, 0x32, 0x31, 0x5B, 0x33, 0x36, 0x5D, 0x1A, 0x18, 0x32, 0x31, - 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x30, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x7C, 0x36, - 0x5B, 0x30, 0x33, 0x2D, 0x35, 0x37, 0x38, 0x5D, 0x29, 0x22, 0x03, 0x30, 0x24, - 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x6F, 0x0A, 0x0E, 0x28, 0x5C, 0x64, - 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x12, 0x05, - 0x24, 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x0B, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, - 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x1A, 0x17, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, - 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x2D, 0x34, 0x36, - 0x2D, 0x39, 0x5D, 0x29, 0x1A, 0x27, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, - 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x37, - 0x2D, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x31, 0x32, 0x34, 0x5D, 0x7C, 0x36, 0x5B, - 0x31, 0x32, 0x36, 0x39, 0x5D, 0x29, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, - 0x30, 0x00, 0x9A, 0x01, 0x61, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x2D, - 0x24, 0x32, 0x1A, 0x0B, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, 0x2D, 0x39, - 0x5D, 0x31, 0x1A, 0x0F, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, 0x2D, 0x39, - 0x5D, 0x31, 0x5B, 0x33, 0x36, 0x5D, 0x1A, 0x21, 0x5B, 0x33, 0x2D, 0x36, 0x5D, - 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x30, 0x33, - 0x35, 0x2D, 0x39, 0x5D, 0x7C, 0x36, 0x5B, 0x30, 0x33, 0x2D, 0x35, 0x37, 0x38, - 0x5D, 0x29, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x0A, 0xA2, 0x07, 0x0A, 0x19, 0x12, 0x0D, 0x5B, 0x31, 0x2D, - 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x08, 0x5C, - 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x31, 0x7D, 0x12, 0x16, 0x12, 0x0A, 0x5B, 0x32, - 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, - 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x11, 0x12, 0x07, 0x31, 0x5C, 0x64, 0x7B, - 0x31, 0x30, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x31, 0x7D, 0x22, 0x12, - 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, - 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x2A, 0x12, 0x12, 0x08, 0x39, 0x30, 0x30, 0x5C, - 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x4D, 0x58, 0x50, 0x34, 0x5A, 0x02, 0x30, 0x30, - 0x62, 0x02, 0x30, 0x31, 0x7A, 0x11, 0x30, 0x31, 0x7C, 0x30, 0x34, 0x5B, 0x34, - 0x35, 0x5D, 0x28, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x29, 0x82, 0x01, 0x03, - 0x31, 0x24, 0x31, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x34, 0x0A, 0x15, 0x28, 0x5C, - 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x1A, 0x06, 0x5B, 0x38, 0x39, 0x5D, 0x30, 0x30, 0x22, 0x05, - 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0x9A, 0x01, 0x36, 0x0A, - 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, - 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x08, 0x33, 0x33, 0x7C, 0x35, 0x35, - 0x7C, 0x38, 0x31, 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, - 0x01, 0x9A, 0x01, 0x56, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, - 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, - 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x28, - 0x5B, 0x32, 0x34, 0x36, 0x37, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, 0x34, - 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, 0x5D, - 0x7C, 0x38, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x39, 0x5B, 0x31, 0x2D, 0x39, - 0x5D, 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0x9A, - 0x01, 0x3F, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, - 0x7D, 0x29, 0x12, 0x0C, 0x30, 0x34, 0x35, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, - 0x20, 0x24, 0x34, 0x1A, 0x0D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x33, 0x7C, 0x35, - 0x35, 0x7C, 0x38, 0x31, 0x29, 0x22, 0x02, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, - 0x9A, 0x01, 0x5B, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, - 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x34, 0x7D, 0x29, 0x12, 0x0C, 0x30, 0x34, 0x35, 0x20, 0x24, 0x32, 0x20, 0x24, - 0x33, 0x20, 0x24, 0x34, 0x1A, 0x29, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x32, - 0x34, 0x35, 0x37, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x2D, - 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, 0x5D, 0x7C, - 0x38, 0x5B, 0x30, 0x32, 0x2D, 0x39, 0x5D, 0x29, 0x22, 0x02, 0x24, 0x31, 0x2A, - 0x00, 0x30, 0x01, 0xA2, 0x01, 0x34, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, + 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x61, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, + 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, + 0x31, 0x2D, 0x24, 0x32, 0x1A, 0x0B, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, + 0x2D, 0x39, 0x5D, 0x31, 0x1A, 0x0F, 0x5B, 0x33, 0x2D, 0x36, 0x5D, 0x5B, 0x31, + 0x2D, 0x39, 0x5D, 0x31, 0x5B, 0x33, 0x36, 0x5D, 0x1A, 0x21, 0x5B, 0x33, 0x2D, + 0x36, 0x5D, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x5B, + 0x30, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x7C, 0x36, 0x5B, 0x30, 0x33, 0x2D, 0x35, + 0x37, 0x38, 0x5D, 0x29, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, + 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xA2, 0x07, 0x0A, 0x19, 0x12, 0x0D, 0x5B, + 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x1A, + 0x08, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x31, 0x7D, 0x12, 0x16, 0x12, 0x0A, + 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x08, 0x5C, + 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x11, 0x12, 0x07, 0x31, 0x5C, + 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x31, 0x7D, + 0x22, 0x12, 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, + 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x2A, 0x12, 0x12, 0x08, 0x39, 0x30, + 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, + 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x4D, 0x58, 0x50, 0x34, 0x5A, 0x02, + 0x30, 0x30, 0x62, 0x02, 0x30, 0x31, 0x7A, 0x11, 0x30, 0x31, 0x7C, 0x30, 0x34, + 0x5B, 0x34, 0x35, 0x5D, 0x28, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x29, 0x82, + 0x01, 0x03, 0x31, 0x24, 0x31, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x34, 0x0A, 0x15, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x06, 0x5B, 0x38, 0x39, 0x5D, 0x30, 0x30, + 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0x9A, 0x01, + 0x36, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, + 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x08, 0x33, 0x33, 0x7C, + 0x35, 0x35, 0x7C, 0x38, 0x31, 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, + 0x00, 0x30, 0x01, 0x9A, 0x01, 0x56, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, - 0x1A, 0x06, 0x5B, 0x38, 0x39, 0x5D, 0x30, 0x30, 0x22, 0x05, 0x30, 0x31, 0x20, - 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, 0x36, 0x0A, 0x15, 0x28, 0x5C, - 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x1A, 0x08, 0x33, 0x33, 0x7C, 0x35, 0x35, 0x7C, 0x38, 0x31, - 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, - 0x56, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, - 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x28, 0x5B, 0x32, 0x34, - 0x36, 0x37, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x2D, 0x39, 0x5D, - 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, 0x5D, 0x7C, 0x38, 0x5B, - 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x39, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x22, 0x05, - 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, 0x36, 0x0A, - 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, - 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, - 0x0D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x33, 0x7C, 0x35, 0x35, 0x7C, 0x38, 0x31, - 0x29, 0xA2, 0x01, 0x52, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, - 0x33, 0x20, 0x24, 0x34, 0x1A, 0x29, 0x31, 0x28, 0x3F, 0x3A, 0x5B, 0x31, 0x32, - 0x34, 0x35, 0x37, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x2D, + 0x1A, 0x28, 0x5B, 0x32, 0x34, 0x36, 0x37, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, + 0x32, 0x34, 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, + 0x39, 0x5D, 0x7C, 0x38, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x39, 0x5B, 0x31, + 0x2D, 0x39, 0x5D, 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, + 0x01, 0x9A, 0x01, 0x3F, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, + 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x0C, 0x30, 0x34, 0x35, 0x20, 0x24, 0x32, 0x20, + 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x0D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x33, + 0x7C, 0x35, 0x35, 0x7C, 0x38, 0x31, 0x29, 0x22, 0x02, 0x24, 0x31, 0x2A, 0x00, + 0x30, 0x01, 0x9A, 0x01, 0x5B, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x0C, 0x30, 0x34, 0x35, 0x20, 0x24, 0x32, + 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x29, 0x31, 0x28, 0x3F, 0x3A, 0x5B, + 0x31, 0x32, 0x34, 0x35, 0x37, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, + 0x34, 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, + 0x5D, 0x7C, 0x38, 0x5B, 0x30, 0x32, 0x2D, 0x39, 0x5D, 0x29, 0x22, 0x02, 0x24, + 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, 0x34, 0x0A, 0x15, 0x28, 0x5C, 0x64, + 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, + 0x24, 0x33, 0x1A, 0x06, 0x5B, 0x38, 0x39, 0x5D, 0x30, 0x30, 0x22, 0x05, 0x30, + 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, 0x36, 0x0A, 0x15, + 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x08, 0x33, 0x33, 0x7C, 0x35, 0x35, 0x7C, + 0x38, 0x31, 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, + 0xA2, 0x01, 0x56, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x28, 0x5B, + 0x32, 0x34, 0x36, 0x37, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, 0x34, 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, 0x5D, 0x7C, - 0x38, 0x5B, 0x30, 0x32, 0x2D, 0x39, 0x5D, 0x29, 0xAA, 0x01, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x0A, 0xEF, 0x03, 0x0A, 0x23, 0x12, 0x17, 0x5B, 0x32, 0x38, 0x39, 0x5D, 0x5C, - 0x64, 0x7B, 0x37, 0x2C, 0x39, 0x7D, 0x7C, 0x5B, 0x33, 0x2D, 0x37, 0x5D, 0x5C, - 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x30, - 0x7D, 0x12, 0x3C, 0x12, 0x31, 0x32, 0x34, 0x30, 0x39, 0x39, 0x5C, 0x64, 0x7B, - 0x33, 0x7D, 0x7C, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x32, 0x2D, 0x37, 0x39, 0x5D, - 0x7C, 0x5B, 0x34, 0x37, 0x39, 0x5D, 0x5B, 0x32, 0x2D, 0x36, 0x38, 0x39, 0x5D, - 0x7C, 0x36, 0x5B, 0x32, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x29, 0x5C, 0x64, 0x7B, - 0x36, 0x7D, 0x1A, 0x07, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x38, 0x7D, 0x1A, 0x5E, - 0x12, 0x52, 0x32, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x32, 0x37, 0x5D, 0x5C, 0x64, - 0x7B, 0x37, 0x7D, 0x7C, 0x39, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x37, 0x7D, 0x7C, - 0x31, 0x28, 0x3F, 0x3A, 0x30, 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x37, 0x7D, 0x7C, - 0x5B, 0x31, 0x32, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x36, 0x7D, 0x7C, 0x5B, - 0x33, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, 0x29, 0x7C, 0x34, 0x5B, - 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x7C, 0x38, 0x5C, 0x64, - 0x7B, 0x37, 0x2C, 0x38, 0x7D, 0x29, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x38, 0x2C, - 0x31, 0x30, 0x7D, 0x22, 0x16, 0x12, 0x0A, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, + 0x38, 0x5B, 0x32, 0x2D, 0x39, 0x5D, 0x7C, 0x39, 0x5B, 0x31, 0x2D, 0x39, 0x5D, + 0x22, 0x05, 0x30, 0x31, 0x20, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, + 0x36, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, + 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, + 0x34, 0x1A, 0x0D, 0x31, 0x28, 0x3F, 0x3A, 0x33, 0x33, 0x7C, 0x35, 0x35, 0x7C, + 0x38, 0x31, 0x29, 0xA2, 0x01, 0x52, 0x0A, 0x18, 0x28, 0x31, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, + 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x1A, 0x29, 0x31, 0x28, 0x3F, 0x3A, 0x5B, + 0x31, 0x32, 0x34, 0x35, 0x37, 0x39, 0x5D, 0x7C, 0x33, 0x5B, 0x30, 0x2D, 0x32, + 0x34, 0x2D, 0x39, 0x5D, 0x7C, 0x35, 0x5B, 0x30, 0x2D, 0x34, 0x36, 0x2D, 0x39, + 0x5D, 0x7C, 0x38, 0x5B, 0x30, 0x32, 0x2D, 0x39, 0x5D, 0x29, 0xAA, 0x01, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x0A, 0xEF, 0x03, 0x0A, 0x23, 0x12, 0x17, 0x5B, 0x32, 0x38, 0x39, + 0x5D, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x39, 0x7D, 0x7C, 0x5B, 0x33, 0x2D, 0x37, + 0x5D, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x37, 0x2C, + 0x31, 0x30, 0x7D, 0x12, 0x3C, 0x12, 0x31, 0x32, 0x34, 0x30, 0x39, 0x39, 0x5C, + 0x64, 0x7B, 0x33, 0x7D, 0x7C, 0x28, 0x3F, 0x3A, 0x33, 0x5B, 0x32, 0x2D, 0x37, + 0x39, 0x5D, 0x7C, 0x5B, 0x34, 0x37, 0x39, 0x5D, 0x5B, 0x32, 0x2D, 0x36, 0x38, + 0x39, 0x5D, 0x7C, 0x36, 0x5B, 0x32, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x29, 0x5C, + 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x07, 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x38, 0x7D, + 0x1A, 0x5E, 0x12, 0x52, 0x32, 0x28, 0x3F, 0x3A, 0x5B, 0x30, 0x32, 0x37, 0x5D, + 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x7C, 0x39, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x37, + 0x7D, 0x7C, 0x31, 0x28, 0x3F, 0x3A, 0x30, 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x37, + 0x7D, 0x7C, 0x5B, 0x31, 0x32, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x2C, 0x36, 0x7D, + 0x7C, 0x5B, 0x33, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x35, 0x7D, 0x29, 0x7C, + 0x34, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x7C, 0x38, + 0x5C, 0x64, 0x7B, 0x37, 0x2C, 0x38, 0x7D, 0x29, 0x1A, 0x08, 0x5C, 0x64, 0x7B, + 0x38, 0x2C, 0x31, 0x30, 0x7D, 0x22, 0x16, 0x12, 0x0A, 0x38, 0x30, 0x30, 0x5C, + 0x64, 0x7B, 0x36, 0x2C, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x39, 0x2C, + 0x31, 0x30, 0x7D, 0x2A, 0x16, 0x12, 0x0A, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x36, 0x2C, 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, - 0x7D, 0x2A, 0x16, 0x12, 0x0A, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x36, 0x2C, - 0x37, 0x7D, 0x1A, 0x08, 0x5C, 0x64, 0x7B, 0x39, 0x2C, 0x31, 0x30, 0x7D, 0x32, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x4E, 0x5A, 0x50, 0x40, 0x5A, 0x02, 0x30, 0x30, - 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x33, 0x0A, - 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x1A, 0x0A, 0x32, 0x34, 0x7C, 0x5B, 0x33, 0x34, 0x36, 0x37, - 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, - 0x31, 0x0A, 0x14, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x35, 0x7D, 0x29, 0x12, 0x08, 0x24, - 0x31, 0x2D, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x06, 0x32, 0x5B, 0x31, 0x37, - 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, - 0x32, 0x0A, 0x17, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, 0x7D, 0x29, - 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x04, 0x5B, - 0x38, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, - 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0x8D, 0x02, 0x0A, 0x13, 0x12, 0x0A, 0x5B, 0x31, - 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, - 0x39, 0x7D, 0x12, 0x13, 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, - 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x28, 0x12, - 0x1F, 0x28, 0x3F, 0x3A, 0x35, 0x5B, 0x30, 0x31, 0x5D, 0x7C, 0x36, 0x5B, 0x30, - 0x36, 0x39, 0x5D, 0x7C, 0x37, 0x5B, 0x32, 0x38, 0x39, 0x5D, 0x7C, 0x38, 0x38, - 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, - 0x22, 0x11, 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, - 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x2A, 0x10, 0x12, 0x07, 0x37, 0x30, 0x5C, - 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x4A, 0x02, 0x50, 0x4C, 0x50, 0x30, 0x5A, 0x02, 0x30, 0x30, 0x62, - 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x34, 0x0A, 0x1C, - 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, - 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, - 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, - 0x24, 0x34, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x0A, 0xE2, 0x02, 0x0A, 0x13, 0x12, 0x0A, 0x5B, 0x32, 0x36, - 0x38, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, - 0x7D, 0x12, 0x1C, 0x12, 0x08, 0x32, 0x36, 0x32, 0x5C, 0x64, 0x7B, 0x36, 0x7D, - 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x32, 0x36, 0x32, 0x31, - 0x36, 0x31, 0x32, 0x33, 0x34, 0x1A, 0x26, 0x12, 0x12, 0x36, 0x28, 0x3F, 0x3A, - 0x39, 0x5B, 0x32, 0x33, 0x5D, 0x7C, 0x34, 0x37, 0x29, 0x5C, 0x64, 0x7B, 0x36, - 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x36, 0x39, 0x32, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x22, 0x1B, 0x12, 0x07, 0x38, 0x30, 0x5C, - 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, - 0x38, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x38, 0x12, 0x24, - 0x38, 0x28, 0x3F, 0x3A, 0x31, 0x5B, 0x30, 0x31, 0x5D, 0x7C, 0x32, 0x5B, 0x30, - 0x31, 0x35, 0x36, 0x5D, 0x7C, 0x38, 0x34, 0x7C, 0x39, 0x5B, 0x30, 0x2D, 0x33, - 0x37, 0x2D, 0x39, 0x5D, 0x29, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, - 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x38, 0x31, 0x30, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x52, 0x45, 0x50, 0x86, 0x02, - 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, - 0x9A, 0x01, 0x39, 0x0A, 0x21, 0x28, 0x5B, 0x32, 0x36, 0x38, 0x5D, 0x5C, 0x64, - 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x12, - 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, 0x34, 0x22, - 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xBA, 0x01, 0x13, 0x32, 0x36, 0x32, 0x7C, - 0x36, 0x28, 0x3F, 0x3A, 0x39, 0x5B, 0x32, 0x33, 0x5D, 0x7C, 0x34, 0x37, 0x29, - 0x7C, 0x38, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xF0, 0x02, 0x0A, - 0x22, 0x12, 0x0F, 0x5B, 0x31, 0x33, 0x36, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x7C, - 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, 0x12, 0x12, 0x12, 0x09, - 0x5B, 0x33, 0x36, 0x5D, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, - 0x7B, 0x38, 0x7D, 0x1A, 0x12, 0x12, 0x09, 0x5B, 0x38, 0x39, 0x5D, 0x5C, 0x64, - 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x22, 0x17, 0x12, - 0x0A, 0x31, 0x3F, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x09, - 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, 0x2A, 0x13, 0x12, 0x09, - 0x31, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, - 0x7B, 0x31, 0x31, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x4E, 0x5A, 0x50, 0x40, 0x5A, 0x02, + 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, + 0x33, 0x0A, 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x2D, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x0A, 0x32, 0x34, 0x7C, 0x5B, 0x33, 0x34, + 0x36, 0x37, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, + 0x9A, 0x01, 0x31, 0x0A, 0x14, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, + 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x35, 0x7D, 0x29, 0x12, + 0x08, 0x24, 0x31, 0x2D, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x06, 0x32, 0x5B, + 0x31, 0x37, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, + 0x9A, 0x01, 0x32, 0x0A, 0x17, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x2C, 0x34, + 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, + 0x04, 0x5B, 0x38, 0x39, 0x5D, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, + 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, + 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, + 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0x8D, 0x02, 0x0A, 0x13, 0x12, 0x0A, + 0x5B, 0x31, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, + 0x64, 0x7B, 0x39, 0x7D, 0x12, 0x13, 0x12, 0x0A, 0x5B, 0x31, 0x2D, 0x39, 0x5D, + 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, + 0x28, 0x12, 0x1F, 0x28, 0x3F, 0x3A, 0x35, 0x5B, 0x30, 0x31, 0x5D, 0x7C, 0x36, + 0x5B, 0x30, 0x36, 0x39, 0x5D, 0x7C, 0x37, 0x5B, 0x32, 0x38, 0x39, 0x5D, 0x7C, + 0x38, 0x38, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, + 0x39, 0x7D, 0x22, 0x11, 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x36, + 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x2A, 0x10, 0x12, 0x07, 0x37, + 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, + 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x50, 0x4C, 0x50, 0x30, 0x5A, 0x02, 0x30, + 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, 0x01, 0x00, 0x9A, 0x01, 0x34, + 0x0A, 0x1C, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, + 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x32, 0x7D, 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, + 0x33, 0x20, 0x24, 0x34, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, + 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xE2, 0x02, 0x0A, 0x13, 0x12, 0x0A, 0x5B, + 0x32, 0x36, 0x38, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, + 0x7B, 0x39, 0x7D, 0x12, 0x1C, 0x12, 0x08, 0x32, 0x36, 0x32, 0x5C, 0x64, 0x7B, + 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x32, 0x36, + 0x32, 0x31, 0x36, 0x31, 0x32, 0x33, 0x34, 0x1A, 0x26, 0x12, 0x12, 0x36, 0x28, + 0x3F, 0x3A, 0x39, 0x5B, 0x32, 0x33, 0x5D, 0x7C, 0x34, 0x37, 0x29, 0x5C, 0x64, + 0x7B, 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x36, + 0x39, 0x32, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x22, 0x1B, 0x12, 0x07, 0x38, + 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, + 0x32, 0x09, 0x38, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x38, + 0x12, 0x24, 0x38, 0x28, 0x3F, 0x3A, 0x31, 0x5B, 0x30, 0x31, 0x5D, 0x7C, 0x32, + 0x5B, 0x30, 0x31, 0x35, 0x36, 0x5D, 0x7C, 0x38, 0x34, 0x7C, 0x39, 0x5B, 0x30, + 0x2D, 0x33, 0x37, 0x2D, 0x39, 0x5D, 0x29, 0x5C, 0x64, 0x7B, 0x36, 0x7D, 0x1A, + 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x38, 0x31, 0x30, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, - 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x53, 0x47, 0x50, - 0x41, 0x5A, 0x0B, 0x30, 0x5B, 0x30, 0x2D, 0x33, 0x5D, 0x5B, 0x30, 0x2D, 0x39, - 0x5D, 0x7A, 0x06, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x90, 0x01, 0x00, 0x9A, - 0x01, 0x2B, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, 0x1A, - 0x0C, 0x5B, 0x33, 0x36, 0x39, 0x5D, 0x7C, 0x38, 0x5B, 0x31, 0x2D, 0x39, 0x5D, - 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x2E, 0x0A, 0x15, 0x28, 0x5C, - 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x1A, 0x05, 0x31, 0x5B, 0x38, 0x39, 0x5D, 0x22, 0x00, 0x2A, - 0x00, 0x30, 0x00, 0x9A, 0x01, 0x2C, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, - 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, - 0x1A, 0x03, 0x38, 0x30, 0x30, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x0A, 0xFB, 0x03, 0x0A, 0x3B, 0x12, 0x1C, 0x5B, 0x31, 0x33, - 0x2D, 0x36, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x7C, 0x32, 0x5B, - 0x30, 0x2D, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, - 0x0F, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x28, 0x3F, 0x3A, 0x5C, 0x64, 0x7B, 0x33, - 0x7D, 0x29, 0x3F, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - 0x39, 0x30, 0x12, 0x3B, 0x12, 0x1C, 0x5B, 0x31, 0x33, 0x2D, 0x36, 0x38, 0x39, - 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x7C, 0x32, 0x5B, 0x30, 0x2D, 0x33, 0x35, - 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, - 0x37, 0x7D, 0x28, 0x3F, 0x3A, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x3F, 0x32, - 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x1A, 0x3B, - 0x12, 0x1C, 0x5B, 0x31, 0x33, 0x2D, 0x36, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, - 0x39, 0x7D, 0x7C, 0x32, 0x5B, 0x30, 0x2D, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x5C, - 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x28, 0x3F, - 0x3A, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x3F, 0x32, 0x0A, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x22, 0x2B, 0x12, 0x15, 0x38, 0x28, - 0x3F, 0x3A, 0x30, 0x30, 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, 0x38, 0x38, - 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, - 0x7D, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, - 0x2A, 0x1E, 0x12, 0x08, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, - 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x52, 0x45, 0x50, + 0x86, 0x02, 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, 0x90, + 0x01, 0x00, 0x9A, 0x01, 0x39, 0x0A, 0x21, 0x28, 0x5B, 0x32, 0x36, 0x38, 0x5D, + 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x32, 0x7D, + 0x29, 0x12, 0x0B, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x20, 0x24, + 0x34, 0x22, 0x03, 0x30, 0x24, 0x31, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xBA, 0x01, 0x13, 0x32, 0x36, + 0x32, 0x7C, 0x36, 0x28, 0x3F, 0x3A, 0x39, 0x5B, 0x32, 0x33, 0x5D, 0x7C, 0x34, + 0x37, 0x29, 0x7C, 0x38, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xF0, + 0x02, 0x0A, 0x22, 0x12, 0x0F, 0x5B, 0x31, 0x33, 0x36, 0x38, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x37, 0x2C, 0x31, 0x30, 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, 0x38, + 0x7D, 0x7C, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, 0x12, 0x12, + 0x12, 0x09, 0x5B, 0x33, 0x36, 0x5D, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, + 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x12, 0x12, 0x09, 0x5B, 0x38, 0x39, 0x5D, + 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x22, + 0x17, 0x12, 0x0A, 0x31, 0x3F, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, + 0x1A, 0x09, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x2C, 0x31, 0x31, 0x7D, 0x2A, 0x13, + 0x12, 0x09, 0x31, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, + 0x5C, 0x64, 0x7B, 0x31, 0x31, 0x7D, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x55, - 0x53, 0x50, 0x01, 0x5A, 0x03, 0x30, 0x31, 0x31, 0x62, 0x01, 0x31, 0x6A, 0x07, - 0x20, 0x65, 0x78, 0x74, 0x6E, 0x2E, 0x20, 0x7A, 0x01, 0x31, 0x90, 0x01, 0x01, - 0x9A, 0x01, 0x1D, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x22, 0x00, 0x2A, 0x00, 0x30, 0x01, 0x9A, 0x01, 0x27, 0x0A, 0x15, 0x28, 0x5C, - 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, - 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, - 0x20, 0x24, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, 0x27, 0x0A, - 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, - 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, - 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x01, 0xAA, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xB0, 0x01, 0x01, - 0xC2, 0x01, 0x1E, 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, 0x7D, - 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x32, 0x33, - 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x80, 0x02, 0x01, 0x0A, 0xE6, 0x01, 0x0A, 0x13, 0x12, 0x0A, - 0x5B, 0x32, 0x36, 0x38, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, - 0x64, 0x7B, 0x39, 0x7D, 0x12, 0x22, 0x12, 0x0E, 0x32, 0x36, 0x39, 0x36, 0x5B, - 0x30, 0x2D, 0x34, 0x5D, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x1A, 0x05, 0x5C, 0x64, - 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x32, 0x36, 0x39, 0x36, 0x30, 0x31, 0x32, 0x33, - 0x34, 0x1A, 0x1C, 0x12, 0x08, 0x36, 0x33, 0x39, 0x5C, 0x64, 0x7B, 0x36, 0x7D, - 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x36, 0x33, 0x39, 0x31, - 0x32, 0x33, 0x34, 0x35, 0x36, 0x22, 0x1B, 0x12, 0x07, 0x38, 0x30, 0x5C, 0x64, - 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x38, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, - 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x59, 0x54, - 0x50, 0x86, 0x02, 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, 0x01, 0x30, - 0x90, 0x01, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xBA, 0x01, 0x07, 0x32, 0x36, 0x39, 0x7C, 0x36, 0x33, 0x39, 0xC2, 0x01, + 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, 0x53, + 0x47, 0x50, 0x41, 0x5A, 0x0B, 0x30, 0x5B, 0x30, 0x2D, 0x33, 0x5D, 0x5B, 0x30, + 0x2D, 0x39, 0x5D, 0x7A, 0x06, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x90, 0x01, + 0x00, 0x9A, 0x01, 0x2B, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, + 0x32, 0x1A, 0x0C, 0x5B, 0x33, 0x36, 0x39, 0x5D, 0x7C, 0x38, 0x5B, 0x31, 0x2D, + 0x39, 0x5D, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x2E, 0x0A, 0x15, + 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x1A, 0x05, 0x31, 0x5B, 0x38, 0x39, 0x5D, 0x22, + 0x00, 0x2A, 0x00, 0x30, 0x00, 0x9A, 0x01, 0x2C, 0x0A, 0x15, 0x28, 0x5C, 0x64, + 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, + 0x24, 0x33, 0x1A, 0x03, 0x38, 0x30, 0x30, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, + 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xE0, 0x01, 0x0A, 0x18, 0x12, 0x05, 0x5C, - 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x32, 0x08, - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x12, 0x12, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x1A, 0x12, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, - 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x22, 0x18, 0x12, 0x05, - 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x32, - 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x2A, 0x08, 0x12, 0x02, - 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x03, 0x30, - 0x30, 0x31, 0x50, 0xA0, 0x06, 0x5A, 0x00, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x1D, - 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, - 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, 0x22, 0x00, 0x2A, - 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, - 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xD0, 0x01, 0x01, - 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xE8, - 0x01, 0x0A, 0x19, 0x12, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x05, 0x5C, - 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x12, 0x13, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, - 0x09, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x1A, 0x13, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, - 0x4E, 0x41, 0x2A, 0x19, 0x12, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, 0x05, - 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, - 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, 0x08, 0x12, - 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x03, 0x30, 0x30, 0x31, 0x50, - 0xD3, 0x07, 0x5A, 0x00, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x24, 0x0A, 0x12, 0x28, - 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, 0x64, - 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, - 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, - 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, - 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, - 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41 + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xFB, 0x03, 0x0A, 0x3B, 0x12, 0x1C, 0x5B, + 0x31, 0x33, 0x2D, 0x36, 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x7C, + 0x32, 0x5B, 0x30, 0x2D, 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, + 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x28, 0x3F, 0x3A, 0x5C, 0x64, + 0x7B, 0x33, 0x7D, 0x29, 0x3F, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x37, 0x38, 0x39, 0x30, 0x12, 0x3B, 0x12, 0x1C, 0x5B, 0x31, 0x33, 0x2D, 0x36, + 0x38, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x7C, 0x32, 0x5B, 0x30, 0x2D, + 0x33, 0x35, 0x2D, 0x39, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x0F, 0x5C, + 0x64, 0x7B, 0x37, 0x7D, 0x28, 0x3F, 0x3A, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, + 0x3F, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, + 0x1A, 0x3B, 0x12, 0x1C, 0x5B, 0x31, 0x33, 0x2D, 0x36, 0x38, 0x39, 0x5D, 0x5C, + 0x64, 0x7B, 0x39, 0x7D, 0x7C, 0x32, 0x5B, 0x30, 0x2D, 0x33, 0x35, 0x2D, 0x39, + 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x0F, 0x5C, 0x64, 0x7B, 0x37, 0x7D, + 0x28, 0x3F, 0x3A, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x3F, 0x32, 0x0A, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x22, 0x2B, 0x12, 0x15, + 0x38, 0x28, 0x3F, 0x3A, 0x30, 0x30, 0x7C, 0x36, 0x36, 0x7C, 0x37, 0x37, 0x7C, + 0x38, 0x38, 0x29, 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, + 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + 0x39, 0x30, 0x2A, 0x1E, 0x12, 0x08, 0x39, 0x30, 0x30, 0x5C, 0x64, 0x7B, 0x37, + 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x32, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, + 0x02, 0x55, 0x53, 0x50, 0x01, 0x5A, 0x03, 0x30, 0x31, 0x31, 0x62, 0x01, 0x31, + 0x6A, 0x07, 0x20, 0x65, 0x78, 0x74, 0x6E, 0x2E, 0x20, 0x7A, 0x01, 0x31, 0x90, + 0x01, 0x01, 0x9A, 0x01, 0x1D, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x01, 0x9A, 0x01, 0x27, 0x0A, 0x15, + 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, + 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, + 0x24, 0x32, 0x20, 0x24, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x01, 0xA2, 0x01, + 0x27, 0x0A, 0x15, 0x28, 0x5C, 0x64, 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, + 0x7B, 0x33, 0x7D, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, + 0x24, 0x31, 0x20, 0x24, 0x32, 0x20, 0x24, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, + 0x01, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xB0, + 0x01, 0x01, 0xC2, 0x01, 0x1E, 0x12, 0x08, 0x38, 0x30, 0x30, 0x5C, 0x64, 0x7B, + 0x37, 0x7D, 0x1A, 0x06, 0x5C, 0x64, 0x7B, 0x31, 0x30, 0x7D, 0x32, 0x0A, 0x31, + 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0xCA, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x80, 0x02, 0x01, 0x0A, 0xE6, 0x01, 0x0A, 0x13, + 0x12, 0x0A, 0x5B, 0x32, 0x36, 0x38, 0x5D, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, + 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x12, 0x22, 0x12, 0x0E, 0x32, 0x36, 0x39, + 0x36, 0x5B, 0x30, 0x2D, 0x34, 0x5D, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x1A, 0x05, + 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x32, 0x36, 0x39, 0x36, 0x30, 0x31, + 0x32, 0x33, 0x34, 0x1A, 0x1C, 0x12, 0x08, 0x36, 0x33, 0x39, 0x5C, 0x64, 0x7B, + 0x36, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x36, 0x33, + 0x39, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x22, 0x1B, 0x12, 0x07, 0x38, 0x30, + 0x5C, 0x64, 0x7B, 0x37, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, + 0x09, 0x38, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x2A, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x02, + 0x59, 0x54, 0x50, 0x86, 0x02, 0x5A, 0x02, 0x30, 0x30, 0x62, 0x01, 0x30, 0x7A, + 0x01, 0x30, 0x90, 0x01, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xBA, 0x01, 0x07, 0x32, 0x36, 0x39, 0x7C, 0x36, 0x33, 0x39, + 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x0A, 0xE0, 0x01, 0x0A, 0x18, 0x12, + 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, + 0x32, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x12, 0x12, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x1A, 0x12, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x32, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x22, 0x18, + 0x12, 0x05, 0x5C, 0x64, 0x7B, 0x38, 0x7D, 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x38, + 0x7D, 0x32, 0x08, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x2A, 0x08, + 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x42, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, + 0x03, 0x30, 0x30, 0x31, 0x50, 0xA0, 0x06, 0x5A, 0x00, 0x90, 0x01, 0x01, 0x9A, + 0x01, 0x1D, 0x0A, 0x0E, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, 0x5C, + 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x05, 0x24, 0x31, 0x20, 0x24, 0x32, 0x22, + 0x00, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xD0, + 0x01, 0x01, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, + 0x0A, 0xE8, 0x01, 0x0A, 0x19, 0x12, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x1A, + 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x12, 0x13, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x1A, + 0x13, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x32, 0x09, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x22, 0x08, 0x12, 0x02, 0x4E, 0x41, + 0x1A, 0x02, 0x4E, 0x41, 0x2A, 0x19, 0x12, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, + 0x1A, 0x05, 0x5C, 0x64, 0x7B, 0x39, 0x7D, 0x32, 0x09, 0x31, 0x32, 0x33, 0x34, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x32, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, + 0x4E, 0x41, 0x3A, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x42, + 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0x4A, 0x03, 0x30, 0x30, + 0x31, 0x50, 0xD3, 0x07, 0x5A, 0x00, 0x90, 0x01, 0x01, 0x9A, 0x01, 0x24, 0x0A, + 0x12, 0x28, 0x5C, 0x64, 0x29, 0x28, 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x28, + 0x5C, 0x64, 0x7B, 0x34, 0x7D, 0x29, 0x12, 0x08, 0x24, 0x31, 0x20, 0x24, 0x32, + 0x20, 0x24, 0x33, 0x22, 0x00, 0x2A, 0x00, 0x30, 0x00, 0xAA, 0x01, 0x08, 0x12, + 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xC2, 0x01, 0x08, 0x12, 0x02, 0x4E, + 0x41, 0x1A, 0x02, 0x4E, 0x41, 0xCA, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, + 0x02, 0x4E, 0x41, 0xE2, 0x01, 0x08, 0x12, 0x02, 0x4E, 0x41, 0x1A, 0x02, 0x4E, + 0x41 }; } // namespace diff --git a/cpp/test/phonenumbers/shortnumberinfo_test.cc b/cpp/test/phonenumbers/shortnumberinfo_test.cc index 27a75ab75..94df9d37c 100644 --- a/cpp/test/phonenumbers/shortnumberinfo_test.cc +++ b/cpp/test/phonenumbers/shortnumberinfo_test.cc @@ -22,8 +22,10 @@ #include +#include "phonenumbers/base/logging.h" #include "phonenumbers/default_logger.h" #include "phonenumbers/phonenumberutil.h" +#include "phonenumbers/stringutil.h" #include "phonenumbers/test_util.h" namespace i18n { @@ -31,10 +33,19 @@ namespace phonenumbers { class ShortNumberInfoTest : public testing::Test { protected: + PhoneNumber ParseNumberForTesting(const string& number, + const string& region_code) { + PhoneNumber phone_number; + CHECK_EQ(phone_util_.Parse(number, region_code, &phone_number), + PhoneNumberUtil::NO_PARSING_ERROR); + return phone_number; + } + ShortNumberInfoTest() : short_info_() { PhoneNumberUtil::GetInstance()->SetLogger(new StdoutLogger()); } + const PhoneNumberUtil phone_util_; const ShortNumberInfo short_info_; private: @@ -46,15 +57,13 @@ TEST_F(ShortNumberInfoTest, IsPossibleShortNumber) { possible_number.set_country_code(33); possible_number.set_national_number(123456ULL); EXPECT_TRUE(short_info_.IsPossibleShortNumber(possible_number)); - EXPECT_TRUE(short_info_.IsPossibleShortNumberForRegion("123456", - RegionCode::FR())); + EXPECT_TRUE(short_info_.IsPossibleShortNumberForRegion( + ParseNumberForTesting("123456", RegionCode::FR()), RegionCode::FR())); PhoneNumber impossible_number; impossible_number.set_country_code(33); impossible_number.set_national_number(9ULL); EXPECT_FALSE(short_info_.IsPossibleShortNumber(impossible_number)); - EXPECT_FALSE(short_info_.IsPossibleShortNumberForRegion("9", - RegionCode::FR())); // Note that GB and GG share the country calling code 44, and that this // number is possible but not valid. @@ -69,15 +78,15 @@ TEST_F(ShortNumberInfoTest, IsValidShortNumber) { valid_number.set_country_code(33); valid_number.set_national_number(1010ULL); EXPECT_TRUE(short_info_.IsValidShortNumber(valid_number)); - EXPECT_TRUE(short_info_.IsValidShortNumberForRegion("1010", - RegionCode::FR())); + EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("1010", RegionCode::FR()), RegionCode::FR())); PhoneNumber invalid_number; invalid_number.set_country_code(33); invalid_number.set_national_number(123456ULL); EXPECT_FALSE(short_info_.IsValidShortNumber(invalid_number)); - EXPECT_FALSE(short_info_.IsValidShortNumberForRegion("123456", - RegionCode::FR())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("123456", RegionCode::FR()), RegionCode::FR())); // Note that GB and GG share the country calling code 44. PhoneNumber shared_number; @@ -90,71 +99,80 @@ TEST_F(ShortNumberInfoTest, GetExpectedCost) { uint64 national_number; const string& premium_rate_example = short_info_.GetExampleShortNumberForCost( - RegionCode::FR(), ShortNumberInfo::ShortNumberCost::PREMIUM_RATE); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::PREMIUM_RATE, - short_info_.GetExpectedCostForRegion(premium_rate_example, - RegionCode::FR())); + RegionCode::FR(), ShortNumberInfo::PREMIUM_RATE); + EXPECT_EQ(ShortNumberInfo::PREMIUM_RATE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(premium_rate_example, RegionCode::FR()), + RegionCode::FR())); PhoneNumber premium_rate_number; premium_rate_number.set_country_code(33); safe_strtou64(premium_rate_example, &national_number); premium_rate_number.set_national_number(national_number); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::PREMIUM_RATE, + EXPECT_EQ(ShortNumberInfo::PREMIUM_RATE, short_info_.GetExpectedCost(premium_rate_number)); const string& standard_rate_example = short_info_.GetExampleShortNumberForCost( - RegionCode::FR(), ShortNumberInfo::ShortNumberCost::STANDARD_RATE); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::STANDARD_RATE, - short_info_.GetExpectedCostForRegion(standard_rate_example, - RegionCode::FR())); + RegionCode::FR(), ShortNumberInfo::STANDARD_RATE); + EXPECT_EQ(ShortNumberInfo::STANDARD_RATE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(standard_rate_example, RegionCode::FR()), + RegionCode::FR())); PhoneNumber standard_rate_number; standard_rate_number.set_country_code(33); safe_strtou64(standard_rate_example, &national_number); standard_rate_number.set_national_number(national_number); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::STANDARD_RATE, + EXPECT_EQ(ShortNumberInfo::STANDARD_RATE, short_info_.GetExpectedCost(standard_rate_number)); const string& toll_free_example = short_info_.GetExampleShortNumberForCost( - RegionCode::FR(), ShortNumberInfo::ShortNumberCost::TOLL_FREE); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion(toll_free_example, - RegionCode::FR())); + RegionCode::FR(), ShortNumberInfo::TOLL_FREE); + EXPECT_EQ(ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(toll_free_example, RegionCode::FR()), + RegionCode::FR())); PhoneNumber toll_free_number; toll_free_number.set_country_code(33); safe_strtou64(toll_free_example, &national_number); toll_free_number.set_national_number(national_number); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, + EXPECT_EQ(ShortNumberInfo::TOLL_FREE, short_info_.GetExpectedCost(toll_free_number)); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion("12345", RegionCode::FR())); + EXPECT_EQ( + ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("12345", RegionCode::FR()), RegionCode::FR())); PhoneNumber unknown_cost_number; unknown_cost_number.set_country_code(33); unknown_cost_number.set_national_number(12345ULL); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, short_info_.GetExpectedCost(unknown_cost_number)); // Test that an invalid number may nevertheless have a cost other than // UNKNOWN_COST. - EXPECT_FALSE(short_info_.IsValidShortNumberForRegion("116123", - RegionCode::FR())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion("116123", RegionCode::FR())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("116123", RegionCode::FR()), RegionCode::FR())); + EXPECT_EQ( + ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("116123", RegionCode::FR()), RegionCode::FR())); PhoneNumber invalid_number; invalid_number.set_country_code(33); invalid_number.set_national_number(116123ULL); EXPECT_FALSE(short_info_.IsValidShortNumber(invalid_number)); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, + EXPECT_EQ(ShortNumberInfo::TOLL_FREE, short_info_.GetExpectedCost(invalid_number)); // Test a nonexistent country code. - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion("911", RegionCode::ZZ())); + EXPECT_EQ( + ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("911", RegionCode::US()), RegionCode::ZZ())); unknown_cost_number.Clear(); unknown_cost_number.set_country_code(123); unknown_cost_number.set_national_number(911ULL); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, short_info_.GetExpectedCost(unknown_cost_number)); } @@ -181,43 +199,64 @@ TEST_F(ShortNumberInfoTest, GetExpectedCostForSharedCountryCallingCode) { EXPECT_TRUE(short_info_.IsValidShortNumber(ambiguous_toll_free_number)); EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( - ambiguous_premium_rate_string, RegionCode::AU())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::PREMIUM_RATE, - short_info_.GetExpectedCostForRegion(ambiguous_premium_rate_string, - RegionCode::AU())); + ParseNumberForTesting(ambiguous_premium_rate_string, RegionCode::AU()), + RegionCode::AU())); + EXPECT_EQ(ShortNumberInfo::PREMIUM_RATE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_premium_rate_string, + RegionCode::AU()), + RegionCode::AU())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( - ambiguous_premium_rate_string, RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion(ambiguous_premium_rate_string, - RegionCode::CX())); + ParseNumberForTesting(ambiguous_premium_rate_string, RegionCode::CX()), + RegionCode::CX())); + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_premium_rate_string, + RegionCode::CX()), + RegionCode::CX())); // PREMIUM_RATE takes precedence over UNKNOWN_COST. - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::PREMIUM_RATE, + EXPECT_EQ(ShortNumberInfo::PREMIUM_RATE, short_info_.GetExpectedCost(ambiguous_premium_rate_number)); EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( - ambiguous_standard_rate_string, RegionCode::AU())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::STANDARD_RATE, - short_info_.GetExpectedCostForRegion(ambiguous_standard_rate_string, - RegionCode::AU())); + ParseNumberForTesting(ambiguous_standard_rate_string, RegionCode::AU()), + RegionCode::AU())); + EXPECT_EQ(ShortNumberInfo::STANDARD_RATE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_standard_rate_string, + RegionCode::AU()), + RegionCode::AU())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( - ambiguous_standard_rate_string, RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion(ambiguous_standard_rate_string, - RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, + ParseNumberForTesting(ambiguous_standard_rate_string, RegionCode::CX()), + RegionCode::CX())); + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_standard_rate_string, + RegionCode::CX()), + RegionCode::CX())); + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, short_info_.GetExpectedCost(ambiguous_standard_rate_number)); EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( - ambiguous_toll_free_string, RegionCode::AU())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion(ambiguous_toll_free_string, + ParseNumberForTesting(ambiguous_toll_free_string, RegionCode::AU()), + RegionCode::AU())); + EXPECT_EQ( + ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_toll_free_string, RegionCode::AU()), RegionCode::AU())); + EXPECT_FALSE(short_info_.IsValidShortNumberForRegion( - ambiguous_toll_free_string, RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion(ambiguous_toll_free_string, + ParseNumberForTesting(ambiguous_toll_free_string, RegionCode::CX()), + RegionCode::CX())); + EXPECT_EQ( + ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting(ambiguous_toll_free_string, RegionCode::CX()), RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, + EXPECT_EQ(ShortNumberInfo::UNKNOWN_COST, short_info_.GetExpectedCost(ambiguous_toll_free_number)); } @@ -231,15 +270,15 @@ TEST_F(ShortNumberInfoTest, GetExampleShortNumber) { TEST_F(ShortNumberInfoTest, GetExampleShortNumberForCost) { EXPECT_EQ("3010", short_info_.GetExampleShortNumberForCost(RegionCode::FR(), - ShortNumberInfo::ShortNumberCost::TOLL_FREE)); + ShortNumberInfo::TOLL_FREE)); EXPECT_EQ("1023", short_info_.GetExampleShortNumberForCost(RegionCode::FR(), - ShortNumberInfo::ShortNumberCost::STANDARD_RATE)); + ShortNumberInfo::STANDARD_RATE)); EXPECT_EQ("42000", short_info_.GetExampleShortNumberForCost(RegionCode::FR(), - ShortNumberInfo::ShortNumberCost::PREMIUM_RATE)); + ShortNumberInfo::PREMIUM_RATE)); EXPECT_EQ("", short_info_.GetExampleShortNumberForCost(RegionCode::FR(), - ShortNumberInfo::ShortNumberCost::UNKNOWN_COST)); + ShortNumberInfo::UNKNOWN_COST)); } TEST_F(ShortNumberInfoTest, ConnectsToEmergencyNumber_US) { @@ -380,18 +419,26 @@ TEST_F(ShortNumberInfoTest, EmergencyNumberForSharedCountryCallingCode) { // Test the emergency number 112, which is valid in both Australia and the // Christmas Islands. EXPECT_TRUE(short_info_.IsEmergencyNumber("112", RegionCode::AU())); - EXPECT_TRUE(short_info_.IsValidShortNumberForRegion("112", RegionCode::AU())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion("112", RegionCode::AU())); + EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("112", RegionCode::AU()), RegionCode::AU())); + EXPECT_EQ( + ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("112", RegionCode::AU()), RegionCode::AU())); + EXPECT_TRUE(short_info_.IsEmergencyNumber("112", RegionCode::CX())); - EXPECT_TRUE(short_info_.IsValidShortNumberForRegion("112", RegionCode::CX())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion("112", RegionCode::CX())); + EXPECT_TRUE(short_info_.IsValidShortNumberForRegion( + ParseNumberForTesting("112", RegionCode::CX()), RegionCode::CX())); + EXPECT_EQ( + ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("112", RegionCode::CX()), RegionCode::CX())); + PhoneNumber shared_emergency_number; shared_emergency_number.set_country_code(61); shared_emergency_number.set_national_number(112ULL); EXPECT_TRUE(short_info_.IsValidShortNumber(shared_emergency_number)); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, + EXPECT_EQ(ShortNumberInfo::TOLL_FREE, short_info_.GetExpectedCost(shared_emergency_number)); } @@ -399,14 +446,22 @@ TEST_F(ShortNumberInfoTest, OverlappingNANPANumber) { // 211 is an emergency number in Barbados, while it is a toll-free // information line in Canada and the USA. EXPECT_TRUE(short_info_.IsEmergencyNumber("211", RegionCode::BB())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::TOLL_FREE, - short_info_.GetExpectedCostForRegion("211", RegionCode::BB())); + EXPECT_EQ( + ShortNumberInfo::TOLL_FREE, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("211", RegionCode::BB()), RegionCode::BB())); + EXPECT_FALSE(short_info_.IsEmergencyNumber("211", RegionCode::US())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion("211", RegionCode::US())); + EXPECT_EQ( + ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("211", RegionCode::US()), RegionCode::US())); + EXPECT_FALSE(short_info_.IsEmergencyNumber("211", RegionCode::CA())); - EXPECT_EQ(ShortNumberInfo::ShortNumberCost::UNKNOWN_COST, - short_info_.GetExpectedCostForRegion("211", RegionCode::CA())); + EXPECT_EQ( + ShortNumberInfo::UNKNOWN_COST, + short_info_.GetExpectedCostForRegion( + ParseNumberForTesting("211", RegionCode::CA()), RegionCode::CA())); } } // namespace phonenumbers diff --git a/cpp/test/phonenumbers/test_util.h b/cpp/test/phonenumbers/test_util.h index 717f27f6d..a15531343 100644 --- a/cpp/test/phonenumbers/test_util.h +++ b/cpp/test/phonenumbers/test_util.h @@ -57,6 +57,10 @@ class RegionCode { return "AE"; } + static const char* AM() { + return "AM"; + } + static const char* AO() { return "AO"; } @@ -73,6 +77,10 @@ class RegionCode { return "AU"; } + static const char* BB() { + return "BB"; + } + static const char* BR() { return "BR"; } @@ -105,6 +113,10 @@ class RegionCode { return "CS"; } + static const char* CX() { + return "CX"; + } + static const char* DE() { return "DE"; } diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java index ae4727cb9..401d260d7 100644 --- a/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/ShortNumberInfo.java @@ -16,13 +16,18 @@ package com.google.i18n.phonenumbers; +import com.google.i18n.phonenumbers.internal.MatcherApi; +import com.google.i18n.phonenumbers.internal.RegexBasedMatcher; import com.google.i18n.phonenumbers.Phonemetadata.PhoneMetadata; import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.logging.Level; import java.util.logging.Logger; @@ -40,7 +45,7 @@ public class ShortNumberInfo { private static final Logger logger = Logger.getLogger(ShortNumberInfo.class.getName()); private static final ShortNumberInfo INSTANCE = - new ShortNumberInfo(PhoneNumberUtil.getInstance()); + new ShortNumberInfo(RegexBasedMatcher.create()); // In these countries, if extra digits are added to an emergency number, it no longer connects // to the emergency service. @@ -65,11 +70,34 @@ public class ShortNumberInfo { return INSTANCE; } - private final PhoneNumberUtil phoneUtil; + // MatcherApi supports the basic matching method for checking if a given national number matches + // a national number patten or a possible number patten defined in the given + // {@code PhoneNumberDesc}. + private final MatcherApi matcherApi; + + // A mapping from a country calling code to the region codes which denote the region represented + // by that country calling code. In the case of multiple regions sharing a calling code, such as + // the NANPA regions, the one indicated with "isMainCountryForCode" in the metadata should be + // first. + private final Map> countryCallingCodeToRegionCodeMap; // @VisibleForTesting - ShortNumberInfo(PhoneNumberUtil util) { - phoneUtil = util; + ShortNumberInfo(MatcherApi matcherApi) { + this.matcherApi = matcherApi; + // TODO: Create ShortNumberInfo for a given map + this.countryCallingCodeToRegionCodeMap = + CountryCodeToRegionCodeMap.getCountryCodeToRegionCodeMap(); + } + + /** + * Returns a list with the region codes that match the specific country calling code. For + * non-geographical country calling codes, the region code 001 is returned. Also, in the case + * of no region code being found, an empty list is returned. + */ + private List getRegionCodesForCountryCode(int countryCallingCode) { + List regionCodes = countryCallingCodeToRegionCodeMap.get(countryCallingCode); + return Collections.unmodifiableList(regionCodes == null ? new ArrayList(0) + : regionCodes); } /** @@ -80,32 +108,55 @@ public class ShortNumberInfo { * @param shortNumber the short number to check as a string * @param regionDialingFrom the region from which the number is dialed * @return whether the number is a possible short number + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #isPossibleShortNumberForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. */ + @Deprecated public boolean isPossibleShortNumberForRegion(String shortNumber, String regionDialingFrom) { PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); if (phoneMetadata == null) { return false; } - PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc(); - return phoneUtil.isNumberPossibleForDesc(shortNumber, generalDesc); + return matcherApi.matchesPossibleNumber(shortNumber, phoneMetadata.getGeneralDesc()); + } + + /** + * Check whether a short number is a possible number when dialed from the given region. This + * provides a more lenient check than {@link #isValidShortNumberForRegion}. + * + * @param number the short number to check + * @param regionDialingFrom the region from which the number is dialed + * @return whether the number is a possible short number + */ + public boolean isPossibleShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + return matcherApi.matchesPossibleNumber(getNationalSignificantNumber(number), + phoneMetadata.getGeneralDesc()); } /** * Check whether a short number is a possible number. If a country calling code is shared by * multiple regions, this returns true if it's possible in any of them. This provides a more * lenient check than {@link #isValidShortNumber}. See {@link - * #isPossibleShortNumberForRegion(String, String)} for details. + * #isPossibleShortNumberForRegion(PhoneNumber, String)} for details. * * @param number the short number to check * @return whether the number is a possible short number */ public boolean isPossibleShortNumber(PhoneNumber number) { - List regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode()); - String shortNumber = phoneUtil.getNationalSignificantNumber(number); + List regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); + String shortNumber = getNationalSignificantNumber(number); for (String region : regionCodes) { PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(region); - if (phoneUtil.isNumberPossibleForDesc(shortNumber, phoneMetadata.getGeneralDesc())) { + if (matcherApi.matchesPossibleNumber(shortNumber, phoneMetadata.getGeneralDesc())) { return true; } } @@ -120,7 +171,13 @@ public class ShortNumberInfo { * @param shortNumber the short number to check as a string * @param regionDialingFrom the region from which the number is dialed * @return whether the short number matches a valid pattern + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #isValidShortNumberForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. */ + @Deprecated public boolean isValidShortNumberForRegion(String shortNumber, String regionDialingFrom) { PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); @@ -128,38 +185,55 @@ public class ShortNumberInfo { return false; } PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc(); - if (!generalDesc.hasNationalNumberPattern() || - !phoneUtil.isNumberMatchingDesc(shortNumber, generalDesc)) { + if (!matchesPossibleNumberAndNationalNumber(shortNumber, generalDesc)) { return false; } PhoneNumberDesc shortNumberDesc = phoneMetadata.getShortCode(); - if (!shortNumberDesc.hasNationalNumberPattern()) { - logger.log(Level.WARNING, "No short code national number pattern found for region: " + - regionDialingFrom); + return matchesPossibleNumberAndNationalNumber(shortNumber, shortNumberDesc); + } + + /** + * Tests whether a short number matches a valid pattern in a region. Note that this doesn't verify + * the number is actually in use, which is impossible to tell by just looking at the number + * itself. + * + * @param number the short number for which we want to test the validity + * @param regionDialingFrom the region from which the number is dialed + * @return whether the short number matches a valid pattern + */ + public boolean isValidShortNumberForRegion(PhoneNumber number, String regionDialingFrom) { + PhoneMetadata phoneMetadata = + MetadataManager.getShortNumberMetadataForRegion(regionDialingFrom); + if (phoneMetadata == null) { + return false; + } + String shortNumber = getNationalSignificantNumber(number); + PhoneNumberDesc generalDesc = phoneMetadata.getGeneralDesc(); + if (!matchesPossibleNumberAndNationalNumber(shortNumber, generalDesc)) { return false; } - return phoneUtil.isNumberMatchingDesc(shortNumber, shortNumberDesc); + PhoneNumberDesc shortNumberDesc = phoneMetadata.getShortCode(); + return matchesPossibleNumberAndNationalNumber(shortNumber, shortNumberDesc); } /** * Tests whether a short number matches a valid pattern. If a country calling code is shared by * multiple regions, this returns true if it's valid in any of them. Note that this doesn't verify * the number is actually in use, which is impossible to tell by just looking at the number - * itself. See {@link #isValidShortNumberForRegion(String, String)} for details. + * itself. See {@link #isValidShortNumberForRegion(PhoneNumber, String)} for details. * * @param number the short number for which we want to test the validity * @return whether the short number matches a valid pattern */ public boolean isValidShortNumber(PhoneNumber number) { - List regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode()); - String shortNumber = phoneUtil.getNationalSignificantNumber(number); + List regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes); if (regionCodes.size() > 1 && regionCode != null) { // If a matching region had been found for the phone number from among two or more regions, // then we have already implicitly verified its validity for that region. return true; } - return isValidShortNumberForRegion(shortNumber, regionCode); + return isValidShortNumberForRegion(number, regionCode); } /** @@ -183,7 +257,13 @@ public class ShortNumberInfo { * @return the expected cost category for that region of the short number. Returns UNKNOWN_COST if * the number does not match a cost category. Note that an invalid number may match any cost * category. + * @deprecated Anyone who was using it and passing in a string with whitespace (or other + * formatting characters) would have been getting the wrong result. You should parse + * the string to PhoneNumber and use the method + * {@code #getExpectedCostForRegion(PhoneNumber, String)}. This method will be + * removed in the next release. */ + @Deprecated public ShortNumberCost getExpectedCostForRegion(String shortNumber, String regionDialingFrom) { // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion( @@ -194,13 +274,64 @@ public class ShortNumberInfo { // The cost categories are tested in order of decreasing expense, since if for some reason the // patterns overlap the most expensive matching cost category should be returned. - if (phoneUtil.isNumberMatchingDesc(shortNumber, phoneMetadata.getPremiumRate())) { + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getPremiumRate())) { + return ShortNumberCost.PREMIUM_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getStandardRate())) { + return ShortNumberCost.STANDARD_RATE; + } + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getTollFree())) { + return ShortNumberCost.TOLL_FREE; + } + if (isEmergencyNumber(shortNumber, regionDialingFrom)) { + // Emergency numbers are implicitly toll-free. + return ShortNumberCost.TOLL_FREE; + } + return ShortNumberCost.UNKNOWN_COST; + } + + /** + * Gets the expected cost category of a short number when dialed from a region (however, nothing + * is implied about its validity). If it is important that the number is valid, then its validity + * must first be checked using {@link #isValidShortNumberForRegion}. Note that emergency numbers + * are always considered toll-free. Example usage: + *
{@code
+   * // The region for which the number was parsed and the region we subsequently check against
+   * // need not be the same. Here we parse the number in the US and check it for Canada.
+   * PhoneNumber number = phoneUtil.parse("110", "US");
+   * ...
+   * String regionCode = "CA";
+   * ShortNumberInfo shortInfo = ShortNumberInfo.getInstance();
+   * if (shortInfo.isValidShortNumberForRegion(shortNumber, regionCode)) {
+   *   ShortNumberCost cost = shortInfo.getExpectedCostForRegion(number, regionCode);
+   *   // Do something with the cost information here.
+   * }}
+ * + * @param number the short number for which we want to know the expected cost category + * @param regionDialingFrom the region from which the number is dialed + * @return the expected cost category for that region of the short number. Returns UNKNOWN_COST if + * the number does not match a cost category. Note that an invalid number may match any cost + * category. + */ + public ShortNumberCost getExpectedCostForRegion(PhoneNumber number, String regionDialingFrom) { + // Note that regionDialingFrom may be null, in which case phoneMetadata will also be null. + PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion( + regionDialingFrom); + if (phoneMetadata == null) { + return ShortNumberCost.UNKNOWN_COST; + } + + String shortNumber = getNationalSignificantNumber(number); + + // The cost categories are tested in order of decreasing expense, since if for some reason the + // patterns overlap the most expensive matching cost category should be returned. + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getPremiumRate())) { return ShortNumberCost.PREMIUM_RATE; } - if (phoneUtil.isNumberMatchingDesc(shortNumber, phoneMetadata.getStandardRate())) { + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getStandardRate())) { return ShortNumberCost.STANDARD_RATE; } - if (phoneUtil.isNumberMatchingDesc(shortNumber, phoneMetadata.getTollFree())) { + if (matchesPossibleNumberAndNationalNumber(shortNumber, phoneMetadata.getTollFree())) { return ShortNumberCost.TOLL_FREE; } if (isEmergencyNumber(shortNumber, regionDialingFrom)) { @@ -213,36 +344,35 @@ public class ShortNumberInfo { /** * Gets the expected cost category of a short number (however, nothing is implied about its * validity). If the country calling code is unique to a region, this method behaves exactly the - * same as {@link #getExpectedCostForRegion(String, String)}. However, if the country calling - * code is shared by multiple regions, then it returns the highest cost in the sequence + * same as {@link #getExpectedCostForRegion(PhoneNumber, String)}. However, if the country + * calling code is shared by multiple regions, then it returns the highest cost in the sequence * PREMIUM_RATE, UNKNOWN_COST, STANDARD_RATE, TOLL_FREE. The reason for the position of * UNKNOWN_COST in this order is that if a number is UNKNOWN_COST in one region but STANDARD_RATE * or TOLL_FREE in another, its expected cost cannot be estimated as one of the latter since it * might be a PREMIUM_RATE number. - * - * For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in Canada, the expected cost - * returned by this method will be STANDARD_RATE, since the NANPA countries share the same country - * calling code. - * + *

+ * For example, if a number is STANDARD_RATE in the US, but TOLL_FREE in Canada, the expected + * cost returned by this method will be STANDARD_RATE, since the NANPA countries share the same + * country calling code. + *

* Note: If the region from which the number is dialed is known, it is highly preferable to call - * {@link #getExpectedCostForRegion(String, String)} instead. + * {@link #getExpectedCostForRegion(PhoneNumber, String)} instead. * * @param number the short number for which we want to know the expected cost category * @return the highest expected cost category of the short number in the region(s) with the given * country calling code */ public ShortNumberCost getExpectedCost(PhoneNumber number) { - List regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode()); + List regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); if (regionCodes.size() == 0) { return ShortNumberCost.UNKNOWN_COST; } - String shortNumber = phoneUtil.getNationalSignificantNumber(number); if (regionCodes.size() == 1) { - return getExpectedCostForRegion(shortNumber, regionCodes.get(0)); + return getExpectedCostForRegion(number, regionCodes.get(0)); } ShortNumberCost cost = ShortNumberCost.TOLL_FREE; for (String regionCode : regionCodes) { - ShortNumberCost costForRegion = getExpectedCostForRegion(shortNumber, regionCode); + ShortNumberCost costForRegion = getExpectedCostForRegion(number, regionCode); switch (costForRegion) { case PREMIUM_RATE: return ShortNumberCost.PREMIUM_RATE; @@ -274,11 +404,11 @@ public class ShortNumberInfo { } else if (regionCodes.size() == 1) { return regionCodes.get(0); } - String nationalNumber = phoneUtil.getNationalSignificantNumber(number); + String nationalNumber = getNationalSignificantNumber(number); for (String regionCode : regionCodes) { PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); - if (phoneMetadata != null && - phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getShortCode())) { + if (phoneMetadata != null + && matchesPossibleNumberAndNationalNumber(nationalNumber, phoneMetadata.getShortCode())) { // The number is valid for this region. return regionCode; } @@ -349,11 +479,14 @@ public class ShortNumberInfo { } /** - * Returns true if the number might be used to connect to an emergency service in the given - * region. - * - * This method takes into account cases where the number might contain formatting, or might have - * additional digits appended (when it is okay to do that in the region specified). + * Returns true if the given number, exactly as dialed, might be used to connect to an emergency + * service in the given region. + *

+ * This method accepts a string, rather than a PhoneNumber, because it needs to distinguish + * cases such as "+1 911" and "911", where the former may not connect to an emergency service in + * all cases but the latter would. This method takes into account cases where the number might + * contain formatting, or might have additional digits appended (when it is okay to do that in + * the specified region). * * @param number the phone number to test * @param regionCode the region where the phone number is being dialed @@ -364,10 +497,12 @@ public class ShortNumberInfo { } /** - * Returns true if the number exactly matches an emergency service number in the given region. - * + * Returns true if the given number exactly matches an emergency service number in the given + * region. + *

* This method takes into account cases where the number might contain formatting, but doesn't - * allow additional digits to be appended. + * allow additional digits to be appended. Note that {@code isEmergencyNumber(number, region)} + * implies {@code connectsToEmergencyNumber(number, region)}. * * @param number the phone number to test * @param regionCode the region where the phone number is being dialed @@ -390,12 +525,13 @@ public class ShortNumberInfo { if (metadata == null || !metadata.hasEmergency()) { return false; } - Pattern emergencyNumberPattern = - Pattern.compile(metadata.getEmergency().getNationalNumberPattern()); + String normalizedNumber = PhoneNumberUtil.normalizeDigitsOnly(number); - return (!allowPrefixMatch || REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.contains(regionCode)) - ? emergencyNumberPattern.matcher(normalizedNumber).matches() - : emergencyNumberPattern.matcher(normalizedNumber).lookingAt(); + PhoneNumberDesc emergencyDesc = metadata.getEmergency(); + boolean allowPrefixMatchForRegion = + allowPrefixMatch && !REGIONS_WHERE_EMERGENCY_NUMBERS_MUST_BE_EXACT.contains(regionCode); + return matcherApi.matchesNationalNumber(normalizedNumber, emergencyDesc, + allowPrefixMatchForRegion); } /** @@ -409,11 +545,43 @@ public class ShortNumberInfo { * number). */ public boolean isCarrierSpecific(PhoneNumber number) { - List regionCodes = phoneUtil.getRegionCodesForCountryCode(number.getCountryCode()); + List regionCodes = getRegionCodesForCountryCode(number.getCountryCode()); String regionCode = getRegionCodeForShortNumberFromRegionList(number, regionCodes); - String nationalNumber = phoneUtil.getNationalSignificantNumber(number); + String nationalNumber = getNationalSignificantNumber(number); PhoneMetadata phoneMetadata = MetadataManager.getShortNumberMetadataForRegion(regionCode); - return (phoneMetadata != null) && - (phoneUtil.isNumberMatchingDesc(nationalNumber, phoneMetadata.getCarrierSpecific())); + return (phoneMetadata != null) + && (matchesPossibleNumberAndNationalNumber(nationalNumber, + phoneMetadata.getCarrierSpecific())); + } + + /** + * Gets the national significant number of the a phone number. Note a national significant number + * doesn't contain a national prefix or any formatting. + *

+ * This is a temporary duplicate of the {@code getNationalSignificantNumber} method from + * {@code PhoneNumberUtil}. Ultimately a canonical static version should exist in a separate + * utility class (to prevent {@code ShortNumberInfo} needing to depend on PhoneNumberUtil). + * + * @param number the phone number for which the national significant number is needed + * @return the national significant number of the PhoneNumber object passed in + */ + private static String getNationalSignificantNumber(PhoneNumber number) { + // If leading zero(s) have been set, we prefix this now. Note this is not a national prefix. + StringBuilder nationalNumber = new StringBuilder(); + if (number.isItalianLeadingZero()) { + char[] zeros = new char[number.getNumberOfLeadingZeros()]; + Arrays.fill(zeros, '0'); + nationalNumber.append(new String(zeros)); + } + nationalNumber.append(number.getNationalNumber()); + return nationalNumber.toString(); + } + + // TODO: Once we have benchmarked ShortNumberInfo, consider if it is worth keeping + // this performance optimization, and if so move this into the matcher implementation. + private boolean matchesPossibleNumberAndNationalNumber(String number, + PhoneNumberDesc numberDesc) { + return matcherApi.matchesPossibleNumber(number, numberDesc) + && matcherApi.matchesNationalNumber(number, numberDesc, false); } } diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java new file mode 100644 index 000000000..4fda1b0ac --- /dev/null +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/MatcherApi.java @@ -0,0 +1,22 @@ +package com.google.i18n.phonenumbers.internal; + +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; + +/** + * Internal phonenumber matching API used to isolate the underlying implementation of the + * matcher and allow different implementations to be swapped in easily. + */ +public interface MatcherApi { + /** + * Returns whether the given national number (a string containing only decimal digits) matches + * the national number pattern defined in the given {@code PhoneNumberDesc} message. + */ + boolean matchesNationalNumber(String nationalNumber, PhoneNumberDesc numberDesc, + boolean allowPrefixMatch); + + /** + * Returns whether the given national number (a string containing only decimal digits) matches + * the possible number pattern defined in the given {@code PhoneNumberDesc} message. + */ + boolean matchesPossibleNumber(String nationalNumber, PhoneNumberDesc numberDesc); +} diff --git a/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java b/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java new file mode 100644 index 000000000..5dd4b70b3 --- /dev/null +++ b/java/libphonenumber/src/com/google/i18n/phonenumbers/internal/RegexBasedMatcher.java @@ -0,0 +1,36 @@ +package com.google.i18n.phonenumbers.internal; + +import com.google.i18n.phonenumbers.Phonemetadata.PhoneNumberDesc; +import com.google.i18n.phonenumbers.RegexCache; + +import java.util.regex.Matcher; + +/** + * Implementation of the matcher API using the regular expressions in the PhoneNumberDesc + * proto message to match numbers. + */ +public final class RegexBasedMatcher implements MatcherApi { + public static MatcherApi create() { + return new RegexBasedMatcher(); + } + + private final RegexCache regexCache = new RegexCache(100); + + private RegexBasedMatcher() {} + + // @Override + public boolean matchesNationalNumber(String nationalNumber, PhoneNumberDesc numberDesc, + boolean allowPrefixMatch) { + Matcher nationalNumberPatternMatcher = regexCache.getPatternForRegex( + numberDesc.getNationalNumberPattern()).matcher(nationalNumber); + return nationalNumberPatternMatcher.matches() + || (allowPrefixMatch && nationalNumberPatternMatcher.lookingAt()); + } + + // @Override + public boolean matchesPossibleNumber(String nationalNumber, PhoneNumberDesc numberDesc) { + Matcher possibleNumberPatternMatcher = regexCache.getPatternForRegex( + numberDesc.getPossibleNumberPattern()).matcher(nationalNumber); + return possibleNumberPatternMatcher.matches(); + } +} diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java index 962ec2e76..676129838 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/CountryCodeToRegionCodeMapForTesting.java @@ -38,9 +38,11 @@ public class CountryCodeToRegionCodeMapForTesting { ArrayList listWithRegionCode; - listWithRegionCode = new ArrayList(2); + listWithRegionCode = new ArrayList(4); listWithRegionCode.add("US"); + listWithRegionCode.add("BB"); listWithRegionCode.add("BS"); + listWithRegionCode.add("CA"); countryCodeToRegionCodeMap.put(1, listWithRegionCode); listWithRegionCode = new ArrayList(1); diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java index 2f1831ffb..b276eb9cf 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ExampleNumbersTest.java @@ -37,7 +37,7 @@ public class ExampleNumbersTest extends TestCase { private static final Logger LOGGER = Logger.getLogger(ExampleNumbersTest.class.getName()); private PhoneNumberUtil phoneNumberUtil = PhoneNumberUtil.createInstance(PhoneNumberUtil.DEFAULT_METADATA_LOADER); - private ShortNumberInfo shortNumberInfo = new ShortNumberInfo(phoneNumberUtil); + private ShortNumberInfo shortNumberInfo = ShortNumberInfo.getInstance(); private List invalidCases = new ArrayList(); private List wrongTypeCases = new ArrayList(); @@ -183,7 +183,8 @@ public class ExampleNumbersTest extends TestCase { List invalidStringCases = new ArrayList(); for (String regionCode : shortNumberInfo.getSupportedRegions()) { String exampleShortNumber = shortNumberInfo.getExampleShortNumber(regionCode); - if (!shortNumberInfo.isValidShortNumberForRegion(exampleShortNumber, regionCode)) { + if (!shortNumberInfo.isValidShortNumberForRegion( + phoneNumberUtil.parse(exampleShortNumber, regionCode), regionCode)) { String invalidStringCase = "region_code: " + regionCode + ", national_number: " + exampleShortNumber; invalidStringCases.add(invalidStringCase); @@ -198,7 +199,8 @@ public class ExampleNumbersTest extends TestCase { for (ShortNumberInfo.ShortNumberCost cost : ShortNumberInfo.ShortNumberCost.values()) { exampleShortNumber = shortNumberInfo.getExampleShortNumberForCost(regionCode, cost); if (!exampleShortNumber.equals("")) { - if (cost != shortNumberInfo.getExpectedCostForRegion(exampleShortNumber, regionCode)) { + if (cost != shortNumberInfo.getExpectedCostForRegion( + phoneNumberUtil.parse(exampleShortNumber, regionCode), regionCode)) { wrongTypeCases.add(phoneNumber); LOGGER.log(Level.SEVERE, "Wrong cost for " + phoneNumber.toString()); } @@ -217,12 +219,13 @@ public class ExampleNumbersTest extends TestCase { MetadataManager.getShortNumberMetadataForRegion(regionCode).getEmergency(); if (desc.hasExampleNumber()) { String exampleNumber = desc.getExampleNumber(); - if (!exampleNumber.matches(desc.getPossibleNumberPattern()) || - !shortNumberInfo.isEmergencyNumber(exampleNumber, regionCode)) { + PhoneNumber phoneNumber = phoneNumberUtil.parse(exampleNumber, regionCode); + if (!shortNumberInfo.isPossibleShortNumberForRegion(phoneNumber, regionCode) + || !shortNumberInfo.isEmergencyNumber(exampleNumber, regionCode)) { wrongTypeCounter++; LOGGER.log(Level.SEVERE, "Emergency example number test failed for " + regionCode); - } else if (shortNumberInfo.getExpectedCostForRegion(exampleNumber, regionCode) != - ShortNumberInfo.ShortNumberCost.TOLL_FREE) { + } else if (shortNumberInfo.getExpectedCostForRegion(phoneNumber, regionCode) + != ShortNumberInfo.ShortNumberCost.TOLL_FREE) { wrongTypeCounter++; LOGGER.log(Level.WARNING, "Emergency example number not toll free for " + regionCode); } @@ -240,8 +243,8 @@ public class ExampleNumbersTest extends TestCase { if (desc.hasExampleNumber()) { String exampleNumber = desc.getExampleNumber(); PhoneNumber carrierSpecificNumber = phoneNumberUtil.parse(exampleNumber, regionCode); - if (!exampleNumber.matches(desc.getPossibleNumberPattern()) || - !shortNumberInfo.isCarrierSpecific(carrierSpecificNumber)) { + if (!shortNumberInfo.isPossibleShortNumberForRegion(carrierSpecificNumber, regionCode) + || !shortNumberInfo.isCarrierSpecific(carrierSpecificNumber)) { wrongTagCounter++; LOGGER.log(Level.SEVERE, "Carrier-specific test failed for " + regionCode); } diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java index dcbff0f6d..63661a903 100644 --- a/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java +++ b/java/libphonenumber/test/com/google/i18n/phonenumbers/ShortNumberInfoTest.java @@ -24,22 +24,18 @@ import com.google.i18n.phonenumbers.Phonenumber.PhoneNumber; * @author Shaopeng Jia */ public class ShortNumberInfoTest extends TestMetadataTestCase { - private ShortNumberInfo shortInfo; - - public ShortNumberInfoTest() { - shortInfo = new ShortNumberInfo(phoneUtil); - } + private static final ShortNumberInfo shortInfo = ShortNumberInfo.getInstance(); public void testIsPossibleShortNumber() { PhoneNumber possibleNumber = new PhoneNumber(); possibleNumber.setCountryCode(33).setNationalNumber(123456L); assertTrue(shortInfo.isPossibleShortNumber(possibleNumber)); - assertTrue(shortInfo.isPossibleShortNumberForRegion("123456", RegionCode.FR)); + assertTrue( + shortInfo.isPossibleShortNumberForRegion(parse("123456", RegionCode.FR), RegionCode.FR)); PhoneNumber impossibleNumber = new PhoneNumber(); impossibleNumber.setCountryCode(33).setNationalNumber(9L); assertFalse(shortInfo.isPossibleShortNumber(impossibleNumber)); - assertFalse(shortInfo.isPossibleShortNumberForRegion("9", RegionCode.FR)); // Note that GB and GG share the country calling code 44, and that this number is possible but // not valid. @@ -50,10 +46,11 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { public void testIsValidShortNumber() { assertTrue(shortInfo.isValidShortNumber( new PhoneNumber().setCountryCode(33).setNationalNumber(1010L))); - assertTrue(shortInfo.isValidShortNumberForRegion("1010", RegionCode.FR)); + assertTrue(shortInfo.isValidShortNumberForRegion(parse("1010", RegionCode.FR), RegionCode.FR)); assertFalse(shortInfo.isValidShortNumber( new PhoneNumber().setCountryCode(33).setNationalNumber(123456L))); - assertFalse(shortInfo.isValidShortNumberForRegion("123456", RegionCode.FR)); + assertFalse( + shortInfo.isValidShortNumberForRegion(parse("123456", RegionCode.FR), RegionCode.FR)); // Note that GB and GG share the country calling code 44. assertTrue(shortInfo.isValidShortNumber( @@ -61,44 +58,45 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { } public void testGetExpectedCost() { - String premiumRateExample = shortInfo.getExampleShortNumberForCost( - RegionCode.FR, ShortNumberInfo.ShortNumberCost.PREMIUM_RATE); - assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, - shortInfo.getExpectedCostForRegion(premiumRateExample, RegionCode.FR)); + String premiumRateExample = shortInfo.getExampleShortNumberForCost(RegionCode.FR, + ShortNumberInfo.ShortNumberCost.PREMIUM_RATE); + assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, shortInfo.getExpectedCostForRegion( + parse(premiumRateExample, RegionCode.FR), RegionCode.FR)); PhoneNumber premiumRateNumber = new PhoneNumber(); premiumRateNumber.setCountryCode(33).setNationalNumber(Integer.parseInt(premiumRateExample)); assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, shortInfo.getExpectedCost(premiumRateNumber)); - String standardRateExample = shortInfo.getExampleShortNumberForCost( - RegionCode.FR, ShortNumberInfo.ShortNumberCost.STANDARD_RATE); - assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE, - shortInfo.getExpectedCostForRegion(standardRateExample, RegionCode.FR)); + String standardRateExample = shortInfo.getExampleShortNumberForCost(RegionCode.FR, + ShortNumberInfo.ShortNumberCost.STANDARD_RATE); + assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE, shortInfo.getExpectedCostForRegion( + parse(standardRateExample, RegionCode.FR), RegionCode.FR)); PhoneNumber standardRateNumber = new PhoneNumber(); standardRateNumber.setCountryCode(33).setNationalNumber(Integer.parseInt(standardRateExample)); assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE, shortInfo.getExpectedCost(standardRateNumber)); - String tollFreeExample = shortInfo.getExampleShortNumberForCost( - RegionCode.FR, ShortNumberInfo.ShortNumberCost.TOLL_FREE); + String tollFreeExample = shortInfo.getExampleShortNumberForCost(RegionCode.FR, + ShortNumberInfo.ShortNumberCost.TOLL_FREE); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion(tollFreeExample, RegionCode.FR)); + shortInfo.getExpectedCostForRegion(parse(tollFreeExample, RegionCode.FR), RegionCode.FR)); PhoneNumber tollFreeNumber = new PhoneNumber(); tollFreeNumber.setCountryCode(33).setNationalNumber(Integer.parseInt(tollFreeExample)); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, shortInfo.getExpectedCost(tollFreeNumber)); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion("12345", RegionCode.FR)); + shortInfo.getExpectedCostForRegion(parse("12345", RegionCode.FR), RegionCode.FR)); PhoneNumber unknownCostNumber = new PhoneNumber(); unknownCostNumber.setCountryCode(33).setNationalNumber(12345L); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCost(unknownCostNumber)); // Test that an invalid number may nevertheless have a cost other than UNKNOWN_COST. - assertFalse(shortInfo.isValidShortNumberForRegion("116123", RegionCode.FR)); + assertFalse( + shortInfo.isValidShortNumberForRegion(parse("116123", RegionCode.FR), RegionCode.FR)); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion("116123", RegionCode.FR)); + shortInfo.getExpectedCostForRegion(parse("116123", RegionCode.FR), RegionCode.FR)); PhoneNumber invalidNumber = new PhoneNumber(); invalidNumber.setCountryCode(33).setNationalNumber(116123L); assertFalse(shortInfo.isValidShortNumber(invalidNumber)); @@ -107,7 +105,7 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { // Test a nonexistent country code. assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion("911", RegionCode.ZZ)); + shortInfo.getExpectedCostForRegion(parse("911", RegionCode.US), RegionCode.ZZ)); unknownCostNumber.clear(); unknownCostNumber.setCountryCode(123).setNationalNumber(911L); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, @@ -119,44 +117,50 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { // code. In Australia, 1234 is premium-rate, 1194 is standard-rate, and 733 is toll-free. These // are not known to be valid numbers in the Christmas Islands. String ambiguousPremiumRateString = "1234"; - PhoneNumber ambiguousPremiumRateNumber = new PhoneNumber().setCountryCode(61) - .setNationalNumber(1234L); + PhoneNumber ambiguousPremiumRateNumber = + new PhoneNumber().setCountryCode(61).setNationalNumber(1234L); String ambiguousStandardRateString = "1194"; - PhoneNumber ambiguousStandardRateNumber = new PhoneNumber().setCountryCode(61) - .setNationalNumber(1194L); + PhoneNumber ambiguousStandardRateNumber = + new PhoneNumber().setCountryCode(61).setNationalNumber(1194L); String ambiguousTollFreeString = "733"; - PhoneNumber ambiguousTollFreeNumber = new PhoneNumber().setCountryCode(61) - .setNationalNumber(733L); + PhoneNumber ambiguousTollFreeNumber = + new PhoneNumber().setCountryCode(61).setNationalNumber(733L); assertTrue(shortInfo.isValidShortNumber(ambiguousPremiumRateNumber)); assertTrue(shortInfo.isValidShortNumber(ambiguousStandardRateNumber)); assertTrue(shortInfo.isValidShortNumber(ambiguousTollFreeNumber)); - assertTrue(shortInfo.isValidShortNumberForRegion(ambiguousPremiumRateString, RegionCode.AU)); - assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, - shortInfo.getExpectedCostForRegion(ambiguousPremiumRateString, RegionCode.AU)); - assertFalse(shortInfo.isValidShortNumberForRegion(ambiguousPremiumRateString, RegionCode.CX)); - assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion(ambiguousPremiumRateString, RegionCode.CX)); + assertTrue(shortInfo.isValidShortNumberForRegion( + parse(ambiguousPremiumRateString, RegionCode.AU), RegionCode.AU)); + assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, shortInfo.getExpectedCostForRegion( + parse(ambiguousPremiumRateString, RegionCode.AU), RegionCode.AU)); + assertFalse(shortInfo.isValidShortNumberForRegion( + parse(ambiguousPremiumRateString, RegionCode.CX), RegionCode.CX)); + assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCostForRegion( + parse(ambiguousPremiumRateString, RegionCode.CX), RegionCode.CX)); // PREMIUM_RATE takes precedence over UNKNOWN_COST. assertEquals(ShortNumberInfo.ShortNumberCost.PREMIUM_RATE, shortInfo.getExpectedCost(ambiguousPremiumRateNumber)); - assertTrue(shortInfo.isValidShortNumberForRegion(ambiguousStandardRateString, RegionCode.AU)); - assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE, - shortInfo.getExpectedCostForRegion(ambiguousStandardRateString, RegionCode.AU)); - assertFalse(shortInfo.isValidShortNumberForRegion(ambiguousStandardRateString, RegionCode.CX)); - assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion(ambiguousStandardRateString, RegionCode.CX)); + assertTrue(shortInfo.isValidShortNumberForRegion( + parse(ambiguousStandardRateString, RegionCode.AU), RegionCode.AU)); + assertEquals(ShortNumberInfo.ShortNumberCost.STANDARD_RATE, shortInfo.getExpectedCostForRegion( + parse(ambiguousStandardRateString, RegionCode.AU), RegionCode.AU)); + assertFalse(shortInfo.isValidShortNumberForRegion( + parse(ambiguousStandardRateString, RegionCode.CX), RegionCode.CX)); + assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCostForRegion( + parse(ambiguousStandardRateString, RegionCode.CX), RegionCode.CX)); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCost(ambiguousStandardRateNumber)); - assertTrue(shortInfo.isValidShortNumberForRegion(ambiguousTollFreeString, RegionCode.AU)); - assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion(ambiguousTollFreeString, RegionCode.AU)); - assertFalse(shortInfo.isValidShortNumberForRegion(ambiguousTollFreeString, RegionCode.CX)); - assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion(ambiguousTollFreeString, RegionCode.CX)); + assertTrue(shortInfo.isValidShortNumberForRegion(parse(ambiguousTollFreeString, RegionCode.AU), + RegionCode.AU)); + assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, shortInfo.getExpectedCostForRegion( + parse(ambiguousTollFreeString, RegionCode.AU), RegionCode.AU)); + assertFalse(shortInfo.isValidShortNumberForRegion(parse(ambiguousTollFreeString, RegionCode.CX), + RegionCode.CX)); + assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCostForRegion( + parse(ambiguousTollFreeString, RegionCode.CX), RegionCode.CX)); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, shortInfo.getExpectedCost(ambiguousTollFreeNumber)); } @@ -301,13 +305,13 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { public void testEmergencyNumberForSharedCountryCallingCode() { // Test the emergency number 112, which is valid in both Australia and the Christmas Islands. assertTrue(shortInfo.isEmergencyNumber("112", RegionCode.AU)); - assertTrue(shortInfo.isValidShortNumberForRegion("112", RegionCode.AU)); + assertTrue(shortInfo.isValidShortNumberForRegion(parse("112", RegionCode.AU), RegionCode.AU)); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion("112", RegionCode.AU)); + shortInfo.getExpectedCostForRegion(parse("112", RegionCode.AU), RegionCode.AU)); assertTrue(shortInfo.isEmergencyNumber("112", RegionCode.CX)); - assertTrue(shortInfo.isValidShortNumberForRegion("112", RegionCode.CX)); + assertTrue(shortInfo.isValidShortNumberForRegion(parse("112", RegionCode.CX), RegionCode.CX)); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion("112", RegionCode.CX)); + shortInfo.getExpectedCostForRegion(parse("112", RegionCode.CX), RegionCode.CX)); PhoneNumber sharedEmergencyNumber = new PhoneNumber().setCountryCode(61).setNationalNumber(112L); assertTrue(shortInfo.isValidShortNumber(sharedEmergencyNumber)); @@ -320,12 +324,21 @@ public class ShortNumberInfoTest extends TestMetadataTestCase { // and the USA. assertTrue(shortInfo.isEmergencyNumber("211", RegionCode.BB)); assertEquals(ShortNumberInfo.ShortNumberCost.TOLL_FREE, - shortInfo.getExpectedCostForRegion("211", RegionCode.BB)); + shortInfo.getExpectedCostForRegion(parse("211", RegionCode.BB), RegionCode.BB)); assertFalse(shortInfo.isEmergencyNumber("211", RegionCode.US)); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion("211", RegionCode.US)); + shortInfo.getExpectedCostForRegion(parse("211", RegionCode.US), RegionCode.US)); assertFalse(shortInfo.isEmergencyNumber("211", RegionCode.CA)); assertEquals(ShortNumberInfo.ShortNumberCost.UNKNOWN_COST, - shortInfo.getExpectedCostForRegion("211", RegionCode.CA)); + shortInfo.getExpectedCostForRegion(parse("211", RegionCode.CA), RegionCode.CA)); + } + + private PhoneNumber parse(String number, String regionCode) { + try { + return phoneUtil.parse(number, regionCode); + } catch (NumberParseException e) { + throw new AssertionError( + "Test input data should always parse correctly: " + number + " (" + regionCode + ")", e); + } } } diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BB b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_BB new file mode 100644 index 0000000000000000000000000000000000000000..672f42b17eba96079fc99a47ec09992428571bb2 GIT binary patch literal 165 zcmZ4UmVvc=J_7>-BO{1_VMYcfKSwYDlAsD3#UO}-BO{1_VMYcfKSwYDlAsD3#UO}ZLw5llh}0H4$ang9R* delta 34 dcmZ3&xQLN$&07Z6@;MXPI)xd)fDuALNC1tP1vCHv diff --git a/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_FR b/java/libphonenumber/test/com/google/i18n/phonenumbers/data/PhoneNumberMetadataProtoForTesting_FR index 486892505f8dd12d037db52231de85ca8d21f600..db0a6b39afcb04d33b228e4aaf03a24b8d60bede 100644 GIT binary patch delta 31 lcmbQpG?|Ha&07Z6Dh38dE(RbmQ9*N}Stm1-fx*NBfdF(?2a5mz delta 29 jcmbQtG?9sS&07Z6Dh38d4hA4GQ9*N}StldI#6y7qXKDv0 diff --git a/resources/PhoneNumberMetadataForTesting.xml b/resources/PhoneNumberMetadataForTesting.xml index 6e598f7f1..7b650b26e 100644 --- a/resources/PhoneNumberMetadataForTesting.xml +++ b/resources/PhoneNumberMetadataForTesting.xml @@ -156,6 +156,10 @@ + + + + @@ -220,6 +224,10 @@ + + + + - + @@ -310,7 +318,8 @@ - +