yiffspace 0.1.7 → 0.2.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 (127) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -10
  3. data/README.md +18 -1
  4. data/Rakefile +6 -7
  5. data/lib/yiffspace/version.rb +1 -1
  6. data/lib/yiffspace.rb +26 -27
  7. metadata +104 -139
  8. data/app/assets/config/yiffspace_manifest.js +0 -1
  9. data/app/assets/stylesheets/yiffspace/application.css +0 -30
  10. data/app/controllers/yiff_space/application_controller.rb +0 -6
  11. data/app/helpers/yiff_space/application_helper.rb +0 -6
  12. data/app/models/yiff_space/application_record.rb +0 -7
  13. data/app/views/layouts/yiff_space/application.html.erb +0 -17
  14. data/app/views/yiff_space/error.html.erb +0 -3
  15. data/lib/yiffspace/concerns/active_record_extensions.rb +0 -45
  16. data/lib/yiffspace/concerns/api_methods.rb +0 -101
  17. data/lib/yiffspace/concerns/attribute_matchers.rb +0 -100
  18. data/lib/yiffspace/concerns/attribute_methods.rb +0 -39
  19. data/lib/yiffspace/concerns/concurrency_methods.rb +0 -20
  20. data/lib/yiffspace/concerns/conditional_includes.rb +0 -43
  21. data/lib/yiffspace/concerns/current_methods.rb +0 -60
  22. data/lib/yiffspace/concerns/has_bit_flags.rb +0 -59
  23. data/lib/yiffspace/concerns/user_class_methods.rb +0 -32
  24. data/lib/yiffspace/concerns/user_methods.rb +0 -77
  25. data/lib/yiffspace/concerns/user_name_methods.rb +0 -53
  26. data/lib/yiffspace/concerns/user_resolvable_methods.rb +0 -38
  27. data/lib/yiffspace/config_builder.rb +0 -192
  28. data/lib/yiffspace/configuration/images.rb +0 -22
  29. data/lib/yiffspace/configuration.rb +0 -116
  30. data/lib/yiffspace/core_ext/active_record/all.rb +0 -8
  31. data/lib/yiffspace/core_ext/active_record/cross_join_lateral.rb +0 -7
  32. data/lib/yiffspace/core_ext/active_record/cross_unnest.rb +0 -7
  33. data/lib/yiffspace/core_ext/active_record/left_join_lateral.rb +0 -7
  34. data/lib/yiffspace/core_ext/active_record/left_unnest.rb +0 -7
  35. data/lib/yiffspace/core_ext/active_record/unnest.rb +0 -8
  36. data/lib/yiffspace/core_ext/active_record/where_chain.rb +0 -6
  37. data/lib/yiffspace/core_ext/all.rb +0 -8
  38. data/lib/yiffspace/core_ext/arel/all.rb +0 -4
  39. data/lib/yiffspace/core_ext/arel/cross_join_lateral.rb +0 -21
  40. data/lib/yiffspace/core_ext/arel/left_join_lateral.rb +0 -21
  41. data/lib/yiffspace/core_ext/enumerable/all.rb +0 -3
  42. data/lib/yiffspace/core_ext/enumerable/parallel.rb +0 -7
  43. data/lib/yiffspace/core_ext/hash/all.rb +0 -3
  44. data/lib/yiffspace/core_ext/hash/to_open_hash.rb +0 -7
  45. data/lib/yiffspace/core_ext/object/all.rb +0 -4
  46. data/lib/yiffspace/core_ext/object/to_b.rb +0 -7
  47. data/lib/yiffspace/core_ext/object/truthy_falsy.rb +0 -7
  48. data/lib/yiffspace/core_ext/string/all.rb +0 -3
  49. data/lib/yiffspace/core_ext/string/sql.rb +0 -7
  50. data/lib/yiffspace/engine.rb +0 -23
  51. data/lib/yiffspace/extensions/active_record/cross_join_lateral.rb +0 -23
  52. data/lib/yiffspace/extensions/active_record/cross_unnest.rb +0 -15
  53. data/lib/yiffspace/extensions/active_record/left_join_lateral.rb +0 -24
  54. data/lib/yiffspace/extensions/active_record/left_unnest.rb +0 -15
  55. data/lib/yiffspace/extensions/active_record/unnest.rb +0 -20
  56. data/lib/yiffspace/extensions/active_record/where_chain.rb +0 -107
  57. data/lib/yiffspace/extensions/arel/nodes/cross_join_lateral.rb +0 -17
  58. data/lib/yiffspace/extensions/arel/nodes/left_join_lateral.rb +0 -17
  59. data/lib/yiffspace/extensions/arel/table/cross_join_lateral.rb +0 -15
  60. data/lib/yiffspace/extensions/arel/table/left_join_lateral.rb +0 -15
  61. data/lib/yiffspace/extensions/arel/visitors/postgresql/cross_join_lateral.rb +0 -19
  62. data/lib/yiffspace/extensions/arel/visitors/postgresql/left_join_lateral.rb +0 -23
  63. data/lib/yiffspace/extensions/enumerable/parallel.rb +0 -39
  64. data/lib/yiffspace/extensions/hash/to_open_hash.rb +0 -15
  65. data/lib/yiffspace/extensions/object/to_b.rb +0 -22
  66. data/lib/yiffspace/extensions/object/truthy_falsy.rb +0 -35
  67. data/lib/yiffspace/extensions/string/sql.rb +0 -21
  68. data/lib/yiffspace/images/avatar/base.rb +0 -41
  69. data/lib/yiffspace/images/avatar/discord.rb +0 -37
  70. data/lib/yiffspace/images/avatar/gravatar.rb +0 -21
  71. data/lib/yiffspace/images/avatar.rb +0 -33
  72. data/lib/yiffspace/images/banner/base.rb +0 -41
  73. data/lib/yiffspace/images/banner/discord.rb +0 -37
  74. data/lib/yiffspace/images/banner.rb +0 -33
  75. data/lib/yiffspace/images.rb +0 -6
  76. data/lib/yiffspace/include/active_record_extensions.rb +0 -5
  77. data/lib/yiffspace/include/all.rb +0 -31
  78. data/lib/yiffspace/include/api_methods.rb +0 -5
  79. data/lib/yiffspace/include/attribute_matchers.rb +0 -5
  80. data/lib/yiffspace/include/attribute_methods.rb +0 -5
  81. data/lib/yiffspace/include/cache.rb +0 -5
  82. data/lib/yiffspace/include/concurrency_methods.rb +0 -5
  83. data/lib/yiffspace/include/conditional_includes.rb +0 -5
  84. data/lib/yiffspace/include/current.rb +0 -5
  85. data/lib/yiffspace/include/current_methods.rb +0 -5
  86. data/lib/yiffspace/include/duration_parser.rb +0 -5
  87. data/lib/yiffspace/include/has_bit_flags.rb +0 -5
  88. data/lib/yiffspace/include/helpers.rb +0 -5
  89. data/lib/yiffspace/include/open_hash.rb +0 -5
  90. data/lib/yiffspace/include/parameter_builder.rb +0 -5
  91. data/lib/yiffspace/include/parse_value.rb +0 -5
  92. data/lib/yiffspace/include/query_builder.rb +0 -5
  93. data/lib/yiffspace/include/query_dsl.rb +0 -5
  94. data/lib/yiffspace/include/query_helper.rb +0 -5
  95. data/lib/yiffspace/include/routes.rb +0 -5
  96. data/lib/yiffspace/include/table_builder.rb +0 -5
  97. data/lib/yiffspace/include/trace_logger.rb +0 -5
  98. data/lib/yiffspace/include/u2id.rb +0 -5
  99. data/lib/yiffspace/include/user_attribute.rb +0 -5
  100. data/lib/yiffspace/include/user_class_methods.rb +0 -5
  101. data/lib/yiffspace/include/user_like.rb +0 -5
  102. data/lib/yiffspace/include/user_methods.rb +0 -5
  103. data/lib/yiffspace/include/user_name_methods.rb +0 -5
  104. data/lib/yiffspace/include/user_resolvable.rb +0 -5
  105. data/lib/yiffspace/include/user_resolvable_methods.rb +0 -5
  106. data/lib/yiffspace/search/query_builder.rb +0 -83
  107. data/lib/yiffspace/search/query_dsl.rb +0 -119
  108. data/lib/yiffspace/search/query_helper.rb +0 -49
  109. data/lib/yiffspace/serializers/avatar_serializer.rb +0 -21
  110. data/lib/yiffspace/serializers/banner_serializer.rb +0 -21
  111. data/lib/yiffspace/serializers/user_resolvable_serializer.rb +0 -21
  112. data/lib/yiffspace/utils/cache.rb +0 -40
  113. data/lib/yiffspace/utils/current.rb +0 -43
  114. data/lib/yiffspace/utils/duration_parser.rb +0 -24
  115. data/lib/yiffspace/utils/helpers.rb +0 -25
  116. data/lib/yiffspace/utils/open_hash.rb +0 -63
  117. data/lib/yiffspace/utils/parameter_builder.rb +0 -121
  118. data/lib/yiffspace/utils/parse_value.rb +0 -174
  119. data/lib/yiffspace/utils/routes.rb +0 -28
  120. data/lib/yiffspace/utils/set_env_constraint.rb +0 -18
  121. data/lib/yiffspace/utils/table_builder.rb +0 -169
  122. data/lib/yiffspace/utils/trace_logger.rb +0 -91
  123. data/lib/yiffspace/utils/user_attribute.rb +0 -272
  124. data/lib/yiffspace/utils/user_like.rb +0 -8
  125. data/lib/yiffspace/utils/user_resolvable.rb +0 -61
  126. data/lib/yiffspace/utils/user_to_id.rb +0 -11
  127. data/lib/yiffspace/utils.rb +0 -6
