rbbt-util 5.44.1 → 6.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (167) hide show
  1. checksums.yaml +4 -4
  2. data/bin/rbbt +67 -90
  3. data/etc/app.d/base.rb +2 -2
  4. data/etc/app.d/semaphores.rb +3 -3
  5. data/lib/rbbt/annotations/annotated_array.rb +207 -207
  6. data/lib/rbbt/annotations/refactor.rb +27 -0
  7. data/lib/rbbt/annotations/util.rb +282 -282
  8. data/lib/rbbt/annotations.rb +343 -320
  9. data/lib/rbbt/association/database.rb +200 -225
  10. data/lib/rbbt/association/index.rb +294 -291
  11. data/lib/rbbt/association/item.rb +227 -227
  12. data/lib/rbbt/association/open.rb +35 -34
  13. data/lib/rbbt/association/util.rb +0 -169
  14. data/lib/rbbt/association.rb +2 -4
  15. data/lib/rbbt/entity/identifiers.rb +119 -118
  16. data/lib/rbbt/entity/refactor.rb +12 -0
  17. data/lib/rbbt/entity.rb +319 -315
  18. data/lib/rbbt/hpc/batch.rb +72 -53
  19. data/lib/rbbt/hpc/lsf.rb +2 -2
  20. data/lib/rbbt/hpc/orchestrate/batches.rb +2 -2
  21. data/lib/rbbt/hpc/orchestrate/chains.rb +25 -5
  22. data/lib/rbbt/hpc/orchestrate/rules.rb +2 -2
  23. data/lib/rbbt/hpc/orchestrate.rb +19 -13
  24. data/lib/rbbt/hpc/slurm.rb +18 -18
  25. data/lib/rbbt/knowledge_base/entity.rb +13 -5
  26. data/lib/rbbt/knowledge_base/query.rb +2 -2
  27. data/lib/rbbt/knowledge_base/registry.rb +32 -31
  28. data/lib/rbbt/knowledge_base/traverse.rb +1 -1
  29. data/lib/rbbt/knowledge_base.rb +1 -1
  30. data/lib/rbbt/monitor.rb +36 -25
  31. data/lib/rbbt/persist/refactor.rb +166 -0
  32. data/lib/rbbt/persist/tsv/tokyocabinet.rb +105 -105
  33. data/lib/rbbt/persist/tsv.rb +187 -185
  34. data/lib/rbbt/persist.rb +556 -551
  35. data/lib/rbbt/refactor.rb +20 -0
  36. data/lib/rbbt/resource/path/refactor.rb +178 -0
  37. data/lib/rbbt/resource/path.rb +317 -497
  38. data/lib/rbbt/resource/util.rb +0 -48
  39. data/lib/rbbt/resource.rb +3 -390
  40. data/lib/rbbt/tsv/accessor.rb +2 -838
  41. data/lib/rbbt/tsv/attach.rb +303 -299
  42. data/lib/rbbt/tsv/change_id.rb +244 -245
  43. data/lib/rbbt/tsv/csv.rb +87 -85
  44. data/lib/rbbt/tsv/dumper.rb +2 -100
  45. data/lib/rbbt/tsv/excel.rb +26 -24
  46. data/lib/rbbt/tsv/field_index.rb +4 -1
  47. data/lib/rbbt/tsv/filter.rb +3 -2
  48. data/lib/rbbt/tsv/index.rb +2 -284
  49. data/lib/rbbt/tsv/manipulate.rb +750 -747
  50. data/lib/rbbt/tsv/marshal.rb +3 -3
  51. data/lib/rbbt/tsv/matrix.rb +2 -2
  52. data/lib/rbbt/tsv/parallel/through.rb +2 -1
  53. data/lib/rbbt/tsv/parallel/traverse.rb +783 -781
  54. data/lib/rbbt/tsv/parser.rb +678 -678
  55. data/lib/rbbt/tsv/refactor.rb +195 -0
  56. data/lib/rbbt/tsv/stream.rb +253 -251
  57. data/lib/rbbt/tsv/util.rb +420 -420
  58. data/lib/rbbt/tsv.rb +210 -208
  59. data/lib/rbbt/util/R/eval.rb +4 -4
  60. data/lib/rbbt/util/R/plot.rb +62 -166
  61. data/lib/rbbt/util/R.rb +21 -18
  62. data/lib/rbbt/util/cmd.rb +2 -318
  63. data/lib/rbbt/util/color.rb +269 -269
  64. data/lib/rbbt/util/colorize.rb +89 -89
  65. data/lib/rbbt/util/concurrency/processes/refactor.rb +22 -0
  66. data/lib/rbbt/util/concurrency/processes/worker.rb +2 -2
  67. data/lib/rbbt/util/concurrency/processes.rb +389 -386
  68. data/lib/rbbt/util/config.rb +169 -167
  69. data/lib/rbbt/util/iruby.rb +20 -0
  70. data/lib/rbbt/util/log/progress/report.rb +241 -241
  71. data/lib/rbbt/util/log/progress/util.rb +99 -99
  72. data/lib/rbbt/util/log/progress.rb +102 -102
  73. data/lib/rbbt/util/log/refactor.rb +49 -0
  74. data/lib/rbbt/util/log.rb +486 -532
  75. data/lib/rbbt/util/migrate.rb +1 -1
  76. data/lib/rbbt/util/misc/concurrent_stream.rb +248 -246
  77. data/lib/rbbt/util/misc/development.rb +12 -11
  78. data/lib/rbbt/util/misc/exceptions.rb +117 -112
  79. data/lib/rbbt/util/misc/format.rb +2 -230
  80. data/lib/rbbt/util/misc/indiferent_hash.rb +2 -107
  81. data/lib/rbbt/util/misc/inspect.rb +2 -476
  82. data/lib/rbbt/util/misc/lock.rb +109 -106
  83. data/lib/rbbt/util/misc/omics.rb +9 -1
  84. data/lib/rbbt/util/misc/pipes.rb +765 -793
  85. data/lib/rbbt/util/misc/refactor.rb +20 -0
  86. data/lib/rbbt/util/misc/ssw.rb +27 -17
  87. data/lib/rbbt/util/misc/system.rb +0 -15
  88. data/lib/rbbt/util/misc.rb +39 -20
  89. data/lib/rbbt/util/named_array/refactor.rb +4 -0
  90. data/lib/rbbt/util/named_array.rb +3 -220
  91. data/lib/rbbt/util/open/refactor.rb +7 -0
  92. data/lib/rbbt/util/open.rb +3 -857
  93. data/lib/rbbt/util/procpath.rb +6 -6
  94. data/lib/rbbt/util/python/paths.rb +27 -0
  95. data/lib/rbbt/util/python/run.rb +115 -0
  96. data/lib/rbbt/util/python/script.rb +110 -0
  97. data/lib/rbbt/util/python/util.rb +3 -3
  98. data/lib/rbbt/util/python.rb +22 -81
  99. data/lib/rbbt/util/semaphore.rb +152 -148
  100. data/lib/rbbt/util/simpleopt.rb +9 -8
  101. data/lib/rbbt/util/ssh/refactor.rb +19 -0
  102. data/lib/rbbt/util/ssh.rb +122 -118
  103. data/lib/rbbt/util/tar.rb +117 -115
  104. data/lib/rbbt/util/tmpfile.rb +69 -67
  105. data/lib/rbbt/util/version.rb +2 -0
  106. data/lib/rbbt/workflow/refactor/entity.rb +11 -0
  107. data/lib/rbbt/workflow/refactor/export.rb +66 -0
  108. data/lib/rbbt/workflow/refactor/inputs.rb +24 -0
  109. data/lib/rbbt/workflow/refactor/recursive.rb +64 -0
  110. data/lib/rbbt/workflow/refactor/task_info.rb +65 -0
  111. data/lib/rbbt/workflow/refactor.rb +153 -0
  112. data/lib/rbbt/workflow/remote_workflow/driver/ssh.rb +55 -32
  113. data/lib/rbbt/workflow/remote_workflow/remote_step/rest.rb +3 -1
  114. data/lib/rbbt/workflow/remote_workflow/remote_step/ssh.rb +14 -5
  115. data/lib/rbbt/workflow/remote_workflow/remote_step.rb +19 -7
  116. data/lib/rbbt/workflow/remote_workflow.rb +6 -1
  117. data/lib/rbbt/workflow/step/run.rb +766 -766
  118. data/lib/rbbt/workflow/step/save_load_inputs.rb +254 -254
  119. data/lib/rbbt/workflow/step.rb +2 -362
  120. data/lib/rbbt/workflow/task.rb +118 -118
  121. data/lib/rbbt/workflow/usage.rb +289 -287
  122. data/lib/rbbt/workflow/util/archive.rb +6 -5
  123. data/lib/rbbt/workflow/util/data.rb +1 -1
  124. data/lib/rbbt/workflow/util/orchestrator.rb +249 -246
  125. data/lib/rbbt/workflow/util/trace.rb +79 -44
  126. data/lib/rbbt/workflow.rb +4 -882
  127. data/lib/rbbt-util.rb +21 -13
  128. data/lib/rbbt.rb +16 -3
  129. data/python/rbbt/__init__.py +19 -1
  130. data/share/Rlib/plot.R +37 -37
  131. data/share/Rlib/svg.R +22 -5
  132. data/share/install/software/lib/install_helpers +1 -1
  133. data/share/rbbt_commands/hpc/list +2 -3
  134. data/share/rbbt_commands/hpc/orchestrate +4 -4
  135. data/share/rbbt_commands/hpc/tail +2 -0
  136. data/share/rbbt_commands/hpc/task +10 -7
  137. data/share/rbbt_commands/lsf/list +2 -3
  138. data/share/rbbt_commands/lsf/orchestrate +4 -4
  139. data/share/rbbt_commands/lsf/tail +2 -0
  140. data/share/rbbt_commands/lsf/task +10 -7
  141. data/share/rbbt_commands/migrate +1 -1
  142. data/share/rbbt_commands/pbs/list +2 -3
  143. data/share/rbbt_commands/pbs/orchestrate +4 -4
  144. data/share/rbbt_commands/pbs/tail +2 -0
  145. data/share/rbbt_commands/pbs/task +10 -7
  146. data/share/rbbt_commands/resource/produce +8 -1
  147. data/share/rbbt_commands/slurm/list +2 -3
  148. data/share/rbbt_commands/slurm/orchestrate +4 -4
  149. data/share/rbbt_commands/slurm/tail +2 -0
  150. data/share/rbbt_commands/slurm/task +10 -7
  151. data/share/rbbt_commands/system/clean +5 -5
  152. data/share/rbbt_commands/system/status +5 -5
  153. data/share/rbbt_commands/tsv/get +2 -3
  154. data/share/rbbt_commands/tsv/info +10 -13
  155. data/share/rbbt_commands/tsv/keys +18 -14
  156. data/share/rbbt_commands/tsv/slice +2 -2
  157. data/share/rbbt_commands/tsv/transpose +6 -2
  158. data/share/rbbt_commands/workflow/info +20 -24
  159. data/share/rbbt_commands/workflow/list +1 -1
  160. data/share/rbbt_commands/workflow/prov +20 -13
  161. data/share/rbbt_commands/workflow/server +11 -1
  162. data/share/rbbt_commands/workflow/task +76 -71
  163. data/share/rbbt_commands/workflow/write_info +26 -9
  164. data/share/software/opt/ssw/ssw.c +861 -0
  165. data/share/software/opt/ssw/ssw.h +130 -0
  166. data/share/workflow_config.ru +3 -3
  167. metadata +40 -2
