glimmer-dsl-swt 4.24.3.1 → 4.24.3.2

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: 44c7406f9588caef592b17f889b509db88771e545300a916f44ea1a928a89937
4
- data.tar.gz: 2933dfdf3e5e1479849793cec5bbfdf3558768bb34b4c828847339c95559242a
3
+ metadata.gz: 89250fa7cc394da176eb7cd91a17c7ad388607c69927a7e22b6b1be62333a0b8
4
+ data.tar.gz: e7e09c62b782c682c0abdb8722001c8925268cfe4bab49b536eb58f3f32fb697
5
5
  SHA512:
6
- metadata.gz: 6d13f0eaa866f47c449caa5ce3e3ae652025940769b8f419c0b4b66df0e1e67b3a4e3494ab539cb81d21de79ac44d81e3982f59083c9bd0453201e1231073ee0
7
- data.tar.gz: 53fe039d009a4d3476bbc2a5d96f11ca3ab4fdb442b790bafd0b9bc920943bb4cc6bc475522f1f040d355da8029cd693a76179d4e247fa9e4bd59fcd2637fe80
6
+ metadata.gz: 136c2625e94629b690a325bdc3c8669a36c612f9f651b04faa5be3dcbcc86b57ae5345c23fcce1b10656b9dca5e8a4e96a318147907785a5bff18eac3dd4b130
7
+ data.tar.gz: 6d1c069b332ccd3139cf0c6377dd64b5341ccd84cc4dda3c72f5255c0eaeff0639bbfcdea35cb6b66baa84fb9ed1093143cafb4897f6ba2b2198dd494e0033c3
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Change Log
2
2
 
3
+ ## 4.24.3.2
4
+
5
+ - Have `table` data-binding infer model attribute names from column names by convention (no need to specify `column_properties`)
6
+ - Support `table` data-binding `column_properties` mapping of column names to model attribute names via a `Hash`
7
+ - Support `table` data-binding alias of `column_attributes` in place of `column_properties` because the word 'attribute' is more Ruby-idiomatic than 'property' in the Ruby world
8
+ - Handle boundary condition of font height reaching 0 on repeated zoom out of `code_text`
9
+ - Battleship Video Tutorial in Glimmer Meta-Sample
10
+
3
11
  ## 4.24.3.1
4
12
 
5
13
  - `code_text` default behavior support of zoom in (CMD+= on Mac, CTRL+= on Win/Linux), zoom out (CMD+- on Mac, CTRL+- on Win/Linux), and restore original font height (CMD+0 on Mac, CTRL+0 on Win/Linux).
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.24.3.1
1
+ # [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 4.24.3.2
2
2
  ## JRuby Desktop Development GUI Framework
3
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
4
4
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
@@ -21,7 +21,7 @@ Featured in JRuby Cookbook](http://shop.oreilly.com/product/9780596519650.do) an
21
21
 
22
22
  ![Eclipse SWT RCP NASA Mars Rover](/images/glimmer-eclipse-swt-rcp-nasa-mars-rover.png)
23
23
 
24
- [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.24.3.1 includes [SWT 4.24](https://download.eclipse.org/eclipse/downloads/drops4/R-4.24-202206070700/), which was released on June 7, 2022. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
24
+ [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) 4.24.3.2 includes [SWT 4.24](https://download.eclipse.org/eclipse/downloads/drops4/R-4.24-202206070700/), which was released on June 7, 2022. Gem version numbers are in sync with the SWT library versions. The first two digits represent the SWT version number. The last two digits represent the minor and patch versions of Glimmer DSL for SWT.
25
25
 
26
26
  **Starting in version 4.20.0.0, [Glimmer DSL for SWT](https://rubygems.org/gems/glimmer-dsl-swt) comes with the new [***Shine***](/docs/reference/GLIMMER_GUI_DSL_SYNTAX.md#shine) syntax** for highly intuitive and visually expressive View/Model Attribute Mapping, relying on `<=>` for bidirectional (two-way) data-binding and `<=` for unidirectional (one-way) data-binding, providing an alternative to the `bind` keyword. That was [originally conceived back in 2007](https://andymaleh.blogspot.com/2007/12/data-shining-in-glimmer.html).
27
27
 
@@ -338,7 +338,7 @@ jgem install glimmer-dsl-swt
338
338
 
339
339
  Or this command if you want a specific version:
340
340
  ```
341
- jgem install glimmer-dsl-swt -v 4.24.3.1
341
+ jgem install glimmer-dsl-swt -v 4.24.3.2
342
342
  ```
343
343
 
344
344
  `jgem` is JRuby's version of `gem` command.
@@ -366,7 +366,7 @@ Note: if you're using activerecord or activesupport, keep in mind that Glimmer u
366
366
 
367
367
  Add the following to `Gemfile`:
368
368
  ```
369
- gem 'glimmer-dsl-swt', '~> 4.24.3.1'
369
+ gem 'glimmer-dsl-swt', '~> 4.24.3.2'
370
370
  ```
371
371
 
372
372
  And, then run:
@@ -389,7 +389,7 @@ glimmer
389
389
  ```
390
390
 
391
391
  ```
392
- Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.24.3.1
392
+ Glimmer (JRuby Desktop Development GUI Framework) - JRuby Gem: glimmer-dsl-swt v4.24.3.2
393
393
 
394
394
  Usage: glimmer [--bundler] [--pd] [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
395
395
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 4.24.3.1
1
+ 4.24.3.2
@@ -3996,13 +3996,13 @@ You may learn more about Glimmer's data-binding syntax by reading the code under
3996
3996
 
3997
3997
  The SWT Tree widget renders a multi-column data table, such as a contact listing or a sales report.
3998
3998
 
3999
- To data-bind a Table, you need the main model, the collection property, and the text display attribute for each table column.
3999
+ To data-bind a Table, you need the main model and the collection property. The text for each row cell will be inferred from column names as underscored model attributes. For example, for a column named "Full Name", it is assumed by convention that the model has a `full_name` attribute.
4000
4000
 
4001
- This involves using the `<=>` operator in addition to a special `column_properties` kwarg that takes an array that maps table columns to model attributes.
4001
+ Data-binding involves using the `<=` operator (one-way data-binding) or `<=>` operator (two-way data-binding), and an optional `column_attributes` kwarg (alias: `column_properties`) that takes an array that maps table columns to model attributes or a hash that maps column name strings to model attributes.
4002
4002
 
4003
4003
  It assumes you have already defined table columns via the `table_column` `table`-nested widget.
4004
4004
 
4005
- Example:
4005
+ Example (automatically inferring table items' [rows'] model attributes by convention from column names):
4006
4006
 
4007
4007
  ```ruby
4008
4008
  shell {
@@ -4019,8 +4019,10 @@ shell {
4019
4019
  text "Adult"
4020
4020
  width 120
4021
4021
  }
4022
- items <=> [group, :people, column_properties: [:name, :age, :adult]]
4022
+
4023
+ items <=> [group, :people]
4023
4024
  selection <=> [group, :selected_person]
4025
+
4024
4026
  on_mouse_up do |event|
4025
4027
  @table.edit_table_item(event.table_item, event.column_index)
4026
4028
  end
@@ -4028,15 +4030,71 @@ shell {
4028
4030
  }
4029
4031
  ```
4030
4032
 
4031
- The code above includes two data-bindings:
4032
- - Table `items`, which first data-binds to the model collection property (group.people), and then maps each column property (name, age, adult) for displaying each table item column.
4033
+ The code above includes two data-bindings and a listener:
4034
+ - Table `items`, which first data-binds to the model collection property (group.people), and then maps each column to a model attribute (name, age, adult) for displaying each table item column.
4033
4035
  - Table `selection`, which data-binds the single table item (row) selected by the user to the model attribute denoted by `<=>` (or data-binds multiple table items to a model attribute array value for a table with `:multi` SWT style)
4034
4036
  - The `on_mouse_up` event handler invokes `@table.edit_table_item(event.table_item, event.column_index)` to start edit mode on the clicked table item cell, and then saves or cancel depending on whether the user hits ENTER or ESC once done editing (or focus-out after either making a change or not making any changes.)
4035
4037
 
4038
+ Example (specifying `column_attributes` explicitly because some diverge from column names):
4039
+
4040
+ ```ruby
4041
+ shell {
4042
+ @table = table {
4043
+ table_column {
4044
+ text "Full Name"
4045
+ width 120
4046
+ }
4047
+ table_column {
4048
+ text "Age in Years"
4049
+ width 120
4050
+ }
4051
+ table_column {
4052
+ text "Adult"
4053
+ width 120
4054
+ }
4055
+
4056
+ items <=> [group, :people, column_attributes: {'Full Name' => :name, 'Age in Years' => :age}]
4057
+ selection <=> [group, :selected_person]
4058
+
4059
+ on_mouse_up do |event|
4060
+ @table.edit_table_item(event.table_item, event.column_index)
4061
+ end
4062
+ }
4063
+ }
4064
+ ```
4065
+
4066
+ Example (specifying `column_attributes` explicitly because all diverge from column names):
4067
+
4068
+ ```ruby
4069
+ shell {
4070
+ @table = table {
4071
+ table_column {
4072
+ text "Full Name"
4073
+ width 120
4074
+ }
4075
+ table_column {
4076
+ text "Age in Years"
4077
+ width 120
4078
+ }
4079
+ table_column {
4080
+ text "Is Adult"
4081
+ width 120
4082
+ }
4083
+
4084
+ items <=> [group, :people, column_attributes: [:name, :age, :adult]]
4085
+ selection <=> [group, :selected_person]
4086
+
4087
+ on_mouse_up do |event|
4088
+ @table.edit_table_item(event.table_item, event.column_index)
4089
+ end
4090
+ }
4091
+ }
4092
+ ```
4093
+
4036
4094
  Additionally, Table `items` data-binding automatically stores each row model in the [SWT `TableItem`](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) object representing it, by using the `set_data` method. This enables things like searchability.
4037
4095
 
4038
- The table widget in Glimmer is represented by a subclass of `WidgetProxy` called `TableProxy`.
4039
- TableProxy includes a `search` method that takes a block to look for a table item.
4096
+ The table widget in Glimmer is represented by a subclass of `Glimmer::SWT::WidgetProxy` called `Glimmer::SWT::TableProxy`.
4097
+ `Glimmer::SWT::TableProxy` includes a `search` method that takes a block to look for a table item.
4040
4098
 
4041
4099
  Example:
4042
4100
 
@@ -4055,7 +4113,7 @@ It automatically persists the change to `items` data-bound model on ENTER/FOCUS-
4055
4113
 
4056
4114
  When data-binding a `table`'s `items`, extra [`TableItem` properties](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) are data-bound automatically by convention for `background` color, `foreground` color, `font`, and `image` if corresponding properties (attributes) are available on the model.
4057
4115
 
4058
- That means that if `column_properties` were `[:name, :age, :adult]`, then the following [`TableItem` properties](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) are also data-bound by convention:
4116
+ That means that if `column_attributes` were `[:name, :age, :adult]`, then the following [`TableItem` properties](https://help.eclipse.org/latest/topic/org.eclipse.platform.doc.isv/reference/api/org/eclipse/swt/widgets/TableItem.html) are also data-bound by convention:
4059
4117
  - `background` to `:name_background, :age_background, :adult_background` model attributes
4060
4118
  - `foreground` to `:name_foreground, :age_foreground, :adult_foreground` model attributes
4061
4119
  - `font` to `:name_font, :age_font, :adult_font` model attributes
@@ -4104,7 +4162,7 @@ shell {
4104
4162
  text "Adult"
4105
4163
  width 120
4106
4164
  }
4107
- items bind(group, :people), column_properties(:name, :age, :adult)
4165
+ items <=> [group, :people]
4108
4166
  selection bind(group, :selected_person)
4109
4167
  }
4110
4168
  }
@@ -4131,7 +4189,7 @@ shell {
4131
4189
  width 120
4132
4190
  editor :checkbox
4133
4191
  }
4134
- items bind(group, :people), column_properties(:name, :age, :adult)
4192
+ items <=> [group, :people]
4135
4193
  selection bind(group, :selected_person)
4136
4194
  }
4137
4195
  }
@@ -4170,7 +4228,7 @@ shell {
4170
4228
  # assume there is a `Person#industry_options` property method on the model to provide items to the `combo`
4171
4229
  editor :combo, :read_only # passes :ready_only SWT style to `combo` widget
4172
4230
  }
4173
- items bind(group, :people), column_properties(:formatted_date, :industry)
4231
+ items <=> [group, :people, column_attributes: {'Date of Birth' => :formatted_date}]
4174
4232
  selection bind(group, :selected_person)
4175
4233
  }
4176
4234
  }
