ehbrs_ruby_utils 0.38.0 → 0.40.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 375d67ec113f9773d1c7f89211884746357a5a56078b21d4f3dd0780385f87ac
4
- data.tar.gz: fc600162f063b6c2bcd529876687422d62abcb2b663f0903f234b1724c7147a5
3
+ metadata.gz: 86fcf26dbec53e9e7e2b04d2197849a7f17ad0850b07d4420e26a115841c3a32
4
+ data.tar.gz: 3a62e456a9d8965f914b47ccd483a92656058cc0a59f99aef595c772fdfeb05e
5
5
  SHA512:
6
- metadata.gz: 3e5e2d657e5fec5a8938a70cb69616572dea93bfbce5b855f5e34f8b2d9d621a6cf0de651cec2420873fd437997e0ee146d67bcbffbcaf0f35df6174cb51c66b
7
- data.tar.gz: c23ae3131b15e9f96d8b59072950b916e36e52b4cfdf60c32498becc377d666acaefcd7e6a82f91c693bdb33bf689a3248f78af0057c2482b87bc085449ed550
6
+ metadata.gz: 171835d362844886ba8032527dd298a8da9913b9a699570686252a35209c8976e77e658ef9ca22a2e386313386a68a1dfc064298832bc9e4a8c622be6a06f89a
7
+ data.tar.gz: 1b03d32256cbf9e3e27dafd52acaac5ae977a0911d014da72ef97b9ef3ba3ff10e66b62208b139d60a42efc0626b320ba226c6b24dfd1cdbab3310b0eeb3cce6
@@ -5,7 +5,7 @@ require 'eac_ruby_utils/core_ext'
5
5
  module EhbrsRubyUtils
6
6
  module Bga
7
7
  class Game
8
- common_constructor :code
8
+ common_constructor :code, :name
9
9
 
10
10
  # @param suffix [String]
