ehbrs_ruby_utils 0.38.0 → 0.40.0

Sign up to get free protection for your applications and to get access to all the features.
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