pwnstyles_rails 0.1.6 → 0.1.7

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.6
1
+ 0.1.7
@@ -5,18 +5,159 @@
5
5
  # library provides a replacement that adheres to the new philosophy of
6
6
  # unobtrusive JavaScript triggered by HTML5 data- attributes.
7
7
 
8
+
9
+ # The class of the singleton instance that tracks all the effects on the page.
10
+ class PwnFxClass
11
+ # Creates an instance that isn't aware of any effects.
12
+ #
13
+ # After defining an effect class, call registerEffect on this instance to make
14
+ # it aware of the effect.
15
+ constructor: ->
16
+ @effects = []
17
+ @effectsByName = {}
18
+
19
+ # Wires JS to elements with data-pwnfx attributes.
20
+ #
21
+ # @param [Element] root the element whose content is wired; use document at
22
+ # load time
23
+ wire: (root) ->
24
+ for effect in @effects
25
+ attrName = "data-pwnfx-#{effect[0]}"
26
+ effectClass = effect[1]
27
+ scopeAttrName = "#{attrName}-scope"
28
+ doneAttrName = "#{attrName}-done"
29
+ attrSelector = "[#{attrName}]"
30
+ for element in document.querySelectorAll(attrSelector)
31
+ attrValue = element.getAttribute attrName
32
+ continue unless attrValue
33
+ element.removeAttribute attrName
34
+ element.setAttribute doneAttrName, attrValue
35
+ scopeId = element.getAttribute scopeAttrName
36
+ new effectClass element, attrValue, scopeId
37
+ null
38
+
39
+ # Registers a PwnFx effect.
40
+ #
41
+ # @param [String] attrName string following data-pwnfx- in the effect's
42
+ # attribute names
43
+ # @param klass the class that wraps the effect's implementation
44
+ registerEffect: (attrPrefix, klass) ->
45
+ if @effectsByName[attrPrefix]
46
+ throw new Error("Effect name {attrPrefix} already registered")
47
+ @effects.push [attrPrefix, klass]
48
+
49
+ # Finds a scoping container.
50
+ #
51
+ # @param [String] scopeId the scope ID to look for
52
+ # @param [Element] element the element where the lookup starts
53
+ # @return [Element] the closest parent of the given element whose
54
+ # data-pwnfx-scope matches the scopeId argument; window.document is
55
+ # returned if no such element exists or if scope is null
56
+ resolveScope: (scopeId, element) ->
57
+ element = null if scopeId is null
58
+ while element != null && element.getAttribute('data-pwnfx-scope') != scopeId
59
+ element = element.parentElement
60
+ element || document
61
+
62
+ # Performs a scoped querySelectAll.
63
+ #
64
+ # @param [Element] scope the DOM element serving as the search scope
65
+ # @param [String] selector the CSS selector to query
66
+ # @return [NodeList, Array] the elements in the scope that match the CSS
67
+ # selector; the scope container can belong to the returned array
68
+ queryScope: (scope, selector) ->
69
+ scopeMatches = false
70
+ if scope != document
71
+ # TODO: machesSelector is in a W3C spec, but only implemented using
72
+ # prefixes; the code below should be simplified once browsers
73
+ # implement it without vendor prefixes
74
+ if scope.matchesSelector
75
+ scopeMatches = scope.matchesSelector selector
76
+ else if scope.webkitMatchesSelector
77
+ scopeMatches = scope.webkitMatchesSelector selector
78
+ else if scope.mozMatchesSelector
79
+ scopeMatches = scope.mozMatchesSelector
80
+
81
+ if scopeMatches
82
+ matches = Array.prototype.slice.call scope.querySelectorAll(selector)
83
+ matches.push scope
84
+ matches
85
+ else
86
+ scope.querySelectorAll selector
87
+
88
+
89
+ # Singleton instance.
90
+ PwnFx = new PwnFxClass
91
+
92
+
93
+ # Moves an element using data-pwnfx-move.
94
+ #
95
+ # Attributes:
96
+ # data-pwnfx-move: an identifier connecting the move's target element
97
+ # data-pwnfx-move-target: set to the same value as data-pwnfx-move on the
98
+ # element that will receive the moved element as its last child
99
+ class PwnFxMove
100
+ constructor: (element, identifier, scopeId) ->
101
+ scope = PwnFx.resolveScope scopeId, element
102
+ target = document.querySelector "[data-pwnfx-move-target=\"#{identifier}\"]"
103
+ target.appendChild element
104
+
105
+ PwnFx.registerEffect 'move', PwnFxMove
106
+
107
+
108
+ # Renders the contents of a template into a DOM element.
109
+ #
110
+ # Attributes:
111
+ # data-pwnfx-render: identifier for the render operation
112
+ # data-pwnfx-render-where: insertAdjacentHTML position argument; can be
113
+ # beforebegin, afterbegin, beforeend, afterend; defaults to beforeend
114
+ # data-pwnfx-render-randomize: regexp pattern whose matches will be replaced
115
+ # with a random string; useful for generating unique IDs
116
+ # data-pwnfx-render-target: set on the element(s) receiving the rendered HTML;
117
+ # set to the identifier in data-pwnfx-render
118
+ # data-pwnfx-render-source: set on the <script> tag containing the source HTML
119
+ # to be rendered; set to the identifier in data-pwnfx-render
120
+ class PwnFxRender
121
+ constructor: (element, identifier, scopeId) ->
122
+ sourceSelector = "script[data-pwnfx-render-source=\"#{identifier}\"]"
123
+ targetSelector = "[data-pwnfx-render-target=\"#{identifier}\"]"
124
+ insertionPoint = element.getAttribute('data-pwnfx-render-where') ||
125
+ 'beforeend'
126
+ randomizedPatten = element.getAttribute('data-pwnfx-render-randomize')
127
+ if randomizedPatten
128
+ randomizeRegExp = new RegExp(randomizedPatten, 'g')
129
+ else
130
+ randomizeRegExp = null
131
+
132
+ onClick = (event) ->
133
+ scope = PwnFx.resolveScope scopeId, element
134
+ source = scope.querySelector sourceSelector
135
+ html = source.innerHTML
136
+ if randomizeRegExp
137
+ randomId = 'r' + Date.now() + '_' + Math.random()
138
+ html = html.replace randomizeRegExp, randomId
139
+ for targetElement in PwnFx.queryScope(scope, targetSelector)
140
+ targetElement.insertAdjacentHTML insertionPoint, html
141
+ PwnFx.wire targetElement
142
+ event.preventDefault()
143
+ false
144
+ element.addEventListener 'click', onClick, false
145
+
146
+ PwnFx.registerEffect 'render', PwnFxRender
147
+
148
+
8
149
  # Fires off an AJAX request (almost) every time when an element changes.
