cactus 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +5 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +121 -0
- data/MIT.LICENSE +20 -0
- data/README.md +131 -0
- data/Rakefile +21 -0
- data/cactus.gemspec +25 -0
- data/ci_build.sh +16 -0
- data/lib/cactus.rb +5 -0
- data/lib/cactus/rails/engine.rb +13 -0
- data/lib/cactus/rails/helpers/view_helper.rb +27 -0
- data/lib/cactus/version.rb +3 -0
- data/spec/cactus/rails/helpers/view_helper_spec.rb +55 -0
- data/spec/dummy/README.rdoc +261 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/assets/javascripts/application.js +15 -0
- data/spec/dummy/app/assets/stylesheets/application.css +13 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.gitkeep +0 -0
- data/spec/dummy/app/models/.gitkeep +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +62 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +37 -0
- data/spec/dummy/config/environments/production.rb +67 -0
- data/spec/dummy/config/environments/test.rb +37 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +15 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +7 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +58 -0
- data/spec/dummy/lib/assets/.gitkeep +0 -0
- data/spec/dummy/log/.gitkeep +0 -0
- data/spec/dummy/log/test.log +0 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +25 -0
- data/spec/dummy/public/cactus_spec/css1_spec.js +0 -0
- data/spec/dummy/public/cactus_spec/css2_spec.js +0 -0
- data/spec/dummy/public/cactus_spec/notcss.js +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/javascripts/cactusReportSpec.js +135 -0
- data/spec/javascripts/cactusSpec.js +124 -0
- data/spec/javascripts/helpers/jquery.min.js +4 -0
- data/spec/javascripts/support/jasmine.yml +73 -0
- data/spec/javascripts/support/jasmine_config.rb +23 -0
- data/spec/javascripts/support/jasmine_runner.rb +32 -0
- data/spec/spec_helper.rb +13 -0
- data/vendor/assets/javascripts/cactus.js +287 -0
- metadata +193 -0
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm --create use ruby-1.9.3-p125@cactus
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
cactus (0.1.0)
|
5
|
+
jquery-rails (>= 2.0.1)
|
6
|
+
rails (>= 3.2.0)
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: http://rubygems.org/
|
10
|
+
specs:
|
11
|
+
actionmailer (3.2.2)
|
12
|
+
actionpack (= 3.2.2)
|
13
|
+
mail (~> 2.4.0)
|
14
|
+
actionpack (3.2.2)
|
15
|
+
activemodel (= 3.2.2)
|
16
|
+
activesupport (= 3.2.2)
|
17
|
+
builder (~> 3.0.0)
|
18
|
+
erubis (~> 2.7.0)
|
19
|
+
journey (~> 1.0.1)
|
20
|
+
rack (~> 1.4.0)
|
21
|
+
rack-cache (~> 1.1)
|
22
|
+
rack-test (~> 0.6.1)
|
23
|
+
sprockets (~> 2.1.2)
|
24
|
+
activemodel (3.2.2)
|
25
|
+
activesupport (= 3.2.2)
|
26
|
+
builder (~> 3.0.0)
|
27
|
+
activerecord (3.2.2)
|
28
|
+
activemodel (= 3.2.2)
|
29
|
+
activesupport (= 3.2.2)
|
30
|
+
arel (~> 3.0.2)
|
31
|
+
tzinfo (~> 0.3.29)
|
32
|
+
activeresource (3.2.2)
|
33
|
+
activemodel (= 3.2.2)
|
34
|
+
activesupport (= 3.2.2)
|
35
|
+
activesupport (3.2.2)
|
36
|
+
i18n (~> 0.6)
|
37
|
+
multi_json (~> 1.0)
|
38
|
+
arel (3.0.2)
|
39
|
+
builder (3.0.0)
|
40
|
+
childprocess (0.3.1)
|
41
|
+
ffi (~> 1.0.6)
|
42
|
+
diff-lcs (1.1.3)
|
43
|
+
erubis (2.7.0)
|
44
|
+
ffi (1.0.11)
|
45
|
+
hike (1.2.1)
|
46
|
+
i18n (0.6.0)
|
47
|
+
jasmine (1.1.2)
|
48
|
+
jasmine-core (>= 1.1.0)
|
49
|
+
rack (>= 1.1)
|
50
|
+
rspec (>= 1.3.1)
|
51
|
+
selenium-webdriver (>= 0.1.3)
|
52
|
+
jasmine-core (1.1.0)
|
53
|
+
journey (1.0.3)
|
54
|
+
jquery-rails (2.0.1)
|
55
|
+
railties (>= 3.2.0, < 5.0)
|
56
|
+
thor (~> 0.14)
|
57
|
+
json (1.6.5)
|
58
|
+
mail (2.4.4)
|
59
|
+
i18n (>= 0.4.0)
|
60
|
+
mime-types (~> 1.16)
|
61
|
+
treetop (~> 1.4.8)
|
62
|
+
mime-types (1.17.2)
|
63
|
+
multi_json (1.1.0)
|
64
|
+
polyglot (0.3.3)
|
65
|
+
rack (1.4.1)
|
66
|
+
rack-cache (1.2)
|
67
|
+
rack (>= 0.4)
|
68
|
+
rack-ssl (1.3.2)
|
69
|
+
rack
|
70
|
+
rack-test (0.6.1)
|
71
|
+
rack (>= 1.0)
|
72
|
+
rails (3.2.2)
|
73
|
+
actionmailer (= 3.2.2)
|
74
|
+
actionpack (= 3.2.2)
|
75
|
+
activerecord (= 3.2.2)
|
76
|
+
activeresource (= 3.2.2)
|
77
|
+
activesupport (= 3.2.2)
|
78
|
+
bundler (~> 1.0)
|
79
|
+
railties (= 3.2.2)
|
80
|
+
railties (3.2.2)
|
81
|
+
actionpack (= 3.2.2)
|
82
|
+
activesupport (= 3.2.2)
|
83
|
+
rack-ssl (~> 1.3.2)
|
84
|
+
rake (>= 0.8.7)
|
85
|
+
rdoc (~> 3.4)
|
86
|
+
thor (~> 0.14.6)
|
87
|
+
rake (0.9.2.2)
|
88
|
+
rdoc (3.12)
|
89
|
+
json (~> 1.4)
|
90
|
+
rspec (2.8.0)
|
91
|
+
rspec-core (~> 2.8.0)
|
92
|
+
rspec-expectations (~> 2.8.0)
|
93
|
+
rspec-mocks (~> 2.8.0)
|
94
|
+
rspec-core (2.8.0)
|
95
|
+
rspec-expectations (2.8.0)
|
96
|
+
diff-lcs (~> 1.1.2)
|
97
|
+
rspec-mocks (2.8.0)
|
98
|
+
rubyzip (0.9.6.1)
|
99
|
+
selenium-webdriver (2.20.0)
|
100
|
+
childprocess (>= 0.2.5)
|
101
|
+
ffi (~> 1.0)
|
102
|
+
multi_json (~> 1.0)
|
103
|
+
rubyzip
|
104
|
+
sprockets (2.1.2)
|
105
|
+
hike (~> 1.2)
|
106
|
+
rack (~> 1.0)
|
107
|
+
tilt (~> 1.1, != 1.3.0)
|
108
|
+
thor (0.14.6)
|
109
|
+
tilt (1.3.3)
|
110
|
+
treetop (1.4.10)
|
111
|
+
polyglot
|
112
|
+
polyglot (>= 0.3.1)
|
113
|
+
tzinfo (0.3.32)
|
114
|
+
|
115
|
+
PLATFORMS
|
116
|
+
ruby
|
117
|
+
|
118
|
+
DEPENDENCIES
|
119
|
+
cactus!
|
120
|
+
jasmine
|
121
|
+
rspec
|
data/MIT.LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012
|
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
ADDED
@@ -0,0 +1,131 @@
|
|
1
|
+
# Cactus
|
2
|
+
|
3
|
+
Designs can be tested too! Cactus is a CSS testing framework proof of concept.
|
4
|
+
|
5
|
+
It ensures that you always have the same CSS styling for DOM elements that you care about.
|
6
|
+
|
7
|
+
## Prerequisites
|
8
|
+
|
9
|
+
- Ruby on Rails, 3.2.x
|
10
|
+
- jquery-rails
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Install the Cactus gem manually or include it in your Rails Gemfile.
|
15
|
+
|
16
|
+
gem install cactus
|
17
|
+
|
18
|
+
Add jQuery to application.js (or any manifest file)
|
19
|
+
|
20
|
+
//= require jquery
|
21
|
+
|
22
|
+
Add the Cactus helper in your application layout, just before the `body` closing tag (assuming haml).
|
23
|
+
|
24
|
+
= cactus
|
25
|
+
|
26
|
+
Finally, add some CSS specs (written in JavaScript) in `public/cactus_spec`. Files need to end with spec.js.
|
27
|
+
|
28
|
+
Cactus.expect(".header", "font-size").toEqual("24px");
|
29
|
+
Cactus.expect("p", "font-size").toEqual("12px");
|
30
|
+
|
31
|
+
## A Brief Explanation
|
32
|
+
|
33
|
+
The Cactus helper in your application layout includes Cactus.js and all spec files located in `public/cactus_spec/` on every page load in the Dev and Test env; the helper will not output anything when in other (Prod, Staging etc) environments.
|
34
|
+
|
35
|
+
Once the files are included, the specs will be verified against the current page DOM, and results will be displayed.
|
36
|
+
|
37
|
+
## Writing Specs
|
38
|
+
|
39
|
+
Write your specs in JavaScript, and place them in the `public/cactus_spec/` folder.
|
40
|
+
|
41
|
+
### Expectations
|
42
|
+
|
43
|
+
You can make an expectation either on a specific element or a group of elements.
|
44
|
+
|
45
|
+
#### `expect`
|
46
|
+
|
47
|
+
Cactus.expect(".header", "font-size").toEqual("24px");
|
48
|
+
|
49
|
+
The `expect` method requires a tag name and an attribute. All elements that resolve to the tag name will be tested.
|
50
|
+
|
51
|
+
### Matchers
|
52
|
+
|
53
|
+
The expectations are chained to matchers for verification of CSS styling.
|
54
|
+
|
55
|
+
#### `toEqual`
|
56
|
+
|
57
|
+
Cactus.expect(".header", "font-size").toEqual("24px");
|
58
|
+
|
59
|
+
This tests for total equality.
|
60
|
+
|
61
|
+
#### `toContain`
|
62
|
+
|
63
|
+
Cactus.expect(".header", "font-family").toContain("Helvetica");
|
64
|
+
|
65
|
+
This tests for partial equality, using a REGEX constructed from the pass in value.
|
66
|
+
|
67
|
+
#### `toHaveColor`
|
68
|
+
|
69
|
+
Cactus.expect(".header", "color").toEqual("#ff0000");
|
70
|
+
|
71
|
+
This tests for total equality, by converting rgba values returned by browser into hex values.
|
72
|
+
|
73
|
+
#### `toHaveMargin`
|
74
|
+
|
75
|
+
Cactus.expect(".header").toHaveMargin("10px");
|
76
|
+
|
77
|
+
This tests equality on all sides of the element. You can pass in shorthand or longhand notation.
|
78
|
+
|
79
|
+
#### `toHavePadding`
|
80
|
+
|
81
|
+
Cactus.expect(".header").toHaveMargin("10px 5px");
|
82
|
+
|
83
|
+
This tests equality on all sides of the element. You can pass in shorthand or longhand notation.
|
84
|
+
|
85
|
+
#### `toHaveBorderWidth`
|
86
|
+
|
87
|
+
Cactus.expect(".header").toHaveBorderWidth("1px");
|
88
|
+
|
89
|
+
This tests equality on all sides of the element. You can pass in shorthand or longhand notation.
|
90
|
+
|
91
|
+
#### `toHaveBorderColor`
|
92
|
+
|
93
|
+
Cactus.expect(".header").toHaveBorderColor("#ff000");
|
94
|
+
|
95
|
+
This tests equality on all sides of the element.
|
96
|
+
|
97
|
+
## Automating
|
98
|
+
|
99
|
+
With RSpec and Capybara (Selenium webdriver), it's possible to automate the Cactus tests by writing request specs.
|
100
|
+
|
101
|
+
Add the following RSpec matcher to `spec/spec_helper.rb`:
|
102
|
+
|
103
|
+
RSpec::Matchers.define :be_cactus do
|
104
|
+
match do |actual|
|
105
|
+
all(".cactus_fail").blank?
|
106
|
+
end
|
107
|
+
|
108
|
+
failure_message_for_should do |actual|
|
109
|
+
message = "Oei! Something is wrong with the CSS on '#{actual.current_url}' lah!\n"
|
110
|
+
all(".cactus_fail").each do |failure|
|
111
|
+
message += "- #{failure.text}\n"
|
112
|
+
end
|
113
|
+
message
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
Write a request spec `spec/requests/cactus_spec.rb`
|
118
|
+
|
119
|
+
describe 'rspec and capybara integration with cactus', js: true do
|
120
|
+
it "is cactus-ready " do
|
121
|
+
page.should be_cactus
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
## Maintainers
|
126
|
+
- [Winston Teo](mailto: winston@newcontext.com), {new context}
|
127
|
+
|
128
|
+
|
129
|
+
## License
|
130
|
+
|
131
|
+
This software is licensed under the MIT License.
|
data/Rakefile
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
Bundler::GemHelper.install_tasks # Gives us rake build, rake install and rake release
|
3
|
+
|
4
|
+
# RSpec Tasks
|
5
|
+
require 'rspec/core/rake_task'
|
6
|
+
|
7
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
8
|
+
t.rspec_opts = ['--options', '.rspec']
|
9
|
+
end
|
10
|
+
|
11
|
+
task :default => :spec
|
12
|
+
|
13
|
+
# Jasmine Tasks
|
14
|
+
begin
|
15
|
+
require 'jasmine'
|
16
|
+
load 'jasmine/tasks/jasmine.rake'
|
17
|
+
rescue LoadError
|
18
|
+
task :jasmine do
|
19
|
+
abort "Jasmine is not available. In order to run jasmine, you must: (sudo) gem install jasmine"
|
20
|
+
end
|
21
|
+
end
|
data/cactus.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
|
4
|
+
require "cactus/version"
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "cactus"
|
8
|
+
s.version = Cactus::VERSION
|
9
|
+
s.authors = ["Winston Teo"]
|
10
|
+
s.email = ["winston@newcontext.com"]
|
11
|
+
s.homepage = "https://github.com/winston/cactus"
|
12
|
+
s.summary = %q{Cactus is a CSS testing framework}
|
13
|
+
s.description = %q{Designs can be tested too. Cactus is a CSS testing framework. It ensures that you always have the same CSS styling for DOM elements that you care about.}
|
14
|
+
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
|
20
|
+
s.add_dependency "rails" , ">= 3.2.0"
|
21
|
+
s.add_dependency "jquery-rails" , ">= 2.0.1"
|
22
|
+
|
23
|
+
s.add_development_dependency "rspec"
|
24
|
+
s.add_development_dependency "jasmine"
|
25
|
+
end
|
data/ci_build.sh
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# RVM
|
4
|
+
source ~/.rvm/scripts/rvm && source .rvmrc
|
5
|
+
|
6
|
+
# Install bundler
|
7
|
+
gem list --local bundler | grep bundler || gem install bundler || exit 1
|
8
|
+
|
9
|
+
# Debugging Info
|
10
|
+
echo USER=$USER && ruby --version && which ruby && which bundle
|
11
|
+
|
12
|
+
# Install project gems from Gemfile
|
13
|
+
bundle check || bundle install || exit 1
|
14
|
+
|
15
|
+
# Test!
|
16
|
+
bundle exec rake && bundle exec rake jasmine:ci
|
data/lib/cactus.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "#{File.dirname(__FILE__)}/helpers/view_helper"
|
2
|
+
|
3
|
+
module Cactus
|
4
|
+
module Rails
|
5
|
+
class Engine < ::Rails::Engine
|
6
|
+
initializer "cactus" do
|
7
|
+
ActiveSupport.on_load(:action_controller) do
|
8
|
+
include Cactus::Rails::ViewHelper
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Cactus
|
2
|
+
module Rails
|
3
|
+
module ViewHelper
|
4
|
+
extend ActiveSupport::Concern
|
5
|
+
|
6
|
+
included do
|
7
|
+
helper_method "cactus"
|
8
|
+
end
|
9
|
+
|
10
|
+
def cactus
|
11
|
+
return unless ::Rails.env.test? || ::Rails.env.development?
|
12
|
+
|
13
|
+
html = "<script src='/assets/cactus.js' type='text/javascript'></script>"
|
14
|
+
|
15
|
+
dir = "#{::Rails.root}/public"
|
16
|
+
specs = Dir[File.join(dir, "/cactus_spec", "/*spec.js")]
|
17
|
+
specs.each do |file|
|
18
|
+
filename = file[-(file.size - dir.size)..-1]
|
19
|
+
|
20
|
+
html += "<script src='#{filename}' type='text/javascript'></script>"
|
21
|
+
end
|
22
|
+
|
23
|
+
html.html_safe
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ApplicationController do
|
4
|
+
|
5
|
+
describe "cactus" do
|
6
|
+
let(:controller) { ApplicationController.new }
|
7
|
+
let(:html) { controller.cactus }
|
8
|
+
|
9
|
+
it "has method" do
|
10
|
+
ApplicationController.instance_methods.should include :cactus
|
11
|
+
end
|
12
|
+
|
13
|
+
it "includes method in corresponding helper" do
|
14
|
+
ApplicationController.helpers.methods.should include :cactus
|
15
|
+
end
|
16
|
+
|
17
|
+
context "rendering" do
|
18
|
+
it "renders cactus.js" do
|
19
|
+
html.should =~ /cactus.js/i
|
20
|
+
end
|
21
|
+
|
22
|
+
it "renders *spec.js files located in public/cactus_spec" do
|
23
|
+
html.should_not =~ /spec\/dummy\/public/i
|
24
|
+
|
25
|
+
html.should =~ /cactus_spec\/css1_spec.js/i
|
26
|
+
html.should =~ /cactus_spec\/css2_spec.js/i
|
27
|
+
|
28
|
+
html.should_not =~ /notcss.js/i
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
context "environment" do
|
33
|
+
it "production renders nothing" do
|
34
|
+
::Rails.should_receive(:env).any_number_of_times.and_return(ActiveSupport::StringInquirer.new("production"))
|
35
|
+
html.should be_blank
|
36
|
+
end
|
37
|
+
|
38
|
+
it "any other renders nothing" do
|
39
|
+
::Rails.should_receive(:env).any_number_of_times.and_return(ActiveSupport::StringInquirer.new("staging"))
|
40
|
+
html.should be_blank
|
41
|
+
end
|
42
|
+
|
43
|
+
it "test renders something" do
|
44
|
+
::Rails.should_receive(:env).any_number_of_times.and_return(ActiveSupport::StringInquirer.new("test"))
|
45
|
+
html.should_not be_blank
|
46
|
+
end
|
47
|
+
|
48
|
+
it "development renders something" do
|
49
|
+
::Rails.should_receive(:env).any_number_of_times.and_return(ActiveSupport::StringInquirer.new("development"))
|
50
|
+
html.should_not be_blank
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|