validators 3.2.1 → 3.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.rubocop.yml +3 -0
- data/README.md +4 -4
- data/bin/sync-disposable-hostnames +120 -110
- data/bin/sync-tld +2 -2
- data/data/country_tlds.txt +235 -0
- data/data/disposable_domains.txt +110996 -0
- data/data/disposable_emails.txt +38 -0
- data/data/reserved_subdomains.txt +2830 -0
- data/data/tld.txt +1508 -0
- data/lib/validators.rb +1 -0
- data/lib/validators/constants.rb +1 -1
- data/lib/validators/disposable_emails.rb +19 -0
- data/lib/validators/disposable_hostnames.rb +2 -2
- data/lib/validators/locale/en.yml +2 -1
- data/lib/validators/locale/pt-BR.yml +1 -0
- data/lib/validators/reserved_subdomains.rb +2 -4
- data/lib/validators/tld.rb +2 -2
- data/lib/validators/validates_email_format_of.rb +19 -4
- data/lib/validators/version.rb +2 -2
- data/test/test_helper.rb +17 -1
- data/test/validators/disposable_email_test.rb +18 -5
- data/test/validators/validates_email_format_of_test.rb +4 -2
- data/validators.gemspec +3 -0
- metadata +53 -43
- data/data/country_tlds.json +0 -237
- data/data/disposable.json +0 -128
- data/data/disposable/10minutemail.json +0 -3
- data/data/disposable/1secmail.json +0 -5
- data/data/disposable/FGRibreau_mailchecker.json +0 -33602
- data/data/disposable/andreis_disposable_email_domains.json +0 -48320
- data/data/disposable/clipmails.json +0 -27
- data/data/disposable/cs.json +0 -15
- data/data/disposable/emailfake.json +0 -128
- data/data/disposable/fake_email_generator.json +0 -11
- data/data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json +0 -20
- data/data/disposable/gmailnator.json +0 -3
- data/data/disposable/guerrillamail.json +0 -13
- data/data/disposable/ically.json +0 -28
- data/data/disposable/itemp.json +0 -4
- data/data/disposable/ivolo_disposable_email_domains.json +0 -48177
- data/data/disposable/jespernissen_disposable_maildomain_list.json +0 -2372
- data/data/disposable/maxmalysh_disposable_emails.json +0 -21372
- data/data/disposable/moakt.json +0 -12
- data/data/disposable/receivemail.json +0 -9
- data/data/disposable/sneakykiwi_LeagueCreatorPublic.json +0 -2364
- data/data/disposable/tempemail.json +0 -7
- data/data/disposable/tempemails.json +0 -10
- data/data/disposable/tempmail.json +0 -31
- data/data/disposable/tempmail_io.json +0 -8
- data/data/disposable/tempmailaddress.json +0 -4
- data/data/disposable/tempomail.json +0 -3
- data/data/disposable/tempr.json +0 -97
- data/data/disposable/tmail.json +0 -3
- data/data/disposable/wesbos_burner_email_providers.json +0 -4711
- data/data/disposable/willwhite_freemail.json +0 -352
- data/data/disposable/yepmail.json +0 -12
- data/data/disposable_emails.json +0 -3
- data/data/disposable_patterns.json +0 -3
- data/data/disposable_raw.json +0 -128
- data/data/reserved_subdomains.json +0 -2838
- data/data/sld.json +0 -5564
- data/data/tld.json +0 -1518
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 862ad7c2a49bcc38d917336b109047a330c6de6c6da16d83ea7953ddefe70096
|
4
|
+
data.tar.gz: fb5e0b9db3ec0fdbc064eb6467cb36fab3d0f4bab6f29a5c8439c8d5edeb46fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b8842cf3ee2161ef2fe18c384efdb5ff6407c135560a95b91689d29b8ff65d87272c599288de55a6422dfaa6ff4be3b0b00fbd7ea8a8472e47bc08acfb973a85
|
7
|
+
data.tar.gz: 7a6fe664d6ef7a33735b8bf41cc198f8509a5712f788a2db93d6f2c4b39678ad6965eea1557fb6e43551a4d947a0cfd2e89c16a53c0721b6ada4390baa8cf293
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/README.md
CHANGED
@@ -32,8 +32,7 @@ class User < ActiveRecord::Base
|
|
32
32
|
end
|
33
33
|
```
|
34
34
|
|
35
|
-
By default, it rejects disposable e-mails (e.g. mailinator). This loads ~
|
36
|
-
but you can disable this validation by setting `disposable: true`.
|
35
|
+
By default, it rejects disposable e-mails (e.g. mailinator). This loads a lot of data (~1.7MB), but you can disable this validation by setting `disposable: true`.
|
37
36
|
|
38
37
|
```ruby
|
39
38
|
class User < ActiveRecord::Base
|
@@ -56,7 +55,7 @@ class User < ActiveRecord::Base
|
|
56
55
|
validates_url_format_of :site
|
57
56
|
|
58
57
|
# validates TLD against list of valid TLD.
|
59
|
-
# Loads ~
|
58
|
+
# Loads ~10KB of text.
|
60
59
|
validates_url_format_of :site, tld: true
|
61
60
|
end
|
62
61
|
```
|
@@ -153,7 +152,8 @@ A valid username/subdomain follows the hostname label validation:
|
|
153
152
|
- cannot begin or end with a hyphen
|
154
153
|
- cannot consist of numeric values only
|
155
154
|
|
156
|
-
The compiled list will be used for both username and subdomain validations.
|
155
|
+
The compiled list will be used for both username and subdomain validations.
|
156
|
+
This validation loads ~20KB of text.
|
157
157
|
|
158
158
|
```ruby
|
159
159
|
class Server < ActiveRecord::Base
|
@@ -4,18 +4,22 @@
|
|
4
4
|
require_relative "helpers"
|
5
5
|
|
6
6
|
def ten_minute_mail
|
7
|
-
path = "disposable/10minutemail.
|
8
|
-
url = "https://10minutemail.com/
|
7
|
+
path = "disposable/10minutemail.txt"
|
8
|
+
url = "https://10minutemail.com/session/address"
|
9
9
|
|
10
|
-
|
11
|
-
|
10
|
+
20.times do
|
11
|
+
refresh_list(url: url, path: path) do |response|
|
12
|
+
_account, host = response.data.fetch("address").split("@")
|
13
|
+
|
14
|
+
[host]
|
15
|
+
end
|
12
16
|
|
13
|
-
|
17
|
+
sleep random_timeout
|
14
18
|
end
|
15
19
|
end
|
16
20
|
|
17
21
|
def temp_mail
|
18
|
-
path = "disposable/tempmail.
|
22
|
+
path = "disposable/tempmail.txt"
|
19
23
|
url = "https://api4.temp-mail.org/request/domains/format/json"
|
20
24
|
|
21
25
|
refresh_list(url: url, path: path) do |response|
|
@@ -24,7 +28,7 @@ def temp_mail
|
|
24
28
|
end
|
25
29
|
|
26
30
|
def temp_mail_address
|
27
|
-
path = "disposable/tempmailaddress.
|
31
|
+
path = "disposable/tempmailaddress.txt"
|
28
32
|
url = "https://www.tempmailaddress.com/index/index"
|
29
33
|
|
30
34
|
refresh_list(url: url, path: path) do |response|
|
@@ -37,7 +41,7 @@ def temp_mail_address
|
|
37
41
|
end
|
38
42
|
|
39
43
|
def tempmail_io
|
40
|
-
path = "disposable/tempmail_io.
|
44
|
+
path = "disposable/tempmail_io.txt"
|
41
45
|
url = "https://api.internal.temp-mail.io/api/v2/domains"
|
42
46
|
|
43
47
|
refresh_list(url: url, path: path) do |response|
|
@@ -46,69 +50,67 @@ def tempmail_io
|
|
46
50
|
end
|
47
51
|
|
48
52
|
def gmailnator
|
49
|
-
|
50
|
-
url = "https://gmailnator.com/index/indexquery"
|
51
|
-
|
52
|
-
refresh_list(
|
53
|
-
verb: :post,
|
54
|
-
url: url,
|
55
|
-
path: path,
|
56
|
-
params: {action: "GenerateEmail"}
|
57
|
-
) do |response|
|
58
|
-
email = response.body.gsub(/(\+[^@]+)/, "")
|
59
|
-
[email]
|
60
|
-
end
|
61
|
-
end
|
53
|
+
emails = []
|
62
54
|
|
63
|
-
|
64
|
-
|
65
|
-
{
|
66
|
-
domain: domain,
|
67
|
-
processed: domain.gsub(/\..*?$/, "")
|
68
|
-
}
|
69
|
-
end
|
55
|
+
5.times do
|
56
|
+
url = "https://gmailnator.com/bulk-emails"
|
57
|
+
default_headers = {"user-agent" => USER_AGENT.sample}
|
70
58
|
|
71
|
-
|
72
|
-
.count_by {|info| info[:processed] }
|
73
|
-
.select {|_processed, count| count > 2 }
|
59
|
+
response = Aitch.get(url: url, headers: default_headers)
|
74
60
|
|
75
|
-
|
76
|
-
buffer[name] = count
|
77
|
-
end
|
61
|
+
throw "Received #{response.status} when getting CSRF token" unless response.ok?
|
78
62
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
63
|
+
cookie_header = response.headers["set-cookie"]
|
64
|
+
attr = response.data.css("#csrf_token").first
|
65
|
+
csrf_token = attr[:value]
|
66
|
+
csrf_field = attr[:name]
|
83
67
|
|
84
|
-
|
85
|
-
|
68
|
+
response = Aitch.post(
|
69
|
+
url: url,
|
70
|
+
params: {email_list: "1000", email: [3], csrf_field => csrf_token},
|
71
|
+
headers: default_headers.merge({"cookie" => cookie_header})
|
72
|
+
)
|
86
73
|
|
87
|
-
|
88
|
-
puts "=> scraping #{url}"
|
74
|
+
throw "Received #{response.status} when fetching list" unless response.ok?
|
89
75
|
|
90
|
-
|
91
|
-
|
92
|
-
|
76
|
+
emails += response.data.css("#email-list-message a").map do |node|
|
77
|
+
mailbox, domain = node.text.gsub(/\+[^@]+/, "").split("@")
|
78
|
+
mailbox = mailbox.gsub(/\./m, "")
|
79
|
+
"#{mailbox}@#{domain}"
|
80
|
+
end
|
93
81
|
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
82
|
+
sleep random_timeout
|
83
|
+
end
|
84
|
+
|
85
|
+
append_to_file("disposable/gmailnator.txt", emails)
|
86
|
+
end
|
87
|
+
|
88
|
+
def domain_scraping(name, url, selector)
|
89
|
+
timeout(10) do
|
90
|
+
puts "=> Scraping #{url}"
|
91
|
+
|
92
|
+
selector, value_selector = selector.split("::")
|
93
|
+
path = "disposable/#{name}.txt"
|
94
|
+
host_regex = /@?(.*?(\.[^.]+)+)/
|
95
|
+
|
96
|
+
refresh_list(url: url, path: path) do |response|
|
97
|
+
new_domains = response
|
98
|
+
.data
|
99
|
+
.css(selector)
|
100
|
+
.map {|element| process_scraping(element, value_selector) }
|
101
|
+
|
102
|
+
new_domains = new_domains
|
103
|
+
.map(&:squish)
|
104
|
+
.reject(&:empty?)
|
105
|
+
.map {|domain| domain[host_regex, 1]&.squish&.tr("@", "") }
|
106
|
+
.reject(&:nil?)
|
107
|
+
.reject(&:empty?)
|
108
|
+
.map {|domain| domain.gsub(/\s*\((.*?)\)/, "") }
|
109
|
+
|
110
|
+
raise "No #{name} hosts found" if new_domains.empty?
|
111
|
+
|
112
|
+
new_domains
|
113
|
+
end
|
112
114
|
end
|
113
115
|
rescue StandardError => error
|
114
116
|
puts "=> [ERROR] Unable to scrape #{url}; #{error.class}: #{error.message}"
|
@@ -139,7 +141,7 @@ def load_github_url(url)
|
|
139
141
|
puts "=> Fetching #{url}"
|
140
142
|
|
141
143
|
basename = URI.parse(url).path[%r{/([^/]+/[^/]+)}, 1].tr("/", "_").tr("-", "_")
|
142
|
-
path = "disposable/#{basename}.
|
144
|
+
path = "disposable/#{basename}.txt"
|
143
145
|
domains = load_file(path)
|
144
146
|
|
145
147
|
ext = File.extname(url)
|
@@ -155,48 +157,43 @@ def load_github_url(url)
|
|
155
157
|
|
156
158
|
append_to_file(path, domains)
|
157
159
|
domains
|
158
|
-
rescue error
|
160
|
+
rescue StandardError => error
|
159
161
|
puts "=> Unable to load #{url}; #{error.class}: #{error.message}"
|
160
162
|
[]
|
161
163
|
end
|
162
164
|
|
163
|
-
domains = []
|
164
165
|
threads = []
|
165
166
|
|
166
|
-
threads << thread {
|
167
|
-
threads << thread {
|
168
|
-
threads << thread {
|
169
|
-
threads << thread {
|
170
|
-
threads << thread {
|
171
|
-
threads << thread {
|
172
|
-
threads << thread {
|
173
|
-
threads << thread {
|
174
|
-
threads << thread {
|
175
|
-
threads << thread {
|
176
|
-
threads << thread {
|
177
|
-
threads << thread {
|
178
|
-
threads << thread {
|
179
|
-
threads << thread {
|
180
|
-
threads << thread {
|
181
|
-
threads << thread {
|
182
|
-
threads << thread {
|
183
|
-
threads << thread {
|
184
|
-
threads << thread {
|
185
|
-
threads << thread {
|
186
|
-
threads << thread {
|
187
|
-
threads << thread {
|
188
|
-
threads << thread {
|
189
|
-
threads << thread {
|
190
|
-
threads << thread {
|
191
|
-
threads << thread {
|
192
|
-
threads << thread {
|
193
|
-
threads << thread {
|
194
|
-
threads << thread {
|
195
|
-
threads << thread {
|
196
|
-
threads << thread { domains += domain_scraping("cs", "https://www.cs.email", "select[id=gm-host-select] option::text()") }
|
197
|
-
threads << thread { domains += domain_scraping("tempmail", "https://tempmail.io/settings/", "select[id=domain] option::text()") }
|
198
|
-
threads << thread { domains += domain_scraping("tempemail", "https://tempemail.co", "select[name=email_domain] option::text()") }
|
199
|
-
threads << thread { domains += domain_scraping("tmail", "https://mytemp-email.com/", "a.domain-selector::text()") }
|
167
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/ivolo/disposable-email-domains/master/index.json") }
|
168
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/andreis/disposable-email-domains/master/domains.json") }
|
169
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/FGRibreau/mailchecker/master/list.txt") }
|
170
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/willwhite/freemail/master/data/disposable.txt") }
|
171
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/maxmalysh/disposable-emails/master/disposable_emails/data/domains.txt") }
|
172
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/jespernissen/disposable-maildomain-list/master/disposable-maildomain-list.txt") }
|
173
|
+
threads << thread { load_github_url("https://raw.githubusercontent.com/wesbos/burner-email-providers/master/emails.txt") }
|
174
|
+
threads << thread { load_github_url("https://gist.github.com/fnando/dafe542cac13f831bbf5521a55248116/raw/disposable.txt") }
|
175
|
+
threads << thread { ten_minute_mail }
|
176
|
+
threads << thread { temp_mail }
|
177
|
+
threads << thread { temp_mail_address }
|
178
|
+
threads << thread { tempmail_io }
|
179
|
+
threads << thread { load_file("disposable/disposable_manually_added.txt") }
|
180
|
+
threads << thread { domain_scraping("guerrillamail", "https://www.guerrillamail.com/", "select option::attr(value)") }
|
181
|
+
threads << thread { domain_scraping("moakt", "https://www.moakt.com", "select option::attr(value)") }
|
182
|
+
threads << thread { domain_scraping("tempr", "https://tempr.email/", "select[name=DomainId] option::text()") }
|
183
|
+
threads << thread { domain_scraping("yepmail", "https://yepmail.co/", "select[name=domain] option::text()") }
|
184
|
+
threads << thread { domain_scraping("fake_email_generator", "https://fakemailgenerator.net", "[data-mailhost]::attr(data-mailhost)") }
|
185
|
+
threads << thread { domain_scraping("tempemails", "https://www.tempemails.net/", "select[name=domain] option::attr(value)") }
|
186
|
+
threads << thread { domain_scraping("clipmails", "https://clipmails.com/", "select[name=domain] option::attr(value)") }
|
187
|
+
threads << thread { domain_scraping("1secmail", "https://www.1secmail.com/", "select[id=domain] option::attr(value)") }
|
188
|
+
threads << thread { domain_scraping("emailfake", "https://generator.email", ".tt-suggestion p::text()") }
|
189
|
+
threads << thread { domain_scraping("emailfake", "https://emailfake.com/", ".tt-suggestion p::text()") }
|
190
|
+
threads << thread { domain_scraping("emailfake", "https://email-fake.com/", ".tt-suggestion p::text()") }
|
191
|
+
threads << thread { domain_scraping("receivemail", "https://www.receivemail.org/", "select[name=domain] option::text()") }
|
192
|
+
threads << thread { domain_scraping("itemp", "https://itemp.email", "select[name=domain] option::text()") }
|
193
|
+
threads << thread { domain_scraping("cs", "https://www.cs.email", "select[id=gm-host-select] option::text()") }
|
194
|
+
threads << thread { domain_scraping("tempmail", "https://tempmail.io/settings/", "select[id=domain] option::text()") }
|
195
|
+
threads << thread { domain_scraping("tempemail", "https://tempemail.co", "select[name=email_domain] option::text()") }
|
196
|
+
threads << thread { domain_scraping("tmail", "https://mytemp-email.com/", "a.domain-selector::text()") }
|
200
197
|
|
201
198
|
threads.each_slice(5) do |slice|
|
202
199
|
slice.each(&:join)
|
@@ -204,17 +201,30 @@ end
|
|
204
201
|
|
205
202
|
threads.clear
|
206
203
|
|
207
|
-
|
208
|
-
|
204
|
+
domains = []
|
205
|
+
|
206
|
+
puts "=> Loading disposable_domains.txt"
|
207
|
+
domains += File.read("#{__dir__}/../data/disposable_domains.txt").lines.map(&:chomp)
|
208
|
+
|
209
|
+
puts "=> Loading disposable/*.txt"
|
210
|
+
Dir["./data/disposable/**/*.txt"].map do |file|
|
211
|
+
file = File.expand_path(file)
|
212
|
+
domains += File.read(file).lines.map(&:chomp).flatten.compact
|
213
|
+
end
|
209
214
|
|
210
|
-
|
211
|
-
domains = root_domains(domains)
|
215
|
+
ignore_domains = %w[gmail.com hotmail.com]
|
212
216
|
|
213
|
-
|
214
|
-
|
217
|
+
puts "=> Normalize domains (count: #{domains.size})"
|
218
|
+
domains = domains
|
219
|
+
.uniq
|
220
|
+
.map {|domain| RootDomain.call(domain.split("@").last.downcase) }
|
221
|
+
.compact
|
222
|
+
.uniq
|
223
|
+
.reject {|domain| ignore_domains.include?(domain) }
|
215
224
|
|
216
|
-
|
217
|
-
save_file("
|
225
|
+
puts "=> Saving domains (count: #{domains.size})"
|
226
|
+
save_file("disposable_domains.txt", domains)
|
218
227
|
|
219
|
-
|
220
|
-
|
228
|
+
emails = gmailnator
|
229
|
+
puts "=> Saving email proxies (count: #{emails.size})"
|
230
|
+
save_file("disposable_emails.txt", emails)
|
data/bin/sync-tld
CHANGED
@@ -10,11 +10,11 @@ tlds.map!(&:downcase)
|
|
10
10
|
tlds.map!(&:strip)
|
11
11
|
tlds.map! {|tld| SimpleIDN.to_ascii(tld) }
|
12
12
|
|
13
|
-
save_file("tld.
|
13
|
+
save_file("tld.txt", tlds)
|
14
14
|
|
15
15
|
country_tlds = JSON.parse(http_request(:get, "https://github.com/samayo/country-json/raw/master/src/country-by-domain-tld.json").body, symbolize_names: true)
|
16
16
|
country_tlds = country_tlds
|
17
17
|
.reject {|info| info[:tld].nil? }
|
18
18
|
.map {|info| info[:tld].gsub(/^\./, "") }
|
19
19
|
|
20
|
-
save_file("country_tlds.
|
20
|
+
save_file("country_tlds.txt", country_tlds)
|
@@ -0,0 +1,235 @@
|
|
1
|
+
ad
|
2
|
+
ae
|
3
|
+
af
|
4
|
+
ag
|
5
|
+
ai
|
6
|
+
al
|
7
|
+
am
|
8
|
+
an
|
9
|
+
ao
|
10
|
+
aq
|
11
|
+
ar
|
12
|
+
as
|
13
|
+
at
|
14
|
+
au
|
15
|
+
aw
|
16
|
+
az
|
17
|
+
ba
|
18
|
+
bb
|
19
|
+
bd
|
20
|
+
be
|
21
|
+
bf
|
22
|
+
bg
|
23
|
+
bh
|
24
|
+
bi
|
25
|
+
bj
|
26
|
+
bm
|
27
|
+
bn
|
28
|
+
bo
|
29
|
+
br
|
30
|
+
bs
|
31
|
+
bt
|
32
|
+
bv
|
33
|
+
bw
|
34
|
+
by
|
35
|
+
bz
|
36
|
+
ca
|
37
|
+
cc
|
38
|
+
cd
|
39
|
+
cf
|
40
|
+
cg
|
41
|
+
ch
|
42
|
+
ci
|
43
|
+
ck
|
44
|
+
cl
|
45
|
+
cm
|
46
|
+
cn
|
47
|
+
co
|
48
|
+
cr
|
49
|
+
cu
|
50
|
+
cv
|
51
|
+
cx
|
52
|
+
cy
|
53
|
+
cz
|
54
|
+
de
|
55
|
+
dj
|
56
|
+
dk
|
57
|
+
dm
|
58
|
+
do
|
59
|
+
dz
|
60
|
+
ec
|
61
|
+
ee
|
62
|
+
eg
|
63
|
+
eh
|
64
|
+
er
|
65
|
+
es
|
66
|
+
et
|
67
|
+
fi
|
68
|
+
fj
|
69
|
+
fk
|
70
|
+
fr
|
71
|
+
ga
|
72
|
+
gb
|
73
|
+
gd
|
74
|
+
ge
|
75
|
+
gf
|
76
|
+
gh
|
77
|
+
gi
|
78
|
+
gl
|
79
|
+
gm
|
80
|
+
gn
|
81
|
+
gp
|
82
|
+
gq
|
83
|
+
gr
|
84
|
+
gs
|
85
|
+
gt
|
86
|
+
gu
|
87
|
+
gw
|
88
|
+
gy
|
89
|
+
hk
|
90
|
+
hm
|
91
|
+
hn
|
92
|
+
hr
|
93
|
+
ht
|
94
|
+
hu
|
95
|
+
id
|
96
|
+
ie
|
97
|
+
il
|
98
|
+
in
|
99
|
+
io
|
100
|
+
iq
|
101
|
+
ir
|
102
|
+
is
|
103
|
+
it
|
104
|
+
jm
|
105
|
+
jo
|
106
|
+
jp
|
107
|
+
ke
|
108
|
+
kg
|
109
|
+
kh
|
110
|
+
ki
|
111
|
+
km
|
112
|
+
kn
|
113
|
+
kp
|
114
|
+
kr
|
115
|
+
kw
|
116
|
+
ky
|
117
|
+
kz
|
118
|
+
la
|
119
|
+
lb
|
120
|
+
lc
|
121
|
+
li
|
122
|
+
lk
|
123
|
+
lr
|
124
|
+
ls
|
125
|
+
lt
|
126
|
+
lu
|
127
|
+
lv
|
128
|
+
ly
|
129
|
+
ma
|
130
|
+
mc
|
131
|
+
md
|
132
|
+
mg
|
133
|
+
mh
|
134
|
+
mk
|
135
|
+
ml
|
136
|
+
mm
|
137
|
+
mn
|
138
|
+
mo
|
139
|
+
mp
|
140
|
+
mq
|
141
|
+
mr
|
142
|
+
ms
|
143
|
+
mt
|
144
|
+
mu
|
145
|
+
mv
|
146
|
+
mw
|
147
|
+
mx
|
148
|
+
my
|
149
|
+
mz
|
150
|
+
na
|
151
|
+
nc
|
152
|
+
ne
|
153
|
+
nf
|
154
|
+
ng
|
155
|
+
ni
|
156
|
+
nl
|
157
|
+
no
|
158
|
+
np
|
159
|
+
nr
|
160
|
+
nu
|
161
|
+
nz
|
162
|
+
om
|
163
|
+
pa
|
164
|
+
pe
|
165
|
+
pf
|
166
|
+
pg
|
167
|
+
ph
|
168
|
+
pk
|
169
|
+
pl
|
170
|
+
pm
|
171
|
+
pn
|
172
|
+
pr
|
173
|
+
ps
|
174
|
+
pt
|
175
|
+
pw
|
176
|
+
py
|
177
|
+
qa
|
178
|
+
re
|
179
|
+
ro
|
180
|
+
ru
|
181
|
+
rw
|
182
|
+
sa
|
183
|
+
sb
|
184
|
+
sc
|
185
|
+
sd
|
186
|
+
se
|
187
|
+
sg
|
188
|
+
sh
|
189
|
+
si
|
190
|
+
sj
|
191
|
+
sk
|
192
|
+
sl
|
193
|
+
sm
|
194
|
+
sn
|
195
|
+
so
|
196
|
+
sr
|
197
|
+
ss
|
198
|
+
st
|
199
|
+
sv
|
200
|
+
sy
|
201
|
+
sz
|
202
|
+
tc
|
203
|
+
td
|
204
|
+
tf
|
205
|
+
tg
|
206
|
+
th
|
207
|
+
tj
|
208
|
+
tk
|
209
|
+
tl
|
210
|
+
tm
|
211
|
+
tn
|
212
|
+
to
|
213
|
+
tr
|
214
|
+
tt
|
215
|
+
tv
|
216
|
+
tz
|
217
|
+
ua
|
218
|
+
ug
|
219
|
+
us
|
220
|
+
uy
|
221
|
+
uz
|
222
|
+
va
|
223
|
+
vc
|
224
|
+
ve
|
225
|
+
vg
|
226
|
+
vi
|
227
|
+
vn
|
228
|
+
vu
|
229
|
+
wf
|
230
|
+
ws
|
231
|
+
ye
|
232
|
+
yt
|
233
|
+
za
|
234
|
+
zm
|
235
|
+
zw
|