9
150
  #
10
151
  # The text / HTML returned by the request is placed in another element.
11
152
  #
12
153
  # Element attributes:
13
- # data-pwnfx-refresh-url: URL to perform an AJAX request to
154
+ # data-pwnfx-refresh: URL to perform an AJAX request to
14
155
  # data-pwnfx-refresh-method: the HTTP method of AJAX request (default: POST)
15
156
  # data-pwnfx-refresh-ms: interval between a change on the source element and
16
157
  # AJAX refresh requests (default: 200ms)
17
158
  # data-pwnfx-target: the element populated with the AJAX response
18
159
  class PwnFxRefresh
19
- constructor: (element, xhrUrl) ->
160
+ constructor: (element, xhrUrl, scopeId) ->
20
161
  targetSelector = '#' + element.getAttribute('data-pwnfx-refresh-target')
21
162
  refreshInterval = parseInt(
22
163
  element.getAttribute('data-pwnfx-refresh-ms') || '200');
@@ -25,15 +166,17 @@ class PwnFxRefresh
25
166
 
26
167
  onXhrSuccess = ->
27
168
  data = @responseText
28
- for targetElement in document.querySelectorAll(targetSelector)
169
+ scope = PwnFx.resolveScope scopeId, element
170
+ for targetElement in PwnFx.queryScope(scope, targetSelector)
29
171
  targetElement.innerHTML = data