@@ -1,272 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module YiffSpace
4
- module Utils
5
- # User class must have id_to_name & name_to_id methods, and global u2id method must exist
6
- class UserAttribute
7
- class CircularAliasError < StandardError; end
8
- class CircularCloneError < StandardError; end
9
- class DuplicateAttributeError < StandardError; end
10
- class CloneError < StandardError; end
11
- attr_reader(:klass, :attribute, :db, :ip, :optional, :clones, :overwrite, :aliases, :ignore_nil, :ar_options)
12
-
13
- # noinspection RubyUnusedLocalVariable
14
- def initialize(klass, attribute, db:, ip: !db, optional: !db, clones: [], clone: [], overwrite: false, aliases: [], alias: [], ignore_nil: false, **ar_options)
15
- UserAttribute.class_setup(klass)
16
- @klass = klass
17
- @attribute = attribute.to_sym
18
- @db = db
19
- # noinspection RubySimplifyBooleanInspection
20
- @ip = ip == true ? :"#{attribute}_ip_addr" : ip
21
- @optional = optional
22
- @clones = Array(clones.presence || clone).map(&:to_sym)
23
- @overwrite = overwrite
24
- @aliases = Array(aliases.presence || binding.local_variable_get(:alias)).map(&:to_sym)
25
- @ignore_nil = ignore_nil
26
- @ar_options = ar_options
27
- if ar_options.any? && !db # rubocop:disable Style/IfUnlessModifier
28
- TraceLogger.warn("UserAttribute", "Unexpected extra options for non-db attribute: #{ar_options.inspect}", ignore: [%r{/concerns/user_methods\.rb}, %r{/logical/user_attribute\.rb}])
29
- end
30
- @ar_options[:optional] = optional
31
- @ar_options[:class_name] = "User"
32
- validate_options!
33
- klass.user_attributes[attribute] = self
34
- define_methods
35
- end
36
-
37
- def validate_options!
38
- raise(DuplicateAttributeError, "user attribute #{attribute} is already defined on #{klass}") if klass.user_attributes.key?(attribute)
39
-
40
- validate_aliases!
41
- validate_clones!
42
- end
43
-
44
- def validate_aliases!
45
- return if aliases.empty?
46
- raise(CircularAliasError, "aliases must not contain attribute (#{klass}.#{attribute}") if aliases.include?(attribute)
47
- end
48
-
49
- def validate_clones!
50
- return if clones.empty?
51
- raise(CircularCloneError, "clones must not contain attribute (#{klass}.#{attribute}") if clones.include?(attribute)
52
- # TODO: implement clone validation logic
53
- end
54
-
55
- def validate_value!(value, type, record: nil)
56
- return if value.nil?
57
-
58
- case type
59
- when :user
60
- return if (optional || ignore_nil) && value.nil?
61
- return if value.is_a?(::User)
62
-
63
- if value.is_a?(::UserResolvable)
64
- return if value.user.is_a?(::User)
65
-
66
- raise(ArgumentError, "Expected User for UserResolvable.user in #{klass.name}##{attribute}, got #{value.user.inspect} (#{value.user.class.name})")
67
- end
68
- value_error("is invalid", "UserLike", attribute, value, record: record)
69
- when :id
70
- value_error("is invalid", "Integer", "#{attribute}_id", value, record: record) unless value.is_a?(Integer) || (value.is_a?(String) && /\A\d+\Z/.match?(value))
71
- when :name
72
- value_error("is invalid", "String", "#{attribute}_name", value, record: record) unless value.is_a?(String)
73
- when :ip_addr
74
- return if value.is_a?(IPAddr)
75
-
76
- begin
77
- IPAddr.new(value)
78
- rescue IPAddr::InvalidAddressError
79
- value_error("is invalid", "IPAddr", ip, value, record: record)
80
- end
81
- else
82
- raise(ArgumentError, "Not sure how to validate #{type}")
83
- end
84
- end
85
-
86
- def value_error(message, expected, attr, value, record: nil)
87
- raise(ArgumentError, "Expected #{expected} for #{klass.name}.#{attr}=, got #{value.inspect} (#{value.class.name})") unless record.respond_to?(:errors) && record.errors.is_a?(ActiveModel::Errors)
88
-
89
- record.errors.add(attr, message)
90
- end
91
-
92
- def define_methods # rubocop:disable Metrics/MethodLength
93
- ua = self
94
- klass.define_singleton_method(:"#{attribute}_attribute") { ua }
95
- klass.belongs_to(attribute, **ar_options) if db
96
- if (klass < ActiveModel::Validations) && ip && !optional
97
- # klass.validates(attribute, presence: { message: "must exist" }) unless optional
98
- klass.validates(ip, presence: true, if: -> { send("#{ua.attribute}_id").present? })
99
- end
100
- klass.define_method(attribute) do
101
- if ua.db
102
- value = super()
103
- else
104
- value = instance_variable_get(:"@#{ua.attribute}")
105
- value = ua.get_clone_value(self) if value.blank?
106
- end
107
- return if value.blank?
108
-
109
- if ua.ip && (ip_addr = send(ua.ip))
110
- ::UserResolvable.new(value, ip_addr)
111
- else
112
- value
113
- end
114
- end
115
- klass.define_method("#{attribute}=") do |value|
116
- ua.validate_value!(value, :user, record: self)
117
- if ua.clones.any?
118
- ua.clones.each do |cattr|
119
- ua.clone_value(self, cattr, value)
120
- end
121
- end
122
-
123
- if value.is_a?(::UserResolvable)
124
- send("#{ua.ip}=", value.ip_addr) if ua.ip
125
- value = value.user
126
- end
127
-
128
- if ua.db
129
- super(value)
130
- else
131
- instance_variable_set(:"@#{ua.attribute}", value)
132
- end
133
- end
134
- klass.define_method("#{attribute}_id") do
135
- if ua.db
136
- read_attribute("#{ua.attribute}_id")
137
- else
138
- value = instance_variable_get(:"@#{ua.attribute}")&.id
139
- value = ua.get_clone_value(self, :id) if value.blank?
140
- value
141
- end
142
- end
143
- klass.define_method("#{attribute}_id=") do |value|
144
- ua.validate_value!(value, :id, record: self)
145
- if ua.db
146
- write_attribute("#{ua.attribute}_id", value)
147
- TraceLogger.warn("UserAttribute", "#{ua.klass.name}.#{ua.attribute}_id= should not be used when clone is enabled (#{ua.clones.join(', ')})", ignore: [%r{/concerns/user_methods\.rb}, %r{/logical/user_attribute\.rb}]) if ua.clones.any?
148
- else
149
- value = ::User.find(value) if value.is_a?(Integer) || value.is_a?(String)
150
- ua.clones.each do |cattr|
151
- ua.clone_direct(self, cattr, value)
152
- end
153
- instance_variable_set(:"@#{ua.attribute}", value)
154
- end
155
- end
156
- klass.define_method("#{attribute}_name") do
157
- value = send("#{ua.attribute}_id")
158
- return "Anonymous" if value.blank?
159
-
160
- ::User.id_to_name(value)
161
- end
162
- klass.define_method("#{attribute}_name=") do |value|
163
- ua.validate_value!(value, :name, record: self)
164
- value = ::User.name_to_id(value)
165
- return send("#{ua.attribute}_id=", value) if value.blank?
166
-
167
- send("#{ua.attribute}=", ::User.find(value))
168
- end
169
- if ip
170
- klass.define_method(ip) do
171
- if ua.db
172
- read_attribute(ua.ip)
173
- else
174
- value = instance_variable_get(:"@#{ua.ip}")
175
- value = ua.get_clone_value(self, :ip_addr) if value.blank?
176
- value
177
- end
178
- end
179
- klass.define_method("#{ip}=") do |value|
180
- ua.validate_value!(value, :ip_addr, record: self)
181
- if ua.db
182
- write_attribute(ua.ip, value)
183
- else
184
- value = value.to_s.strip if value.is_a?(String)
185
- ua.clones.each do |cattr|
186
- ua.clone_ip(self, cattr, value)
187
- end
188
- instance_variable_set(:"@#{ua.ip}", value)
189
- end
190
- end
191
- end
192
- klass.instance_exec do
193
- scope("for_#{ua.attribute}", ->(value) { where(ua.db && ua.ar_options.key?(:foreign_key) ? ua.ar_options[:foreign_key] : "#{ua.attribute}_id" => u2id(value)) }) unless respond_to?("for_#{ua.attribute}")
194
- scope("for_#{ua.attribute}_id", ->(value) { where(ua.db && ua.ar_options.key?(:foreign_key) ? ua.ar_options[:foreign_key] : "#{ua.attribute}_id" => value) }) unless respond_to?("for_#{ua.attribute}_id")
195
- scope("for_#{ua.attribute}_name", ->(value) { where(ua.db && ua.ar_options.key?(:foreign_key) ? ua.ar_options[:foreign_key] : "#{ua.attribute}_id" => YiffSpace.config.user_class.name_to_id(value)) }) unless respond_to?("for_#{ua.attribute}_name")
196
- end
197
-
198
- aliases.each do |alias_attr|
199
- create_alias(alias_attr)
200
- end
201
- end
202
-
203
- def get_clone_value(record, type = nil)
204
- attrs = klass.user_attributes.select { |_attr, options| options.clones.include?(attribute) }
205
- value = nil
206
- attrs.each_key do |cattr|
207
- case type
208
- when :id
209
- value = record.send("#{cattr}_id")
210
- when :ip_addr
211
- value = record.send(attrs[cattr].ip) if attrs[cattr].ip
212
- else
213
- value = record.send(cattr)
214
- end
215
- break if value.present?
216
- end
217
- value
218
- end
219
-
220
- def clone_value(record, attr, value)
221
- return record.send("#{attr}=", value) if overwrite
222
-
223
- if record.respond_to?(:"#{attr}_id")
224
- record.send(:"#{attr}=", value) if record.send(:"#{attr}_id").blank?
225
- elsif record.respond_to?(attr)
226
- record.send(:"#{attr}=", value) if record.send(attr).blank?
227
- else
228
- raise(CloneError, "Not sure how to clone to #{attr}, #{record.class} does not respond_to? #{attr}_id or #{attr}")
229
- end
230
- end
231
-
232
- def clone_ip(record, attr, value)
233
- ip_attr = klass.user_attributes.find { |uattr, _value| uattr == attr }&.second&.ip
234
- raise(CloneError, "Not sure how to clone ip for #{attr}, no ip attribute defined") unless ip_attr
235
-
236
- clone_direct(record, ip_attr, value)
237
- end
238
-
239
- def clone_direct(record, attr, value)
240
- return record.send("#{attr}=", value) if overwrite
241
-
242
- raise(CloneError, "Not sure how to clone to #{attr}, #{record.class} does not respond_to? #{attr}") unless record.respond_to?(attr)
243
-
244
- record.send(:"#{attr}=", value) if record.send(attr).blank?
245
- end
246
-
247
- def create_alias(attr)
248
- ua = self
249
- klass.class_eval do
250
- define_method(attr) { send(ua.attribute) }
251
- define_method("#{attr}=") { |value| send("#{ua.attribute}=", value) }
252
- define_method("#{attr}_id") { send("#{ua.attribute}_id") }
253
- define_method("#{attr}_id=") { |value| send("#{ua.attribute}_id=", value) }
254
- define_method("#{attr}_name") { send("#{ua.attribute}_name") }
255
- define_method("#{attr}_name=") { |value| send("#{ua.attribute}_name=", value) }
256
- if ua.ip
257
- define_method("#{attr}_ip_addr") { send(ua.ip) }
258
- define_method("#{attr}_ip_addr=") { |value| send("#{ua.ip}=", value) }
259
- end
260
- end
261
- end
262
-
263
- def self.class_setup(klass)
264
- return if klass.method_defined?(:user_attributes)
265
-
266
- klass.class_eval do
267
- class_attribute(:user_attributes, default: {})
268
- end
269
- end
270
- end
271
- end
272
- end
@@ -1,8 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module YiffSpace
4
- module Utils
5
- module UserLike
6
- end
7
- end
8
- end
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require("active_support/core_ext/module/delegation")
4
- require("active_support/core_ext/string/inflections")
5
-
6
- module YiffSpace
7
- module Utils
8
- class UserResolvable
9
- attr_reader(:user, :ip_addr)
10
-
11
- def initialize(user, ip_addr, validate: true)
12
- if user.is_a?(YiffSpace.config.user_resolvable_class)
13
- TraceLogger.warn(self.class.name.demodulize, "Unexpectedly received #{user.class.name} for user argument")
14
- user = recursive_resolve(user)
15
- end
16
- @user = user
17
- ip_addr = ip_addr.to_s if ip_addr.is_a?(IPAddr)
18
- @ip_addr = ip_addr
19
- return unless validate
20
- raise(ArgumentError, "Expected User for user argument, got #{user.inspect} (#{user.class.name})") unless user.is_a?(YiffSpace.config.user_class)
21
- raise(ArgumentError, "Expected String for ip_addr argument, got #{ip_addr.inspect} (#{ip_addr.class.name})") unless ip_addr.is_a?(String)
22
- end
23
-
24
- alias resolve user
25
-
26
- def resolvable(ip_addr = nil)
27
- @ip_addr = ip_addr if ip_addr.present?
28
- self
29
- end
30
-
31
- delegate(:recursive_resolve, to: :class)
32
- delegate(:to_param, :serializable_hash, :as_json, :to_json, to: :user)
33
- delegate_missing_to(:user, allow_nil: true)
34
-
35
- # needed to allow passing the class around when creating records, active record attempts to call several methods on the provided record's class
36
- class << self
37
- delegate_missing_to(:User, allow_nil: false)
38
- end
39
-
40
- def self.recursive_resolve(resolvable)
41
- result = resolvable
42
- result = result.resolve while result.is_a?(YiffSpace.config.user_resolvable_class)
43
- result
44
- end
45
-
46
- def ==(other)
47
- return other == user if other.is_a?(YiffSpace.config.user_class)
48
-
49
- other.is_a?(YiffSpace.config.user_resolvable_class) && user == other.user
50
- end
51
-
52
- def ===(other)
53
- (other == YiffSpace.config.user_like_class && user.is_a?(YiffSpace.config.user_class)) || super
54
- end
55
-
56
- def is_a?(other)
57
- (other == YiffSpace.config.user_like_class && user.is_a?(YiffSpace.config.user_class)) || super
58
- end
59
- end
60
- end
61
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module YiffSpace
4
- module Utils
5
- module UserToId
6
- def u2id(value, klass = YiffSpace.config.user_class)
7
- value.is_a?(klass) || (klass == YiffSpace.config.user_class && value.is_a?(YiffSpace.config.user_resolvable_class)) ? value.id : value
8
- end
9
- end
10
- end
11
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module YiffSpace
4
- module Utils
5
- end
6
- end