validators 3.2.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +3 -0
  4. data/README.md +4 -4
  5. data/bin/sync-disposable-hostnames +120 -110
  6. data/bin/sync-tld +2 -2
  7. data/data/country_tlds.txt +235 -0
  8. data/data/disposable_domains.txt +110996 -0
  9. data/data/disposable_emails.txt +38 -0
  10. data/data/reserved_subdomains.txt +2830 -0
  11. data/data/tld.txt +1508 -0
  12. data/lib/validators.rb +1 -0
  13. data/lib/validators/constants.rb +1 -1
  14. data/lib/validators/disposable_emails.rb +19 -0
  15. data/lib/validators/disposable_hostnames.rb +2 -2
  16. data/lib/validators/locale/en.yml +2 -1
  17. data/lib/validators/locale/pt-BR.yml +1 -0
  18. data/lib/validators/reserved_subdomains.rb +2 -4
  19. data/lib/validators/tld.rb +2 -2
  20. data/lib/validators/validates_email_format_of.rb +19 -4
  21. data/lib/validators/version.rb +2 -2
  22. data/test/test_helper.rb +17 -1
  23. data/test/validators/disposable_email_test.rb +18 -5
  24. data/test/validators/validates_email_format_of_test.rb +4 -2
  25. data/validators.gemspec +3 -0
  26. metadata +53 -43
  27. data/data/country_tlds.json +0 -237
  28. data/data/disposable.json +0 -128
  29. data/data/disposable/10minutemail.json +0 -3
  30. data/data/disposable/1secmail.json +0 -5
  31. data/data/disposable/FGRibreau_mailchecker.json +0 -33602
  32. data/data/disposable/andreis_disposable_email_domains.json +0 -48320
  33. data/data/disposable/clipmails.json +0 -27
  34. data/data/disposable/cs.json +0 -15
  35. data/data/disposable/emailfake.json +0 -128
  36. data/data/disposable/fake_email_generator.json +0 -11
  37. data/data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json +0 -20
  38. data/data/disposable/gmailnator.json +0 -3
  39. data/data/disposable/guerrillamail.json +0 -13
  40. data/data/disposable/ically.json +0 -28
  41. data/data/disposable/itemp.json +0 -4
  42. data/data/disposable/ivolo_disposable_email_domains.json +0 -48177
  43. data/data/disposable/jespernissen_disposable_maildomain_list.json +0 -2372
  44. data/data/disposable/maxmalysh_disposable_emails.json +0 -21372
  45. data/data/disposable/moakt.json +0 -12
  46. data/data/disposable/receivemail.json +0 -9
  47. data/data/disposable/sneakykiwi_LeagueCreatorPublic.json +0 -2364
  48. data/data/disposable/tempemail.json +0 -7
  49. data/data/disposable/tempemails.json +0 -10
  50. data/data/disposable/tempmail.json +0 -31
  51. data/data/disposable/tempmail_io.json +0 -8
  52. data/data/disposable/tempmailaddress.json +0 -4
  53. data/data/disposable/tempomail.json +0 -3
  54. data/data/disposable/tempr.json +0 -97
  55. data/data/disposable/tmail.json +0 -3
  56. data/data/disposable/wesbos_burner_email_providers.json +0 -4711
  57. data/data/disposable/willwhite_freemail.json +0 -352
  58. data/data/disposable/yepmail.json +0 -12
  59. data/data/disposable_emails.json +0 -3
  60. data/data/disposable_patterns.json +0 -3
  61. data/data/disposable_raw.json +0 -128
  62. data/data/reserved_subdomains.json +0 -2838
  63. data/data/sld.json +0 -5564
  64. data/data/tld.json +0 -1518
@@ -8,6 +8,7 @@ module Validators
8
8
  require "validators/tld"
9
9
  require "validators/hostname"
10
10
  require "validators/disposable_hostnames"
11
+ require "validators/disposable_emails"
11
12
  require "validators/reserved_subdomains"
12
13
 