172
+ # HACK: <script>s are removed and re-inserted so the browser runs them
30
173
  for scriptElement in targetElement.querySelectorAll('script')
31
174
  parent = scriptElement.parentElement
32
175
  nextSibling = scriptElement.nextSibling
33
176
  parent.removeChild scriptElement
34
- parent.insertBefore scriptElement.cloneNode(true), nextSibling
35
-
36
-
177
+ parent.insertBefore scriptElement.cloneNode(true), nextSibling
178
+ PwnFx.wire targetElement
179
+
37
180
  refreshPending = false
38
181
  refreshOldValue = null
39
182
  ajaxRefresh = ->
@@ -53,9 +196,9 @@ class PwnFxRefresh
53
196
  window.setTimeout ajaxRefresh, refreshInterval
54
197
  true
55
198
 
56
- element.addEventListener 'change', onChange
57
- element.addEventListener 'keydown', onChange
58
- element.addEventListener 'keyup', onChange
199
+ element.addEventListener 'change', onChange, false
200
+ element.addEventListener 'keydown', onChange, false
201
+ element.addEventListener 'keyup', onChange, false
59
202
 
60
203
 
61
204
  # The closest form element wrapping a node.
@@ -64,80 +207,87 @@ class PwnFxRefresh
64
207
  return element if element.nodeName == 'FORM'
65
208
  element = element.parentNode
66
209
  null
67
-
210
+
211
+ PwnFx.registerEffect 'refresh', PwnFxRefresh
212
+
213
+
68
214
  # Shows elements conditionally, depending on whether some inputs' values match.
69
215
  #
70
216
  # Element attributes:
71
217
  # data-pwnfx-confirm: all elements with the same value for this attribute
72
218
  # belong to the same confirmation group; their values have to match to
73
219
  # trigger the "win" condition
220
+ # data-pwnfx-confirm-class: the CSS class that is added to hidden elements;
221
+ # (default: hidden)
74
222
  # data-pwnfx-confirm-win: CSS selector identifying the elements to be shown
75
223
  # when the "win" condition is triggered, and hidden otherwise
76
224
  # data-pwnfx-confirm-fail: CSS selector identifying the elements to be hidden
77
225
  # when the "win" condition is triggered, and shown otherwise
78
226
  class PwnFxConfirm
79
- constructor: (element, identifier) ->
227
+ constructor: (element, identifier, scopeId) ->
228
+ hiddenClass = element.getAttribute('data-pwnfx-confirm-class') || 'hidden'
80
229
  sourceSelector = "[data-pwnfx-confirm-done=\"#{identifier}\"]"
81
230
  winSelector = "[data-pwnfx-confirm-win=\"#{identifier}\"]"
82
231
  failSelector = "[data-pwnfx-confirm-fail=\"#{identifier}\"]"
83
232
 
84
233
  onChange = ->
234
+ scope = PwnFx.resolveScope scopeId, element
85
235
  value = null
86
236
  matching = true
87
- for element, index in document.querySelectorAll(sourceSelector)
237
+ for sourceElement, index in PwnFx.queryScope(scope, sourceSelector)
88
238
  if index == 0
89
- value = element.value
90
- else if element.value != value
239
+ value = sourceElement.value
240
+ else if sourceElement.value != value
91
241
  matching = false
92
242
  break
93
243
 
94
244
  hideSelector = if matching then failSelector else winSelector
95
245
  showSelector = if matching then winSelector else failSelector
96
- for targetElement in document.querySelectorAll(showSelector)
97
- targetElement.classList.remove 'hidden'
98
- for targetElement in document.querySelectorAll(hideSelector)
99
- targetElement.classList.add 'hidden'
246
+ for targetElement in PwnFx.queryScope(scope, winSelector)
247
+ targetElement.classList.remove hiddenClass
248
+ for targetElement in PwnFx.queryScope(scope, hideSelector)
249
+ targetElement.classList.add hiddenClass
100
250
  true