11
11
  # @return [EhbrsRubyUtils::Bga::Game::Image]
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Bga
7
+ class GameStatistics
8
+ class WhatsappFormatter
9
+ class PlayerContent
10
+ acts_as_instance_method
11
+ common_constructor :formatter, :player
12
+
13
+ # @return [Hash<String, String>]
14
+ def result
15
+ formatter.ranks.to_h do |rank|
16
+ [rank_label(rank), rank_value(rank)]
17
+ end
18
+ end
19
+
20
+ # @param rank [Integer]
21
+ # @return [String]
22
+ def rank_label(rank)
23
+ "#{rank}º"
24
+ end
25
+
26
+ # @param rank [Integer]
27
+ # @return [String]
28
+ def rank_value(rank)
29
+ count = 0
30
+ formatter.normal_tables.each do |table|
31
+ count += 1 if table.player_by_id(player.id).if_present(false) do |v|
32
+ v.rank == rank
33
+ end
34
+ end
35
+ "#{count} (#{rank_percent(count)}%)"
36
+ end
37
+
38
+ # @param count [Integer]
39
+ # @return [String]
40
+ def rank_percent(count)
41
+ (count * 100 / formatter.normal_tables.count).round
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Bga
7
+ class GameStatistics
8
+ class WhatsappFormatter
9
+ class PlayerTitle
10
+ acts_as_instance_method
11
+ common_constructor :formatter, :player
12
+
13
+ # @return [String]
14
+ def result
15
+ username_by_tables || player.name
16
+ end
17
+
18
+ # @return [String, nil]
19
+ def username_by_tables
20
+ formatter.with_players_tables.lazy.map { |table| username_by_table(table) }
21
+ .find(&:present?)
22
+ end
23
+
24
+ # @param table [EhbrsRubyUtils::Bga::Table]
25
+ # @return [String, nil]
26
+ def username_by_table(table)
27
+ table.player_by_id(player.id).if_present(&:name)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+ require 'ehbrs_ruby_utils/bga/whatsapp_formatter'
5
+
6
+ module EhbrsRubyUtils
7
+ module Bga
8
+ class GameStatistics
9
+ class WhatsappFormatter
10
+ include ::EhbrsRubyUtils::Bga::WhatsappFormatter
11
+
12
+ ROOT_TITLE = 'Estatísticas'
13
+ TITLE_ICON = 0x1F4CA.chr(::Encoding::UTF_8)
14
+
15
+ enable_simple_cache
16
+ common_constructor :game_statistics
17
+ delegate :game, :friendly_tables_count, :normal_tables, :players, :until_table,
18
+ :with_players_tables, to: :game_statistics
19
+
20
+ # @return [Hash]
21
+ def root_content
22
+ r = { 'Jogo' => game.name, 'Mesas normais' => normal_tables.count,
23
+ 'Mesas amigáveis' => friendly_tables_count }
24
+ until_table.if_present { |v| r['Após mesa'] = v.url }
25
+ r
26
+ end
27
+
28
+ # @return [Hash<String, String>] "title" => "content"
29
+ def sections
30
+ r = { ROOT_TITLE => root_content }
31
+ players.each do |player|
32
+ r[player_title(player)] = player_content(player)
33
+ end
34
+ r
35
+ end
36
+
37
+ # @return [String]
38
+ def title_icon
39
+ TITLE_ICON
40
+ end
41
+
42
+ private
43
+
44
+ # @return [Array<Integer>]
45
+ def ranks_uncached
46
+ r = ::Set.new
47
+ normal_tables.each do |table|
48
+ table.players.each do |player|
49
+ r.add(player.rank)
50
+ end
51
+ end
52
+ r.sort
53
+ end
54
+
55
+ require_sub __FILE__, require_mode: :kernel
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Bga
7
+ class GameStatistics
8
+ enable_simple_cache
9
+ common_constructor :game, :game_tables, :players, :until_table, default: [nil]
10
+
11
+ # @return [Integer]
12
+ def friendly_tables_count
13
+ with_players_tables.count - normal_tables.count
14
+ end
15
+
16
+ private
17
+
18
+ # @return [Enumerable<EhbrsRubyUtils::Bga::Table>]
19
+ def normal_tables_uncached
20
+ with_players_tables.reject(&:friendly?)
21
+ end
22
+
23
+ # @param table [EhbrsRubyUtils::Bga::Table]
24
+ # @return [Boolean]
25
+ def with_players_table?(table)
26
+ table.players.count == players.count &&
27
+ players.all? { |player| table.player_by_id(player.id).present? }
28
+ end
29
+
30
+ # @return [Enumerable<EhbrsRubyUtils::Bga::Table>]
31
+ def with_players_tables_uncached
32
+ game_tables.select { |table| with_players_table?(table) }
33
+ end
34
+
35
+ require_sub __FILE__
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ehbrs_ruby_utils/bga/parsers/table/active_players'
4
+ require 'eac_ruby_utils/core_ext'
5
+
6
+ module EhbrsRubyUtils
7
+ module Bga
8
+ class Player
9
+ common_constructor :data
10
+
11
+ ::EhbrsRubyUtils::Bga::Parsers::Table::ActivePlayers.fields.map(&:name).each do |field|
12
+ define_method field do
13
+ data.fetch(field)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
+ require 'ehbrs_ruby_utils/bga/whatsapp_formatter/option'
4
5
 
5
6
  module EhbrsRubyUtils
6
7
  module Bga
@@ -11,8 +12,9 @@ module EhbrsRubyUtils
11
12
  acts_as_instance_method
12
13
  common_constructor :table_formatter, :option
13
14
 
15
+ # @return [String]
14
16
  def result
15
- "*#{option.label}:* #{option.value}"
17
+ ::EhbrsRubyUtils::Bga::WhatsappFormatter::Option.assert(option).to_s
16
18
  end
17
19
  end