13
14
  require "validators/validates_datetime"
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Validators
4
4
  EMAIL_FORMAT = /\A[a-z0-9]+([-._][a-z0-9]+)*(\+[^@]+)?@[a-z0-9]+([.-][a-z0-9]+)*\.[a-z]{2,}\z/i.freeze
5
- MICROSOFT_EMAIL_FORMAT = /\A[\w][\w\d._-]*[\w\d_-]+(\+[\w\d]+)?@(hotmail|outlook).com\z/i.freeze
5
+ MICROSOFT_EMAIL_FORMAT = /\A[a-z0-9][a-z0-9._-]*[a-z0-9_-]+(\+[a-z0-9]+)?@(hotmail|outlook).com\z/i.freeze
6
6
 
7
7
  # Source: https://github.com/henrik/validates_url_format_of
8
8
  IPV4_PART = /\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]/.freeze # 0-255
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Validators
4
+ class DisposableEmails
5
+ FILE_PATH = File.expand_path("../../data/disposable_emails.txt", __dir__)
6
+
7
+ def self.all
8
+ @all ||= File.read(FILE_PATH).lines.map(&:chomp)
9
+ end
10
+
11
+ def self.include?(email)
12
+ mailbox, domain = email.to_s.split("@")
13
+ mailbox = mailbox.to_s.gsub(".", "")
14
+ mailbox = mailbox.gsub(/\+(.+)?\Z/, "")
15
+
16
+ all.include?("#{mailbox}@#{domain}")
17
+ end
18
+ end
19
+ end
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Validators
4
4
  class DisposableHostnames
5
- FILE_PATH = File.expand_path("../../data/disposable.json", __dir__)
5
+ FILE_PATH = File.expand_path("../../data/disposable_domains.txt", __dir__)
6
6
 
7
7
  def self.all
8
- @all ||= JSON.parse(File.read(FILE_PATH))
8
+ @all ||= File.read(FILE_PATH).lines.map(&:chomp)
9
9
  end
10
10
  end
11
11
  end
@@ -3,7 +3,8 @@ en:
3
3
  activemodel: &activemodel
4
4
  errors:
5
5
  messages:
6
- disposable_email: "is not allowed (high-bounce domain)"
6
+ disposable_email: "is not allowed (high-bounce email)"
7
+ disposable_domain: "is not allowed (high-bounce domain)"
7
8
  invalid_cnpj: "is not a valid CNPJ"
8
9
  invalid_cpf: "is not a valid CPF"
9
10
  invalid_date: "is not a valid date"
@@ -4,6 +4,7 @@ pt-BR:
4
4
  errors:
5
5
  messages:
6
6
  disposable_email: "não é permitido (e-mail temporário)"
7
+ disposable_domain: "não é permitido (e-mail temporário)"
7
8
  invalid_cnpj: "não é um CNPJ válido"
8
9
  invalid_cpf: "não é um CPF válido"
9
10
  invalid_date: "não é uma data válida"
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Validators
4
4
  class ReservedSubdomains
5
- FILE_PATH = File.expand_path("../../data/reserved_subdomains.json", __dir__)
5
+ FILE_PATH = File.expand_path("../../data/reserved_subdomains.txt", __dir__)
6
6
 
7
7
  def self.reserved?(hostname, matchers = nil)
8
8
  matchers = parse_list(matchers) if matchers
@@ -11,9 +11,7 @@ module Validators
11
11
  end
12
12
 
13
13
  def self.all
14
- @all ||= JSON
15
- .parse(File.read(FILE_PATH))
16
- .map {|matcher| parse(matcher) }
14
+ @all ||= File.read(FILE_PATH).lines.map {|matcher| parse(matcher.chomp) }
17
15
  end
18
16
 
19
17
  def self.parse(matcher)
@@ -2,10 +2,10 @@
2
2
 
3
3
  module Validators
4
4
  class TLD
5
- FILE_PATH = File.expand_path("../../data/tld.json", __dir__)
5
+ FILE_PATH = File.expand_path("../../data/tld.txt", __dir__)
6
6
 
7
7
  def self.all
8
- @all ||= JSON.parse(File.read(FILE_PATH))
8
+ @all ||= File.read(FILE_PATH).lines.map(&:chomp)
9
9
  end