101
251
  onChange()
102
252
 
103
- element.addEventListener 'change', onChange
104
- element.addEventListener 'keydown', onChange
105
- element.addEventListener 'keyup', onChange
106
-
107
- # Moves an element using data-pwnfx-move.
108
- class PwnFxMove
109
- constructor: (element, identifier) ->
110
- targetSelector =
111
- target = document.querySelector "[data-pwnfx-move-target=\"#{identifier}\"]"
112
- target.appendChild element
253
+ element.addEventListener 'change', onChange, false
254
+ element.addEventListener 'keydown', onChange, false
255
+ element.addEventListener 'keyup', onChange, false
256
+
257
+ PwnFx.registerEffect 'confirm', PwnFxConfirm
258
+
113
259
 
114
260
  # Shows / hides elements when an element is clicked or checked / unchecked.
115
261
  #
116
262
  # Attributes:
117
- # data-pwnfx-reveal: a name for the events caused by this element's triggering
118
- # data-pwnfx-trigger: 'click' means events are triggered when the element is
119
- # clicked, 'check' means events are triggered when the element is checked;
120
- # (default: click)
121
- # data-pwnfx-positive: set to the same value as data-pwnfx-reveal on elements
122
- # that will be shown when a positive event (click / check) is triggered,
123
- # and hidden when a negative event (uncheck) is triggered
124
- # data-pwnfx-negative: set to the same value as data-pwnfx-reveal on elements
125
- # that will be hidden when a positive event (click / check) is triggered,
126
- # and shown when a negative event (uncheck) is triggered
127
- class PwnFxReveal
128
- constructor: (element, identifier) ->
129
- trigger = element.getAttribute('data-pwnfx-reveal-trigger') || 'click'
130
- positiveSelector = "[data-pwnfx-reveal-positive=\"#{identifier}\"]"
131
- negativeSelector = "[data-pwnfx-reveal-negative=\"#{identifier}\"]"
263
+ # data-pwnfx-hide: a name for the events caused by this element's triggering
264
+ # data-pwnfx-hide-trigger: "click" means events are triggered when the
265
+ # element is clicked, "checked" means events are triggered when the
266
+ # element is checked; (default: click)
267
+ # data-pwnfx-hide-class: the CSS class that is added to hidden elements;
268
+ # (default: hidden)
269
+ # data-pwnfx-hide-positive: set to the same value as data-pwnfx-hide on
270
+ # elements that will be hidden when a positive event (click / check) is
271
+ # triggered, and shown when a negative event (uncheck) is triggered
272
+ # data-pwnfx-hide-negative: set to the same value as data-pwnfx-hide on
273
+ # elements that will be shown when a positive event (click / check) is
274
+ # triggered, and hidden when a negative event (uncheck) is triggered
275
+ class PwnFxHide
276
+ constructor: (element, identifier, scopeId) ->
277
+ trigger = element.getAttribute('data-pwnfx-hide-trigger') || 'click'
278
+ hiddenClass = element.getAttribute('data-pwnfx-hide-class') || 'hidden'
279
+ positiveSelector = "[data-pwnfx-hide-positive=\"#{identifier}\"]"
280
+ negativeSelector = "[data-pwnfx-hide-negative=\"#{identifier}\"]"
132
281
  onChange = (event) ->
133
282
  positive = (trigger == 'click') || element.checked
283
+ hideSelector = if positive then positiveSelector else negativeSelector
284
+ showSelector = if positive then negativeSelector else positiveSelector
134
285
 
135
- showSelector = if positive then positiveSelector else negativeSelector
136
- hideSelector = if positive then negativeSelector else positiveSelector
137
- for targetElement in document.querySelectorAll(showSelector)
138
- targetElement.classList.remove 'hidden'
139
- for targetElement in document.querySelectorAll(hideSelector)
140
- targetElement.classList.add 'hidden'
286
+ scope = PwnFx.resolveScope scopeId, element
287
+ for targetElement in PwnFx.queryScope(scope, hideSelector)
288
+ targetElement.classList.add hiddenClass
289
+ for targetElement in PwnFx.queryScope(scope, showSelector)
290
+ targetElement.classList.remove hiddenClass
141
291
  if trigger == 'click'
