ruote-kit 2.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.document +0 -0
  2. data/.gitignore +8 -0
  3. data/Gemfile +10 -0
  4. data/README.rdoc +132 -0
  5. data/Rakefile +57 -0
  6. data/config.ru +21 -0
  7. data/lib/ruote-kit/application.rb +50 -0
  8. data/lib/ruote-kit/configuration.rb +52 -0
  9. data/lib/ruote-kit/helpers/engine_helpers.rb +24 -0
  10. data/lib/ruote-kit/helpers/form_helpers.rb +11 -0
  11. data/lib/ruote-kit/helpers/launch_item_parser.rb +59 -0
  12. data/lib/ruote-kit/helpers/navigation_helpers.rb +54 -0
  13. data/lib/ruote-kit/helpers/render_helpers.rb +103 -0
  14. data/lib/ruote-kit/helpers.rb +9 -0
  15. data/lib/ruote-kit/public/_ruote/images/bg.gif +0 -0
  16. data/lib/ruote-kit/public/_ruote/images/bg_button_left.gif +0 -0
  17. data/lib/ruote-kit/public/_ruote/images/bg_button_left_cancel.gif +0 -0
  18. data/lib/ruote-kit/public/_ruote/images/bg_button_left_submit.gif +0 -0
  19. data/lib/ruote-kit/public/_ruote/images/bg_button_right.gif +0 -0
  20. data/lib/ruote-kit/public/_ruote/javascripts/SimplyButtons.js +191 -0
  21. data/lib/ruote-kit/public/_ruote/javascripts/fluo-can.js +1111 -0
  22. data/lib/ruote-kit/public/_ruote/javascripts/fluo-dial.js +149 -0
  23. data/lib/ruote-kit/public/_ruote/javascripts/fluo-json.js +183 -0
  24. data/lib/ruote-kit/public/_ruote/javascripts/fluo-tred.js +515 -0
  25. data/lib/ruote-kit/public/_ruote/stylesheets/SimplyButtons.css +226 -0
  26. data/lib/ruote-kit/public/_ruote/stylesheets/base.css +336 -0
  27. data/lib/ruote-kit/public/_ruote/stylesheets/rk.css +30 -0
  28. data/lib/ruote-kit/public/_ruote/stylesheets/style.css +393 -0
  29. data/lib/ruote-kit/resources/expressions.rb +55 -0
  30. data/lib/ruote-kit/resources/processes.rb +52 -0
  31. data/lib/ruote-kit/resources/workitems.rb +64 -0
  32. data/lib/ruote-kit/spec/ruote_helpers.rb +47 -0
  33. data/lib/ruote-kit/vendor/sinatra-respond_to/LICENSE +21 -0
  34. data/lib/ruote-kit/vendor/sinatra-respond_to/README.markdown +102 -0
  35. data/lib/ruote-kit/vendor/sinatra-respond_to/Rakefile +30 -0
  36. data/lib/ruote-kit/vendor/sinatra-respond_to/VERSION.yml +4 -0
  37. data/lib/ruote-kit/vendor/sinatra-respond_to/lib/sinatra/respond_to.rb +206 -0
  38. data/lib/ruote-kit/vendor/sinatra-respond_to/sinatra-respond_to.gemspec +56 -0
  39. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/public/static folder/.keep +0 -0
  40. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/public/static.txt +1 -0
  41. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/test_app.rb +53 -0
  42. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/unreachable_static.txt +1 -0
  43. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/layout.html.haml +2 -0
  44. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.html.haml +1 -0
  45. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.js.erb +3 -0
  46. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/app/views/resource.xml.builder +3 -0
  47. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/extension_spec.rb +403 -0
  48. data/lib/ruote-kit/vendor/sinatra-respond_to/spec/spec_helper.rb +18 -0
  49. data/lib/ruote-kit/views/expression.html.haml +38 -0
  50. data/lib/ruote-kit/views/expressions.html.haml +30 -0
  51. data/lib/ruote-kit/views/index.html.haml +1 -0
  52. data/lib/ruote-kit/views/launch_process.html.haml +19 -0
  53. data/lib/ruote-kit/views/layout.html.haml +46 -0
  54. data/lib/ruote-kit/views/process.html.haml +55 -0
  55. data/lib/ruote-kit/views/processes.html.haml +27 -0
  56. data/lib/ruote-kit/views/resource_not_found.html.haml +7 -0
  57. data/lib/ruote-kit/views/workitem.html.haml +39 -0
  58. data/lib/ruote-kit/views/workitems.html.haml +23 -0
  59. data/lib/ruote-kit.rb +105 -0
  60. data/ruote-kit.gemspec +136 -0
  61. data/spec/helpers/render_helpers_spec.rb +211 -0
  62. data/spec/resources/expressions_spec.rb +179 -0
  63. data/spec/resources/index_spec.rb +46 -0
  64. data/spec/resources/processes_spec.rb +259 -0
  65. data/spec/resources/workitems_spec.rb +308 -0
  66. data/spec/ruote-kit_spec.rb +4 -0
  67. data/spec/spec.opts +2 -0
  68. data/spec/spec_helper.rb +152 -0
  69. data/spec/views/launch_process.html.haml_spec.rb +21 -0
  70. data/spec/views/process.html.haml_spec.rb +16 -0
  71. data/spec/views/processes.html.haml_spec.rb +30 -0
  72. data/spec/views/workitems.html.haml_spec.rb +68 -0
  73. metadata +185 -0