10
10
 
11
11
  def self.host_with_valid_tld?(host)
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "root_domain"
4
+
3
5
  module ActiveModel
4
6
  module Validations
5
7
  class EmailValidator < EachValidator
@@ -14,6 +16,7 @@ module ActiveModel
14
16
 
15
17
  validate_tld(record, attribute, value, options) if check_tld
16
18
  validate_email_format(record, attribute, value, options)
19
+ validate_disposable_domain(record, attribute, value, options) unless allow_disposable
17
20
  validate_disposable_email(record, attribute, value, options) unless allow_disposable
18
21
  end
19
22
 
@@ -41,12 +44,24 @@ module ActiveModel
41
44
  )
42
45
  end
43
46
 
44
- def validate_disposable_email(record, attribute, value, _options)
47
+ def validate_disposable_domain(record, attribute, value, _options)
48
+ return unless value
49
+
45
50
  hostname = value.to_s.split(AT_SIGN).last.to_s.downcase
51
+ root_domain = RootDomain.call(hostname)
46
52
 
47
- return if Validators::DisposableHostnames.all.none? do |disposable_hostname|
48
- hostname == disposable_hostname || hostname.end_with?(".#{disposable_hostname}")
49
- end
53
+ return unless Validators::DisposableHostnames.all.include?(root_domain)
54
+
55
+ record.errors.add(
56
+ attribute,
57
+ :disposable_domain,
58
+ value: value
59
+ )
60
+ end
61
+
62
+ def validate_disposable_email(record, attribute, value, _options)
63
+ return unless value
64
+ return unless Validators::DisposableEmails.include?(value)
50
65
 