18
20
  end
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'eac_ruby_utils/core_ext'
4
+ require 'ehbrs_ruby_utils/bga/whatsapp_formatter'
4
5
 
5
6
  module EhbrsRubyUtils
6
7
  module Bga
7
8
  class Table
8
9
  module WhatsappFormatters
9
10
  class Base
10
- acts_as_abstract :players_title, :root_items_title, :title_icon
11
+ include ::EhbrsRubyUtils::Bga::WhatsappFormatter
12
+ acts_as_abstract :players_title, :root_items_title
11
13
  enable_simple_cache
12
14
  common_constructor :table
13
15
 
@@ -18,24 +20,21 @@ module EhbrsRubyUtils
18
20
  'Duração' => :estimated_duration,
19
21
  'Endereço' => :url
20
22
  }.freeze
21
- SECTION_SEPARATOR = "\n\n"
22
23
 
23
- # @return [Pathname]
24
- def image_local_path
25
- table.game.box_large_image.local_path
26
- end
27
-
28
- def to_s
29
- [root_items_to_s, players_to_s, options_to_s].map(&:strip).join(SECTION_SEPARATOR)
30
- end
24
+ delegate :game, to: :table
31
25
 
32
- def root_items_to_s
33
- title_to_s(root_items_title) + ROOT_ITENS.map { |k, v| "*#{k}*: #{table.send(v)}" }
34
- .join("\n")
26
+ # @return [Hash<String, String>] "title" => "content"
27
+ def sections
28
+ {
29
+ root_items_title => root_items,
30
+ players_title => players_to_s,
31
+ 'Opções' => options
32
+ }
35
33
  end
36
34
 
37
- def options_to_s
38
- title_to_s('Opções') + options.join("\n")
35
+ # @return [Hash]
36
+ def root_items
37
+ ROOT_ITENS.transform_values { |v| table.send(v) }
39
38
  end
40
39
 
41
40
  # @return [String]
@@ -45,11 +44,7 @@ module EhbrsRubyUtils
45
44
 
46
45
  # @return [String]
47
46
  def players_to_s
48
- title_to_s(players_title) + players_extra + players.join("\n")
49
- end
50
-
51
- def title_to_s(title)
52
- "*#{[title_icon, title, title_icon].join(' ')}*\n\n"
47
+ players_extra + players.join("\n")
53
48
  end
54
49
 
55
50
  def players
@@ -13,6 +13,9 @@ module EhbrsRubyUtils
13
13
  enable_simple_cache
14
14
  common_constructor :data
15
15
 
16
+ GAME_MODE_KEY = 'Modo de Jogo'
17
+ GAME_MODE_FRIENDLY_VALUE = 'Modo Amigável'
18
+ GAME_MODE_NORMAL_VALUE = 'Modo Normal'
16
19
  SET_ITEMS = %i[options players].freeze
17
20
 
18
21
  ([:id] + ::EhbrsRubyUtils::Bga::Parsers::Table.fields.map(&:name) - SET_ITEMS)
@@ -22,11 +25,32 @@ module EhbrsRubyUtils
22
25
  end
23
26
  end
24
27
 
28
+ # @return [Boolean]
29
+ def friendly?
30
+ value = option_value(GAME_MODE_KEY)
31
+ return true if value == GAME_MODE_FRIENDLY_VALUE
32
+ return false if value == GAME_MODE_NORMAL_VALUE
33
+
34
+ raise "Unknown \"#{GAME_MODE_KEY}\" value: \"#{value}\""
35
+ end
36
+
25
37
  # @return [Boolean]
26
38
  def game_conceded?
27
39
  game_conceded
28
40
  end
29
41
 
42
+ # @param key [String]
43
+ # @return [String, nil]
44
+ def option_value(label)
45
+ options.find { |o| o.label == label }.if_present(&:value)
46
+ end
47
+
48
+ # @param id [Integer]
49
+ # @return [EhbrsRubyUtils::Bga::Table::Player, nil]
50
+ def player_by_id(id)
51
+ players.find { |p| p.id.to_s == id.to_s }
52
+ end
53
+
30
54
  # @return [Addressable::URI]