142
292
  event.preventDefault()
143
293
  false
@@ -145,34 +295,39 @@ class PwnFxReveal
145
295
  true
146
296
 
147
297
  if trigger == 'click'
148
- element.addEventListener 'click', onChange
149
- else if trigger == 'check'
150
- element.addEventListener 'change', onChange
298
+ element.addEventListener 'click', onChange, false
299
+ else if trigger == 'checked'
300
+ element.addEventListener 'change', onChange, false
151
301
  onChange()
302
+ else
303
+ throw new Error("Unimplemented trigger #{trigger}")
304
+
305
+ PwnFx.registerEffect 'hide', PwnFxHide
306
+
307
+
308
+ # Removes elements from the DOM when an element is clicked.
309
+ #
310
+ # Attributes:
311
+ # data-pwnfx-remove: an identifier connecting the elements to be removed
312
+ # data-pwnfx-remove-target: set to the same value as data-pwnfx-remove on
313
+ # elements that will be removed when the element is clicked
314
+ class PwnFxRemove
315
+ constructor: (element, identifier, scopeId) ->
316
+ targetSelector = "[data-pwnfx-remove-target=\"#{identifier}\"]"
317
+
318
+ onClick = (event) ->
319
+ scope = PwnFx.resolveScope scopeId, element
320
+ for targetElement in PwnFx.queryScope(scope, targetSelector)
321
+ targetElement.parentNode.removeChild targetElement
322
+ event.preventDefault()
323
+ false
324
+ element.addEventListener 'click', onClick, false
325
+
326
+ PwnFx.registerEffect 'remove', PwnFxRemove
327
+
152
328
 
329
+ # Export the PwnFx instance.
330
+ window.PwnFx = PwnFx
153
331
 
154
- # List of effects.
155
- pwnEffects = [
156
- ['data-pwnfx-move', PwnFxMove],
157
- ['data-pwnfx-refresh-url', PwnFxRefresh],
158
- ['data-pwnfx-confirm', PwnFxConfirm],
159
- ['data-pwnfx-reveal', PwnFxReveal]
160
- ]
161
-
162
- # Wires JS to elements with data-pwnfx attributes.
163
- window.PwnFx = ->
164
- for effect in pwnEffects
165
- attrName = effect[0]
166
- effectClass = effect[1]
167
- doneAttrName = "#{attrName}-done"
168
- attrSelector = "[#{attrName}]"
169
- for element in document.querySelectorAll(attrSelector)
170
- attrValue = element.getAttribute attrName
171
- continue unless attrValue
172
- element.removeAttribute attrName
173
- element.setAttribute doneAttrName, attrValue
174
- new effectClass element, attrValue
175
- null
176
-
177
- # Honor data-pwnfx attributes after the DOM is loaded.
178
- window.addEventListener 'load', -> window.PwnFx()
332
+ # Wire up the entire DOM after the document is loaded.
333
+ window.addEventListener 'load', -> PwnFx.wire(document)
@@ -1,16 +1,16 @@
1
1
  <% if flash[:error] %>
2
- <p class="status-bar error" data-pwnfx-reveal-negative="status-bar">
2
+ <p class="status-bar error" data-pwnfx-hide-positive="status-bar">
3
3
  <%= flash[:error] %>
4
4
 
5
5
  <span class="actions">
6
- <%= link_to 'Hide', '#', 'data-pwnfx-reveal' => 'status-bar' %>
6
+ <%= link_to 'Hide', '#', 'data-pwnfx-hide' => 'status-bar' %>
7
7
  </span>
8
8
  </p>
9
9
  <% elsif flash[:errors] && flash[:errors].any? %>
10
- <div class="status-bar error" data-pwnfx-reveal-negative="status-bar">
10
+ <div class="status-bar error" data-pwnfx-hide-positive="status-bar">
11
11
  <%= pluralize(flash[:errors].count, "error") %> occurred:
