rack-pack 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -1,4 +1,4 @@
1
- pkg/*
2
- *.gem
3
1
  .bundle
4
- Gemfile.lock
2
+ .rvmrc
3
+ pkg/*
4
+ *.gem
data/Gemfile.lock ADDED
@@ -0,0 +1,45 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ rack-pack (0.2.2)
5
+ rack (~> 1.2.1)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ activesupport (3.0.1)
11
+ closure-compiler (0.3.3)
12
+ diff-lcs (1.1.2)
13
+ jsmin (1.0.1)
14
+ oyster (0.9.4)
15
+ packr (3.1.0)
16
+ oyster
17
+ rack (1.2.1)
18
+ rainpress (1.0)
19
+ rspec (2.0.1)
20
+ rspec-core (~> 2.0.1)
21
+ rspec-expectations (~> 2.0.1)
22
+ rspec-mocks (~> 2.0.1)
23
+ rspec-core (2.0.1)
24
+ rspec-expectations (2.0.1)
25
+ diff-lcs (>= 1.1.2)
26
+ rspec-mocks (2.0.1)
27
+ rspec-core (~> 2.0.1)
28
+ rspec-expectations (~> 2.0.1)
29
+ test-construct (1.2.0)
30
+ yui-compressor (0.9.1)
31
+
32
+ PLATFORMS
33
+ ruby
34
+
35
+ DEPENDENCIES
36
+ activesupport (~> 3.0.0)
37
+ closure-compiler (~> 0.3.2)
38
+ jsmin (~> 1.0.1)
39
+ packr (~> 3.1.0)
40
+ rack (~> 1.2.1)
41
+ rack-pack!
42
+ rainpress (~> 1.0.0)
43
+ rspec (~> 2.0.0)
44
+ test-construct (~> 1.2.0)
45
+ yui-compressor (~> 0.9.1)
data/README.md CHANGED
@@ -4,7 +4,7 @@ Rack::Pack is a piece of Rack Middleware that packages and optionally compresses
4
4
 
5
5
  ### Why?
6
6
 
7
- I've tried a dozen different asset packaging solutions including AssetPackager, BundleFu, Jammit, Sprockets, etc...none of which were quite what I wanted. I didn't need any helpers, controllers, embedded images, rake tasks, or Yaml config files. I just wanted something to take my assets and package them into one file, and you're looking at it.
7
+ I've tried a dozen different asset packaging solutions inlcuding AssetPackager, BundleFu, Jammit, Sprockets, etc...none of which were quite what I wanted. I didn't need any helpers, controllers, embedded images, rake tasks, or Yaml config files. I just wanted something to take my assets and package them into one file, and you're looking at it.
8
8
 
9
9
  ## Installation
10
10
 
@@ -19,7 +19,6 @@ or in Rails:
19
19
 
20
20
  # Gemfile
21
21
  gem 'rack-pack'
22
-
23
22
  # config/application.rb
24
23
  config.middleware.use Rack::Pack
25
24
 
@@ -66,19 +65,22 @@ or in Rails:
66
65
 
67
66
  # Gemfile
68
67
  gem 'jsmin'
69
-
70
68
  # config/application.rb
71
69
  config.middleware.use Rack::Pack
72
70
  # would use JSMin
73
71
 
74
72
  To pass options to the javascript compressor just use the `:js_compressor` option:
75
73
 
76
- require 'packr'
74
+ requrie 'packr'
77
75
  use Rack::Pack, :js_compression => { :shrink_vars => true }
78
76
 
79
77
  By default, packages are only compressed in a production environment. If for some reason you want them to always be compressed, pass the `:always_compress` option:
80
78
 
81
79
  use Rack::Pack, :always_compress => true
80
+
81
+ ## Advanced Usage
82
+
83
+ TODO
82
84
 
83
85
  ## Heroku and other read-only filesystems
84
86
 
data/lib/rack/pack.rb CHANGED
@@ -69,17 +69,17 @@ module Rack
69
69
 
70
70
  protected
71
71
 
72
- def update_packages
73
- Pack.packages.each_value do |package|
74
- package.update if package.stale?
72
+ def update_packages
73
+ Pack.packages.each_value do |package|
74
+ package.update if package.stale?
75
+ end
76
+ @updated = true
77
+ end
78
+
79
+ def skip_update?
80
+ return false if Pack.options[:always_update]
81
+ Pack.production? && @updated
75
82
  end
76
- @updated = true
77
- end
78
-
79
- def skip_update?
80
- return false if Pack.options[:always_update]
81
- Pack.production? && @updated
82
- end
83
83
 
84
84
  Package.register :js, Javascript
85
85
  Package.register :css, Stylesheet
@@ -19,10 +19,10 @@ module Rack
19
19
 
20
20
  protected
21
21
 
22
- def compression_options(defaults = {})
23
- return defaults unless Pack.options
24
- defaults.merge Pack.options[:js_compression]
25
- end
22
+ def compression_options(defaults = {})
23
+ return defaults unless Pack.options
24
+ defaults.merge Pack.options[:js_compression]
25
+ end
26
26
  end
27
27
  end
28
28
  end
@@ -38,6 +38,7 @@ module Rack
38
38
  end
39
39
 
40
40
  def compile
41
+ @size = source_files.size
41
42
  compiled = source_files.map(&:read).join
42
43
  compiled = compress(compiled) if compress?
43
44
  compiled.strip
@@ -49,11 +50,11 @@ module Rack
49
50
 
50
51
  def stale?
51
52
  @source_files = nil
52
- source_files? && (file_missing? || source_files_newer?)
53
+ source_files? && (file_missing? || source_files_added_or_removed? || source_files_newer?)
53
54
  end
54
55
 
55
56
  def source_files
56
- @source_files ||= @from.is_a?(Array) ? @from : Pathname.glob(@from)
57
+ @source_files ||= glob? ? Pathname.glob(@from) : @from
57
58
  end
58
59
 
59
60
  def compress?
@@ -62,21 +63,29 @@ module Rack
62
63
 
63
64
  protected
64
65
 
65
- def to_pathname(file)
66
- file.is_a?(Pathname) ? file : Pathname.new(file)
67
- end
68
-
69
- def source_files?
70
- !source_files.empty?
71
- end
72
-
73
- def file_missing?
74
- !file.exist?
75
- end
76
-
77
- def source_files_newer?
78
- source_files.map(&:mtime).max > file.mtime
79
- end
66
+ def to_pathname(file)
67
+ file.is_a?(Pathname) ? file : Pathname.new(file)
68
+ end
69
+
70
+ def glob?
71
+ @from.is_a?(String)
72
+ end
73
+
74
+ def source_files?
75
+ !source_files.empty?
76
+ end
77
+
78
+ def file_missing?
79
+ !file.exist?
80
+ end
81
+
82
+ def source_files_added_or_removed?
83
+ glob? && source_files.size != @size
84
+ end
85
+
86
+ def source_files_newer?
87
+ source_files.map(&:mtime).max > file.mtime
88
+ end
80
89
  end
81
90
  end
82
91
  end
@@ -13,10 +13,10 @@ module Rack
13
13
 
14
14
  protected
15
15
 
16
- def compression_options(defaults = {})
17
- return defaults unless Pack.options
18
- defaults.merge Pack.options[:css_compression]
19
- end
16
+ def compression_options(defaults = {})
17
+ return defaults unless Pack.options
18
+ defaults.merge Pack.options[:css_compression]
19
+ end
20
20
  end
21
21
  end
22
22
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Pack
3
- VERSION = '0.2.1'
3
+ VERSION = '0.2.2'
4
4
  end
5
5
  end
data/rack-pack.gemspec CHANGED
@@ -10,14 +10,14 @@ Gem::Specification.new do |s|
10
10
  s.email = 'me@petebrowne.com'
11
11
  s.homepage = 'http://rubygems.org/gems/rack-pack'
12
12
  s.summary = 'Rack Middleware for packaging assets such as javascripts and stylesheets.'
13
- s.description = 'Packages assets such as javascripts and stylesheets using a method inspired by Sass::Plugin. In development mode, the assets are packaged on each request. In production mode, the assets are packaged only one time.'
13
+ s.description = 'Rack::Pack is a piece of Rack Middleware that packages and optionally compresses assets such as javascripts and stylesheets into single files. In a development environment, assets will be packaged on each request if there have been changes to the source files. In a production environment, assets will only be packaged one time, and only if there have been changes.'
14
14
 
15
15
  s.required_rubygems_version = '>= 1.3.6'
16
16
  s.rubyforge_project = 'rack-pack'
17
17
 
18
18
  s.add_dependency 'rack', '~> 1.2.1'
19
- s.add_development_dependency 'rspec', '~> 2.0.0.beta.20'
20
- s.add_development_dependency 'activesupport', '~> 3.0.0.rc2'
19
+ s.add_development_dependency 'rspec', '~> 2.0.0'
20
+ s.add_development_dependency 'activesupport', '~> 3.0.0'
21
21
  s.add_development_dependency 'test-construct', '~> 1.2.0'
22
22
  s.add_development_dependency 'jsmin', '~> 1.0.1'
23
23
  s.add_development_dependency 'packr', '~> 3.1.0'
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Rack::Pack::Javascript do
4
4
  describe '#compile' do
5
- it 'should by default strip the concatenated output' do
5
+ it 'strips the concatenated output' do
6
6
  within_construct do |c|
7
7
  c.file 'input-1.js', ' 1'
8
8
  c.file 'input-2.js', '2 '
@@ -18,7 +18,7 @@ describe Rack::Pack::Javascript do
18
18
  end
19
19
 
20
20
  context 'when JSMin is required' do
21
- it 'should compress using JSMin' do
21
+ it 'compresses using JSMin' do
22
22
  reveal_const :JSMin do
23
23
  within_construct do |c|
24
24
  c.file 'input.js', 'function(number) { return number + 2; }'
@@ -31,7 +31,7 @@ describe Rack::Pack::Javascript do
31
31
  end
32
32
 
33
33
  context 'when packr is required' do
34
- it 'should compress using Packr' do
34
+ it 'compresses using Packr' do
35
35
  reveal_const :Packr do
36
36
  within_construct do |c|
37
37
  c.file 'input.js', '1'
@@ -44,7 +44,7 @@ describe Rack::Pack::Javascript do
44
44
  end
45
45
 
46
46
  context 'when yui/compressor is required' do
47
- it 'should compress using YUI::JavaScriptCompressor' do
47
+ it 'compresses using YUI::JavaScriptCompressor' do
48
48
  reveal_const :YUI do
49
49
  within_construct do |c|
50
50
  c.file 'input.js', '1'
@@ -59,7 +59,7 @@ describe Rack::Pack::Javascript do
59
59
  end
60
60
 
61
61
  context 'when closure-compiler is required' do
62
- it 'should compress using Closure::Compiler' do
62
+ it 'compresses using Closure::Compiler' do
63
63
  reveal_const :Closure do
64
64
  within_construct do |c|
65
65
  c.file 'input.js', '1'
@@ -14,35 +14,35 @@ describe Rack::Pack::Package do
14
14
  end
15
15
 
16
16
  describe '.register' do
17
- it 'will store the package class for the given extension' do
17
+ it 'stores the package class for the given extension' do
18
18
  Rack::Pack::Package.register :mock, MockPackage
19
19
  Rack::Pack::Package.mappings['mock'].should == MockPackage
20
20
  end
21
21
  end
22
22
 
23
23
  describe '.mappings' do
24
- it 'should by default have a Javascript mapping' do
24
+ it 'has a Javascript mapping' do
25
25
  Rack::Pack::Package.mappings['js'].should == Rack::Pack::Javascript
26
26
  end
27
27
 
28
- it 'should by default have a Stylesheet mapping' do
28
+ it 'has a Stylesheet mapping' do
29
29
  Rack::Pack::Package.mappings['css'].should == Rack::Pack::Stylesheet
30
30
  end
31
31
  end
32
32
 
33
33
  describe '.[]' do
34
- it 'should find the correct package class for the given file' do
34
+ it 'finds the package class for the given file' do
35
35
  Rack::Pack::Package['some/javascript.js'].should == Rack::Pack::Javascript
36
36
  end
37
37
 
38
- it 'should default to the base Package' do
38
+ it 'defaults to the base Package' do
39
39
  Rack::Pack::Package['missing.ext'].should == Rack::Pack::Package
40
40
  end
41
41
  end
42
42
 
43
43
  describe '#file' do
44
44
  context 'when initialized with a string' do
45
- it 'should convert it to a pathname' do
45
+ it 'converts it to a pathname' do
46
46
  package = Rack::Pack::Package.new('hello', [])
47
47
  package.file.should == Pathname.new('hello')
48
48
  end
@@ -50,14 +50,14 @@ describe Rack::Pack::Package do
50
50
 
51
51
  describe '#source_files'
52
52
  context 'when initialized with an array of strings' do
53
- it 'should convert them to pathnames' do
53
+ it 'converts them to pathnames' do
54
54
  package = Rack::Pack::Package.new('', %w(file-1 file-2))
55
55
  package.source_files.should =~ [ Pathname.new('file-1'), Pathname.new('file-2') ]
56
56
  end
57
57
  end
58
58
 
59
59
  context 'when initialized with a string' do
60
- it 'should treat it as a Dir glob' do
60
+ it 'treats it as a Dir glob' do
61
61
  within_construct do |c|
62
62
  c.file 'dir/file-1.js'
63
63
  c.file 'dir/file-2.js'
@@ -115,7 +115,7 @@ describe Rack::Pack::Package do
115
115
  end
116
116
 
117
117
  context 'when given a glob string' do
118
- it 'should check for new files' do
118
+ it 'checks for new files' do
119
119
  within_construct do |c|
120
120
  c.file 'directory/file-1'
121
121
 
@@ -133,7 +133,7 @@ describe Rack::Pack::Package do
133
133
  end
134
134
 
135
135
  describe '#update' do
136
- it 'should combine the files and write it to the output file' do
136
+ it 'combines the files and writes it to the output file' do
137
137
  within_construct do |c|
138
138
  to_file = c.file('packed-file', 'Stale Content')
139
139
  package = Rack::Pack::Package.new(
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Rack::Pack::Stylesheet do
4
4
  describe '#compile' do
5
- it 'should by default strip the concatenated output' do
5
+ it 'strips the concatenated output' do
6
6
  within_construct do |c|
7
7
  c.file 'input-1.css', ' 1'
8
8
  c.file 'input-2.css', '2 '
@@ -18,7 +18,7 @@ describe Rack::Pack::Stylesheet do
18
18
  end
19
19
 
20
20
  context 'when yui/compressor is required' do
21
- it 'should compress using YUI::JavaScriptCompressor' do
21
+ it 'compresses using YUI::JavaScriptCompressor' do
22
22
  reveal_const :YUI do
23
23
  within_construct do |c|
24
24
  c.file 'input.css', '1'
@@ -33,7 +33,7 @@ describe Rack::Pack::Stylesheet do
33
33
  end
34
34
 
35
35
  context 'when rainpress is required' do
36
- it 'should compress using Rainpress' do
36
+ it 'compresses using Rainpress' do
37
37
  reveal_const :Rainpress do
38
38
  within_construct do |c|
39
39
  c.file 'input.css', '1'
@@ -15,7 +15,7 @@ describe Rack::Pack do
15
15
  alias_method :request, :request_for
16
16
 
17
17
  context 'with default settings' do
18
- it 'should pack javascripts' do
18
+ it 'packs javascripts' do
19
19
  within_construct do |c|
20
20
  c.file 'vendor/javascripts/file-1.js', '1'
21
21
  c.file 'javascripts/file-2.js', '2'
@@ -27,7 +27,7 @@ describe Rack::Pack do
27
27
  end
28
28
  end
29
29
 
30
- it 'should pack stylesheets' do
30
+ it 'packs stylesheets' do
31
31
  within_construct do |c|
32
32
  c.file 'vendor/stylesheets/file-1.css', '1'
33
33
  c.file 'stylesheets/file-2.css', '2'
@@ -39,7 +39,7 @@ describe Rack::Pack do
39
39
  end
40
40
  end
41
41
 
42
- it 'should not compress the packages' do
42
+ it 'does not compress the packages' do
43
43
  reveal_const :JSMin do
44
44
  within_construct do |c|
45
45
  c.file 'app/javascripts/file.js', '1'
@@ -52,8 +52,8 @@ describe Rack::Pack do
52
52
  end
53
53
 
54
54
  context 'on next request' do
55
- context 'with updates' do
56
- it 'should re-pack the package' do
55
+ context 'when files are updated' do
56
+ it 're-packs the package' do
57
57
  within_construct do |c|
58
58
  c.file 'app/stylesheets/file-1.css', '1'
59
59
  c.file 'app/stylesheets/file-2.css', '2'
@@ -70,8 +70,8 @@ describe Rack::Pack do
70
70
  end
71
71
  end
72
72
 
73
- context 'without updates' do
74
- it 'should not re-pack the package' do
73
+ context 'when files are not updated' do
74
+ it 'does not re-pack the package' do
75
75
  within_construct do |c|
76
76
  c.file 'app/stylesheets/file-1.css', '1'
77
77
  c.file 'app/stylesheets/file-2.css', '2'
@@ -88,10 +88,46 @@ describe Rack::Pack do
88
88
  end
89
89
  end
90
90
  end
91
+
92
+ context 'when files are added' do
93
+ it 're-packs the package' do
94
+ within_construct do |c|
95
+ c.file 'app/stylesheets/file-1.css', '1'
96
+ c.file 'app/stylesheets/file-2.css', '2'
97
+
98
+ @app = build_app
99
+ @app.call(request)
100
+ File.read('public/stylesheets/application.css').should == '12'
101
+
102
+ sleep 1
103
+ c.file 'app/stylesheets/file-3.css', '3'
104
+ @app.call(request)
105
+ File.read('public/stylesheets/application.css').should == '123'
106
+ end
107
+ end
108
+ end
109
+
110
+ context 'when files are removed' do
111
+ it 're-packs the package' do
112
+ within_construct do |c|
113
+ c.file 'app/stylesheets/file-1.css', '1'
114
+ c.file 'app/stylesheets/file-2.css', '2'
115
+
116
+ @app = build_app
117
+ @app.call(request)
118
+ File.read('public/stylesheets/application.css').should == '12'
119
+
120
+ sleep 1
121
+ FileUtils.rm 'app/stylesheets/file-2.css'
122
+ @app.call(request)
123
+ File.read('public/stylesheets/application.css').should == '1'
124
+ end
125
+ end
126
+ end
91
127
  end
92
128
 
93
129
  context 'with some custom packages' do
94
- it 'should pack the files' do
130
+ it 'packs the files' do
95
131
  within_construct do |c|
96
132
  c.file 'vendor/javascripts/file-1.js', '1'
97
133
  c.file 'app/javascripts/file-2.js', '2'
@@ -104,7 +140,7 @@ describe Rack::Pack do
104
140
  end
105
141
 
106
142
  context 'with :always_compress on' do
107
- it 'should compress the packages' do
143
+ it 'compresses the packages' do
108
144
  reveal_const :JSMin do
109
145
  within_construct do |c|
110
146
  c.file 'app/javascripts/file.js', '1'
@@ -118,7 +154,7 @@ describe Rack::Pack do
118
154
  end
119
155
 
120
156
  context 'with a default package set to nil' do
121
- it 'should not pack the files' do
157
+ it 'does not pack the files' do
122
158
  within_construct do |c|
123
159
  c.file 'vendor/javascripts/file-1.js', '1'
124
160
 
@@ -138,7 +174,7 @@ describe Rack::Pack do
138
174
  Object.send(:remove_const, :Rails)
139
175
  end
140
176
 
141
- it 'should pack files only one time' do
177
+ it 'packs files only one time' do
142
178
  within_construct do |c|
143
179
  c.file 'app/javascripts/file.js', '1'
144
180
 
@@ -152,8 +188,8 @@ describe Rack::Pack do
152
188
  end
153
189
  end
154
190
 
155
- context 'with always_update option as true' do
156
- it 'should pack the files on each request' do
191
+ context 'with :always_update on' do
192
+ it 'packs the files on each request' do
157
193
  within_construct do |c|
158
194
  c.file 'app/javascripts/file.js', '1'
159
195
 
@@ -169,7 +205,7 @@ describe Rack::Pack do
169
205
  end
170
206
 
171
207
  context 'with javascript compression options' do
172
- it 'should pass the options to the javascript compressor' do
208
+ it 'passes the options to the javascript compressor' do
173
209
  reveal_const :Packr do
174
210
  within_construct do |c|
175
211
  c.file 'app/javascripts/file.js', '1'
data/spec/spec_helper.rb CHANGED
@@ -2,6 +2,7 @@ lib = File.expand_path('../../lib', __FILE__)
2
2
  $:.unshift(lib) unless $:.include?(lib)
3
3
 
4
4
  require 'rubygems'
5
+ require 'fileutils'
5
6
  require 'rspec'
6
7
  require 'construct'
7
8
  # To get 2.weeks.ago syntax...
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-pack
3
3
  version: !ruby/object:Gem::Version
4
- hash: 21
4
+ hash: 19
5
5
  prerelease: false
6
6
  segments:
7
7
  - 0
8
8
  - 2
9
- - 1
10
- version: 0.2.1
9
+ - 2
10
+ version: 0.2.2
11
11
  platform: ruby
12
12
  authors:
13
13
  - Pete Browne
@@ -15,7 +15,7 @@ autorequire:
15
15
  bindir: bin
16
16
  cert_chain: []
17
17
 
18
- date: 2010-08-29 00:00:00 -05:00
18
+ date: 2010-11-11 00:00:00 -06:00
19
19
  default_executable:
20
20
  dependencies:
21
21
  - !ruby/object:Gem::Dependency
@@ -40,14 +40,12 @@ dependencies:
40
40
  requirements:
41
41
  - - ~>
42
42
  - !ruby/object:Gem::Version
43
- hash: 62196427
43
+ hash: 15
44
44
  segments:
45
45
  - 2
46
46
  - 0
47
47
  - 0
48
- - beta
49
- - 20
50
- version: 2.0.0.beta.20
48
+ version: 2.0.0
51
49
  requirement: *id002
52
50
  name: rspec
53
51
  prerelease: false
@@ -58,13 +56,12 @@ dependencies:
58
56
  requirements:
59
57
  - - ~>
60
58
  - !ruby/object:Gem::Version
61
- hash: 977940607
59
+ hash: 7
62
60
  segments:
63
61
  - 3
64
62
  - 0
65
63
  - 0
66
- - rc2
67
- version: 3.0.0.rc2
64
+ version: 3.0.0
68
65
  requirement: *id003
69
66
  name: activesupport
70
67
  prerelease: false
@@ -165,7 +162,7 @@ dependencies:
165
162
  name: rainpress
166
163
  prerelease: false
167
164
  type: :development
168
- description: Packages assets such as javascripts and stylesheets using a method inspired by Sass::Plugin. In development mode, the assets are packaged on each request. In production mode, the assets are packaged only one time.
165
+ description: Rack::Pack is a piece of Rack Middleware that packages and optionally compresses assets such as javascripts and stylesheets into single files. In a development environment, assets will be packaged on each request if there have been changes to the source files. In a production environment, assets will only be packaged one time, and only if there have been changes.
169
166
  email: me@petebrowne.com
170
167
  executables: []
171
168
 
@@ -177,7 +174,7 @@ files:
177
174
  - .gitignore
178
175
  - .rspec
179
176
  - Gemfile
180
- - LICENSE
177
+ - Gemfile.lock
181
178
  - README.md
182
179
  - Rakefile
183
180
  - lib/rack-pack.rb
data/LICENSE DELETED
@@ -1,20 +0,0 @@
1
- Copyright (c) 2010 Peter Browne
2
-
3
- Permission is hereby granted, free of charge, to any person obtaining
4
- a copy of this software and associated documentation files (the
5
- "Software"), to deal in the Software without restriction, including
6
- without limitation the rights to use, copy, modify, merge, publish,
7
- distribute, sublicense, and/or sell copies of the Software, and to
8
- permit persons to whom the Software is furnished to do so, subject to
9
- the following conditions:
10
-
11
- The above copyright notice and this permission notice shall be
12
- included in all copies or substantial portions of the Software.
13
-
14
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.