@@ -4229,7 +4287,7 @@ Example:
4229
4287
  sort { |d1, d2| d1.to_date <=> d2.to_date }
4230
4288
  }
4231
4289
  additional_sort_properties :project_name, :duration_in_hours, :name
4232
- items bind(Task, :list), column_properties(:name, :project_name, :duration, :priority, :start_date)
4290
+ items <=> [Task, :list, column_attributes: [:name, :project_name, :duration, :priority, :start_date]]
4233
4291
  # ...
4234
4292
  }
4235
4293
  # ...
@@ -4242,7 +4300,7 @@ Here is an explanation of the example above:
4242
4300
  - Task Start Date table column has a custom sort comparator block
4243
4301
  - Additional (secondary) sort properties are applied when sorting by Task, Project, or Duration in the order specified
4244
4302
 
4245
- `bind(model, :property, read_only_sort: true)` could be used with items to make sorting not propagate sorting changes to model.
4303
+ `<= [model, :property, read_only_sort: true]` could be used with items to make sorting not propagate sorting changes to model.
4246
4304
 
4247
4305
  #### Tree
4248
4306
 
Binary file
@@ -42,12 +42,14 @@ module Glimmer
42
42
  @table = parent
43
43
  @model_binding = model_binding
44
44
  @read_only_sort = @model_binding.binding_options[:read_only_sort]