@@ -1,269 +1,269 @@
1
- # Copyright (c) 2007 McClain Looney
2
- #
3
- # Permission is hereby granted, free of charge, to any person obtaining a copy
4
- # of this software and associated documentation files (the "Software"), to deal
5
- # in the Software without restriction, including without limitation the rights
6
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- # copies of the Software, and to permit persons to whom the Software is
8
- # furnished to do so, subject to the following conditions:
9
- #
10
- # The above copyright notice and this permission notice shall be included in
11
- # all copies or substantial portions of the Software.
12
- #
13
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
- # THE SOFTWARE.
20
-
21
-
22
- # Implements a color (r,g,b + a) with conversion to/from web format (eg #aabbcc), and
23
- # with a number of utilities to lighten, darken and blend values.
24
- class Color
25
-
26
- attr_reader :r, :g, :b, :a
27
-
28
- # Table for conversion to hex
29
- HEXVAL = (('0'..'9').to_a).concat(('A'..'F').to_a).freeze
30
- # Default value for #darken, #lighten etc.
31
- BRIGHTNESS_DEFAULT = 0.2
32
-
33
- SOLARIZED = {
34
- :base03 => '#002b36',
35
- :base02 => '#073642',
36
- :base01 => '#586e75',
37
- :base00 => '#657b83',
38
- :base0 => '#839496',
39
- :base1 => '#93a1a1',
40
- :base2 => '#eee8d5',
41
- :base3 => '#fdf6e3',
42
- :yellow => '#b58900',
43
- :orange => '#cb4b16',
44
- :red => '#dc322f',
45
- :magenta => '#d33682',
46
- :violet => '#6c71c4',
47
- :blue => '#268bd2',
48
- :cyan => '#2aa198',
49
- :green => '#859900',
50
- }
51
-
52
- # Constructor. Inits to white (#FFFFFF) by default, or accepts any params
53
- # supported by #parse.
54
- def initialize(*args)
55
- @r = 255
56
- @g = 255
57
- @b = 255
58
- @a = 255
59
-
60
- if args.size.between?(3,4)
61
- self.r = args[0]
62
- self.g = args[1]
63
- self.b = args[2]
64
- self.a = args[3] if args[3]
65
- else
66
- set(*args)
67
- end
68
- end
69
-
70
- # All-purpose setter - pass in another Color, '#000000', rgb vals... whatever
71
- def set(*args)
72
- val = Color.parse(*args)
73
- unless val.nil?
74
- self.r = val.r
75
- self.g = val.g
76
- self.b = val.b
77
- self.a = val.a
78
- end
79
- self
80
- end
81
-
82
- # Test for equality, accepts string vals as well, eg Color.new('aaa') == '#AAAAAA' => true
83
- def ==(val)
84
- val = Color.parse(val)
85
- return false if val.nil?
86
- return r == val.r && g == val.g && b == val.b && a == val.a
87
- end
88
-
89
- # Setters for individual channels - take 0-255 or '00'-'FF' values
90
- def r=(val); @r = from_hex(val); end
91
- def g=(val); @g = from_hex(val); end
92
- def b=(val); @b = from_hex(val); end
93
- def a=(val); @a = from_hex(val); end
94
-
95
- # Attempt to read in a string and parse it into values
96
- def self.parse(*args)
97
- case args.size
98
-
99
- when 0 then
100
- return nil
101
-
102
- when 1 then
103
- val = args[0]
104
-
105
- # Trivial parse... :-)
106
- return val if val.is_a?(Color)
107
-
108
- # Single value, assume grayscale
109
- return Color.new(val, val, val) if val.is_a?(Numeric)
110
-
111
- # Assume string
112
- str = val.to_s.upcase
113
- str = str[/[0-9A-F]{3,8}/] || ''
114
- case str.size
115
- when 3, 4 then
116
- r, g, b, a = str.scan(/[0-9A-F]/)
117
- when 6,8 then
118
- r, g, b, a = str.scan(/[0-9A-F]{2}/)
119
- else
120
- return nil
121
- end
122
-
123
- return Color.new(r,g,b,a || 255)
124
-
125
- when 3,4 then
126
- return Color.new(*args)
127
-
128
- end
129
- nil
130
- end
131
-
132
- def inspect
133
- to_s(true)
134
- end
135
-
136
- def to_s(add_hash = true)
137
- trans? ? to_rgba(add_hash) : to_rgb(add_hash)
138
- end
139
-
140
- def to_rgb(add_hash = true)
141
- (add_hash ? '#' : '') + to_hex(r) + to_hex(g) + to_hex(b)
142
- end
143
-
144
- def to_rgba(add_hash = true)
145
- to_rgb(add_hash) + to_hex(a)
146
- end
147
-
148
- def opaque?
149
- @a == 255
150
- end
151
-
152
- def trans?
153
- @a != 255
154
- end
155
-
156
- def grayscale?
157
- @r == @g && @g == @b
158
- end
159
-
160
- # Lighten color towards white. 0.0 is a no-op, 1.0 will return #FFFFFF
161
- def lighten(amt = BRIGHTNESS_DEFAULT)
162
- return self if amt <= 0
163
- return WHITE if amt >= 1.0
164
- val = Color.new(self)
165
- val.r += ((255-val.r) * amt).to_i
166
- val.g += ((255-val.g) * amt).to_i
167
- val.b += ((255-val.b) * amt).to_i
168
- val
169
- end
170
-
171
- # In place version of #lighten
172
- def lighten!(amt = BRIGHTNESS_DEFAULT)
173
- set(lighten(amt))
174
- self
175
- end
176
-
177
- # Darken a color towards full black. 0.0 is a no-op, 1.0 will return #000000
178
- def darken(amt = BRIGHTNESS_DEFAULT)
179
- return self if amt <= 0
180
- return BLACK if amt >= 1.0
181
- val = Color.new(self)
182
- val.r -= (val.r * amt).to_i
183
- val.g -= (val.g * amt).to_i
184
- val.b -= (val.b * amt).to_i
185
- val
186
- end
187
-
188
- # In place version of #darken
189
- def darken!(amt = BRIGHTNESS_DEFAULT)
190
- set(darken(amt))
191
- self
192
- end
193
-
194
- # Convert to grayscale, using perception-based weighting
195
- def grayscale
196
- val = Color.new(self)
197
- val.r = val.g = val.b = (0.2126 * val.r + 0.7152 * val.g + 0.0722 * val.b)
198
- val
199
- end
200
-
201
- # In place version of #grayscale
202
- def grayscale!
203
- set(grayscale)
204
- self
205
- end
206
-
207
- # Blend to a color amt % towards another color value, eg
208
- # red.blend(blue, 0.5) will be purple, white.blend(black, 0.5) will be gray, etc.
209
- def blend(other, amt)
210
- other = Color.parse(other)
211
- return Color.new(self) if amt <= 0 || other.nil?
212
- return Color.new(other) if amt >= 1.0
213
- val = Color.new(self)
214
- val.r += ((other.r - val.r)*amt).to_i
215
- val.g += ((other.g - val.g)*amt).to_i
216
- val.b += ((other.b - val.b)*amt).to_i
217
- val
218
- end
219
-
220
- # In place version of #blend
221
- def blend!(other, amt)
222
- set(blend(other, amt))
223
- self
224
- end
225
-
226
- # Class-level version for explicit blends of two values, useful with constants
227
- def self.blend(col1, col2, amt)
228
- col1 = Color.parse(col1)
229
- col2 = Color.parse(col2)
230
- col1.blend(col2, amt)
231
- end
232
-
233
- protected
234
-
235
- # Convert int to string hex, eg 255 => 'FF'
236
- def to_hex(val)
237
- HEXVAL[val / 16] + HEXVAL[val % 16]
238
- end
239
-
240
- # Convert int or string to int, eg 80 => 80, 'FF' => 255, '7' => 119
241
- def from_hex(val)
242
- if val.is_a?(String)
243
- # Double up if single char form
244
- val = val + val if val.size == 1
245
- # Convert to integer
246
- val = val.hex
247
- end
248
- # Clamp
249
- val = 0 if val < 0
250
- val = 255 if val > 255
251
- val
252
- end
253
-
254
- public
255
-
256
- # Some constants for general use
257
- WHITE = Color.new(255,255,255).freeze
258
- BLACK = Color.new(0,0,0).freeze
259
-
260
- end
261
-
262
- # "Global" method for creating Color objects, eg:
263
- # new_color = rgb(params[:new_color])
264
- # style="border: 1px solid <%= rgb(10,50,80).lighten %>"
265
- def rgb(*args)
266
- Color.parse(*args)
267
- end
268
-
269
-
1
+ ## Copyright (c) 2007 McClain Looney
2
+ ##
3
+ ## Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ ## of this software and associated documentation files (the "Software"), to deal
5
+ ## in the Software without restriction, including without limitation the rights
6
+ ## to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ ## copies of the Software, and to permit persons to whom the Software is
8
+ ## furnished to do so, subject to the following conditions:
9
+ ##
10
+ ## The above copyright notice and this permission notice shall be included in
11
+ ## all copies or substantial portions of the Software.
12
+ ##
13
+ ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ ## OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ ## THE SOFTWARE.
20
+ #
21
+ #
22
+ ## Implements a color (r,g,b + a) with conversion to/from web format (eg #aabbcc), and
23
+ ## with a number of utilities to lighten, darken and blend values.
24
+ #class Color
25
+ #
26
+ # attr_reader :r, :g, :b, :a
27
+ #
28
+ # # Table for conversion to hex
29
+ # HEXVAL = (('0'..'9').to_a).concat(('A'..'F').to_a).freeze
30
+ # # Default value for #darken, #lighten etc.
31
+ # BRIGHTNESS_DEFAULT = 0.2
32
+ #
33
+ # SOLARIZED = {
34
+ # :base03 => '#002b36',
35
+ # :base02 => '#073642',
36
+ # :base01 => '#586e75',
37
+ # :base00 => '#657b83',
38
+ # :base0 => '#839496',
39
+ # :base1 => '#93a1a1',
40
+ # :base2 => '#eee8d5',
41
+ # :base3 => '#fdf6e3',
42
+ # :yellow => '#b58900',
43
+ # :orange => '#cb4b16',
44
+ # :red => '#dc322f',
45
+ # :magenta => '#d33682',
46
+ # :violet => '#6c71c4',
47
+ # :blue => '#268bd2',
48
+ # :cyan => '#2aa198',
49
+ # :green => '#859900',
50
+ # }
51
+ #
52
+ # # Constructor. Inits to white (#FFFFFF) by default, or accepts any params
53
+ # # supported by #parse.
54
+ # def initialize(*args)
55
+ # @r = 255
56
+ # @g = 255
57
+ # @b = 255
58
+ # @a = 255
59
+ #
60
+ # if args.size.between?(3,4)
61
+ # self.r = args[0]
62
+ # self.g = args[1]
63
+ # self.b = args[2]
64
+ # self.a = args[3] if args[3]
65
+ # else
66
+ # set(*args)
67
+ # end
68
+ # end
69
+ #
70
+ # # All-purpose setter - pass in another Color, '#000000', rgb vals... whatever
71
+ # def set(*args)
72
+ # val = Color.parse(*args)
73
+ # unless val.nil?
74
+ # self.r = val.r
75
+ # self.g = val.g
76
+ # self.b = val.b
77
+ # self.a = val.a
78
+ # end
79
+ # self
80
+ # end
81
+ #
82
+ # # Test for equality, accepts string vals as well, eg Color.new('aaa') == '#AAAAAA' => true
83
+ # def ==(val)
84
+ # val = Color.parse(val)
85
+ # return false if val.nil?
86
+ # return r == val.r && g == val.g && b == val.b && a == val.a
87
+ # end
88
+ #
89
+ # # Setters for individual channels - take 0-255 or '00'-'FF' values
90
+ # def r=(val); @r = from_hex(val); end
91
+ # def g=(val); @g = from_hex(val); end
92
+ # def b=(val); @b = from_hex(val); end
93
+ # def a=(val); @a = from_hex(val); end
94
+ #
95
+ # # Attempt to read in a string and parse it into values
96
+ # def self.parse(*args)
97
+ # case args.size
98
+ #
99
+ # when 0 then
100
+ # return nil
101
+ #
102
+ # when 1 then
103
+ # val = args[0]
104
+ #
105
+ # # Trivial parse... :-)
106
+ # return val if val.is_a?(Color)
107
+ #
108
+ # # Single value, assume grayscale
109
+ # return Color.new(val, val, val) if val.is_a?(Numeric)
110
+ #
111
+ # # Assume string
112
+ # str = val.to_s.upcase
113
+ # str = str[/[0-9A-F]{3,8}/] || ''
114
+ # case str.size
115
+ # when 3, 4 then
116
+ # r, g, b, a = str.scan(/[0-9A-F]/)
117
+ # when 6,8 then
118
+ # r, g, b, a = str.scan(/[0-9A-F]{2}/)
119
+ # else
120
+ # return nil
121
+ # end
122
+ #
123
+ # return Color.new(r,g,b,a || 255)
124
+ #
125
+ # when 3,4 then
126
+ # return Color.new(*args)
127
+ #
128
+ # end
129
+ # nil
130
+ # end
131
+ #
132
+ # def inspect
133
+ # to_s(true)
134
+ # end
135
+ #
136
+ # def to_s(add_hash = true)
137
+ # trans? ? to_rgba(add_hash) : to_rgb(add_hash)
138
+ # end
139
+ #
140
+ # def to_rgb(add_hash = true)
141
+ # (add_hash ? '#' : '') + to_hex(r) + to_hex(g) + to_hex(b)
142
+ # end
143
+ #
144
+ # def to_rgba(add_hash = true)
145
+ # to_rgb(add_hash) + to_hex(a)
146
+ # end
147
+ #
148
+ # def opaque?
149
+ # @a == 255
150
+ # end
151
+ #
152
+ # def trans?
153
+ # @a != 255
154
+ # end
155
+ #
156
+ # def grayscale?
157
+ # @r == @g && @g == @b
158
+ # end
159
+ #
160
+ # # Lighten color towards white. 0.0 is a no-op, 1.0 will return #FFFFFF
161
+ # def lighten(amt = BRIGHTNESS_DEFAULT)
162
+ # return self if amt <= 0
163
+ # return WHITE if amt >= 1.0
164
+ # val = Color.new(self)
165
+ # val.r += ((255-val.r) * amt).to_i
166
+ # val.g += ((255-val.g) * amt).to_i
167
+ # val.b += ((255-val.b) * amt).to_i
168
+ # val
169
+ # end
170
+ #
171
+ # # In place version of #lighten
172
+ # def lighten!(amt = BRIGHTNESS_DEFAULT)
173
+ # set(lighten(amt))
174
+ # self
175
+ # end
176
+ #
177
+ # # Darken a color towards full black. 0.0 is a no-op, 1.0 will return #000000
178
+ # def darken(amt = BRIGHTNESS_DEFAULT)
179
+ # return self if amt <= 0
180
+ # return BLACK if amt >= 1.0
181
+ # val = Color.new(self)
182
+ # val.r -= (val.r * amt).to_i
183
+ # val.g -= (val.g * amt).to_i
184
+ # val.b -= (val.b * amt).to_i
185
+ # val
186
+ # end
187
+ #
188
+ # # In place version of #darken
189
+ # def darken!(amt = BRIGHTNESS_DEFAULT)
190
+ # set(darken(amt))
191
+ # self
192
+ # end
193
+ #
194
+ # # Convert to grayscale, using perception-based weighting
195
+ # def grayscale
196
+ # val = Color.new(self)
197
+ # val.r = val.g = val.b = (0.2126 * val.r + 0.7152 * val.g + 0.0722 * val.b)
198
+ # val
199
+ # end
200
+ #
201
+ # # In place version of #grayscale
202
+ # def grayscale!
203
+ # set(grayscale)
204
+ # self
205
+ # end
206
+ #
207
+ # # Blend to a color amt % towards another color value, eg
208
+ # # red.blend(blue, 0.5) will be purple, white.blend(black, 0.5) will be gray, etc.
209
+ # def blend(other, amt)
210
+ # other = Color.parse(other)
211
+ # return Color.new(self) if amt <= 0 || other.nil?
212
+ # return Color.new(other) if amt >= 1.0
213
+ # val = Color.new(self)
214
+ # val.r += ((other.r - val.r)*amt).to_i
215
+ # val.g += ((other.g - val.g)*amt).to_i
216
+ # val.b += ((other.b - val.b)*amt).to_i
217
+ # val
218
+ # end
219
+ #
220
+ # # In place version of #blend
221
+ # def blend!(other, amt)
222
+ # set(blend(other, amt))
223
+ # self
224
+ # end
225
+ #
226
+ # # Class-level version for explicit blends of two values, useful with constants
227
+ # def self.blend(col1, col2, amt)
228
+ # col1 = Color.parse(col1)
229
+ # col2 = Color.parse(col2)
230
+ # col1.blend(col2, amt)
231
+ # end
232
+ #
233
+ # protected
234
+ #
235
+ # # Convert int to string hex, eg 255 => 'FF'
236
+ # def to_hex(val)
237
+ # HEXVAL[val / 16] + HEXVAL[val % 16]
238
+ # end
239
+ #
240
+ # # Convert int or string to int, eg 80 => 80, 'FF' => 255, '7' => 119
241
+ # def from_hex(val)
242
+ # if val.is_a?(String)
243
+ # # Double up if single char form
244
+ # val = val + val if val.size == 1
245
+ # # Convert to integer
246
+ # val = val.hex
247
+ # end
248
+ # # Clamp
249
+ # val = 0 if val < 0
250
+ # val = 255 if val > 255
251
+ # val
252
+ # end
253
+ #
254
+ # public
255
+ #
256
+ # # Some constants for general use
257
+ # WHITE = Color.new(255,255,255).freeze
258
+ # BLACK = Color.new(0,0,0).freeze
259
+ #
260
+ #end
261
+ #
262
+ ## "Global" method for creating Color objects, eg:
263
+ ## new_color = rgb(params[:new_color])
264
+ ## style="border: 1px solid <%= rgb(10,50,80).lighten %>"
265
+ #def rgb(*args)
266
+ # Color.parse(*args)
267
+ #end
268
+ #
269
+ #