12
12
  <span class="actions">
13
- <%= link_to 'Hide', '#', 'data-pwnfx-reveal' => 'status-bar' %>
13
+ <%= link_to 'Hide', '#', 'data-pwnfx-hide' => 'status-bar' %>
14
14
  </span>
15
15
 
16
16
  <ul>
@@ -20,11 +20,11 @@
20
20
  </ul>
21
21
  </div>
22
22
  <% elsif flash[:notice] %>
23
- <p class="status-bar notice" data-pwnfx-reveal-negative="status-bar">
23
+ <p class="status-bar notice" data-pwnfx-hide-positive="status-bar">
24
24
  <%= flash[:notice] %>
25
25
 
26
26
  <span class="actions">
27
- <%= link_to 'Hide', '#', 'data-pwnfx-reveal' => 'status-bar' %>
27
+ <%= link_to 'Hide', '#', 'data-pwnfx-hide' => 'status-bar' %>
28
28
  </span>
29
29
  </p>
30
30
  <% end %>
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "pwnstyles_rails"
8
- s.version = "0.1.6"
8
+ s.version = "0.1.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Victor Costan"]
12
- s.date = "2012-02-04"
12
+ s.date = "2012-02-06"
13
13
  s.description = "Included CSS was designed for reuse across pwnb.us apps."
14
14
  s.email = "victor@costan.us"
15
15
  s.extra_rdoc_files = [
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pwnstyles_rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.1.7
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-04 00:00:00.000000000 Z
12
+ date: 2012-02-06 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
16
- requirement: &7895040 !ruby/object:Gem::Requirement
16
+ requirement: &16773780 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.2.0
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *7895040
24
+ version_requirements: *16773780
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: sass-rails
27
- requirement: &7893040 !ruby/object:Gem::Requirement
27
+ requirement: &16771860 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: 3.2.4
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *7893040
35
+ version_requirements: *16771860
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: shoulda
38
- requirement: &7891480 !ruby/object:Gem::Requirement
38
+ requirement: &16791900 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *7891480
46
+ version_requirements: *16791900
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: bundler
49
- requirement: &7890520 !ruby/object:Gem::Requirement
49
+ requirement: &16797760 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.0.0
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *7890520
57
+ version_requirements: *16797760
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: jeweler
60
- requirement: &7889360 !ruby/object:Gem::Requirement
60
+ requirement: &16823860 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,10 +65,10 @@ dependencies:
65
65
  version: 1.8.0
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *7889360
68
+ version_requirements: *16823860
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rcov
71
- requirement: &7888140 !ruby/object:Gem::Requirement
71
+ requirement: &16823100 !ruby/object:Gem::Requirement
72
72
  none: false
73
73
  requirements:
74
74
  - - ! '>='
@@ -76,10 +76,10 @@ dependencies:
76
76
  version: '0'
77
77
  type: :development
78
78
  prerelease: false
79
- version_requirements: *7888140
79
+ version_requirements: *16823100
80
80
  - !ruby/object:Gem::Dependency
81
81
  name: simplecov
82
- requirement: &7887200 !ruby/object:Gem::Requirement
82
+ requirement: &16833240 !ruby/object:Gem::Requirement
83
83
  none: false
84
84
  requirements:
85
85
  - - ! '>='
@@ -87,7 +87,7 @@ dependencies:
87
87
  version: '0'
88
88
  type: :development
89
89
  prerelease: false
90
- version_requirements: *7887200
90
+ version_requirements: *16833240
91
91
  description: Included CSS was designed for reuse across pwnb.us apps.
92
92
  email: victor@costan.us
93
93
  executables: []
@@ -152,7 +152,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
152
  version: '0'
153
153
  segments:
154
154
  - 0
155
- hash: -808311045673830044
155
+ hash: 714706419940380793
156
156
  required_rubygems_version: !ruby/object:Gem::Requirement
157
157
  none: false
158
158
  requirements: