summaryrefslogtreecommitdiff
path: root/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib
diff options
context:
space:
mode:
authorBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
committerBenjamin Sanders <ben@Benjamins-MacBook-Pro.local>2025-10-11 10:34:24 -0400
commit5571dc766e2143e39762ff0b47c41d1c2e154f4c (patch)
treef4f124d314a7e76c04484515aa0fd1f2e271a601 /vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib
parent359f3309c97fc894b63e0a295c76ab298504d635 (diff)
Vendor bundled gems for deployment
Diffstat (limited to 'vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib')
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table.rb26
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/cell.rb94
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/import.rb3
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/row.rb66
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/separator.rb66
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/style.rb284
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table.rb372
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table_helper.rb9
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/util.rb13
-rw-r--r--vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/version.rb5
10 files changed, 938 insertions, 0 deletions
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table.rb
new file mode 100644
index 0000000..ebea259
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table.rb
@@ -0,0 +1,26 @@
+#--
+# Copyright (c) 2008-2009 TJ Holowaychuk <tj@vision-media.ca>
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#++
+
+%w(cell row separator style table table_helper util version).each do |file|
+ require_relative "./terminal-table/#{file}"
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/cell.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/cell.rb
new file mode 100644
index 0000000..0ec261d
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/cell.rb
@@ -0,0 +1,94 @@
+require 'unicode/display_width'
+
+module Terminal
+ class Table
+ class Cell
+ ##
+ # Cell value.
+
+ attr_reader :value
+
+ ##
+ # Column span.
+
+ attr_reader :colspan
+
+ ##
+ # Initialize with _options_.
+
+ def initialize options = nil
+ @value, options = options, {} unless Hash === options
+ @value = options.fetch :value, value
+ @alignment = options.fetch :alignment, nil
+ @colspan = options.fetch :colspan, 1
+ @width = options.fetch :width, @value.to_s.size
+ @index = options.fetch :index
+ @table = options.fetch :table
+ end
+
+ def alignment?
+ !@alignment.nil?
+ end
+
+ def alignment
+ @alignment || @table.style.alignment || :left
+ end
+
+ def alignment=(val)
+ supported = %w(left center right)
+ if supported.include?(val.to_s)
+ @alignment = val
+ else
+ raise "Aligment must be one of: #{supported.join(' ')}"
+ end
+ end
+
+ def align(val, position, length)
+ positions = { :left => :ljust, :right => :rjust, :center => :center }
+ val.public_send(positions[position], length)
+ end
+ def lines
+ @value.to_s.split(/\n/)
+ end
+
+ ##
+ # Render the cell.
+
+ def render(line = 0)
+ left = " " * @table.style.padding_left
+ right = " " * @table.style.padding_right
+ display_width = Unicode::DisplayWidth.of(Util::ansi_escape(lines[line]))
+ render_width = lines[line].to_s.size - display_width + width
+ align("#{left}#{lines[line]}#{right}", alignment, render_width + @table.cell_padding)
+ end
+ alias :to_s :render
+
+ ##
+ # Returns the longest line in the cell and
+ # removes all ANSI escape sequences (e.g. color)
+
+ def value_for_column_width_recalc
+ lines.map{ |s| Util::ansi_escape(s) }.max_by{ |s| Unicode::DisplayWidth.of(s) }
+ end
+
+ ##
+ # Returns the width of this cell
+
+ def width
+ padding = (colspan - 1) * @table.cell_spacing
+ inner_width = (1..@colspan).to_a.inject(0) do |w, counter|
+ w + @table.column_width(@index + counter - 1)
+ end
+ inner_width + padding
+ end
+
+ def inspect
+ fields = %i[alignment colspan index value width].map do |name|
+ val = self.instance_variable_get('@'+name.to_s)
+ "@#{name}=#{val.inspect}"
+ end.join(', ')
+ return "#<#{self.class} #{fields}>"
+ end
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/import.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/import.rb
new file mode 100644
index 0000000..33b2791
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/import.rb
@@ -0,0 +1,3 @@
+require 'terminal-table' #required as some people require this file directly from their Gemfiles
+
+include Terminal::Table::TableHelper
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/row.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/row.rb
new file mode 100644
index 0000000..a549008
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/row.rb
@@ -0,0 +1,66 @@
+module Terminal
+ class Table
+ class Row
+
+ ##
+ # Row cells
+
+ attr_reader :cells
+
+ attr_reader :table
+
+ ##
+ # Initialize with _width_ and _options_.
+
+ def initialize table, array = [], **_kwargs
+ @cell_index = 0
+ @table = table
+ @cells = []
+ array.each { |item| self << item }
+ end
+
+ def add_cell item
+ options = item.is_a?(Hash) ? item : {:value => item}
+ cell = Cell.new(options.merge(:index => @cell_index, :table => @table))
+ @cell_index += cell.colspan
+ @cells << cell
+ end
+ alias << add_cell
+
+ def [] index
+ cells[index]
+ end
+
+ def height
+ cells.map { |c| c.lines.count }.max || 0
+ end
+
+ def render
+ vleft, vcenter, vright = @table.style.vertical
+ (0...height).to_a.map do |line|
+ vleft + cells.map do |cell|
+ cell.render(line)
+ end.join(vcenter) + vright
+ end.join("\n")
+ end
+
+ def number_of_columns
+ @cells.collect(&:colspan).inject(0, &:+)
+ end
+
+ # used to find indices where we have table '+' crossings.
+ # in cases where the colspan > 1, then we will skip over some numbers
+ # if colspan is always 1, then the list should be incrementing by 1.
+ #
+ # skip 0 entry, because it's the left side.
+ # skip last entry, because it's the right side.
+ # we only care about "+/T" style crossings.
+ def crossings
+ idx = 0
+ @cells[0...-1].map { |c| idx += c.colspan }
+ end
+
+ end
+
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/separator.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/separator.rb
new file mode 100644
index 0000000..0413925
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/separator.rb
@@ -0,0 +1,66 @@
+module Terminal
+ class Table
+ class Separator < Row
+
+ ##
+ # `prevrow`, `nextrow` contain references to adjacent rows.
+ #
+ # `border_type` is a symbol used to control which type of border is used
+ # on the separator (:top for top-edge, :bot for bottom-edge,
+ # :div for interior, and :strong for emphasized-interior)
+ #
+ # `implicit` is false for user-added separators, and true for
+ # implicit/auto-generated separators.
+
+ def initialize(*args, border_type: :div, implicit: false)
+ super
+ @prevrow, @nextrow = nil, nil
+ @border_type = border_type
+ @implicit = implicit
+ end
+
+ attr_accessor :border_type
+ attr_reader :implicit
+
+ def render
+ left_edge, ctrflat, ctrud, right_edge, ctrdn, ctrup = @table.style.horizontal(border_type)
+
+ prev_crossings = @prevrow.respond_to?(:crossings) ? @prevrow.crossings : []
+ next_crossings = @nextrow.respond_to?(:crossings) ? @nextrow.crossings : []
+ rval = [left_edge]
+ numcols = @table.number_of_columns
+ (0...numcols).each do |idx|
+ rval << ctrflat * (@table.column_width(idx) + @table.cell_padding)
+ pcinc = prev_crossings.include?(idx+1)
+ ncinc = next_crossings.include?(idx+1)
+ border_center = if pcinc && ncinc
+ ctrud
+ elsif pcinc
+ ctrup
+ elsif ncinc
+ ctrdn
+ elsif !ctrud.empty?
+ # special case if the center-up-down intersection is empty
+ # which happens when verticals/intersections are removed. in that case
+ # we do not want to replace with a flat element so return empty-string in else block
+ ctrflat
+ else
+ ''
+ end
+ rval << border_center if idx < numcols-1
+ end
+
+ rval << right_edge
+ rval.join
+ end
+
+ # Save off neighboring rows, so that we can use them later in determining
+ # which types of table edges to use.
+ def save_adjacent_rows(prevrow, nextrow)
+ @prevrow = prevrow
+ @nextrow = nextrow
+ end
+
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/style.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/style.rb
new file mode 100644
index 0000000..dc89737
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/style.rb
@@ -0,0 +1,284 @@
+# coding: utf-8
+require 'forwardable'
+
+module Terminal
+ class Table
+
+ class Border
+
+ attr_accessor :data, :top, :bottom, :left, :right
+ def initialize
+ @top, @bottom, @left, @right = true, true, true, true
+ end
+ def []=(key, val)
+ @data[key] = val
+ end
+ def [](key)
+ @data[key]
+ end
+ def initialize_dup(other)
+ super
+ @data = other.data.dup
+ end
+ def remove_verticals
+ self.class.const_get("VERTICALS").each { |key| @data[key] = "" }
+ self.class.const_get("INTERSECTIONS").each { |key| @data[key] = "" }
+ end
+ def remove_horizontals
+ self.class.const_get("HORIZONTALS").each { |key| @data[key] = "" }
+ end
+
+ # If @left, return the edge else empty-string.
+ def maybeleft(key) ; @left ? @data[key] : '' ; end
+
+ # If @right, return the edge else empty-string.
+ def mayberight(key) ; @right ? @data[key] : '' ; end
+
+ end
+
+ class AsciiBorder < Border
+ HORIZONTALS = %i[x]
+ VERTICALS = %i[y]
+ INTERSECTIONS = %i[i]
+
+ def initialize
+ super
+ @data = { x: "-", y: "|", i: "+" }
+ end
+
+ # Get vertical border elements
+ # @return [Array] 3-element list of [left, center, right]
+ def vertical
+ [maybeleft(:y), @data[:y], mayberight(:y)] # left, center, right
+ end
+
+ # Get horizontal border elements
+ # @return [Array] a 6 element list of: [i-left, horizontal-bar, i-up/down, i-right, i-down, i-up]
+ def horizontal(_type)
+ x, i = @data[:x], @data[:i]
+ [maybeleft(:i), x, i, mayberight(:i), i, i]
+ end
+ end
+
+ class MarkdownBorder < AsciiBorder
+ def initialize
+ super
+ @top, @bottom = false, false
+ @data = { x: "-", y: "|", i: "|" }
+ end
+ end
+
+ class UnicodeBorder < Border
+
+ ALLOWED_SEPARATOR_BORDER_STYLES = %i[
+ top bot
+ div dash dot3 dot4
+ thick thick_dash thick_dot3 thick_dot4
+ heavy heavy_dash heavy_dot3 heavy_dot4
+ bold bold_dash bold_dot3 bold_dot4
+ double
+ ]
+
+ HORIZONTALS = %i[x sx ax bx nx bx_dot3 bx_dot4 bx_dash x_dot3 x_dot4 x_dash]
+ VERTICALS = %i[y yw ye]
+ INTERSECTIONS = %i[nw n ne nd
+ aw ai ae ad au
+ bw bi be bd bu
+ w i e dn up
+ sw s se su]
+ def initialize
+ super
+ @data = {
+ nil => nil,
+ nw: "┌", nx: "─", n: "┬", ne: "┐",
+ yw: "│", y: "│", ye: "│",
+ aw: "╞", ax: "═", ai: "╪", ae: "╡", ad: '╤', au: "╧", # double
+ bw: "┝", bx: "━", bi: "┿", be: "┥", bd: '┯', bu: "┷", # heavy/bold/thick
+ w: "├", x: "─", i: "┼", e: "┤", dn: "┬", up: "┴", # normal div
+ sw: "└", sx: "─", s: "┴", se: "┘",
+ # alternative dots/dashes
+ x_dot4: '┈', x_dot3: '┄', x_dash: '╌',
+ bx_dot4: '┉', bx_dot3: '┅', bx_dash: '╍',
+ }
+ end
+ # Get vertical border elements
+ # @return [Array] 3-element list of [left, center, right]
+ def vertical
+ [maybeleft(:yw), @data[:y], mayberight(:ye)]
+ end
+
+ # Get horizontal border elements
+ # @return [Array] a 6 element list of: [i-left, horizontal-bar, i-up/down, i-right, i-down, i-up]
+ def horizontal(type)
+ raise ArgumentError, "Border type is #{type.inspect}, must be one of #{ALLOWED_SEPARATOR_BORDER_STYLES.inspect}" unless ALLOWED_SEPARATOR_BORDER_STYLES.include?(type)
+ lookup = case type
+ when :top
+ [:nw, :nx, :n, :ne, :n, nil]
+ when :bot
+ [:sw, :sx, :s, :se, nil, :s]
+ when :double
+ # typically used for the separator below the heading row or above a footer row)
+ [:aw, :ax, :ai, :ae, :ad, :au]
+ when :thick, :thick_dash, :thick_dot3, :thick_dot4,
+ :heavy, :heavy_dash, :heavy_dot3, :heavy_dot4,
+ :bold, :bold_dash, :bold_dot3, :bold_dot4
+ # alternate thick/bold border
+ xref = type.to_s.sub(/^(thick|heavy|bold)/,'bx').to_sym
+ [:bw, xref, :bi, :be, :bd, :bu]
+ when :dash, :dot3, :dot4
+ # alternate thin dividers
+ xref = "x_#{type}".to_sym
+ [:w, xref, :i, :e, :dn, :up]
+ else # :div (center, non-emphasized)
+ [:w, :x, :i, :e, :dn, :up]
+ end
+ rval = lookup.map { |key| @data.fetch(key) }
+ rval[0] = '' unless @left
+ rval[3] = '' unless @right
+ rval
+ end
+ end
+
+ # Unicode Border With rounded edges
+ class UnicodeRoundBorder < UnicodeBorder
+ def initialize
+ super
+ @data.merge!({nw: '╭', ne: '╮', sw: '╰', se: '╯'})
+ end
+ end
+
+ # Unicode Border with thick outer edges
+ class UnicodeThickEdgeBorder < UnicodeBorder
+ def initialize
+ super
+ @data = {
+ nil => nil,
+ nw: "┏", nx: "━", n: "┯", ne: "┓", nd: nil,
+ yw: "┃", y: "│", ye: "┃",
+ aw: "┣", ax: "═", ai: "╪", ae: "┫", ad: '╤', au: "╧", # double
+ bw: "┣", bx: "━", bi: "┿", be: "┫", bd: '┯', bu: "┷", # heavy/bold/thick
+ w: "┠", x: "─", i: "┼", e: "┨", dn: "┬", up: "┴", # normal div
+ sw: "┗", sx: "━", s: "┷", se: "┛", su: nil,
+ # alternative dots/dashes
+ x_dot4: '┈', x_dot3: '┄', x_dash: '╌',
+ bx_dot4: '┉', bx_dot3: '┅', bx_dash: '╍',
+ }
+ end
+ end
+
+ # A Style object holds all the formatting information for a Table object
+ #
+ # To create a table with a certain style, use either the constructor
+ # option <tt>:style</tt>, the Table#style object or the Table#style= method
+ #
+ # All these examples have the same effect:
+ #
+ # # by constructor
+ # @table = Table.new(:style => {:padding_left => 2, :width => 40})
+ #
+ # # by object
+ # @table.style.padding_left = 2
+ # @table.style.width = 40
+ #
+ # # by method
+ # @table.style = {:padding_left => 2, :width => 40}
+ #
+ # To set a default style for all tables created afterwards use Style.defaults=
+ #
+ # Terminal::Table::Style.defaults = {:width => 80}
+ #
+ class Style
+ extend Forwardable
+ def_delegators :@border, :vertical, :horizontal, :remove_verticals, :remove_horizontals
+
+ @@defaults = {
+ :border => AsciiBorder.new,
+ :padding_left => 1, :padding_right => 1,
+ :margin_left => '',
+ :width => nil, :alignment => nil,
+ :all_separators => false,
+ }
+
+ ## settors/gettor for legacy ascii borders
+ def border_x=(val) ; @border[:x] = val ; end
+ def border_y=(val) ; @border[:y] = val ; end
+ def border_i=(val) ; @border[:i] = val ; end
+ def border_y ; @border[:y] ; end
+ def border_y_width ; Util::ansi_escape(@border[:y]).length ; end
+
+ # Accessor for instance of Border
+ attr_reader :border
+ def border=(val)
+ if val.is_a? Symbol
+ # convert symbol name like :foo_bar to get class FooBarBorder
+ klass_str = val.to_s.split('_').collect(&:capitalize).join + "Border"
+ begin
+ klass = Terminal::Table::const_get(klass_str)
+ @border = klass.new
+ rescue NameError
+ raise "Cannot lookup class Terminal::Table::#{klass_str} from symbol #{val.inspect}"
+ end
+ else
+ @border = val
+ end
+ end
+
+ def border_top=(val) ; @border.top = val ; end
+ def border_bottom=(val) ; @border.bottom = val ; end
+ def border_left=(val) ; @border.left = val ; end
+ def border_right=(val) ; @border.right = val ; end
+
+ def border_top ; @border.top ; end
+ def border_bottom ; @border.bottom ; end
+ def border_left ; @border.left ; end
+ def border_right ; @border.right ; end
+
+
+ attr_accessor :padding_left
+ attr_accessor :padding_right
+
+ attr_accessor :margin_left
+
+ attr_accessor :width
+ attr_accessor :alignment
+
+ attr_accessor :all_separators
+
+
+ def initialize options = {}
+ apply self.class.defaults.merge(options)
+ end
+
+ def apply options
+ options.each do |m, v|
+ __send__ "#{m}=", v
+ end
+ end
+
+ class << self
+ def defaults
+ klass_defaults = @@defaults.dup
+ # border is an object that needs to be duplicated on instantiation,
+ # otherwise everything will be referencing the same object-id.
+ klass_defaults[:border] = klass_defaults[:border].dup
+ klass_defaults
+ end
+
+ def defaults= options
+ @@defaults = defaults.merge(options)
+ end
+
+ end
+
+ def on_change attr
+ method_name = :"#{attr}="
+ old_method = method method_name
+ define_singleton_method(method_name) do |value|
+ old_method.call value
+ yield attr.to_sym, value
+ end
+ end
+
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table.rb
new file mode 100644
index 0000000..f483e31
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table.rb
@@ -0,0 +1,372 @@
+require 'unicode/display_width'
+
+module Terminal
+ class Table
+
+ attr_reader :title
+ attr_reader :headings
+
+ ##
+ # Generates a ASCII/Unicode table with the given _options_.
+
+ def initialize options = {}, &block
+ @elaborated = false
+ @headings = []
+ @rows = []
+ @column_widths = []
+ self.style = options.fetch :style, {}
+ self.headings = options.fetch :headings, []
+ self.rows = options.fetch :rows, []
+ self.title = options.fetch :title, nil
+ yield_or_eval(&block) if block
+
+ style.on_change(:width) { require_column_widths_recalc }
+ end
+
+ ##
+ # Align column _n_ to the given _alignment_ of :center, :left, or :right.
+
+ def align_column n, alignment
+ # nil forces the column method to return the cell itself
+ column(n, nil).each do |cell|
+ cell.alignment = alignment unless cell.alignment?
+ end
+ end
+
+ ##
+ # Add a row.
+
+ def add_row array
+ row = array == :separator ? Separator.new(self) : Row.new(self, array)
+ @rows << row
+ require_column_widths_recalc unless row.is_a?(Separator)
+ end
+ alias :<< :add_row
+
+ ##
+ # Add a separator.
+
+ def add_separator(border_type: :div)
+ @rows << Separator.new(self, border_type: border_type)
+ end
+
+ def cell_spacing
+ cell_padding + style.border_y_width
+ end
+
+ def cell_padding
+ style.padding_left + style.padding_right
+ end
+
+ ##
+ # Return column _n_.
+
+ def column n, method = :value, array = rows
+ array.map { |row|
+ # for each cells in a row, find the column with index
+ # just greater than the required one, and go back one.
+ index = col = 0
+ row.cells.each do |cell|
+ break if index > n
+ index += cell.colspan
+ col += 1
+ end
+ cell = row[col - 1]
+ cell && method ? cell.__send__(method) : cell
+ }.compact
+ end
+
+ ##
+ # Return _n_ column including headings.
+
+ def column_with_headings n, method = :value
+ column n, method, headings_with_rows
+ end
+
+ ##
+ # Return columns.
+
+ def columns
+ (0...number_of_columns).map { |n| column n }
+ end
+
+ ##
+ # Return length of column _n_.
+
+ def column_width n
+ column_widths[n] || 0
+ end
+ alias length_of_column column_width # for legacy support
+
+ ##
+ # Return total number of columns available.
+
+ def number_of_columns
+ headings_with_rows.map { |r| r.number_of_columns }.max || 0
+ end
+
+ ##
+ # Set the headings
+
+ def headings= arrays
+ arrays = [arrays] unless arrays.first.is_a?(Array)
+ @headings = arrays.map do |array|
+ row = Row.new(self, array)
+ require_column_widths_recalc
+ row
+ end
+ end
+
+ ##
+ # Elaborate rows to form an Array of Rows and Separators with adjacency properties added.
+ #
+ # This is separated from the String rendering so that certain features may be tweaked
+ # before the String is built.
+
+ def elaborate_rows
+
+ buffer = style.border_top ? [Separator.new(self, border_type: :top, implicit: true)] : []
+ unless @title.nil?
+ buffer << Row.new(self, [title_cell_options])
+ buffer << Separator.new(self, implicit: true)
+ end
+ @headings.each do |row|
+ unless row.cells.empty?
+ buffer << row
+ buffer << Separator.new(self, border_type: :double, implicit: true)
+ end
+ end
+ if style.all_separators
+ @rows.each_with_index do |row, idx|
+ # last separator is bottom, others are :div
+ border_type = (idx == @rows.size - 1) ? :bot : :div
+ buffer << row
+ buffer << Separator.new(self, border_type: border_type, implicit: true)
+ end
+ else
+ buffer += @rows
+ buffer << Separator.new(self, border_type: :bot, implicit: true) if style.border_bottom
+ end
+
+ # After all implicit Separators are inserted we need to save off the
+ # adjacent rows so that we can decide what type of intersections to use
+ # based on column spans in the adjacent row(s).
+ buffer.each_with_index do |r, idx|
+ if r.is_a?(Separator)
+ prev_row = idx > 0 ? buffer[idx - 1] : nil
+ next_row = buffer.fetch(idx + 1, nil)
+ r.save_adjacent_rows(prev_row, next_row)
+ end
+ end
+
+ @elaborated = true
+ @rows = buffer
+ end
+
+ ##
+ # Render the table.
+
+ def render
+ elaborate_rows unless @elaborated
+ @rows.map { |r| style.margin_left + r.render.rstrip }.join("\n")
+ end
+ alias :to_s :render
+
+ ##
+ # Return rows without separator rows.
+
+ def rows
+ @rows.reject { |row| row.is_a? Separator }
+ end
+
+ def rows= array
+ @rows = []
+ array.each { |arr| self << arr }
+ end
+
+ def style=(options)
+ style.apply options
+ end
+
+ def style
+ @style ||= Style.new
+ end
+
+ def title=(title)
+ @title = title
+ require_column_widths_recalc
+ end
+
+ ##
+ # Check if _other_ is equal to self. _other_ is considered equal
+ # if it contains the same headings and rows.
+
+ def == other
+ if other.respond_to? :render and other.respond_to? :rows
+ self.headings == other.headings and self.rows == other.rows
+ end
+ end
+
+ private
+
+ def columns_width
+ column_widths.inject(0) { |s, i| s + i + cell_spacing } + style.border_y_width
+ end
+
+ def recalc_column_widths
+ @require_column_widths_recalc = false
+ n_cols = number_of_columns
+ space_width = cell_spacing
+ return if n_cols == 0
+
+ # prepare rows
+ all_rows = headings_with_rows
+ all_rows << Row.new(self, [title_cell_options]) unless @title.nil?
+
+ # DP states, dp[colspan][index][split_offset] => column_width.
+ dp = []
+
+ # prepare initial value for DP.
+ all_rows.each do |row|
+ index = 0
+ row.cells.each do |cell|
+ cell_value = cell.value_for_column_width_recalc
+ cell_width = Unicode::DisplayWidth.of(cell_value.to_s)
+ colspan = cell.colspan
+
+ # find column width from each single cell.
+ dp[colspan] ||= []
+ dp[colspan][index] ||= [0] # add a fake cell with length 0.
+ dp[colspan][index][colspan] ||= 0 # initialize column length to 0.
+
+ # the last index `colspan` means width of the single column (split
+ # at end of each column), not a width made up of multiple columns.
+ single_column_length = [cell_width, dp[colspan][index][colspan]].max
+ dp[colspan][index][colspan] = single_column_length
+
+ index += colspan
+ end
+ end
+
+ # run DP.
+ (1..n_cols).each do |colspan|
+ dp[colspan] ||= []
+ (0..n_cols-colspan).each do |index|
+ dp[colspan][index] ||= [1]
+ (1...colspan).each do |offset|
+ # processed level became reverse map from width => [offset, ...].
+ left_colspan = offset
+ left_index = index
+ left_width = dp[left_colspan][left_index].keys.first
+
+ right_colspan = colspan - left_colspan
+ right_index = index + offset
+ right_width = dp[right_colspan][right_index].keys.first
+
+ dp[colspan][index][offset] = left_width + right_width + space_width
+ end
+
+ # reverse map it for resolution (max width and short offset first).
+ rmap = {}
+ dp[colspan][index].each_with_index do |width, offset|
+ rmap[width] ||= []
+ rmap[width] << offset
+ end
+
+ # sort reversely and store it back.
+ dp[colspan][index] = Hash[rmap.sort.reverse]
+ end
+ end
+
+ resolve = lambda do |colspan, full_width, index = 0|
+ # stop if reaches the bottom level.
+ return @column_widths[index] = full_width if colspan == 1
+
+ # choose best split offset for partition, or second best result
+ # if first one is not dividable.
+ candidate_offsets = dp[colspan][index].collect(&:last).flatten
+ offset = candidate_offsets[0]
+ offset = candidate_offsets[1] if offset == colspan
+
+ # prepare for next round.
+ left_colspan = offset
+ left_index = index
+ left_width = dp[left_colspan][left_index].keys.first
+
+ right_colspan = colspan - left_colspan
+ right_index = index + offset
+ right_width = dp[right_colspan][right_index].keys.first
+
+ # calculate reference column width, give remaining spaces to left.
+ total_non_space_width = full_width - (colspan - 1) * space_width
+ ref_column_width = total_non_space_width / colspan
+ remainder = total_non_space_width % colspan
+ rem_left_width = [remainder, left_colspan].min
+ rem_right_width = remainder - rem_left_width
+ ref_left_width = ref_column_width * left_colspan +
+ (left_colspan - 1) * space_width + rem_left_width
+ ref_right_width = ref_column_width * right_colspan +
+ (right_colspan - 1) * space_width + rem_right_width
+
+ # at most one width can be greater than the reference width.
+ if left_width <= ref_left_width and right_width <= ref_right_width
+ # use refernce width (evenly partition).
+ left_width = ref_left_width
+ right_width = ref_right_width
+ else
+ # the wider one takes its value, shorter one takes the rest.
+ if left_width > ref_left_width
+ right_width = full_width - left_width - space_width
+ else
+ left_width = full_width - right_width - space_width
+ end
+ end
+
+ # run next round.
+ resolve.call(left_colspan, left_width, left_index)
+ resolve.call(right_colspan, right_width, right_index)
+ end
+
+ full_width = dp[n_cols][0].keys.first
+ unless style.width.nil?
+ new_width = style.width - space_width - style.border_y_width
+ if new_width < full_width
+ raise "Table width exceeds wanted width " +
+ "of #{style.width} characters."
+ end
+ full_width = new_width
+ end
+
+ resolve.call(n_cols, full_width)
+ end
+
+ ##
+ # Return headings combined with rows.
+
+ def headings_with_rows
+ @headings + rows
+ end
+
+ def yield_or_eval &block
+ return unless block
+ if block.arity > 0
+ yield self
+ else
+ self.instance_eval(&block)
+ end
+ end
+
+ def title_cell_options
+ {:value => @title, :alignment => :center, :colspan => number_of_columns}
+ end
+
+ def require_column_widths_recalc
+ @require_column_widths_recalc = true
+ end
+
+ def column_widths
+ recalc_column_widths if @require_column_widths_recalc
+ @column_widths
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table_helper.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table_helper.rb
new file mode 100644
index 0000000..5a85325
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/table_helper.rb
@@ -0,0 +1,9 @@
+module Terminal
+ class Table
+ module TableHelper
+ def table headings = [], *rows, &block
+ Terminal::Table.new :headings => headings.to_a, :rows => rows, &block
+ end
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/util.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/util.rb
new file mode 100644
index 0000000..a584c3d
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/util.rb
@@ -0,0 +1,13 @@
+module Terminal
+ class Table
+ module Util
+ # removes all ANSI escape sequences (e.g. color)
+ def ansi_escape(line)
+ line.to_s.gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
+ gsub(/\x1b(\[|\(|\))[;?0-9]*[0-9A-Za-z]/, '').
+ gsub(/(\x03|\x1a)/, '')
+ end
+ module_function :ansi_escape
+ end
+ end
+end
diff --git a/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/version.rb b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/version.rb
new file mode 100644
index 0000000..42c0c18
--- /dev/null
+++ b/vendor/bundle/ruby/3.4.0/gems/terminal-table-3.0.2/lib/terminal-table/version.rb
@@ -0,0 +1,5 @@
+module Terminal
+ class Table
+ VERSION = '3.0.2'
+ end
+end