31
55
  def url
32
56
  table_url(id)
@@ -36,7 +60,7 @@ module EhbrsRubyUtils
36
60
 
37
61
  # @return [EhbrsRubyUtils::Bga::Game]
38
62
  def game_uncached
39
- ::EhbrsRubyUtils::Bga::Game.new(game_code)
63
+ ::EhbrsRubyUtils::Bga::Game.new(game_code, game_name)
40
64
  end
41
65
 
42
66
  SET_ITEMS.each do |item|
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Bga
7
+ module WhatsappFormatter
8
+ class Option
9
+ class << self
10
+ # @param obj [Object]
11
+ # @return [EhbrsRubyUtils::Bga::WhatsappFormatter::Option]
12
+ def assert(obj)
13
+ return obj if obj.is_a?(self)
14
+ return new(obj.label, obj.value) if obj.respond_to?(:label) && obj.respond_to?(:value)
15
+ return new(obj.fetch(:label), obj.fetch(:value)) if obj.is_a?(::Hash)
16
+ return new(*obj) if obj.is_a?(::Enumerable)
17
+
18
+ raise(::ArgumentError, "\"#{obj}\" não pôde ser convertido para #{self}")
19
+ end
20
+ end
21
+
22
+ common_constructor :label, :value
23
+
24
+ # @return [String]
25
+ def to_s
26
+ "*#{label}:* #{value}"
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'eac_ruby_utils/core_ext'
4
+
5
+ module EhbrsRubyUtils
6
+ module Bga
7
+ module WhatsappFormatter
8
+ common_concern do
9
+ acts_as_abstract
10
+ end
11
+
12
+ LINE_SEPARATOR = "\n"
13
+ OPTION_SEPARATOR = LINE_SEPARATOR
14
+ SECTION_SEPARATOR = "#{LINE_SEPARATOR}#{LINE_SEPARATOR}"
15
+
16
+ # @param content [String, Enumerable]
17
+ # @return [String]
18
+ def content_to_s(content)
19
+ if content.is_a?(::Hash)
20
+ content_to_s(
21
+ content.map { |k, v| ::EhbrsRubyUtils::Bga::WhatsappFormatter::Option.new(k, v) }
22
+ )
23
+ elsif content.is_a?(::Enumerable)
24
+ content.to_a.join(OPTION_SEPARATOR)
25
+ else
26
+ content.to_s
27
+ end
28
+ end
29
+
30
+ # @return [EhbrsRubyUtils::Bga::Game]
31
+ def game
32
+ raise_abstract_method __method__
33
+ end
34
+
35
+ # @return [Pathname]
36
+ def image_local_path
37
+ game.box_large_image.local_path
38
+ end
39
+
40
+ # @param options [Enumerable<EhbrsRubyUtils::Bga::WhatsappFormatters::Option>]
41
+ # @return [String]
42
+ def options_to_s(options)
43
+ options.map { |o| "#{o}#{OPTION_SEPARATOR}" }
44
+ end
45
+
46
+ # @param title {String]
47
+ # @param content {String]
48
+ # @return [String]
49
+ def section_to_s(title, content)
50
+ [title_to_s(title), content_to_s(content)].map(&:strip).join(SECTION_SEPARATOR)
51
+ end
52
+
53
+ # @return [Hash<String, String>] "title" => "content"
54
+ def sections
55
+ raise_abstract_method __method__
56
+ end
57
+
58
+ # @return [String]
59
+ def title_icon
60
+ raise_abstract_method __method__
61
+ end
62
+
63
+ def to_s
64
+ sections.map { |title, content| section_to_s(title, content) }.join(SECTION_SEPARATOR)
65
+ end
66
+
67
+ def title_to_s(title)
68
+ "*#{[title_icon, title, title_icon].join(' ')}*"
69
+ end
70
+ end
71
+ end
72
+ end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'ehbrs_ruby_utils/bga/session'
4
+ require 'ehbrs_ruby_utils/bga/game_statistics/whatsapp_formatter'
4
5
  require 'ehbrs_ruby_utils/executables'