45
- @column_properties = @model_binding.binding_options[:column_properties] || @model_binding.binding_options[:column_attributes] || column_properties
46
45
  @table.editable = false if @model_binding.binding_options[:read_only]
47
- if @table.respond_to?(:column_properties=)
48
- @table.column_properties = @column_properties
46
+ column_properties = @model_binding.binding_options[:column_properties] || @model_binding.binding_options[:column_attributes] || column_properties
47
+ if @table.is_a?(Glimmer::SWT::TableProxy)
48
+ @table.column_properties = column_properties
49
+ @column_properties = @table.column_properties # normalized column properties
49
50
  else # assume custom widget
50
51
  @table.body_root.column_properties = @column_properties
52
+ @column_properties = @table.body_root.column_properties # normalized column properties
51
53
  end
52
54
  Glimmer::SWT::DisplayProxy.instance.auto_exec(override_sync_exec: @model_binding.binding_options[:sync_exec], override_async_exec: @model_binding.binding_options[:async_exec]) do
53
55
  @table.swt_widget.data = @model_binding
@@ -349,7 +349,7 @@ module Glimmer
349
349
 
350
350
  def bump_font_height_down
351
351
  @original_font_height ||= font_datum.height
352
- new_font_height = font_datum.height - 1
352
+ new_font_height = (font_datum.height - 1) == 0 ? font_datum.height : (font_datum.height - 1)
353
353
  update_font_height(new_font_height)
354
354
  end
355
355
 
@@ -246,7 +246,8 @@ module Glimmer
246
246
  end
247
247
 
248
248
  attr_reader :table_editor, :table_editor_widget_proxy, :sort_property, :sort_direction, :sort_block, :sort_type, :sort_by_block, :additional_sort_properties, :editor, :editable
249
- attr_accessor :column_properties
249
+ attr_writer :column_properties
250
+ alias column_attributes= column_properties=
250
251
  alias editable? editable
251
252
 
252
253
  def initialize(underscored_widget_name, parent, args)
@@ -258,6 +259,19 @@ module Glimmer
258
259
  @table_editor.minimumHeight = 20
259
260
  self.editable = editable_style
260
261
  end
262
+
263
+ def column_properties
264
+ if @column_properties.nil?
265
+ swt_widget.columns.to_a.map(&:text).map(&:underscore)
266
+ elsif @column_properties.is_a?(Hash)
267
+ @column_properties = swt_widget.columns.to_a.map(&:text).map do |column_name|
268
+ @column_properties[column_name] || column_name.underscore
269
+ end
270
+ else
271
+ @column_properties
272
+ end
273
+ end
274
+ alias column_attributes column_properties
261
275
 
262
276
  def items
263
277
  auto_exec do
@@ -144,7 +144,7 @@ class ContactManager
144
144
  width 200
145
145
  }
146
146
 
147
- items <=> [@contact_manager_presenter, :results, column_properties: [:first_name, :last_name, :email]]
147
+ items <=> [@contact_manager_presenter, :results]
148
148
 
149
149
  on_mouse_up do |event|
150
150
  table_proxy.edit_table_item(event.table_item, event.column_index)
@@ -29,3 +29,4 @@ Parking: kw-6icVgDR4
29
29
  Hello, Custom Widget!: aJHLo5yLDZc
30
30
  Hello, Custom Shell!: c8Eb8GWM_XQ
31
31
  Hello, Custom Shape!: H3J8ecp30Ak
32
+ Battleship: b00OWeLZOt8
@@ -41,9 +41,11 @@ class Sample
41
41
 
42
42
  def ensure_user_glimmer_directory
43
43
  unless @ensured_glimmer_directory
44
- FileUtils.rm_rf(user_glimmer_directory)
45
- FileUtils.cp_r(glimmer_directory, user_glimmer_directory)
46
- @ensured_glimmer_directory = true
44
+ Thread.new do
45
+ FileUtils.rm_rf(user_glimmer_directory)
46
+ FileUtils.cp_r(glimmer_directory, user_glimmer_directory)
47
+ @ensured_glimmer_directory = true
48
+ end
47
49
  end