51
66
  record.errors.add(
52
67
  attribute,
@@ -3,8 +3,8 @@
3
3
  module Validators
4
4
  module Version
5
5
  MAJOR = 3
6
- MINOR = 2
7
- PATCH = 1
6
+ MINOR = 3
7
+ PATCH = 0
8
8
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
9
9
  end
10
10
  end
@@ -17,9 +17,25 @@ require "active_support/all"
17
17
  require "minitest/utils"
18
18
  require "minitest/autorun"
19
19
 
20
+ def build_email_with_filter(email)
21
+ mailbox, domain = email.split("@")
22
+ "#{mailbox}+#{SecureRandom.hex(3)}@#{domain}"
23
+ end
24
+
25
+ def build_email_with_dots(email)
26
+ mailbox, domain = email.split("@")
27
+ new_mailbox = mailbox.chars.map {|char| [char, "."] }.flatten[0..-2].join
28
+
29
+ "#{new_mailbox}@#{domain}"
30
+ end
31
+
20
32
  Time.zone = "America/Sao_Paulo"
21
33
  TLDs = Validators::TLD.all.sample(10)
22
- DISPOSABLE_EMAILS = Validators::DisposableHostnames.all.sample(10)
34
+ DISPOSABLE_DOMAINS = Validators::DisposableHostnames.all.sample(10)
35
+ DISPOSABLE_EMAILS = Validators::DisposableEmails.all +
36
+ Validators::DisposableEmails.all.sample(10).map {|email| build_email_with_filter(email) } +
37
+ Validators::DisposableEmails.all.sample(10).map {|email| build_email_with_dots(email) } +
38
+ Validators::DisposableEmails.all.sample(10).map {|email| build_email_with_filter(build_email_with_dots(email)) }
23
39
 
24
40
  Dir[File.join(__dir__, "support/**/*.rb")].sort.each {|f| require f }
25
41
 
@@ -3,18 +3,19 @@
3
3
  require "test_helper"
4
4
 
5
5
  class DisposableEmailTest < Minitest::Test
6
- DISPOSABLE_EMAILS.each do |domain|
7
- test "rejects disposable e-mail (#{domain})" do
6
+ DISPOSABLE_DOMAINS.each do |domain|
7
+ test "rejects disposable domain (#{domain})" do
8
8
  User.validates_email_format_of :email
9
9
 
10
10
  user = User.new(email: "user@#{domain}")
11
11
  user.valid?
12
12
 
13
- assert_includes user.errors[:email], I18n.t("activerecord.errors.messages.disposable_email")
13
+ assert_includes user.errors[:email],
14
+ I18n.t("activerecord.errors.messages.disposable_domain")
14
15
  end
15
16
  end
16
17
 
17
- DISPOSABLE_EMAILS.each do |domain|
18
+ DISPOSABLE_DOMAINS.each do |domain|
18
19
  test "rejects disposable e-mail with subdomain (custom.#{domain})" do
19
20
  User.validates_email_format_of :email
20
21
 
@@ -22,7 +23,7 @@ class DisposableEmailTest < Minitest::Test
22
23
  user.valid?
23
24
 
24
25
  assert_includes user.errors[:email],
25
- "is not allowed (high-bounce domain)"
26
+ I18n.t("activerecord.errors.messages.disposable_domain")
26
27
  end
27
28
  end
28
29
 
@@ -34,4 +35,16 @@ class DisposableEmailTest < Minitest::Test
34
35
 
35
36
  assert user.errors[:email].empty?
36
37
  end
38
+
39
+ DISPOSABLE_EMAILS.each do |email|
40
+ test "rejects disposable e-mail (#{email})" do
41
+ User.validates_email_format_of :email
42
+
43
+ user = User.new(email: email)
44
+ user.valid?
45
+
46
+ assert_includes user.errors[:email],
47
+ I18n.t("activerecord.errors.messages.disposable_email")
48
+ end
49
+ end
37
50
  end
@@ -12,10 +12,12 @@ class ValidatesEmailFormatOfTest < Minitest::Test
12
12
  VALID_EMAILS.each do |email|
13
13
  test "accepts #{email.inspect} as a valid email" do
14
14
  user = User.new(email: email, corporate_email: email)
15
- assert user.valid?
15
+ user.valid?
16
+ assert_empty user.errors
16
17
 
17
18
  user = Person.new(email: email)
18
- assert user.valid?
19
+ user.valid?
20
+ assert_empty user.errors
19
21
  end
20
22
  end
21
23
 
@@ -28,6 +28,7 @@ Gem::Specification.new do |s|
28
28
  s.add_development_dependency "nokogiri"
29
29
  s.add_development_dependency "pry-meta"
30
30
  s.add_development_dependency "rake"
31
+ s.add_development_dependency "root_domain"
31
32
  s.add_development_dependency "rubocop"
32
33
  s.add_development_dependency "rubocop-fnando"
33
34
  s.add_development_dependency "simplecov"
@@ -35,4 +36,6 @@ Gem::Specification.new do |s|
35
36
  s.add_development_dependency "simpleidn"
36
37
  s.add_development_dependency "sqlite3", "~> 1.4"
37
38
  s.add_development_dependency "sshkey"
39
+ s.add_development_dependency "whois"
40
+ s.add_development_dependency "whois-parser"
38
41
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: validators
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.1
4
+ version: 3.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-10 00:00:00.000000000 Z
11
+ date: 2020-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -122,6 +122,20 @@ dependencies:
122
122
  - - ">="
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: root_domain
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
125
139
  - !ruby/object:Gem::Dependency
126
140
  name: rubocop
127
141
  requirement: !ruby/object:Gem::Requirement
@@ -220,6 +234,34 @@ dependencies:
220
234
  - - ">="
221
235
  - !ruby/object:Gem::Version
222
236
  version: '0'
237
+ - !ruby/object:Gem::Dependency
238
+ name: whois
239
+ requirement: !ruby/object:Gem::Requirement
240
+ requirements:
241
+ - - ">="
242
+ - !ruby/object:Gem::Version
243
+ version: '0'
244
+ type: :development
245
+ prerelease: false
246
+ version_requirements: !ruby/object:Gem::Requirement
247
+ requirements:
248
+ - - ">="
249
+ - !ruby/object:Gem::Version
250
+ version: '0'
251
+ - !ruby/object:Gem::Dependency
252
+ name: whois-parser
253
+ requirement: !ruby/object:Gem::Requirement
254
+ requirements:
255
+ - - ">="
256
+ - !ruby/object:Gem::Version
257
+ version: '0'
258
+ type: :development
259
+ prerelease: false
260
+ version_requirements: !ruby/object:Gem::Requirement
261
+ requirements:
262
+ - - ">="
263
+ - !ruby/object:Gem::Version
264
+ version: '0'
223
265
  description: Add some nice ActiveModel/ActiveRecord validators.
224
266
  email:
225
267
  - fnando.vieira@gmail.com
@@ -237,46 +279,14 @@ files:
237
279
  - Rakefile
238
280
  - bin/sync-disposable-hostnames
239
281
  - bin/sync-tld
240
- - data/country_tlds.json
241
- - data/disposable.json
242
- - data/disposable/10minutemail.json
243
- - data/disposable/1secmail.json
244
- - data/disposable/FGRibreau_mailchecker.json
245
- - data/disposable/andreis_disposable_email_domains.json
246
- - data/disposable/clipmails.json
247
- - data/disposable/cs.json
248
- - data/disposable/emailfake.json
249
- - data/disposable/fake_email_generator.json
250
- - data/disposable/fnando_dafe542cac13f831bbf5521a55248116.json
251
- - data/disposable/gmailnator.json
252
- - data/disposable/guerrillamail.json
253
- - data/disposable/ically.json
254
- - data/disposable/itemp.json
255
- - data/disposable/ivolo_disposable_email_domains.json
256
- - data/disposable/jespernissen_disposable_maildomain_list.json
257
- - data/disposable/maxmalysh_disposable_emails.json
258
- - data/disposable/moakt.json
259
- - data/disposable/receivemail.json
260
- - data/disposable/sneakykiwi_LeagueCreatorPublic.json
261
- - data/disposable/tempemail.json
262
- - data/disposable/tempemails.json
263
- - data/disposable/tempmail.json
264
- - data/disposable/tempmail_io.json
265
- - data/disposable/tempmailaddress.json
266
- - data/disposable/tempomail.json
267
- - data/disposable/tempr.json
268
- - data/disposable/tmail.json
269
- - data/disposable/wesbos_burner_email_providers.json
270
- - data/disposable/willwhite_freemail.json
271
- - data/disposable/yepmail.json
272
- - data/disposable_emails.json
273
- - data/disposable_patterns.json
274
- - data/disposable_raw.json
275
- - data/reserved_subdomains.json
276
- - data/sld.json
277
- - data/tld.json
282
+ - data/country_tlds.txt
283
+ - data/disposable_domains.txt
284
+ - data/disposable_emails.txt
285
+ - data/reserved_subdomains.txt
286
+ - data/tld.txt
278
287
  - lib/validators.rb
279
288
  - lib/validators/constants.rb
289
+ - lib/validators/disposable_emails.rb
280
290
  - lib/validators/disposable_hostnames.rb
281
291
  - lib/validators/hostname.rb
282
292
  - lib/validators/ip.rb
@@ -333,7 +343,7 @@ homepage: http://rubygems.org/gems/validators
333
343
  licenses:
334
344
  - MIT
335
345
  metadata: {}
336
- post_install_message:
346
+ post_install_message:
337
347
  rdoc_options: []
338
348
  require_paths:
339
349
  - lib
@@ -349,7 +359,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
349
359
  version: '0'
350
360
  requirements: []
351
361
  rubygems_version: 3.1.2
352
- signing_key:
362
+ signing_key:
353
363
  specification_version: 4
354
364
  summary: Add some nice ActiveModel/ActiveRecord validators.
355
365
  test_files:
@@ -1,237 +0,0 @@
1
- [
2
- "ad",
3
- "ae",
4
- "af",
5
- "ag",
6
- "ai",
7
- "al",
8
- "am",
9
- "an",
10
- "ao",
11
- "aq",
12
- "ar",
13
- "as",
14
- "at",
15
- "au",
16
- "aw",
17
- "az",
18
- "ba",
19
- "bb",
20
- "bd",
21
- "be",
22
- "bf",
23
- "bg",
24
- "bh",
25
- "bi",
26
- "bj",
27
- "bm",
28
- "bn",
29
- "bo",
30
- "br",
31
- "bs",
32
- "bt",
33
- "bv",
34
- "bw",
35
- "by",
36
- "bz",
37
- "ca",
38
- "cc",
39
- "cd",
40
- "cf",
41
- "cg",
42
- "ch",
43
- "ci",
44
- "ck",
45
- "cl",
46
- "cm",
47
- "cn",
48
- "co",
49
- "cr",
50
- "cu",
51
- "cv",
52
- "cx",
53
- "cy",
54
- "cz",
55
- "de",
56
- "dj",
57
- "dk",
58
- "dm",
59
- "do",
60
- "dz",
61
- "ec",
62
- "ee",
63
- "eg",
64
- "eh",
65
- "er",
66
- "es",
67
- "et",
68
- "fi",
69
- "fj",
70
- "fk",
71
- "fr",
72
- "ga",
73
- "gb",
74
- "gd",
75
- "ge",
76
- "gf",
77
- "gh",
78
- "gi",
79
- "gl",
80
- "gm",
81
- "gn",
82
- "gp",
83
- "gq",
84
- "gr",
85
- "gs",
86
- "gt",
87
- "gu",
88
- "gw",
89
- "gy",
90
- "hk",
91
- "hm",
92
- "hn",
93
- "hr",
94
- "ht",
95
- "hu",
96
- "id",
97
- "ie",
98
- "il",
99
- "in",
100
- "io",
101
- "iq",
102
- "ir",
103
- "is",
104
- "it",
105
- "jm",
106
- "jo",
107
- "jp",
108
- "ke",
109
- "kg",
110
- "kh",
111
- "ki",
112
- "km",
113
- "kn",
114
- "kp",
115
- "kr",
116
- "kw",
117
- "ky",
118
- "kz",
119
- "la",
120
- "lb",
121
- "lc",
122
- "li",
123
- "lk",
124
- "lr",
125
- "ls",
126
- "lt",
127
- "lu",
128
- "lv",
129
- "ly",
130
- "ma",
131
- "mc",
132
- "md",
133
- "mg",
134
- "mh",
135
- "mk",
136
- "ml",
137
- "mm",
138
- "mn",
139
- "mo",
140
- "mp",
141
- "mq",
142
- "mr",
143
- "ms",
144
- "mt",
145
- "mu",
146
- "mv",
147
- "mw",
148
- "mx",
149
- "my",
150
- "mz",
151
- "na",
152
- "nc",
153
- "ne",
154
- "nf",
155
- "ng",
156
- "ni",
157
- "nl",
158
- "no",
159
- "np",
160
- "nr",
161
- "nu",
162
- "nz",
163
- "om",
164
- "pa",
165
- "pe",
166
- "pf",
167
- "pg",
168
- "ph",
169
- "pk",
170
- "pl",
171
- "pm",
172
- "pn",
173
- "pr",
174
- "ps",
175
- "pt",
176
- "pw",
177
- "py",
178
- "qa",
179
- "re",
180
- "ro",
181
- "ru",
182
- "rw",
183
- "sa",
184
- "sb",
185
- "sc",
186
- "sd",
187
- "se",
188
- "sg",
189
- "sh",
190
- "si",
191
- "sj",
192
- "sk",
193
- "sl",
194
- "sm",
195
- "sn",
196
- "so",
197
- "sr",
198
- "ss",
199
- "st",
200
- "sv",
201
- "sy",
202
- "sz",
203
- "tc",
204
- "td",
205
- "tf",
206
- "tg",
207
- "th",
208
- "tj",
209
- "tk",
210
- "tl",
211
- "tm",
212
- "tn",
213
- "to",
214
- "tr",
215
- "tt",
216
- "tv",
217
- "tz",
218
- "ua",
219
- "ug",
220
- "us",
221
- "uy",
222
- "uz",
223
- "va",
224
- "vc",
225
- "ve",
226
- "vg",
227
- "vi",
228
- "vn",
229
- "vu",
230
- "wf",
231
- "ws",
232
- "ye",
233
- "yt",
234
- "za",
235
- "zm",
236
- "zw"
237
- ]