5
6
  require 'ehbrs_ruby_utils/mudslide/message'
6
7
  require 'eac_ruby_utils/core_ext'
@@ -15,12 +16,21 @@ module EhbrsRubyUtils
15
16
  # @param table [EhbrsRubyUtils::Bga::Table]
16
17
  # @return [void]
17
18
  define_method "bga_table_#{type}_notify" do |table|
18
- formatter = ::EhbrsRubyUtils::Bga::Table::WhatsappFormatters.const_get(type.camelize)
19
- .new(table)
20
- whatsapp_send(formatter.to_s, formatter.image_local_path)
19
+ whatsapp_formatter_send(
20
+ ::EhbrsRubyUtils::Bga::Table::WhatsappFormatters.const_get(type.camelize),
21
+ table
22
+ )
21
23
  end
22
24
  end
23
25
 
26
+ # @param game_statistics [EhbrsRubyUtils::Bga::GameStatistics]
27
+ # @return [void]
28
+ def bga_game_statistics_notify(game_statistics)
29
+ whatsapp_formatter_send(
30
+ ::EhbrsRubyUtils::Bga::GameStatistics::WhatsappFormatter, game_statistics
31
+ )
32
+ end
33
+
24
34
  def on_bga_logged_session(&block)
25
35
  bga_session = new_bga_session
26
36
  begin
@@ -49,6 +59,12 @@ module EhbrsRubyUtils
49
59
  def mudslide_run(*args)
50
60
  ::EhbrsRubyUtils::Executables.mudslide.command(*args).system!
51
61
  end
62
+
63
+ # @return [void]
64
+ def whatsapp_formatter_send(formatter_class, formatter_owner)
65
+ formatter = formatter_class.new(formatter_owner)
66
+ whatsapp_send(formatter.to_s, formatter.image_local_path)
67
+ end
52
68
  end
53
69
  end
54
70
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module EhbrsRubyUtils
4
- VERSION = '0.38.0'
4
+ VERSION = '0.40.0'
5
5
  end
@@ -9,7 +9,7 @@ module EhbrsRubyUtils
9
9
  module Rename
10
10
  class ResultsBuilder < LineResultGroup
11
11
  def initialize(files)
12
- super '', files
12
+ super('', files)
13
13
  end
14
14
 
15
15
  def line_out
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ehbrs_ruby_utils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.38.0
4
+ version: 0.40.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Eduardo H. Bogoni
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-26 00:00:00.000000000 Z
11
+ date: 2024-01-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aranha
@@ -50,14 +50,14 @@ dependencies:
50
50
  requirements:
51
51
  - - "~>"
52
52
  - !ruby/object:Gem::Version
53
- version: '0.7'
53
+ version: '0.8'
54
54
  type: :runtime
55
55
  prerelease: false
56
56
  version_requirements: !ruby/object:Gem::Requirement
57
57
  requirements:
58
58
  - - "~>"
59
59
  - !ruby/object:Gem::Version
60
- version: '0.7'
60
+ version: '0.8'
61
61
  - !ruby/object:Gem::Dependency
62
62
  name: avm
63
63
  requirement: !ruby/object:Gem::Requirement
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '3.5'
88
88
  - - ">="
89
89
  - !ruby/object:Gem::Version
90
- version: 3.5.1
90
+ version: 3.5.2
91
91
  type: :runtime
92
92
  prerelease: false
93
93
  version_requirements: !ruby/object:Gem::Requirement