48
50
  end
49
51
 
@@ -123,11 +125,11 @@ class Sample
123
125
  end
124
126
 
125
127
  def file_relative_path
126
- file.sub(self.class.glimmer_directory, '')
128
+ file.sub(Sample.glimmer_directory, '')
127
129
  end
128
130
 
129
131
  def user_file
130
- File.join(self.class.user_glimmer_directory, file_relative_path)
132
+ File.join(Sample.user_glimmer_directory, file_relative_path)
131
133
  end
132
134
 
133
135
  def user_file_parent_directory
@@ -209,10 +211,10 @@ class SampleDirectory
209
211
  @samples.each do |sample|
210
212
  observe(sample, :selected) do |new_selected_value|
211
213
  if new_selected_value
212
- self.class.all_samples.reject {|a_sample| a_sample.name == sample.name}.each do |other_sample|
214
+ SampleDirectory.all_samples.reject {|a_sample| a_sample.name == sample.name}.each do |other_sample|
213
215
  other_sample.selected = false
214
216
  end
215
- self.class.selected_sample = sample
217
+ SampleDirectory.selected_sample = sample
216
218
  end
217
219
  end
218
220
  end
@@ -227,8 +229,8 @@ class SampleDirectory
227
229
  def selected_sample_name=(selected_name)
228
230
  @selected_sample_name = selected_name
229
231
  unless selected_name.nil?
230
- (self.class.sample_directories - [self]).each { |sample_dir| sample_dir.selected_sample_name = nil }
231
- self.class.selected_sample = samples.detect { |sample| sample.name == @selected_sample_name }
232
+ (SampleDirectory.sample_directories - [self]).each { |sample_dir| sample_dir.selected_sample_name = nil }
233
+ SampleDirectory.selected_sample = samples.detect { |sample| sample.name == @selected_sample_name }
232
234
  end
233
235
  end
234
236
 
@@ -66,7 +66,7 @@ class Tetris
66
66
  text 'Level'
67
67
  }
68
68
 
69
- items <=> [game, :high_scores, read_only_sort: true, column_properties: [:name, :score, :lines, :level]]
69
+ items <=> [game, :high_scores, read_only_sort: true]
70
70
  }
71
71
  composite {
72
72
  row_layout :horizontal
@@ -157,19 +157,19 @@ class HelloCustomShell
157
157
  layout_data :fill, :fill, true, true
158
158
 
159
159
  table_column {
160
- text 'Date:'
160
+ text 'Date'
161
161
  width 180
162
162
  }
163
163
  table_column {
164
- text 'Subject:'
164
+ text 'Subject'
165
165
  width 180
166
166
  }
167
167
  table_column {
168
- text 'From:'
168
+ text 'From'
169
169
  width 360
170
170
  }
171
171
 
172
- items <=> [@email_system, :emails, column_properties: [:date, :subject, :from]]
172
+ items <=> [@email_system, :emails]
173
173
  selection <=> [@email_system, :selected_email]
174
174
 
175
175
  on_mouse_up do |event|
@@ -302,15 +302,16 @@ class HelloTable
302
302
  }
303
303
 
304
304
  # Data-bind table items (rows) to a model collection (BaseballGame.schedule),
305
- # mapping columns in declaration order to row model properties (attributes)
306
- # By convention, every column property can be accompanied by extra properties
307
- # with the following suffixes: `_background`, `_foreground`, `_font`, and `_image`
308
- # For example, for `game_date`, model could also implement these related properties:
305
+ # automatically inferring model attributes from column names by convention
306
+ # (e.g. 'Home Team' column assumes a `home_team` attribute on models)
307
+ #
308
+ # By convention, every inferred model attribute can be accompanied by extra
309
+ # model attributes to set extra table properties with the following suffixes:
310
+ # `_background`, `_foreground`, `_font`, and `_image`
311
+ #
312
+ # For example, for :game_date, model could also implement these related properties:
309
313
  # `game_date_background`, `game_date_foreground`, `game_date_font`, `game_date_image`
310
- # That is done in order to let the table widget set extra properties if needed.
311
- items <=> [BaseballGame, :schedule,
312
- column_properties: [:game_date, :game_time, :ballpark, :home_team, :away_team, :promotion]
313
- ]
314
+ items <=> [BaseballGame, :schedule]
314
315
 
315
316
  # Data-bind table selection
316
317
  selection <=> [BaseballGame, :selected_game]
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-dsl-swt
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.24.3.1
4
+ version: 4.24.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-08-28 00:00:00.000000000 Z
11
+ date: 2022-09-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement