sinatra-asset-snack 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ NjZiMDU1ZjkzZmE0OTEyNmMwYmQ3OWM5MWJmYTcwNmY2YWVlMWExMA==
5
+ data.tar.gz: !binary |-
6
+ ZDViM2MzNzdlOWViODNiMDgyZGM1ZDdjODZlYWU5YTAxOWQ1N2EyMw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ ZWJmMjBjMzk3ZWQwODBjYzZiZmJkYjRhZWZlYzMyOTk2NDQ4ZDI0MmEwMTY2
10
+ NDYwMjU0NTFjMzk3YzJiMzg4MmY3OTYwNmFmN2VkYjFkMjQxN2U3YjA0OWJi
11
+ N2VlYzE5OWY1YjY3ZjhmNWU4YWQ2MGI3ZmZmYjU4Y2FkY2QwYzk=
12
+ data.tar.gz: !binary |-
13
+ NzBkNDFiNTA3MjgzYjc4YmJhMTEwNWEyZGEzODZmY2JlZWRkYjRmYjVjYTE3
14
+ NjE4M2U2OGQyYjBmNDcwNzA0MWQ1YWU3YzI3Mzk5MTc1NDUxODRmN2ZkM2Y0
15
+ NGE3NDYwMGIyNGYzYjc0ODUyNGUxMGE2NzQyY2FmODFlZTlkZjk=
data/.gitignore CHANGED
@@ -1 +1,2 @@
1
1
  .*.swp
2
+ .rvmrc
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,56 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ sinatra-asset-snack (0.1.0)
5
+ coffee-script
6
+ sass
7
+ sinatra
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ ansi (1.4.3)
13
+ builder (3.2.0)
14
+ coffee-script (2.2.0)
15
+ coffee-script-source
16
+ execjs
17
+ coffee-script-source (1.6.2)
18
+ execjs (1.4.0)
19
+ multi_json (~> 1.0)
20
+ hashie (2.0.3)
21
+ metaclass (0.0.1)
22
+ minitest (4.7.0)
23
+ minitest-reporters (0.14.10)
24
+ ansi
25
+ builder
26
+ minitest (>= 2.12, < 5.0)
27
+ powerbar
28
+ mocha (0.13.3)
29
+ metaclass (~> 0.0.1)
30
+ multi_json (1.7.2)
31
+ powerbar (1.0.11)
32
+ ansi (~> 1.4.0)
33
+ hashie (>= 1.1.0)
34
+ rack (1.5.2)
35
+ rack-protection (1.5.0)
36
+ rack
37
+ rack-test (0.6.2)
38
+ rack (>= 1.0)
39
+ rake (10.0.3)
40
+ sass (3.2.7)
41
+ sinatra (1.4.2)
42
+ rack (~> 1.5, >= 1.5.2)
43
+ rack-protection (~> 1.4)
44
+ tilt (~> 1.3, >= 1.3.4)
45
+ tilt (1.3.6)
46
+
47
+ PLATFORMS
48
+ ruby
49
+
50
+ DEPENDENCIES
51
+ minitest
52
+ minitest-reporters
53
+ mocha
54
+ rack-test
55
+ rake
56
+ sinatra-asset-snack!
data/LICENSE.txt ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013 Ben Kitzelman
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.
data/README.md CHANGED
@@ -4,6 +4,9 @@ A lean asset compiler for Sinatra developed specifically for Coffeescript and SA
4
4
  It stitches all assets for a route into a single file, no uglification, no minification (configure your server to use Gzip),
5
5
  just lean, fast compilation.
6
6
 
7
+ [![Build Status](https://travis-ci.org/benkitzelman/sinatra-asset-snack.png?branch=master)](https://travis-ci.org/benkitzelman/sinatra-asset-snack)
8
+ [![Gem Version](https://badge.fury.io/rb/sinatra-asset-snack.png)](http://badge.fury.io/rb/sinatra-asset-snack)
9
+
7
10
  ## Installation
8
11
  ### Bundler users
9
12
 
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs.push "lib"
5
+ t.test_files = FileList['test/*_test.rb', 'test/compilers/*_test.rb']
6
+ t.verbose = true
7
+ end
8
+ task :default => :test
@@ -54,6 +54,5 @@ module Sinatra
54
54
  paths.reduce([]) { |file_list, path| file_list + Dir.glob(path) }.uniq
55
55
  end
56
56
  end #InstanceMethods
57
-
58
57
  end # AssetSnack
59
58
  end #Sinatra
@@ -0,0 +1,33 @@
1
+ module Sinatra
2
+ module AssetSnack
3
+ module Compilers
4
+ class AssetCompiler
5
+
6
+ class << self
7
+ attr_reader :compiled_mime_type, :handled_extensions
8
+
9
+ def compile_file(file_path)
10
+ ext = File.extname(file_path).downcase[1..-1]
11
+ return unless ext && handled_extensions.include?(ext.to_sym)
12
+
13
+ file_content = File.read file_path
14
+ new.compile(file_content)
15
+ end
16
+
17
+ def handle_extensions(*extensions)
18
+ @handled_extensions = extensions
19
+ AssetSnack.register_compiler self, extensions
20
+ end
21
+
22
+ def mime_type(type)
23
+ @compiled_mime_type = type
24
+ end
25
+ end
26
+
27
+ def compile
28
+ throw "Not Implemented"
29
+ end
30
+ end
31
+ end #Compilers
32
+ end #Asset
33
+ end #Sinatra
@@ -0,0 +1,14 @@
1
+ module Sinatra
2
+ module AssetSnack
3
+ module Compilers
4
+ class CoffeeScriptCompiler < AssetCompiler
5
+ handle_extensions :coffee
6
+ mime_type 'text/js'
7
+
8
+ def compile(coffee_script)
9
+ CoffeeScript.compile(coffee_script, {bare: true})
10
+ end
11
+ end
12
+ end # Compilers
13
+ end # AssetSnack
14
+ end # Sinatra
@@ -0,0 +1,14 @@
1
+ module Sinatra
2
+ module AssetSnack
3
+ module Compilers
4
+ class SassCompiler < AssetCompiler
5
+ handle_extensions :scss
6
+ mime_type 'text/css'
7
+
8
+ def compile(sass_script)
9
+ Sass.compile(sass_script)
10
+ end
11
+ end
12
+ end # Compilers
13
+ end # AssetSnack
14
+ end # Sinatra
@@ -3,7 +3,10 @@ module Sinatra
3
3
  module Helpers
4
4
 
5
5
  def nocache(url)
6
- "#{url}?cb=#{Time.now.to_i}"
6
+ uri = URI.parse(url)
7
+ params = Rack::Utils.parse_query(uri.query).merge(cb: Time.now.to_i)
8
+ uri.query = Rack::Utils.build_query params
9
+ uri.to_s
7
10
  end
8
11
 
9
12
  end # Helpers
@@ -1,7 +1,7 @@
1
1
  module Sinatra
2
2
  module AssetSnack
3
3
  def self.version
4
- '0.0.1'
4
+ '0.1.0'
5
5
  end
6
- end
7
- end
6
+ end # AssetSnack
7
+ end # Sinatra
@@ -2,4 +2,8 @@ require 'sass'
2
2
  require 'coffee-script'
3
3
 
4
4
  here = File.dirname(__FILE__)
5
- Dir[File.join(here, 'asset_snack', '*.rb')].each { |f| require f }
5
+
6
+ require File.join here, 'asset_snack', 'compilers', 'asset_compiler'
7
+
8
+ Dir[File.join(here, 'asset_snack', '*.rb')].each { |f| require f }
9
+ Dir[File.join(here, 'asset_snack', 'compilers', '*.rb')].each { |f| require f }
@@ -1,4 +1,4 @@
1
- require './lib/sinatra/asset_snack'
1
+ require './lib/sinatra/asset_snack/version'
2
2
  Gem::Specification.new do |s|
3
3
  s.name = 'sinatra-asset-snack'
4
4
  s.version = Sinatra::AssetSnack.version
@@ -13,4 +13,10 @@ Gem::Specification.new do |s|
13
13
  s.add_dependency 'sinatra'
14
14
  s.add_dependency 'coffee-script'
15
15
  s.add_dependency 'sass'
16
+
17
+ s.add_development_dependency "minitest"
18
+ s.add_development_dependency "minitest-reporters"
19
+ s.add_development_dependency "mocha"
20
+ s.add_development_dependency "rake"
21
+ s.add_development_dependency "rack-test"
16
22
  end
@@ -0,0 +1,23 @@
1
+ require './test/test_helper'
2
+ include Rack::Test::Methods
3
+
4
+ module Sinatra
5
+ describe AssetSnack do
6
+ let(:app) { App.new }
7
+
8
+ it "must include the helpers" do
9
+ app.helpers.respond_to?(:nocache).must_equal true
10
+ end
11
+
12
+ it 'should stitch gouped assets into a common file' do
13
+ get '/javascript/application.js'
14
+ last_response.body.must_include '/** test.coffee **/'
15
+ last_response.body.must_include '/** test_two.coffee **/'
16
+ end
17
+
18
+ it 'should return the compilers mime type as a header' do
19
+ get '/javascript/application.js'
20
+ last_response.headers['Content-Type'].must_equal 'text/js'
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,39 @@
1
+ require './test/test_helper'
2
+
3
+ module Sinatra
4
+ describe AssetSnack::Compilers::CoffeeScriptCompiler do
5
+ subject { AssetSnack::Compilers::CoffeeScriptCompiler.new }
6
+ let(:file_path) { File.join File.dirname(__FILE__), '../', 'fixtures', 'test.coffee' }
7
+ let(:source) { '-> x = "test"' }
8
+ let(:compiled) {
9
+ <<-EOS
10
+ (function() {
11
+ var x;
12
+
13
+ return x = "test";
14
+ });
15
+ EOS
16
+ }
17
+
18
+ it 'must compile a coffeesript file' do
19
+ subject.class.compile_file(file_path).must_equal compiled
20
+ end
21
+
22
+ it 'must compile coffeescript' do
23
+ js = subject.compile source
24
+ js.must_equal compiled
25
+ end
26
+
27
+ it 'should handle files with extension coffee' do
28
+ subject.class.handled_extensions.must_include :coffee
29
+ end
30
+
31
+ it 'should compile to text/js' do
32
+ subject.class.compiled_mime_type.must_equal 'text/js'
33
+ end
34
+
35
+ it 'should register itself with the AssetCompiler' do
36
+ AssetSnack.compiler_for('test.coffee').must_equal AssetSnack::Compilers::CoffeeScriptCompiler
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,45 @@
1
+ require './test/test_helper'
2
+
3
+ module Sinatra
4
+ describe AssetSnack::Compilers::SassCompiler do
5
+ let(:file_path) { File.join File.dirname(__FILE__), '../', 'fixtures', 'test.scss' }
6
+ subject { AssetSnack::Compilers::SassCompiler.new }
7
+ let(:source) {
8
+ <<-EOS
9
+ .test{
10
+ .one {
11
+ color: red;
12
+ }
13
+ }
14
+ EOS
15
+ }
16
+
17
+ let(:compiled) {
18
+ <<-EOS
19
+ .test .one {
20
+ color: red; }
21
+ EOS
22
+ }
23
+
24
+ it 'must compile a sass file' do
25
+ subject.class.compile_file(file_path).must_equal compiled
26
+ end
27
+
28
+ it 'must compile sass' do
29
+ css = subject.compile source
30
+ css.must_equal compiled
31
+ end
32
+
33
+ it 'should handle files with extension scss' do
34
+ subject.class.handled_extensions.must_include :scss
35
+ end
36
+
37
+ it 'should compile to text/css' do
38
+ subject.class.compiled_mime_type.must_equal 'text/css'
39
+ end
40
+
41
+ it 'should register itself with the AssetCompiler' do
42
+ AssetSnack.compiler_for('test.scss').must_equal AssetSnack::Compilers::SassCompiler
43
+ end
44
+ end
45
+ end
@@ -0,0 +1 @@
1
+ -> x = "test"
@@ -0,0 +1,5 @@
1
+ .test{
2
+ .one {
3
+ color: red;
4
+ }
5
+ }
@@ -0,0 +1 @@
1
+ -> x = "test two"
@@ -0,0 +1,10 @@
1
+ require './test/test_helper'
2
+ module Sinatra
3
+ describe AssetSnack::Helpers do
4
+ subject { Class.new { self.class.send(:include, AssetSnack::Helpers) }}
5
+
6
+ it 'should apply a cache buster to a url' do
7
+ subject.nocache('/mytest.js?somevar=123').must_match /\A\/mytest.js\?somevar=123&cb=\d+\z/
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,15 @@
1
+ ENV['RACK_ENV'] = 'test'
2
+ require 'minitest/spec'
3
+ require 'minitest/autorun'
4
+ require "minitest/reporters"
5
+ require "mocha/setup"
6
+ require 'rack/test'
7
+ require 'sinatra/base'
8
+ require './lib/sinatra/asset_snack'
9
+ MiniTest::Reporters.use! MiniTest::Reporters::SpecReporter.new
10
+
11
+ class App < Sinatra::Base
12
+ register Sinatra::AssetSnack
13
+ asset_map '/javascript/application.js', ['test/fixtures/**/*.coffee']
14
+ asset_map '/stylesheets/application.css', ['test/fixtures/**/*.scss']
15
+ end
data/travis.yml ADDED
@@ -0,0 +1,7 @@
1
+ language: ruby
2
+ rvm:
3
+ - "1.9.2"
4
+ - "1.9.3"
5
+ - jruby-19mode # JRuby in 1.9 mode
6
+ - rbx-19mode
7
+ # script: "rake ci"
metadata CHANGED
@@ -1,20 +1,18 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sinatra-asset-snack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Ben Kitzelman
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-11-19 00:00:00.000000000 Z
11
+ date: 2013-03-28 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: sinatra
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
17
  - - ! '>='
20
18
  - !ruby/object:Gem::Version
@@ -22,7 +20,6 @@ dependencies:
22
20
  type: :runtime
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
24
  - - ! '>='
28
25
  - !ruby/object:Gem::Version
@@ -30,7 +27,6 @@ dependencies:
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: coffee-script
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
31
  - - ! '>='
36
32
  - !ruby/object:Gem::Version
@@ -38,7 +34,6 @@ dependencies:
38
34
  type: :runtime
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
38
  - - ! '>='
44
39
  - !ruby/object:Gem::Version
@@ -46,7 +41,6 @@ dependencies:
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: sass
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
45
  - - ! '>='
52
46
  - !ruby/object:Gem::Version
@@ -54,7 +48,76 @@ dependencies:
54
48
  type: :runtime
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: minitest-reporters
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ! '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: mocha
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ! '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rake
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ! '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rack-test
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
58
121
  requirements:
59
122
  - - ! '>='
60
123
  - !ruby/object:Gem::Version
@@ -68,38 +131,50 @@ extensions: []
68
131
  extra_rdoc_files: []
69
132
  files:
70
133
  - .gitignore
134
+ - Gemfile
135
+ - Gemfile.lock
136
+ - LICENSE.txt
71
137
  - README.md
138
+ - Rakefile
72
139
  - lib/sinatra/asset_snack.rb
73
- - lib/sinatra/asset_snack/asset_compiler.rb
74
140
  - lib/sinatra/asset_snack/asset_snack.rb
75
- - lib/sinatra/asset_snack/coffee_compiler.rb
141
+ - lib/sinatra/asset_snack/compilers/asset_compiler.rb
142
+ - lib/sinatra/asset_snack/compilers/coffee_script_compiler.rb
143
+ - lib/sinatra/asset_snack/compilers/sass_compiler.rb
76
144
  - lib/sinatra/asset_snack/helpers.rb
77
- - lib/sinatra/asset_snack/sass_compiler.rb
78
145
  - lib/sinatra/asset_snack/version.rb
79
146
  - sinatra-asset-snack.gemspec
147
+ - test/asset_snack_test.rb
148
+ - test/compilers/coffee_script_compiler_test.rb
149
+ - test/compilers/sass_compiler_test.rb
150
+ - test/fixtures/test.coffee
151
+ - test/fixtures/test.scss
152
+ - test/fixtures/test_two.coffee
153
+ - test/helpers_test.rb
154
+ - test/test_helper.rb
155
+ - travis.yml
80
156
  homepage: http://github.com/benkitzelman/sinatra-asset-snack
81
157
  licenses: []
158
+ metadata: {}
82
159
  post_install_message:
83
160
  rdoc_options: []
84
161
  require_paths:
85
162
  - lib
86
163
  required_ruby_version: !ruby/object:Gem::Requirement
87
- none: false
88
164
  requirements:
89
165
  - - ! '>='
90
166
  - !ruby/object:Gem::Version
91
167
  version: '0'
92
168
  required_rubygems_version: !ruby/object:Gem::Requirement
93
- none: false
94
169
  requirements:
95
170
  - - ! '>='
96
171
  - !ruby/object:Gem::Version
97
172
  version: '0'
98
173
  requirements: []
99
174
  rubyforge_project:
100
- rubygems_version: 1.8.24
175
+ rubygems_version: 2.0.3
101
176
  signing_key:
102
- specification_version: 3
177
+ specification_version: 4
103
178
  summary: Real quick asset compilation of Coffeescript to Javascript and SASS to CSS
104
179
  for Sinatra
105
180
  test_files: []
@@ -1,28 +0,0 @@
1
- module Sinatra
2
- module AssetSnack
3
- class AssetCompiler
4
-
5
- class << self
6
- attr_reader :compiled_mime_type, :handled_extensions
7
-
8
- def compile_file(file_path)
9
- ext = File.extname(file_path).downcase[1..-1]
10
- return unless ext && handled_extensions.include?(ext.to_sym)
11
-
12
- file_content = File.read file_path
13
- new.compile(file_content)
14
- end
15
-
16
- def handle_extensions(*extensions)
17
- @handled_extensions = extensions
18
- AssetSnack.register_compiler self, extensions
19
- end
20
-
21
- def mime_type(type)
22
- @compiled_mime_type = type
23
- end
24
-
25
- end
26
- end
27
- end #Asset
28
- end #GreyNomad
@@ -1,12 +0,0 @@
1
- module Sinatra
2
- module AssetSnack
3
- class CoffeeCompiler < AssetCompiler
4
- handle_extensions :coffee
5
- mime_type 'text/js'
6
-
7
- def compile(coffee_script)
8
- CoffeeScript.compile(coffee_script, {bare: true})
9
- end
10
- end
11
- end
12
- end
@@ -1,12 +0,0 @@
1
- module Sinatra
2
- module AssetSnack
3
- class SassCompiler < AssetCompiler
4
- handle_extensions :scss
5
- mime_type 'text/css'
6
-
7
- def compile(sass_script)
8
- Sass.compile(sass_script)
9
- end
10
- end
11
- end
12
- end