country-codes-library 1.1.3 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/utils.js ADDED
@@ -0,0 +1,241 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCountryByCode2 = getCountryByCode2;
4
+ exports.getCountryByCode3 = getCountryByCode3;
5
+ exports.getCountryByName = getCountryByName;
6
+ exports.getCountriesByCurrency = getCountriesByCurrency;
7
+ exports.getCountriesByCallingCode = getCountriesByCallingCode;
8
+ exports.searchCountries = searchCountries;
9
+ exports.convertCountryCode = convertCountryCode;
10
+ exports.getCallingCode = getCallingCode;
11
+ exports.getCurrencyCode = getCurrencyCode;
12
+ exports.getCurrencySymbol = getCurrencySymbol;
13
+ exports.getAllCurrencies = getAllCurrencies;
14
+ exports.getAllCallingCodes = getAllCallingCodes;
15
+ const countryData_1 = require("./countryData");
16
+ /**
17
+ * Get country information by 2-letter ISO code
18
+ * @param code - ISO 3166-1 alpha-2 code (e.g., "US", "GB", "CN")
19
+ * @returns Country object or null if not found
20
+ * @example
21
+ * ```ts
22
+ * const country = getCountryByCode2("US");
23
+ * // Returns: { name: "UnitedStates", code2: "US", code3: "USA", ... }
24
+ * ```
25
+ */
26
+ function getCountryByCode2(code) {
27
+ const upperCode = code.toUpperCase();
28
+ for (const country of (0, countryData_1.getAllCountries)()) {
29
+ if (country.code2.toUpperCase() === upperCode) {
30
+ return country;
31
+ }
32
+ }
33
+ return null;
34
+ }
35
+ /**
36
+ * Get country information by 3-letter ISO code
37
+ * @param code - ISO 3166-1 alpha-3 code (e.g., "USA", "GBR", "CHN")
38
+ * @returns Country object or null if not found
39
+ * @example
40
+ * ```ts
41
+ * const country = getCountryByCode3("USA");
42
+ * // Returns: { name: "UnitedStates", code2: "US", code3: "USA", ... }
43
+ * ```
44
+ */
45
+ function getCountryByCode3(code) {
46
+ const upperCode = code.toUpperCase();
47
+ for (const country of (0, countryData_1.getAllCountries)()) {
48
+ if (country.code3.toUpperCase() === upperCode) {
49
+ return country;
50
+ }
51
+ }
52
+ return null;
53
+ }
54
+ /**
55
+ * Get country information by name
56
+ * @param name - Country name (e.g., "UnitedStates", "United States")
57
+ * @returns Country object or null if not found
58
+ * @example
59
+ * ```ts
60
+ * const country = getCountryByName("UnitedStates");
61
+ * // Returns: { name: "UnitedStates", code2: "US", code3: "USA", ... }
62
+ * ```
63
+ */
64
+ function getCountryByName(name) {
65
+ // Try exact match first
66
+ if (countryData_1.CountryData[name]) {
67
+ return countryData_1.CountryData[name];
68
+ }
69
+ // Try case-insensitive match
70
+ const lowerName = name.toLowerCase().replace(/\s+/g, '');
71
+ for (const countryName in countryData_1.CountryData) {
72
+ if (countryName.toLowerCase().replace(/\s+/g, '') === lowerName) {
73
+ return countryData_1.CountryData[countryName];
74
+ }
75
+ }
76
+ return null;
77
+ }
78
+ /**
79
+ * Get all countries that use a specific currency
80
+ * @param currencyCode - ISO 4217 currency code (e.g., "USD", "EUR")
81
+ * @returns Array of countries using the currency
82
+ * @example
83
+ * ```ts
84
+ * const countries = getCountriesByCurrency("EUR");
85
+ * // Returns array of European countries using Euro
86
+ * ```
87
+ */
88
+ function getCountriesByCurrency(currencyCode) {
89
+ const upperCurrency = currencyCode.toUpperCase();
90
+ return (0, countryData_1.getAllCountries)().filter(country => country.currencyCode.toUpperCase() === upperCurrency);
91
+ }
92
+ /**
93
+ * Get all countries with a specific calling code
94
+ * @param callingCode - International calling code (e.g., "+1", "+44")
95
+ * @returns Array of countries with the calling code
96
+ * @example
97
+ * ```ts
98
+ * const countries = getCountriesByCallingCode("+1");
99
+ * // Returns: [USA, Canada, and other +1 countries]
100
+ * ```
101
+ */
102
+ function getCountriesByCallingCode(callingCode) {
103
+ // Normalize calling code (add + if missing)
104
+ const normalizedCode = callingCode.startsWith('+') ? callingCode : `+${callingCode}`;
105
+ return (0, countryData_1.getAllCountries)().filter(country => country.callingCode === normalizedCode);
106
+ }
107
+ /**
108
+ * Search countries by name (supports partial matching)
109
+ * @param query - Search query
110
+ * @param options - Search options
111
+ * @returns Array of matching countries
112
+ * @example
113
+ * ```ts
114
+ * const results = searchCountries("united");
115
+ * // Returns: [UnitedStates, UnitedKingdom, UnitedArabEmirates]
116
+ * ```
117
+ */
118
+ function searchCountries(query, options = {}) {
119
+ const { caseSensitive = false, exactMatch = false } = options;
120
+ const searchQuery = caseSensitive ? query : query.toLowerCase();
121
+ return (0, countryData_1.getAllCountries)().filter(country => {
122
+ const countryName = caseSensitive ? country.name : country.name.toLowerCase();
123
+ if (exactMatch) {
124
+ return countryName === searchQuery;
125
+ }
126
+ return countryName.includes(searchQuery);
127
+ });
128
+ }
129
+ /**
130
+ * Convert between 2-letter and 3-letter country codes
131
+ * @param code - Country code to convert
132
+ * @param targetFormat - Target format ('code2' or 'code3')
133
+ * @returns Converted code or null if not found
134
+ * @example
135
+ * ```ts
136
+ * convertCountryCode("US", "code3"); // Returns: "USA"
137
+ * convertCountryCode("GBR", "code2"); // Returns: "GB"
138
+ * ```
139
+ */
140
+ function convertCountryCode(code, targetFormat) {
141
+ // Try as 2-letter code first
142
+ let country = getCountryByCode2(code);
143
+ // If not found, try as 3-letter code
144
+ if (!country) {
145
+ country = getCountryByCode3(code);
146
+ }
147
+ if (!country) {
148
+ return null;
149
+ }
150
+ return targetFormat === 'code2' ? country.code2 : country.code3;
151
+ }
152
+ /**
153
+ * Get calling code for a country
154
+ * @param countryIdentifier - Country name, code2, or code3
155
+ * @returns Calling code or null if not found
156
+ * @example
157
+ * ```ts
158
+ * getCallingCode("US"); // Returns: "+1"
159
+ * getCallingCode("UnitedStates"); // Returns: "+1"
160
+ * ```
161
+ */
162
+ function getCallingCode(countryIdentifier) {
163
+ let country = getCountryByName(countryIdentifier);
164
+ if (!country) {
165
+ country = getCountryByCode2(countryIdentifier);
166
+ }
167
+ if (!country) {
168
+ country = getCountryByCode3(countryIdentifier);
169
+ }
170
+ return country ? country.callingCode : null;
171
+ }
172
+ /**
173
+ * Get currency code for a country
174
+ * @param countryIdentifier - Country name, code2, or code3
175
+ * @returns Currency code or null if not found
176
+ * @example
177
+ * ```ts
178
+ * getCurrencyCode("US"); // Returns: "USD"
179
+ * getCurrencyCode("Germany"); // Returns: "EUR"
180
+ * ```
181
+ */
182
+ function getCurrencyCode(countryIdentifier) {
183
+ let country = getCountryByName(countryIdentifier);
184
+ if (!country) {
185
+ country = getCountryByCode2(countryIdentifier);
186
+ }
187
+ if (!country) {
188
+ country = getCountryByCode3(countryIdentifier);
189
+ }
190
+ return country ? country.currencyCode : null;
191
+ }
192
+ /**
193
+ * Get currency symbol for a country
194
+ * @param countryIdentifier - Country name, code2, or code3
195
+ * @returns Currency symbol or null if not found
196
+ * @example
197
+ * ```ts
198
+ * getCurrencySymbol("US"); // Returns: "$"
199
+ * getCurrencySymbol("Japan"); // Returns: "¥"
200
+ * ```
201
+ */
202
+ function getCurrencySymbol(countryIdentifier) {
203
+ let country = getCountryByName(countryIdentifier);
204
+ if (!country) {
205
+ country = getCountryByCode2(countryIdentifier);
206
+ }
207
+ if (!country) {
208
+ country = getCountryByCode3(countryIdentifier);
209
+ }
210
+ return country ? country.currencySymbol : null;
211
+ }
212
+ /**
213
+ * Get all unique currencies used worldwide
214
+ * @returns Array of unique currency codes
215
+ */
216
+ function getAllCurrencies() {
217
+ const currencies = new Set();
218
+ (0, countryData_1.getAllCountries)().forEach(country => {
219
+ if (country.currencyCode) {
220
+ currencies.add(country.currencyCode);
221
+ }
222
+ });
223
+ return Array.from(currencies).sort();
224
+ }
225
+ /**
226
+ * Get all unique calling codes
227
+ * @returns Array of unique calling codes
228
+ */
229
+ function getAllCallingCodes() {
230
+ const codes = new Set();
231
+ (0, countryData_1.getAllCountries)().forEach(country => {
232
+ if (country.callingCode && country.callingCode !== '+0') {
233
+ codes.add(country.callingCode);
234
+ }
235
+ });
236
+ return Array.from(codes).sort((a, b) => {
237
+ const numA = parseInt(a.replace('+', ''));
238
+ const numB = parseInt(b.replace('+', ''));
239
+ return numA - numB;
240
+ });
241
+ }
@@ -0,0 +1,94 @@
1
+ import { PhoneValidationResult } from './types';
2
+ /**
3
+ * Validate if a string is a valid ISO 3166-1 alpha-2 country code
4
+ * @param code - The code to validate
5
+ * @returns true if valid, false otherwise
6
+ * @example
7
+ * ```ts
8
+ * isValidCountryCode2("US"); // true
9
+ * isValidCountryCode2("XX"); // false
10
+ * ```
11
+ */
12
+ export declare function isValidCountryCode2(code: string): boolean;
13
+ /**
14
+ * Validate if a string is a valid ISO 3166-1 alpha-3 country code
15
+ * @param code - The code to validate
16
+ * @returns true if valid, false otherwise
17
+ * @example
18
+ * ```ts
19
+ * isValidCountryCode3("USA"); // true
20
+ * isValidCountryCode3("XXX"); // false
21
+ * ```
22
+ */
23
+ export declare function isValidCountryCode3(code: string): boolean;
24
+ /**
25
+ * Validate if a string is a valid country code (2-letter or 3-letter)
26
+ * @param code - The code to validate
27
+ * @returns true if valid, false otherwise
28
+ * @example
29
+ * ```ts
30
+ * isValidCountryCode("US"); // true
31
+ * isValidCountryCode("USA"); // true
32
+ * isValidCountryCode("INVALID"); // false
33
+ * ```
34
+ */
35
+ export declare function isValidCountryCode(code: string): boolean;
36
+ /**
37
+ * Validate if a string is a valid country name
38
+ * @param name - The country name to validate
39
+ * @returns true if valid, false otherwise
40
+ * @example
41
+ * ```ts
42
+ * isValidCountryName("UnitedStates"); // true
43
+ * isValidCountryName("United States"); // true (case-insensitive)
44
+ * isValidCountryName("Atlantis"); // false
45
+ * ```
46
+ */
47
+ export declare function isValidCountryName(name: string): boolean;
48
+ /**
49
+ * Validate if a currency code is valid (ISO 4217)
50
+ * @param currencyCode - The currency code to validate
51
+ * @returns true if valid, false otherwise
52
+ * @example
53
+ * ```ts
54
+ * isValidCurrencyCode("USD"); // true
55
+ * isValidCurrencyCode("EUR"); // true
56
+ * isValidCurrencyCode("XXX"); // false (not used by any country)
57
+ * ```
58
+ */
59
+ export declare function isValidCurrencyCode(currencyCode: string): boolean;
60
+ /**
61
+ * Validate if a calling code is valid
62
+ * @param callingCode - The calling code to validate (with or without +)
63
+ * @returns true if valid, false otherwise
64
+ * @example
65
+ * ```ts
66
+ * isValidCallingCode("+1"); // true
67
+ * isValidCallingCode("44"); // true
68
+ * isValidCallingCode("+999"); // false
69
+ * ```
70
+ */
71
+ export declare function isValidCallingCode(callingCode: string): boolean;
72
+ /**
73
+ * Basic phone number validation for a specific country
74
+ * @param phoneNumber - The phone number to validate
75
+ * @param countryIdentifier - Country name, code2, or code3
76
+ * @returns Validation result object
77
+ * @example
78
+ * ```ts
79
+ * validatePhoneNumber("2025551234", "US");
80
+ * // Returns: { isValid: true, formatted: "+1-202-555-1234", countryCode: "+1" }
81
+ * ```
82
+ */
83
+ export declare function validatePhoneNumber(phoneNumber: string, countryIdentifier: string): PhoneValidationResult;
84
+ /**
85
+ * Parse a phone number and detect the country
86
+ * @param phoneNumber - The phone number to parse (with calling code)
87
+ * @returns Validation result with detected country
88
+ * @example
89
+ * ```ts
90
+ * parsePhoneNumber("+1-202-555-1234");
91
+ * // Returns: { isValid: true, formatted: "+1-2025551234", countryCode: "+1" }
92
+ * ```
93
+ */
94
+ export declare function parsePhoneNumber(phoneNumber: string): PhoneValidationResult;
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isValidCountryCode2 = isValidCountryCode2;
4
+ exports.isValidCountryCode3 = isValidCountryCode3;
5
+ exports.isValidCountryCode = isValidCountryCode;
6
+ exports.isValidCountryName = isValidCountryName;
7
+ exports.isValidCurrencyCode = isValidCurrencyCode;
8
+ exports.isValidCallingCode = isValidCallingCode;
9
+ exports.validatePhoneNumber = validatePhoneNumber;
10
+ exports.parsePhoneNumber = parsePhoneNumber;
11
+ const utils_1 = require("./utils");
12
+ /**
13
+ * Validate if a string is a valid ISO 3166-1 alpha-2 country code
14
+ * @param code - The code to validate
15
+ * @returns true if valid, false otherwise
16
+ * @example
17
+ * ```ts
18
+ * isValidCountryCode2("US"); // true
19
+ * isValidCountryCode2("XX"); // false
20
+ * ```
21
+ */
22
+ function isValidCountryCode2(code) {
23
+ if (!code || typeof code !== 'string') {
24
+ return false;
25
+ }
26
+ if (code.length !== 2) {
27
+ return false;
28
+ }
29
+ return (0, utils_1.getCountryByCode2)(code) !== null;
30
+ }
31
+ /**
32
+ * Validate if a string is a valid ISO 3166-1 alpha-3 country code
33
+ * @param code - The code to validate
34
+ * @returns true if valid, false otherwise
35
+ * @example
36
+ * ```ts
37
+ * isValidCountryCode3("USA"); // true
38
+ * isValidCountryCode3("XXX"); // false
39
+ * ```
40
+ */
41
+ function isValidCountryCode3(code) {
42
+ if (!code || typeof code !== 'string') {
43
+ return false;
44
+ }
45
+ if (code.length !== 3) {
46
+ return false;
47
+ }
48
+ return (0, utils_1.getCountryByCode3)(code) !== null;
49
+ }
50
+ /**
51
+ * Validate if a string is a valid country code (2-letter or 3-letter)
52
+ * @param code - The code to validate
53
+ * @returns true if valid, false otherwise
54
+ * @example
55
+ * ```ts
56
+ * isValidCountryCode("US"); // true
57
+ * isValidCountryCode("USA"); // true
58
+ * isValidCountryCode("INVALID"); // false
59
+ * ```
60
+ */
61
+ function isValidCountryCode(code) {
62
+ if (!code || typeof code !== 'string') {
63
+ return false;
64
+ }
65
+ if (code.length === 2) {
66
+ return isValidCountryCode2(code);
67
+ }
68
+ if (code.length === 3) {
69
+ return isValidCountryCode3(code);
70
+ }
71
+ return false;
72
+ }
73
+ /**
74
+ * Validate if a string is a valid country name
75
+ * @param name - The country name to validate
76
+ * @returns true if valid, false otherwise
77
+ * @example
78
+ * ```ts
79
+ * isValidCountryName("UnitedStates"); // true
80
+ * isValidCountryName("United States"); // true (case-insensitive)
81
+ * isValidCountryName("Atlantis"); // false
82
+ * ```
83
+ */
84
+ function isValidCountryName(name) {
85
+ if (!name || typeof name !== 'string') {
86
+ return false;
87
+ }
88
+ return (0, utils_1.getCountryByName)(name) !== null;
89
+ }
90
+ /**
91
+ * Validate if a currency code is valid (ISO 4217)
92
+ * @param currencyCode - The currency code to validate
93
+ * @returns true if valid, false otherwise
94
+ * @example
95
+ * ```ts
96
+ * isValidCurrencyCode("USD"); // true
97
+ * isValidCurrencyCode("EUR"); // true
98
+ * isValidCurrencyCode("XXX"); // false (not used by any country)
99
+ * ```
100
+ */
101
+ function isValidCurrencyCode(currencyCode) {
102
+ if (!currencyCode || typeof currencyCode !== 'string') {
103
+ return false;
104
+ }
105
+ if (currencyCode.length !== 3) {
106
+ return false;
107
+ }
108
+ const { getAllCountries } = require('./countryData');
109
+ const countries = getAllCountries();
110
+ return countries.some((country) => country.currencyCode.toUpperCase() === currencyCode.toUpperCase());
111
+ }
112
+ /**
113
+ * Validate if a calling code is valid
114
+ * @param callingCode - The calling code to validate (with or without +)
115
+ * @returns true if valid, false otherwise
116
+ * @example
117
+ * ```ts
118
+ * isValidCallingCode("+1"); // true
119
+ * isValidCallingCode("44"); // true
120
+ * isValidCallingCode("+999"); // false
121
+ * ```
122
+ */
123
+ function isValidCallingCode(callingCode) {
124
+ if (!callingCode || typeof callingCode !== 'string') {
125
+ return false;
126
+ }
127
+ const normalizedCode = callingCode.startsWith('+') ? callingCode : `+${callingCode}`;
128
+ const { getAllCountries } = require('./countryData');
129
+ const countries = getAllCountries();
130
+ return countries.some((country) => country.callingCode === normalizedCode);
131
+ }
132
+ /**
133
+ * Basic phone number validation for a specific country
134
+ * @param phoneNumber - The phone number to validate
135
+ * @param countryIdentifier - Country name, code2, or code3
136
+ * @returns Validation result object
137
+ * @example
138
+ * ```ts
139
+ * validatePhoneNumber("2025551234", "US");
140
+ * // Returns: { isValid: true, formatted: "+1-202-555-1234", countryCode: "+1" }
141
+ * ```
142
+ */
143
+ function validatePhoneNumber(phoneNumber, countryIdentifier) {
144
+ if (!phoneNumber || typeof phoneNumber !== 'string') {
145
+ return {
146
+ isValid: false,
147
+ error: 'Phone number is required'
148
+ };
149
+ }
150
+ const callingCode = (0, utils_1.getCallingCode)(countryIdentifier);
151
+ if (!callingCode) {
152
+ return {
153
+ isValid: false,
154
+ error: 'Invalid country identifier'
155
+ };
156
+ }
157
+ // Remove all non-digit characters
158
+ const digits = phoneNumber.replace(/\D/g, '');
159
+ if (digits.length === 0) {
160
+ return {
161
+ isValid: false,
162
+ error: 'Phone number must contain digits'
163
+ };
164
+ }
165
+ // Basic length validation (most phone numbers are between 7-15 digits)
166
+ if (digits.length < 7 || digits.length > 15) {
167
+ return {
168
+ isValid: false,
169
+ error: 'Phone number length is invalid'
170
+ };
171
+ }
172
+ // Format: +[country code]-[number]
173
+ const formatted = `${callingCode}-${digits}`;
174
+ return {
175
+ isValid: true,
176
+ formatted,
177
+ countryCode: callingCode
178
+ };
179
+ }
180
+ /**
181
+ * Parse a phone number and detect the country
182
+ * @param phoneNumber - The phone number to parse (with calling code)
183
+ * @returns Validation result with detected country
184
+ * @example
185
+ * ```ts
186
+ * parsePhoneNumber("+1-202-555-1234");
187
+ * // Returns: { isValid: true, formatted: "+1-2025551234", countryCode: "+1" }
188
+ * ```
189
+ */
190
+ function parsePhoneNumber(phoneNumber) {
191
+ if (!phoneNumber || typeof phoneNumber !== 'string') {
192
+ return {
193
+ isValid: false,
194
+ error: 'Phone number is required'
195
+ };
196
+ }
197
+ // Extract calling code if present
198
+ const match = phoneNumber.match(/^\+?(\d{1,3})/);
199
+ if (!match) {
200
+ return {
201
+ isValid: false,
202
+ error: 'Could not detect calling code'
203
+ };
204
+ }
205
+ const detectedCode = `+${match[1]}`;
206
+ if (!isValidCallingCode(detectedCode)) {
207
+ return {
208
+ isValid: false,
209
+ error: 'Invalid calling code'
210
+ };
211
+ }
212
+ // Remove all non-digit characters
213
+ const digits = phoneNumber.replace(/\D/g, '');
214
+ if (digits.length === 0) {
215
+ return {
216
+ isValid: false,
217
+ error: 'Phone number must contain digits'
218
+ };
219
+ }
220
+ return {
221
+ isValid: true,
222
+ formatted: `+${digits}`,
223
+ countryCode: detectedCode
224
+ };
225
+ }
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "country-codes-library",
3
- "version": "1.1.3",
3
+ "version": "2.0.0",
4
4
  "description": "The Country Code Library provides a collection of two-letter and three-letter country codes according to the ISO 3166-1 standard, as well as it provides USA, China and Canada Province codes (State codes / adminstrative division codes). In addition, it includes telephone calling codes, currency codes, currency Symbols for countries across the world.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