@@ -0,0 +1,393 @@
1
+ a:link, a:visited { color: #07b; text-decoration: none; }
2
+ a, a:hover, a:active { color: #d30; }
3
+ h1, h2, h3 {color: #444}
4
+
5
+ body {
6
+ color: #333;
7
+ background: #EBEBEB;
8
+ font: normal 12px/1.5em "Lucida Grande", "Helvetica Neue", Arial, sans-serif;
9
+ }
10
+
11
+ hr {
12
+ background: #aaa;
13
+ }
14
+
15
+ p {
16
+ font-size: 12px;
17
+ line-height: 20px;
18
+ }
19
+
20
+ input.checkbox {
21
+ vertical-align:middle;
22
+ }
23
+
24
+ #header h1 {
25
+ font-size: 28px;
26
+ padding: 5px 0;
27
+ margin: 5px 0;
28
+ }
29
+
30
+ .hightlight {
31
+ background-color: #ffc;
32
+ }
33
+ .small {
34
+ font-size: 11px;
35
+ }
36
+ .gray {
37
+ color: #999;
38
+ }
39
+ #header {
40
+ background: #232C30;
41
+ }
42
+
43
+ #header h1 a:link, #header h1 a:active, #header h1 a:hover, #header h1 a:visited {
44
+ color: #eaeaea;
45
+ }
46
+
47
+ #main {
48
+ background: #EBEBEB;
49
+ /*width: 73%;*/
50
+ }
51
+
52
+ #main .block {
53
+ -moz-border-radius-topleft: 4px;
54
+ -moz-border-radius-topright: 4px;
55
+ padding: 0;
56
+ margin-bottom:20px;
57
+ padding-bottom: 20px;
58
+ background: transparent;
59
+ }
60
+
61
+ #main .block .content {
62
+ border-left: 1px solid #ddd;
63
+ border-top: 1px solid #ddd;
64
+ border-bottom: 1px solid #ccc;
65
+ border-right: 1px solid #ccc;
66
+ background: #fff;
67
+ }
68
+
69
+ #main .block h2.title {
70
+ margin: 10px 0 5px 0;
71
+ background-color: none;
72
+ padding: 5px 5px 5px 15px;
73
+ font-size:18px;
74
+ color: #456;
75
+ }
76
+
77
+ .main_container {
78
+ padding:10px;
79
+ }
80
+
81
+ #footer {
82
+ background-color: #ddd;
83
+ border-top: 1px solid #bbb;
84
+ }
85
+
86
+ #footer .block {
87
+ font-size:11px;
88
+ background-color: #ddd;
89
+ padding: 0 10px;
90
+ text-align: right;
91
+ }
92
+
93
+ /* #sidebar .block { background: #FFF; padding-bottom:0px; } */
94
+
95
+ #sidebar .notice {
96
+ background-color: #ffc;
97
+ padding: 0 10px;
98
+ border-bottom:1px solid #ddd;
99
+ border-right:1px solid #ddd;
100
+ border-top:1px solid #fff;
101
+ border-left:1px solid #fff;
102
+ }
103
+ #sidebar .notice h2 {
104
+ font-size:16px;
105
+ margin: 5px 0;
106
+ border-bottom:1px solid #456;
107
+ }
108
+ #sidebar .notice p {
109
+ font-size:12px;
110
+ }
111
+
112
+ #sidebar .block {
113
+ padding-bottom: 0;
114
+ }
115
+
116
+ #sidebar .block .content {
117
+ padding: 0 10px;
118
+ }
119
+
120
+
121
+ #sidebar h3 {
122
+ background: #fff;
123
+ border-bottom:1px solid #ccc;
124
+ border-right:1px solid #ccc;
125
+ border-left:1px solid #ddd;
126
+ border-top:1px solid #ddd;
127
+ padding: 5px 10px;
128
+ color: #333;
129
+ font-weight: bold;
130
+ }
131
+
132
+ #sidebar ul li a:link, #sidebar ul li a:visited {
133
+ font-size:12px;
134
+ }
135
+
136
+ #sidebar ul li a:hover, #sidebar ul li a:active {
137
+ background: none;
138
+ color: #444;
139
+ font-size:12px;
140
+ text-decoration:underline;
141
+ }
142
+ #sidebar ul.navigation li.last a {
143
+ border-bottom: none;
144
+ }
145
+
146
+ #sidebar ul.navigation li a:link,#sidebar ul.navigation li a:visited {
147
+ padding: 5px 10px;
148
+ color:#6a6a6a;
149
+ text-decoration: none;
150
+ }
151
+ #sidebar ul.navigation li a:hover {
152
+ text-decoration:underline;
153
+ }
154
+ #sidebar .block .sidebar-block h4 {
155
+ border-bottom: 1px dotted #aaa;
156
+ }
157
+ #main-navigation ul li {
158
+ background: #456;
159
+ border-top: 1px solid #5C738A;
160
+ color: #eee;
161
+ border-top-left-radius: 5px;
162
+ border-top-right-radius: 5px;
163
+ }
164
+
165
+ #main-navigation ul li:hover {
166
+ border-top-color: #7593B0;
167
+ background-color: #576C82 !important;
168
+ color: #fff;
169
+ }
170
+
171
+ #main-navigation ul li.active {
172
+ border-top: 1px solid #fff;
173
+ background-color: #eee !important;
174
+ color: #333;
175
+ }
176
+
177
+ #main-navigation ul li a:link, #main-navigation ul li a:visited, #main-navigation ul li a:hover, #main-navigation ul li a:active,
178
+ .secondary-navigation ul li a:link, .secondary-navigation ul li a:visited, .secondary-navigation ul li a:hover, .secondary-navigation ul li a:active,
179
+ #user-navigation ul li a:link, #user-navigation ul li a:visited, #user-navigation ul li a:hover, #user-navigation ul li a:active {
180
+ text-decoration: none;
181
+ color: #FFF;
182
+ }
183
+
184
+ #user-navigation ul li a:link, #user-navigation ul li a:visited {
185
+ color: #CDE;
186
+ border-bottom: 1px dotted #345;
187
+ }
188
+
189
+ #user-navigation ul li a:hover {
190
+ color: #fff;
191
+ border-bottom: 1px dotted #CDE;
192
+ text-decoration: none;
193
+ }
194
+
195
+ #main-navigation ul li a {
196
+ font-size: 12px;
197
+ padding: 3px 10px;
198
+ }
199
+
200
+ #main-navigation ul li.active a:link, #main-navigation ul li.active a:visited, #main-navigation ul li.active a:hover, #main-navigation ul li.active a:active {
201
+ color: #364b69;
202
+ }
203
+
204
+ .secondary-navigation {
205
+ background: #eaeaea;
206
+ border-bottom: 0px;
207
+ }
208
+
209
+ .secondary-navigation ul li {
210
+ background: #456;
211
+ border-top: 1px solid #5C738A;
212
+ color: #eee;
213
+ margin-right: 5px;
214
+ border-top-left-radius: 5px;
215
+ border-top-right-radius: 5px;
216
+ }
217
+
218
+ .secondary-navigation ul li a {
219
+ padding: 3px 10px;
220
+ }
221
+
222
+ .secondary-navigation ul li.active:hover {
223
+ background: #fff !important;
224
+ border-top: 1px solid #ccc;
225
+ border-right: 1px solid #ccc;
226
+ }
227
+
228
+ .secondary-navigation ul li.active {
229
+ border-top: 1px solid #ddd;
230
+ border-left: 1px solid #ddd;
231
+ border-right: 1px solid #ccc;
232
+ border-bottom: 1px solid #fff;
233
+ margin-bottom: -1px;
234
+ background-color: #fff !important;
235
+ color: #333;
236
+ }
237
+
238
+ .secondary-navigation ul li.active a {
239
+ color: #333;
240
+ }
241
+
242
+ .secondary-navigation ul li:hover {
243
+ border-top-color: #7593B0;
244
+ background-color: #576C82 !important;
245
+ color: #fff;
246
+ }
247
+
248
+ /* pagination */
249
+
250
+ .pagination span.current {
251
+ background: #576C82;
252
+ color: #FFF;
253
+ border: 1px solid #7593B0;
254
+ -moz-border-radius:5px;
255
+ }
256
+
257
+ .pagination span.disabled {
258
+ background: #eee;
259
+ color: #aaa;
260
+ border: 1px solid #ddd;
261
+ -moz-border-radius:5px;
262
+ }
263
+
264
+ .pagination a {
265
+ color: #364B69;
266
+ border: 1px solid #ddd;
267
+ -moz-border-radius:5px;
268
+ font-size:11px;
269
+ }
270
+
271
+ .pagination a:hover {
272
+ color: #444;
273
+ background: #eaeaea;
274
+ border: 1px solid #576C82;
275
+ }
276
+
277
+ /* tables */
278
+
279
+ .table th {
280
+ background: #576C82;
281
+ color: #FFF;
282
+ font-weight:normal;
283
+ padding:3px;
284
+ }
285
+
286
+ .table th a.toggle {
287
+ display: block;
288
+ width: 12px;
289
+ height: 12px;
290
+ background: transparent url('images/tick.png') center no-repeat;
291
+ text-indent: -9999px;
292
+ -moz-outline: none;
293
+ }
294
+
295
+ .table th.first {
296
+ width: 30px;
297
+ text-align: center;
298
+ }
299
+
300
+ .table td {
301
+ border-bottom: 1px solid #AAA;
302
+ }
303
+
304
+ /* forms */
305
+
306
+ .form input.text, .form textarea.textarea {
307
+ border: 1px solid #ddd;
308
+ padding: 5px;
309
+ width:99%;
310
+ }
311
+
312
+ .form input.text_field, .form textarea.text_area {
313
+ border-right: 1px solid #ddd;
314
+ border-bottom: 1px solid #ddd;
315
+ border-top: 2px solid #ccc;
316
+ border-left: 2px solid #ccc;
317
+ width:99%;
318
+ }
319
+
320
+ .form .navform {
321
+ padding:10px;
322
+ background-color: #eee;
323
+ font-size:14px;
324
+ border-bottom:1px solid #ddd;
325
+ border-right:1px solid #ddd;
326
+ border-top:1px solid #eee;
327
+ border-left:1px solid #eee;
328
+ }
329
+
330
+ .form .navform input {
331
+ font-size:14px;
332
+ }
333
+
334
+ .description {
335
+ color:#aaa;
336
+ font-family:Georgia, serif;
337
+ }
338
+
339
+ /* flash-messages */
340
+ .flash .message {
341
+ -moz-border-radius: 3px;
342
+ -webkit-border-radius: 3px;
343
+ text-align:center;
344
+ margin:0 auto 5px;
345
+ width:80%;
346
+ }
347
+ .flash .message p {
348
+ margin:8px;
349
+ }
350
+ .flash .error {
351
+ border: 1px solid #fbb;
352
+ background-color: #fdd;
353
+ }
354
+ .flash .warning {
355
+ border: 1px solid #fffaaa;
356
+ background-color: #ffffcc;
357
+ }
358
+ .flash .notice {
359
+ border: 1px solid #ddf;
360
+ background-color: #eef;
361
+ }
362
+
363
+ /* lists */
364
+
365
+ ul.list li {
366
+ border-bottom-color: #F0F0EE;
367
+ }
368
+
369
+ ul.list li .item .avatar {
370
+ border-color: #F0F0EE;
371
+ margin: 3px 10px 0 0;
372
+ }
373
+
374
+ ul.list li .left {
375
+ padding: 5px 5px;
376
+ }
377
+
378
+ /* box */
379
+
380
+ #box .block {
381
+ background: #FFF;
382
+ border: 1px solid #ddd;
383
+ border-radius: 10px;
384
+ }
385
+
386
+ #box .block h2 {
387
+ background: #576C82;
388
+ color: #FFF;
389
+ border-top-left-radius: 5px;
390
+ border-top-right-radius: 5px;
391
+ }
392
+
393
+
@@ -0,0 +1,55 @@
1
+ class RuoteKit::Application
2
+
3
+ get "/_ruote/expressions" do
4
+ respond_to do |format|
5
+ format.html { haml :expressions }
6
+ format.json { json( :status, :ok ) }
7
+ end
8
+ end
9
+
10
+ get "/_ruote/expressions/:wfid" do
11
+ @process = engine.process( params[:wfid] )
12
+
13
+ if @process
14
+ respond_to do |format|
15
+ format.html { haml :expressions }
16
+ format.json { json( :expressions, @process.expressions ) }
17
+ end
18
+ else
19
+ resource_not_found
20
+ end
21
+ end
22
+
23
+ get "/_ruote/expressions/:wfid/:expid" do
24
+ @process = engine.process( params[:wfid] )
25
+
26
+ if @process && @expression = @process.expressions.detect { |exp| exp.fei.expid == params[:expid] }
27
+ respond_to do |format|
28
+ format.html { haml :expression }
29
+ format.json { json( :expression, @expression ) }
30
+ end
31
+ else
32
+ resource_not_found
33
+ end
34
+ end
35
+
36
+ delete "/_ruote/expressions/:wfid/:expid" do
37
+ process = engine.process( params[:wfid] )
38
+
39
+ if process && expression = process.expressions.detect { |exp| exp.fei.expid == params[:expid] }
40
+ if params[:_kill]
41
+ engine.kill_expression( expression.fei )
42
+ else
43
+ engine.cancel_expression( expression.fei )
44
+ end
45
+
46
+ respond_to do |format|
47
+ format.html { redirect "/_ruote/expressions/#{params[:wfid]}" }
48
+ format.json { json( :status, :ok ) }
49
+ end
50
+ else
51
+ resource_not_found
52
+ end
53
+ end
54
+
55
+ end
@@ -0,0 +1,52 @@
1
+ class RuoteKit::Application
2
+
3
+ get "/_ruote/processes" do
4
+ @processes = engine.processes
5
+
6
+ respond_to do |format|
7
+ format.html { haml :processes }
8
+ format.json { json( :processes, @processes ) }
9
+ end
10
+ end
11
+
12
+ get "/_ruote/processes/new" do
13
+ haml :launch_process
14
+ end
15
+
16
+ get "/_ruote/processes/:wfid" do
17
+ @process = engine.process( params[:wfid] )
18
+
19
+ if @process
20
+ respond_to do |format|
21
+ format.html { haml :process }
22
+ format.json { json( :process, @process ) }
23
+ end
24
+ else
25
+ resource_not_found
26
+ end
27
+ end
28
+
29
+ post "/_ruote/processes" do
30
+ launch_item = launch_item_from_post
31
+
32
+ @wfid = engine.launch( launch_item['pdef'], launch_item['fields'], launch_item['variables'] )
33
+
34
+ respond_to do |format|
35
+ format.html { redirect "/_ruote/processes/#{@wfid}" }
36
+ format.json { json( :launched, @wfid ) }
37
+ end
38
+ end
39
+
40
+ delete "/_ruote/processes/:wfid" do
41
+ if params[:_kill] == "1"
42
+ engine.kill_process( params[:wfid] )
43
+ else
44
+ engine.cancel_process( params[:wfid] )
45
+ end
46
+
47
+ respond_to do |format|
48
+ format.html { redirect "/_ruote/processes" }
49
+ format.json { json( :status, :ok ) }
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,64 @@
1
+ class RuoteKit::Application
2
+
3
+ get "/_ruote/workitems" do
4
+ if params[:participant]
5
+ @participants = params[:participant].split(',')
6
+ @workitems = @participants.inject([]) do |memo, part|
7
+ memo.concat store_participant.by_participant( part )
8
+ end
9
+ else
10
+ @workitems = store_participant.all
11
+ end
12
+
13
+ respond_to do |format|
14
+ format.html { haml :workitems }
15
+ format.json { json( :workitems, @workitems ) }
16
+ end
17
+ end
18
+
19
+ get "/_ruote/workitems/:wfid" do
20
+ @wfid = params[:wfid]
21
+ @workitems = find_workitems( params[:wfid] )
22
+
23
+ respond_to do |format|
24
+ format.html { haml( :workitems ) }
25
+ format.json { json( :workitems, @workitems ) }
26
+ end
27
+ end
28
+
29
+ get "/_ruote/workitems/:wfid/:expid" do
30
+ @workitem = find_workitem( params[:wfid], params[:expid] )
31
+
32
+ if @workitem
33
+ respond_to do |format|
34
+ format.html { haml :workitem }
35
+ format.json { json( :workitem, @workitem ) }
36
+ end
37
+ else
38
+ resource_not_found
39
+ end
40
+ end
41
+
42
+ put "/_ruote/workitems/:wfid/:expid" do
43
+ workitem = find_workitem( params[:wfid], params[:expid] )
44
+
45
+ options = field_updates_and_proceed_from_put
46
+
47
+ unless options[:fields].empty?
48
+ workitem.fields = options[:fields]
49
+ store_participant.update( workitem )
50
+ end
51
+
52
+ if options[:proceed]
53
+ store_participant.reply( workitem )
54
+ end
55
+
56
+ respond_to do |format|
57
+ format.html {
58
+ redirect options[:proceed] ? "/_ruote/workitems/#{params[:wfid]}" : "/_ruote/workitems/#{params[:wfid]}/#{params[:expid]}"
59
+ }
60
+ format.json { json( :workitem, workitem ) }
61
+ end
62
+ end
63
+
64
+ end
@@ -0,0 +1,47 @@
1
+ module RuoteKit
2
+ module Spec
3
+ module RuoteHelpers
4
+
5
+ # Launch a dummy process and return the wfid
6
+ def launch_test_process( &block )
7
+ pdef = if block_given?
8
+ yield
9
+ else
10
+ Ruote.process_definition :name => 'test' do
11
+ sequence do
12
+ nada
13
+ end
14
+ end
15
+ end
16
+
17
+ wfid = RuoteKit.engine.launch( pdef )
18
+
19
+ # Wait for the process list to populate
20
+ sleep 0.1 while RuoteKit.engine.process( wfid ).nil?
21
+
22
+ # Give the process some time to traverse the expression tree
23
+ sleep 0.4
24
+ #wait_for( 1 )
25
+
26
+ wfid
27
+ end
28
+
29
+ def noisy( on = true )
30
+ RuoteKit.engine.context[:noisy] = on
31
+ end
32
+
33
+ def store_participant
34
+ RuoteKit.engine.context.plist.lookup('.*')
35
+ end
36
+
37
+ def find_workitem( wfid, expid )
38
+ store_participant.by_wfid( wfid ).detect { |wi| wi.fei.expid == expid }
39
+ end
40
+
41
+ def wait_for( wfid )
42
+ @_spec_worker.context.logger.wait_for( wfid )
43
+ end
44
+
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2009 Chris Hoffman
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.