sevgi 0.0.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.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +9 -0
  3. data/LICENSE +674 -0
  4. data/README.md +15 -0
  5. data/bin/sevgi +136 -0
  6. data/lib/sevgi/errors.rb +11 -0
  7. data/lib/sevgi/external.rb +8 -0
  8. data/lib/sevgi/function.rb +35 -0
  9. data/lib/sevgi/geometry/elements/rect.rb +133 -0
  10. data/lib/sevgi/geometry/elements/segment.rb +102 -0
  11. data/lib/sevgi/geometry/elements.rb +41 -0
  12. data/lib/sevgi/geometry/equation/line/diagonal.rb +90 -0
  13. data/lib/sevgi/geometry/equation/line/horizontal.rb +15 -0
  14. data/lib/sevgi/geometry/equation/line/vertical.rb +52 -0
  15. data/lib/sevgi/geometry/equation/line.rb +38 -0
  16. data/lib/sevgi/geometry/equation.rb +3 -0
  17. data/lib/sevgi/geometry/errors.rb +5 -0
  18. data/lib/sevgi/geometry/external.rb +15 -0
  19. data/lib/sevgi/geometry/operation/align.rb +40 -0
  20. data/lib/sevgi/geometry/operation/sweep.rb +52 -0
  21. data/lib/sevgi/geometry/operation.rb +28 -0
  22. data/lib/sevgi/geometry/point.rb +62 -0
  23. data/lib/sevgi/geometry.rb +10 -0
  24. data/lib/sevgi/graphics/attribute.rb +125 -0
  25. data/lib/sevgi/graphics/canvas.rb +51 -0
  26. data/lib/sevgi/graphics/content.rb +72 -0
  27. data/lib/sevgi/graphics/document/base.rb +51 -0
  28. data/lib/sevgi/graphics/document/default.rb +19 -0
  29. data/lib/sevgi/graphics/document/html.rb +11 -0
  30. data/lib/sevgi/graphics/document/inkscape.rb +17 -0
  31. data/lib/sevgi/graphics/document/minimal.rb +11 -0
  32. data/lib/sevgi/graphics/document.rb +53 -0
  33. data/lib/sevgi/graphics/element.rb +85 -0
  34. data/lib/sevgi/graphics/external.rb +15 -0
  35. data/lib/sevgi/graphics/mixtures/core.rb +81 -0
  36. data/lib/sevgi/graphics/mixtures/duplicate.rb +36 -0
  37. data/lib/sevgi/graphics/mixtures/hatch.rb +21 -0
  38. data/lib/sevgi/graphics/mixtures/identify.rb +93 -0
  39. data/lib/sevgi/graphics/mixtures/inkscape.rb +15 -0
  40. data/lib/sevgi/graphics/mixtures/lint.rb +33 -0
  41. data/lib/sevgi/graphics/mixtures/render.rb +149 -0
  42. data/lib/sevgi/graphics/mixtures/replicate.rb +125 -0
  43. data/lib/sevgi/graphics/mixtures/save.rb +23 -0
  44. data/lib/sevgi/graphics/mixtures/transform.rb +78 -0
  45. data/lib/sevgi/graphics/mixtures/underscore.rb +21 -0
  46. data/lib/sevgi/graphics/mixtures/validate.rb +27 -0
  47. data/lib/sevgi/graphics/mixtures/wrappers.rb +63 -0
  48. data/lib/sevgi/graphics/mixtures.rb +16 -0
  49. data/lib/sevgi/graphics.rb +10 -0
  50. data/lib/sevgi/internal/constant.rb +5 -0
  51. data/lib/sevgi/internal/dim.rb +13 -0
  52. data/lib/sevgi/internal/function/file.rb +30 -0
  53. data/lib/sevgi/internal/function/float.rb +35 -0
  54. data/lib/sevgi/internal/function/formula.rb +71 -0
  55. data/lib/sevgi/internal/function/math.rb +43 -0
  56. data/lib/sevgi/internal/function/string.rb +13 -0
  57. data/lib/sevgi/internal/function.rb +7 -0
  58. data/lib/sevgi/internal/list.rb +27 -0
  59. data/lib/sevgi/internal/locate.rb +47 -0
  60. data/lib/sevgi/internal/margin.rb +23 -0
  61. data/lib/sevgi/internal/minitest/script.rb +50 -0
  62. data/lib/sevgi/internal/minitest/shell.rb +71 -0
  63. data/lib/sevgi/internal/minitest/suite.rb +35 -0
  64. data/lib/sevgi/internal/minitest.rb +5 -0
  65. data/lib/sevgi/internal/paper.rb +26 -0
  66. data/lib/sevgi/internal.rb +10 -0
  67. data/lib/sevgi/standard/conform.rb +55 -0
  68. data/lib/sevgi/standard/data/attribute.rb +496 -0
  69. data/lib/sevgi/standard/data/element.rb +269 -0
  70. data/lib/sevgi/standard/data/specification.rb +1841 -0
  71. data/lib/sevgi/standard/data.rb +79 -0
  72. data/lib/sevgi/standard/errors.rb +28 -0
  73. data/lib/sevgi/standard/model.rb +82 -0
  74. data/lib/sevgi/standard.rb +26 -0
  75. data/lib/sevgi/utensils/external.rb +22 -0
  76. data/lib/sevgi/utensils/grid.rb +49 -0
  77. data/lib/sevgi/utensils/ruler.rb +47 -0
  78. data/lib/sevgi/utensils/tsquare.rb +28 -0
  79. data/lib/sevgi/utensils.rb +7 -0
  80. data/lib/sevgi/version.rb +5 -0
  81. data/lib/sevgi.rb +10 -0
  82. metadata +127 -0
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ module Standard
5
+ module Group
6
+ def all = @all ||= Set[*data.values.flatten.uniq.sort]
7
+
8
+ def is?(name, group) = self[group].include?(name)
9
+
10
+ def pick(names, *groups) = names.select { |name| groups.any? { is?(name, _1) } }
11
+
12
+ def set(*groups) = groups.empty? ? all : Set[*data.values_at(*groups).flatten.compact.uniq.sort]
13
+
14
+ def unpick(names, *groups) = names.reject { |name| groups.any? { is?(name, _1) } }
15
+
16
+ class << self
17
+ def extended(base) = base.extend(List)
18
+ end
19
+ end
20
+
21
+ private_constant :Group
22
+
23
+ module Attribute
24
+ extend Group
25
+
26
+ require_relative "data/attribute"
27
+ end
28
+
29
+ private_constant :Attribute
30
+
31
+ module Element
32
+ extend Group
33
+
34
+ require_relative "data/element"
35
+ end
36
+
37
+ private_constant :Element
38
+
39
+ module Specification
40
+ extend List
41
+ extend self
42
+
43
+ require_relative "data/specification"
44
+
45
+ def [](name) = expand(name)
46
+
47
+ def group?(name) = F.start_with_upper?(name)
48
+
49
+ def model?(name, *models) = models.any? { (self[name] || {})[:model] == name }
50
+
51
+ private
52
+
53
+ @spec = {}
54
+
55
+ def expand(name)
56
+ @spec[name] ||= if data[name]
57
+ data[name].dup.tap do |spec|
58
+ expand_names(spec[:elements], Element.data)
59
+ expand_names(spec[:attributes], Attribute.data)
60
+ end
61
+ end
62
+ end
63
+
64
+ def expand_names(names, list)
65
+ return unless names
66
+
67
+ names.replace(names.map { |name| group?(name) ? list[name] : name }.flatten)
68
+ end
69
+
70
+ # For testing purposes
71
+
72
+ def charge = data.keys { expand(_1) }
73
+
74
+ def flush = (@spec = {})
75
+ end
76
+
77
+ private_constant :Specification
78
+ end
79
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ class ValidationError < Error
5
+ def initialize(context, args)
6
+ @context = context
7
+ @args = Array(args)
8
+
9
+ super()
10
+ end
11
+
12
+ class << self
13
+ def call(context, args) = raise(new(context, args))
14
+
15
+ def variant(message)
16
+ Class.new(self) do
17
+ define_method(:message) { [@context, message, @args.map { "'#{_1}'" }.join(", ")].join(": ") }
18
+ end
19
+ end
20
+ end
21
+ end
22
+
23
+ InvalidAttributesError = ValidationError.variant("Invalid attribute(s)")
24
+ InvalidElementsError = ValidationError.variant("Invalid element(s)")
25
+ UnallowedCDataError = ValidationError.variant("Character data not allowed")
26
+ UnallowedElementsError = ValidationError.variant("Element(s) not allowed")
27
+ UnmetConditionError = ValidationError.variant("Condition unmet for the element")
28
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ module Standard
5
+ module Model
6
+ module CDataOnly
7
+ def apply(cdata:, elements:)
8
+ UnallowedElementsError.(element, elements) unless elements.empty?
9
+ end
10
+ end
11
+
12
+ module CDataOrSomeElements
13
+ def apply(cdata:, elements:)
14
+ unallowed = elements - spec[:elements]
15
+ UnallowedElementsError.(element, unallowed) unless unallowed.empty?
16
+ end
17
+ end
18
+
19
+ module NoneElements
20
+ def apply(cdata:, elements:)
21
+ UnallowedCDataError.(element, cdata) if cdata
22
+
23
+ UnallowedElementsError.(element, elements) unless elements.empty?
24
+ end
25
+ end
26
+
27
+ module SomeElements
28
+ def apply(cdata:, elements:)
29
+ UnallowedCDataError.(element, cdata) if cdata
30
+
31
+ unallowed = elements - spec[:elements]
32
+ UnallowedElementsError.(element, unallowed) unless unallowed.empty?
33
+ end
34
+ end
35
+
36
+ module SpecialFeDiffuseLighting
37
+ # Any number of Descriptive elements and exactly one FilterLightSource element, in any order.
38
+ def apply(cdata:, elements:)
39
+ UnallowedCDataError.(element, cdata) if cdata
40
+
41
+ unless (filter_light_source_elements = Element.pick(elements, :FilterLightSource)).size == 1
42
+ UnmetConditionError.(element, "Exactly one FilterLightSource element required")
43
+ end
44
+
45
+ unless (unallowed = Element.unpick(elements - filter_light_source_elements, :Descriptive)).empty?
46
+ UnallowedElementsError.(element, unallowed)
47
+ end
48
+ end
49
+ end
50
+
51
+ module SpecialFeSpecularLighting
52
+ # Exactly one FilterLightSource element first and any number of Descriptive elements in any order.
53
+ def apply(cdata:, elements:)
54
+ UnallowedCDataError.(element, cdata) if cdata
55
+
56
+ unless Element.is?(elements.first, :FilterLightSource)
57
+ UnmetConditionError.(element, "Exactly one FilterLightSource element as first required")
58
+ end
59
+
60
+ unless (unallowed = Element.unpick(elements[1..], :Descriptive)).empty?
61
+ UnallowedElementsError.(element, unallowed) unless unallowed.empty?
62
+ end
63
+ end
64
+ end
65
+
66
+ module SpecialFontFace
67
+ # Any number of Descriptive elements and at most one font-face element in any order.
68
+ def apply(cdata:, elements:)
69
+ UnallowedCDataError.(element, cdata) if cdata
70
+
71
+ if (font_face_elements = elements.select { |element| element == :"font-face" }).size > 1
72
+ UnmetConditionError.(element, "At most one font-face element allowed")
73
+ end
74
+
75
+ unless (unallowed = Element.unpick(elements - font_face_elements, :Descriptive)).empty?
76
+ UnallowedElementsError.(element, unallowed)
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "standard/errors"
4
+
5
+ require_relative "standard/data"
6
+ require_relative "standard/conform"
7
+
8
+ module Sevgi
9
+ module Standard
10
+ extend self
11
+
12
+ def attributes(...) = Attribute.set(...)
13
+
14
+ def attribute?(name) = Attribute.all.include?(name.to_sym)
15
+
16
+ def conform(...) = Conform.(...)
17
+
18
+ def elements(...) = Element.set(...)
19
+
20
+ def element?(name) = Element.all.include?(name.to_sym)
21
+
22
+ def model?(...) = Specification.model?(...)
23
+
24
+ def [](name) = Specification[name.to_sym]
25
+ end
26
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ module Utensils
5
+ module External
6
+ def Ruler(...)
7
+ Ruler.new(...)
8
+ end
9
+
10
+ def Ts(canvas, unit:, multiple:)
11
+ ArgumentError.("Must be a Canvas: #{canvas}") unless canvas.is_a?(Graphics::Canvas)
12
+
13
+ Tsquare.new(
14
+ hruler: Utensils::Ruler.new(brut: canvas.width, unit:, multiple:, minspace: canvas.left),
15
+ vruler: Utensils::Ruler.new(brut: canvas.height, unit:, multiple:, minspace: canvas.top),
16
+ )
17
+ end
18
+ end
19
+
20
+ extend External
21
+ end
22
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ module Utensils
5
+ class Grid
6
+ Types = Struct.new(:point, :contour, :segment)
7
+ private_constant :Types
8
+
9
+ Parts = Struct.new(:halves, :majors, :minors)
10
+ private_constant :Parts
11
+
12
+ attr_reader :h, :v
13
+
14
+ def initialize(ts)
15
+ @h = Types.new
16
+ @v = Types.new
17
+
18
+ compute(ts)
19
+ end
20
+
21
+ def all = @all ||= Parts.new(halves: h.point.halves.flatten, majors: h.point.majors.flatten, minors: h.point.minors.flatten)
22
+
23
+ alias_method :a, :all
24
+
25
+ private
26
+
27
+ def compute(ts)
28
+ lps = points(ts.v.ls, ts.h.ls) # array of halve (l) points
29
+ mps = points(ts.v.ms, ts.h.ms) # array of major (m) points
30
+ nps = points(ts.v.ns, ts.h.ns) # array of minor (n) points
31
+
32
+ h.point, h.contour, h.segment = parts(lps, mps, nps)
33
+ v.point, v.contour, v.segment = parts(lps.transpose, mps.transpose, nps.transpose)
34
+ end
35
+
36
+ def parts(lps, mps, nps)
37
+ [
38
+ Parts.new(halves: lps, majors: mps, minors: nps), # points
39
+ Parts.new(halves: [lps.first, lps.last], majors: [mps.first, mps.last], minors: [nps.first, nps.last]), # contours
40
+ Parts.new(halves: segments(lps), majors: segments(mps), minors: segments(nps)), # segments
41
+ ]
42
+ end
43
+
44
+ def segments(a) = a.first.zip(a.last).map { Geometry::Segment[_1, _2] }
45
+
46
+ def points(va, ha) = va.map { |y| ha.map { |x| Geometry::Point[x, y] } }
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # codebeat:disable[TOO_MANY_IVARS]
4
+
5
+ module Sevgi
6
+ module Utensils
7
+ #
8
+ # <------------------------------------------------- brut -------------------------------------------------->
9
+ # <------------------------- length = (n - 1) x minor = (m - 1) x major ----------------------->
10
+ # <- space -> <- minor -> <------- major = multiple x minor ------>
11
+ # |............|---------+---------+---------+---------|---------+---------+---------+---------|............|
12
+ # |
13
+ # +--> space = minspace + computed space for evenness
14
+ #
15
+ class Ruler
16
+ attr_reader :unit, :multiple, :brut, :minspace
17
+
18
+ def initialize(unit:, multiple:, brut:, minspace:)
19
+ @brut, @unit, @minspace = brut.to_f, unit.to_f, minspace.to_f
20
+ @multiple = multiple
21
+ end
22
+
23
+ def halve = @halve ||= major / 2.0
24
+ def length = @length ||= (n - 1) * unit
25
+ def major = @major ||= multiple * unit
26
+ def space = @space ||= brut - length
27
+
28
+ def l = @l ||= 2 * m - 1
29
+ def ls = @ls ||= Array.new(l) { |i| i * halve }
30
+
31
+ def m = @m ||= even(unit: major) + 1
32
+ def ms = @ms ||= Array.new(m) { |i| i * major }
33
+
34
+ def n = @n ||= even(unit:, multiple:) + 1
35
+ def ns = @ns ||= Array.new(n) { |i| i * unit }
36
+
37
+ alias_method :minor, :unit
38
+
39
+ private
40
+
41
+ def even(unit: nil, multiple: 1)
42
+ (n = ((brut - 2 * minspace) / (multiple * unit).to_f).to_i).even? ? n : (n - 1)
43
+ n * multiple
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "forwardable"
4
+
5
+ module Sevgi
6
+ module Utensils
7
+ class Tsquare
8
+ extend Forwardable
9
+ def_delegators :@h, :halve, :major, :minor
10
+
11
+ def_delegator :@h, :length, :width
12
+ def_delegator :@v, :length, :height
13
+
14
+ attr_reader :h, :v
15
+
16
+ def initialize(hruler:, vruler:)
17
+ @h = hruler
18
+ @v = vruler
19
+ end
20
+
21
+ def canvas = Graphics::Canvas.new(**Dim[h.brut, v.brut].to_h, margins: Margin[v.space / 2.0, h.space / 2.0].to_a)
22
+
23
+ def grid = Grid.new(self)
24
+
25
+ alias_method :unit, :minor
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "utensils/ruler"
4
+ require_relative "utensils/tsquare"
5
+ require_relative "utensils/grid"
6
+
7
+ require_relative "utensils/external"
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Sevgi
4
+ VERSION = "0.0.0"
5
+ end
data/lib/sevgi.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "sevgi/internal"
4
+ require_relative "sevgi/errors"
5
+ require_relative "sevgi/function"
6
+
7
+ require_relative "sevgi/graphics"
8
+ require_relative "sevgi/geometry"
9
+ require_relative "sevgi/standard"
10
+ require_relative "sevgi/utensils"
metadata ADDED
@@ -0,0 +1,127 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sevgi
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Recai Oktaş
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-09-23 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Toolkit for Creating SVG Content Programmatically with Ruby
14
+ email: roktas@gmail.com
15
+ executables:
16
+ - sevgi
17
+ extensions: []
18
+ extra_rdoc_files: []
19
+ files:
20
+ - CHANGELOG.md
21
+ - LICENSE
22
+ - README.md
23
+ - bin/sevgi
24
+ - lib/sevgi.rb
25
+ - lib/sevgi/errors.rb
26
+ - lib/sevgi/external.rb
27
+ - lib/sevgi/function.rb
28
+ - lib/sevgi/geometry.rb
29
+ - lib/sevgi/geometry/elements.rb
30
+ - lib/sevgi/geometry/elements/rect.rb
31
+ - lib/sevgi/geometry/elements/segment.rb
32
+ - lib/sevgi/geometry/equation.rb
33
+ - lib/sevgi/geometry/equation/line.rb
34
+ - lib/sevgi/geometry/equation/line/diagonal.rb
35
+ - lib/sevgi/geometry/equation/line/horizontal.rb
36
+ - lib/sevgi/geometry/equation/line/vertical.rb
37
+ - lib/sevgi/geometry/errors.rb
38
+ - lib/sevgi/geometry/external.rb
39
+ - lib/sevgi/geometry/operation.rb
40
+ - lib/sevgi/geometry/operation/align.rb
41
+ - lib/sevgi/geometry/operation/sweep.rb
42
+ - lib/sevgi/geometry/point.rb
43
+ - lib/sevgi/graphics.rb
44
+ - lib/sevgi/graphics/attribute.rb
45
+ - lib/sevgi/graphics/canvas.rb
46
+ - lib/sevgi/graphics/content.rb
47
+ - lib/sevgi/graphics/document.rb
48
+ - lib/sevgi/graphics/document/base.rb
49
+ - lib/sevgi/graphics/document/default.rb
50
+ - lib/sevgi/graphics/document/html.rb
51
+ - lib/sevgi/graphics/document/inkscape.rb
52
+ - lib/sevgi/graphics/document/minimal.rb
53
+ - lib/sevgi/graphics/element.rb
54
+ - lib/sevgi/graphics/external.rb
55
+ - lib/sevgi/graphics/mixtures.rb
56
+ - lib/sevgi/graphics/mixtures/core.rb
57
+ - lib/sevgi/graphics/mixtures/duplicate.rb
58
+ - lib/sevgi/graphics/mixtures/hatch.rb
59
+ - lib/sevgi/graphics/mixtures/identify.rb
60
+ - lib/sevgi/graphics/mixtures/inkscape.rb
61
+ - lib/sevgi/graphics/mixtures/lint.rb
62
+ - lib/sevgi/graphics/mixtures/render.rb
63
+ - lib/sevgi/graphics/mixtures/replicate.rb
64
+ - lib/sevgi/graphics/mixtures/save.rb
65
+ - lib/sevgi/graphics/mixtures/transform.rb
66
+ - lib/sevgi/graphics/mixtures/underscore.rb
67
+ - lib/sevgi/graphics/mixtures/validate.rb
68
+ - lib/sevgi/graphics/mixtures/wrappers.rb
69
+ - lib/sevgi/internal.rb
70
+ - lib/sevgi/internal/constant.rb
71
+ - lib/sevgi/internal/dim.rb
72
+ - lib/sevgi/internal/function.rb
73
+ - lib/sevgi/internal/function/file.rb
74
+ - lib/sevgi/internal/function/float.rb
75
+ - lib/sevgi/internal/function/formula.rb
76
+ - lib/sevgi/internal/function/math.rb
77
+ - lib/sevgi/internal/function/string.rb
78
+ - lib/sevgi/internal/list.rb
79
+ - lib/sevgi/internal/locate.rb
80
+ - lib/sevgi/internal/margin.rb
81
+ - lib/sevgi/internal/minitest.rb
82
+ - lib/sevgi/internal/minitest/script.rb
83
+ - lib/sevgi/internal/minitest/shell.rb
84
+ - lib/sevgi/internal/minitest/suite.rb
85
+ - lib/sevgi/internal/paper.rb
86
+ - lib/sevgi/standard.rb
87
+ - lib/sevgi/standard/conform.rb
88
+ - lib/sevgi/standard/data.rb
89
+ - lib/sevgi/standard/data/attribute.rb
90
+ - lib/sevgi/standard/data/element.rb
91
+ - lib/sevgi/standard/data/specification.rb
92
+ - lib/sevgi/standard/errors.rb
93
+ - lib/sevgi/standard/model.rb
94
+ - lib/sevgi/utensils.rb
95
+ - lib/sevgi/utensils/external.rb
96
+ - lib/sevgi/utensils/grid.rb
97
+ - lib/sevgi/utensils/ruler.rb
98
+ - lib/sevgi/utensils/tsquare.rb
99
+ - lib/sevgi/version.rb
100
+ homepage: https://roktas.dev/sevgi
101
+ licenses:
102
+ - GPL-3.0-or-later
103
+ metadata:
104
+ changelog_uri: https://github.com/roktas/sevgi/blob/main/CHANGELOG.md
105
+ source_code_uri: https://github.com/roktas/sevgi
106
+ bug_tracker_uri: https://github.com/roktas/sevgi/issues
107
+ rubygems_mfa_required: 'true'
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: 3.2.2
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubygems_version: 3.4.19
124
+ signing_key:
125
+ specification_version: 4
126
+ summary: Toolkit for Creating SVG Content Programmatically with Ruby
127
+ test_files: []