7
  "scripts": {
8
- "build": "tsc"
8
+ "build": "tsc",
9
+ "test" : "jest"
9
10
  },
10
11
  "files": [
11
12
  "dist"
@@ -21,34 +22,39 @@
21
22
  },
22
23
  "homepage": "https://github.com/mohansenthil/countrycodes-node#readme",
23
24
  "devDependencies": {
25
+ "@types/jest": "^29.5.13",
26
+ "jest": "^29.7.0",
27
+ "ts-jest": "^29.2.5",
24
28
  "typescript": "^5.6.2"
25
29
  },
26
30
  "publishConfig": {
27
31
  "registry": "https://registry.npmjs.org"
28
32
  },
29
33
  "keywords": [
30
- "telephone",
31
- "calling",
32
- "two digit",
33
- "three digit",
34
- "two-digit-country-code",
35
- "three-digit-country-code",
36
- "twolettercountrycode",
37
- "countrycode",
38
- "threelettercountrycode",
39
- "USAStateCode",
40
- "+2digitcode",
41
- "+3digitcode",
42
- "ISO-3166",
43
34
  "country-codes",
35
+ "iso-3166",
36
+ "country-data",
37
+ "calling-codes",
38
+ "phone-codes",
39
+ "currency-codes",
40
+ "currency-symbols",
41
+ "iso-4217",
42
+ "country-lookup",
43
+ "country-validation",
44
+ "phone-validation",
45
+ "country-search",
46
+ "reverse-lookup",
47
+ "country-info",
48
+ "typescript",
49
+ "usa-states",
50
+ "canada-provinces",
51
+ "china-provinces",
52
+ "administrative-divisions",
53
+ "international-codes",
54
+ "telephone-codes",
55
+ "country-utilities",
44
56
  "geography",
45
- "canadaprovince",
46
- "chinaprovince",
47
- "proviencecode",
48
- "provience",
49
- "geocode",
50
- "countrycodes",
51
- "currencycodes",
52
- "currencysymbols"
57
+ "localization",
58
+ "i18n"
53
59
  ]
54
60
  }