@@ -97,35 +97,35 @@ dependencies:
97
97
  version: '3.5'
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
- version: 3.5.1
100
+ version: 3.5.2
101
101
  - !ruby/object:Gem::Dependency
102
102
  name: eac_fs
103
103
  requirement: !ruby/object:Gem::Requirement
104
104
  requirements:
105
105
  - - "~>"
106
106
  - !ruby/object:Gem::Version
107
- version: '0.16'
107
+ version: '0.17'
108
108
  type: :runtime
109
109
  prerelease: false
110
110
  version_requirements: !ruby/object:Gem::Requirement
111
111
  requirements:
112
112
  - - "~>"
113
113
  - !ruby/object:Gem::Version
114
- version: '0.16'
114
+ version: '0.17'
115
115
  - !ruby/object:Gem::Dependency
116
116
  name: eac_rest
117
117
  requirement: !ruby/object:Gem::Requirement
118
118
  requirements:
119
119
  - - "~>"
120
120
  - !ruby/object:Gem::Version
121
- version: '0.10'
121
+ version: '0.12'
122
122
  type: :runtime
123
123
  prerelease: false
124
124
  version_requirements: !ruby/object:Gem::Requirement
125
125
  requirements:
126
126
  - - "~>"
127
127
  - !ruby/object:Gem::Version
128
- version: '0.10'
128
+ version: '0.12'
129
129
  - !ruby/object:Gem::Dependency
130
130
  name: eac_ruby_utils
131
131
  requirement: !ruby/object:Gem::Requirement
@@ -252,6 +252,10 @@ files:
252
252
  - lib/ehbrs_ruby_utils/bga.rb
253
253
  - lib/ehbrs_ruby_utils/bga/game.rb
254
254
  - lib/ehbrs_ruby_utils/bga/game/image.rb
255
+ - lib/ehbrs_ruby_utils/bga/game_statistics.rb
256
+ - lib/ehbrs_ruby_utils/bga/game_statistics/whatsapp_formatter.rb
257
+ - lib/ehbrs_ruby_utils/bga/game_statistics/whatsapp_formatter/player_content.rb
258
+ - lib/ehbrs_ruby_utils/bga/game_statistics/whatsapp_formatter/player_title.rb
255
259
  - lib/ehbrs_ruby_utils/bga/parsers/game_in_progress.rb
256
260
  - lib/ehbrs_ruby_utils/bga/parsers/game_stats.rb
257
261
  - lib/ehbrs_ruby_utils/bga/parsers/game_stats/players.rb
@@ -259,6 +263,7 @@ files:
259
263
  - lib/ehbrs_ruby_utils/bga/parsers/table/active_players.rb
260
264
  - lib/ehbrs_ruby_utils/bga/parsers/table/ended_players.rb
261
265
  - lib/ehbrs_ruby_utils/bga/parsers/table/options.rb
266
+ - lib/ehbrs_ruby_utils/bga/player.rb
262
267
  - lib/ehbrs_ruby_utils/bga/session.rb
263
268
  - lib/ehbrs_ruby_utils/bga/session/login.rb
264
269
  - lib/ehbrs_ruby_utils/bga/session/player.rb
@@ -279,6 +284,8 @@ files:
279
284
  - lib/ehbrs_ruby_utils/bga/table/whatsapp_formatters/ending.rb
280
285
  - lib/ehbrs_ruby_utils/bga/table/whatsapp_formatters/ending/format_player.rb
281
286
  - lib/ehbrs_ruby_utils/bga/urls.rb
287
+ - lib/ehbrs_ruby_utils/bga/whatsapp_formatter.rb
288
+ - lib/ehbrs_ruby_utils/bga/whatsapp_formatter/option.rb
282
289
  - lib/ehbrs_ruby_utils/circular_list_spreader.rb
283
290
  - lib/ehbrs_ruby_utils/circular_list_spreader/base_level.rb
284
291
  - lib/ehbrs_ruby_utils/circular_list_spreader/group_level.rb