hamlit 2.7.5 → 2.8.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.
- checksums.yaml +4 -4
- data/.travis.yml +11 -9
- data/CHANGELOG.md +7 -0
- data/Gemfile +4 -1
- data/REFERENCE.md +5 -5
- data/benchmark/etc/tags_loop.haml +2 -0
- data/benchmark/slim/run-benchmarks.rb +6 -5
- data/hamlit.gemspec +1 -1
- data/lib/hamlit/attribute_compiler.rb +7 -8
- data/lib/hamlit/compiler/script_compiler.rb +1 -2
- data/lib/hamlit/compiler/tag_compiler.rb +1 -2
- data/lib/hamlit/engine.rb +1 -2
- data/lib/hamlit/version.rb +1 -1
- metadata +8 -9
- data/bin/lineprof +0 -48
- data/lib/hamlit/static_analyzer.rb +0 -58
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 76bc9ab1e8d7db1673f0e064e6c49df5c90b314f
|
4
|
+
data.tar.gz: ea809b1885e208feda51f67dedc79c9fb6603f0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5e2e1820481a329f96c02256a0bc106f4ab0fbf10776cb8ac931f30a27c565f5a584da7f5eb77703690d7b77864c50bf7aad0f7d3a2e72f9b493d35f59b2995e
|
7
|
+
data.tar.gz: 48658e6ad6370dd1d2805755deb800cb576e74102fe1cd3448bf08e6686c99bc78ac183e8da7df576f76dd9fc4022661d755e671c1ad2bb0a5cd12bf020cc37f
|
data/.travis.yml
CHANGED
@@ -9,25 +9,27 @@ matrix:
|
|
9
9
|
include:
|
10
10
|
- rvm: 2.1.10
|
11
11
|
env: TASK=test
|
12
|
-
- rvm: 2.2.
|
12
|
+
- rvm: 2.2.6
|
13
13
|
env: TASK=test
|
14
|
-
- rvm: 2.3.
|
14
|
+
- rvm: 2.3.3
|
15
|
+
env: TASK=test
|
16
|
+
- rvm: 2.4.0
|
15
17
|
env: TASK=test
|
16
18
|
- rvm: ruby-head
|
17
19
|
env: TASK=test
|
18
|
-
- rvm: 2.
|
20
|
+
- rvm: 2.4.0
|
19
21
|
env: TASK=bench TEMPLATE=benchmark/boolean_attribute.haml,benchmark/class_attribute.haml,benchmark/id_attribute.haml,benchmark/data_attribute.haml,benchmark/common_attribute.haml
|
20
|
-
- rvm: 2.
|
22
|
+
- rvm: 2.4.0
|
21
23
|
env: TASK=bench TEMPLATE=benchmark/dynamic_attributes/boolean_attribute.haml,benchmark/dynamic_attributes/class_attribute.haml,benchmark/dynamic_attributes/id_attribute.haml,benchmark/dynamic_attributes/data_attribute.haml,benchmark/dynamic_attributes/common_attribute.haml
|
22
|
-
- rvm: 2.
|
24
|
+
- rvm: 2.4.0
|
23
25
|
env: TASK=bench SLIM_BENCH=1
|
24
|
-
- rvm: 2.
|
26
|
+
- rvm: 2.4.0
|
25
27
|
env: TASK=bench TEMPLATE=benchmark/etc/attribute_builder.haml
|
26
|
-
- rvm: 2.
|
28
|
+
- rvm: 2.4.0
|
27
29
|
env: TASK=bench TEMPLATE=benchmark/etc/static_analyzer.haml
|
28
|
-
- rvm: 2.
|
30
|
+
- rvm: 2.4.0
|
29
31
|
env: TASK=bench TEMPLATE=benchmark/etc/string_interpolation.haml
|
30
|
-
- rvm: 2.
|
32
|
+
- rvm: 2.4.0
|
31
33
|
env: TASK=bench TEMPLATE=test/haml/templates/standard.haml COMPILE=1
|
32
34
|
allow_failures:
|
33
35
|
- rvm: ruby-head
|
data/CHANGELOG.md
CHANGED
@@ -4,6 +4,13 @@ All notable changes to this project will be documented in this file. This
|
|
4
4
|
project adheres to [Semantic Versioning](http://semver.org/). This change log is based upon
|
5
5
|
[keep-a-changelog](https://github.com/olivierlacan/keep-a-changelog).
|
6
6
|
|
7
|
+
## [2.8.0](https://github.com/k0kubun/hamlit/compare/v2.7.5...v2.8.0) - 2017-02-12
|
8
|
+
|
9
|
+
### Changed
|
10
|
+
|
11
|
+
- Support Temple >= 0.8.0 and change to use StaticAnalyzer in Temple
|
12
|
+
- Optimize attribute building code a little
|
13
|
+
|
7
14
|
## [2.7.5](https://github.com/k0kubun/hamlit/compare/v2.7.4...v2.7.5) - 2016-10-15
|
8
15
|
|
9
16
|
### Fixed
|
data/Gemfile
CHANGED
@@ -3,12 +3,15 @@ source 'https://rubygems.org'
|
|
3
3
|
# Specify your gem's dependencies in hamlit.gemspec
|
4
4
|
gemspec
|
5
5
|
|
6
|
+
if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.2')
|
7
|
+
gem 'rack', '< 2'
|
8
|
+
end
|
9
|
+
|
6
10
|
gem 'benchmark-ips', '2.3.0'
|
7
11
|
gem 'minitest-line'
|
8
12
|
gem 'pry-byebug'
|
9
13
|
|
10
14
|
if RUBY_PLATFORM !~ /mswin|mingw|bccwin|wince/
|
11
15
|
gem 'faml'
|
12
|
-
gem 'lineprof'
|
13
16
|
gem 'stackprof'
|
14
17
|
end
|
data/REFERENCE.md
CHANGED
@@ -10,16 +10,16 @@ See [Haml's tutorial](http://haml.info/tutorial.html) if you are not familiar wi
|
|
10
10
|
See [Haml's reference](http://haml.info/docs/yardoc/file.REFERENCE.html)
|
11
11
|
for full features in original implementation.
|
12
12
|
|
13
|
-
- [
|
13
|
+
- [ ] Using Haml
|
14
14
|
- [x] Rails XSS Protection
|
15
15
|
- [x] Ruby Module
|
16
16
|
- [x] Options
|
17
17
|
- [ ] Encodings
|
18
18
|
- [x] Plain Text
|
19
19
|
- [x] Escaping: \
|
20
|
-
- [
|
20
|
+
- [ ] HTML Elements
|
21
21
|
- [x] Element Name: %
|
22
|
-
- [
|
22
|
+
- [ ] Attributes: `
|
23
23
|
- [x] :class and :id Attributes
|
24
24
|
- [x] HTML-style Attributes: ()
|
25
25
|
- [x] Ruby 1.9-style Hashes
|
@@ -44,7 +44,7 @@ for full features in original implementation.
|
|
44
44
|
- [x] Ruby Interpolation: #{}
|
45
45
|
- [x] Escaping HTML: &=
|
46
46
|
- [x] Unescaping HTML: !=
|
47
|
-
- [
|
47
|
+
- [ ] Filters
|
48
48
|
- [x] :cdata
|
49
49
|
- [x] :coffee
|
50
50
|
- [x] :css
|
@@ -61,7 +61,7 @@ for full features in original implementation.
|
|
61
61
|
- [x] :scss
|
62
62
|
- [ ] :textile
|
63
63
|
- [ ] Custom Filters
|
64
|
-
- [
|
64
|
+
- [x] Helper Methods
|
65
65
|
- [x] preserve
|
66
66
|
- [x] surround
|
67
67
|
- [x] precede
|
@@ -47,8 +47,9 @@ require 'faml'
|
|
47
47
|
require 'hamlit'
|
48
48
|
|
49
49
|
class SlimBenchmarks
|
50
|
-
def initialize(
|
51
|
-
@
|
50
|
+
def initialize(only_haml)
|
51
|
+
@only_haml = only_haml
|
52
|
+
@benches = []
|
52
53
|
|
53
54
|
@erb_code = File.read(File.dirname(__FILE__) + '/view.erb')
|
54
55
|
@haml_code = File.read(File.dirname(__FILE__) + '/view.haml')
|
@@ -70,8 +71,8 @@ class SlimBenchmarks
|
|
70
71
|
def run_hamlit; #{Hamlit::Engine.new.call @haml_code}; end
|
71
72
|
}
|
72
73
|
|
73
|
-
bench("erubis v#{Erubis::VERSION}") { context.run_erubis }
|
74
|
-
bench("slim v#{Slim::VERSION}") { context.run_slim_ugly }
|
74
|
+
bench("erubis v#{Erubis::VERSION}") { context.run_erubis } unless @only_haml
|
75
|
+
bench("slim v#{Slim::VERSION}") { context.run_slim_ugly } unless @only_haml
|
75
76
|
bench("haml v#{Haml::VERSION}") { context.run_haml_ugly }
|
76
77
|
bench("faml v#{Faml::VERSION}") { context.run_faml }
|
77
78
|
bench("hamlit v#{Hamlit::VERSION}") { context.run_hamlit }
|
@@ -91,4 +92,4 @@ class SlimBenchmarks
|
|
91
92
|
end
|
92
93
|
end
|
93
94
|
|
94
|
-
SlimBenchmarks.new(ENV['
|
95
|
+
SlimBenchmarks.new(ENV['ONLY_HAML'] == '1').run
|
data/hamlit.gemspec
CHANGED
@@ -21,7 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.require_paths = ['lib']
|
22
22
|
spec.required_ruby_version = '>= 2.1.0'
|
23
23
|
|
24
|
-
spec.add_dependency 'temple', '
|
24
|
+
spec.add_dependency 'temple', '>= 0.8.0'
|
25
25
|
spec.add_dependency 'thor'
|
26
26
|
spec.add_dependency 'tilt'
|
27
27
|
|
@@ -2,7 +2,6 @@
|
|
2
2
|
require 'hamlit/attribute_builder'
|
3
3
|
require 'hamlit/attribute_parser'
|
4
4
|
require 'hamlit/ruby_expression'
|
5
|
-
require 'hamlit/static_analyzer'
|
6
5
|
|
7
6
|
module Hamlit
|
8
7
|
class AttributeCompiler
|
@@ -30,7 +29,7 @@ module Hamlit
|
|
30
29
|
attrs = node.value[:attributes_hashes]
|
31
30
|
attrs.unshift(node.value[:attributes].inspect) if node.value[:attributes] != {}
|
32
31
|
|
33
|
-
args = [@escape_attrs, @quote, @format
|
32
|
+
args = [@escape_attrs.inspect, "#{@quote.inspect}.freeze", @format.inspect].push(node.value[:object_ref]) + attrs
|
34
33
|
[:html, :attrs, [:dynamic, "::Hamlit::AttributeBuilder.build(#{args.join(', ')})"]]
|
35
34
|
end
|
36
35
|
|
@@ -59,7 +58,7 @@ module Hamlit
|
|
59
58
|
|
60
59
|
def compile_id!(temple, key, values)
|
61
60
|
build_code = attribute_builder(:id, values)
|
62
|
-
if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
|
61
|
+
if values.all? { |type, exp| type == :static || Temple::StaticAnalyzer.static?(exp) }
|
63
62
|
temple << [:html, :attr, key, [:static, eval(build_code).to_s]]
|
64
63
|
else
|
65
64
|
temple << [:html, :attr, key, [:dynamic, build_code]]
|
@@ -68,7 +67,7 @@ module Hamlit
|
|
68
67
|
|
69
68
|
def compile_class!(temple, key, values)
|
70
69
|
build_code = attribute_builder(:class, values)
|
71
|
-
if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
|
70
|
+
if values.all? { |type, exp| type == :static || Temple::StaticAnalyzer.static?(exp) }
|
72
71
|
temple << [:html, :attr, key, [:static, eval(build_code).to_s]]
|
73
72
|
else
|
74
73
|
temple << [:html, :attr, key, [:dynamic, build_code]]
|
@@ -76,10 +75,10 @@ module Hamlit
|
|
76
75
|
end
|
77
76
|
|
78
77
|
def compile_data!(temple, key, values)
|
79
|
-
args = [@escape_attrs.inspect, @quote.inspect, values.map { |v| literal_for(v) }]
|
78
|
+
args = [@escape_attrs.inspect, "#{@quote.inspect}.freeze", values.map { |v| literal_for(v) }]
|
80
79
|
build_code = "::Hamlit::AttributeBuilder.build_data(#{args.join(', ')})"
|
81
80
|
|
82
|
-
if values.all? { |type, exp| type == :static || StaticAnalyzer.static?(exp) }
|
81
|
+
if values.all? { |type, exp| type == :static || Temple::StaticAnalyzer.static?(exp) }
|
83
82
|
temple << [:static, eval(build_code).to_s]
|
84
83
|
else
|
85
84
|
temple << [:dynamic, build_code]
|
@@ -89,7 +88,7 @@ module Hamlit
|
|
89
88
|
def compile_boolean!(temple, key, values)
|
90
89
|
exp = literal_for(values.last)
|
91
90
|
|
92
|
-
if StaticAnalyzer.static?(exp)
|
91
|
+
if Temple::StaticAnalyzer.static?(exp)
|
93
92
|
value = eval(exp)
|
94
93
|
case value
|
95
94
|
when true then temple << [:html, :attr, key, @format == :xhtml ? [:static, key] : [:multi]]
|
@@ -118,7 +117,7 @@ module Hamlit
|
|
118
117
|
|
119
118
|
def literal_for(value)
|
120
119
|
type, exp = value
|
121
|
-
type == :static ? exp.inspect : exp
|
120
|
+
type == :static ? "#{exp.inspect}.freeze" : exp
|
122
121
|
end
|
123
122
|
end
|
124
123
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'hamlit/ruby_expression'
|
3
|
-
require 'hamlit/static_analyzer'
|
4
3
|
require 'hamlit/string_splitter'
|
5
4
|
|
6
5
|
module Hamlit
|
@@ -17,7 +16,7 @@ module Hamlit
|
|
17
16
|
compile_interpolated_plain(node)
|
18
17
|
when no_children && RubyExpression.string_literal?(node.value[:text])
|
19
18
|
delegate_optimization(node)
|
20
|
-
when no_children && StaticAnalyzer.static?(node.value[:text])
|
19
|
+
when no_children && Temple::StaticAnalyzer.static?(node.value[:text])
|
21
20
|
static_compile(node)
|
22
21
|
else
|
23
22
|
dynamic_compile(node, &block)
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
require 'hamlit/parser/haml_util'
|
3
3
|
require 'hamlit/attribute_compiler'
|
4
|
-
require 'hamlit/static_analyzer'
|
5
4
|
require 'hamlit/string_splitter'
|
6
5
|
|
7
6
|
module Hamlit
|
@@ -30,7 +29,7 @@ module Hamlit
|
|
30
29
|
when node.value[:parse]
|
31
30
|
return compile_interpolated_plain(node) if node.value[:escape_interpolation]
|
32
31
|
return delegate_optimization(node) if RubyExpression.string_literal?(node.value[:value])
|
33
|
-
return delegate_optimization(node) if StaticAnalyzer.static?(node.value[:value])
|
32
|
+
return delegate_optimization(node) if Temple::StaticAnalyzer.static?(node.value[:value])
|
34
33
|
|
35
34
|
var = @identity.generate
|
36
35
|
[:multi,
|
data/lib/hamlit/engine.rb
CHANGED
@@ -6,7 +6,6 @@ require 'hamlit/escapable'
|
|
6
6
|
require 'hamlit/force_escapable'
|
7
7
|
require 'hamlit/html'
|
8
8
|
require 'hamlit/string_splitter'
|
9
|
-
require 'hamlit/static_analyzer'
|
10
9
|
|
11
10
|
module Hamlit
|
12
11
|
class Engine < Temple::Engine
|
@@ -27,7 +26,7 @@ module Hamlit
|
|
27
26
|
use Compiler
|
28
27
|
use HTML
|
29
28
|
use StringSplitter
|
30
|
-
|
29
|
+
filter :StaticAnalyzer
|
31
30
|
use Escapable
|
32
31
|
use ForceEscapable
|
33
32
|
filter :ControlFlow
|
data/lib/hamlit/version.rb
CHANGED
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hamlit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2017-02-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: temple
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 0.
|
19
|
+
version: 0.8.0
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.
|
26
|
+
version: 0.8.0
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: thor
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -267,6 +267,7 @@ files:
|
|
267
267
|
- benchmark/etc/static_analyzer.haml
|
268
268
|
- benchmark/etc/string_interpolation.haml
|
269
269
|
- benchmark/etc/tags.haml
|
270
|
+
- benchmark/etc/tags_loop.haml
|
270
271
|
- benchmark/ext/build_data.rb
|
271
272
|
- benchmark/ext/build_id.rb
|
272
273
|
- benchmark/id_attribute.haml
|
@@ -281,7 +282,6 @@ files:
|
|
281
282
|
- benchmark/utils/benchmark_ips_extension.rb
|
282
283
|
- bin/bench
|
283
284
|
- bin/console
|
284
|
-
- bin/lineprof
|
285
285
|
- bin/ruby
|
286
286
|
- bin/setup
|
287
287
|
- bin/stackprof
|
@@ -344,7 +344,6 @@ files:
|
|
344
344
|
- lib/hamlit/rails_template.rb
|
345
345
|
- lib/hamlit/railtie.rb
|
346
346
|
- lib/hamlit/ruby_expression.rb
|
347
|
-
- lib/hamlit/static_analyzer.rb
|
348
347
|
- lib/hamlit/string_splitter.rb
|
349
348
|
- lib/hamlit/template.rb
|
350
349
|
- lib/hamlit/utils.rb
|
@@ -369,7 +368,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
369
368
|
version: '0'
|
370
369
|
requirements: []
|
371
370
|
rubyforge_project:
|
372
|
-
rubygems_version: 2.
|
371
|
+
rubygems_version: 2.5.1
|
373
372
|
signing_key:
|
374
373
|
specification_version: 4
|
375
374
|
summary: High Performance Haml Implementation
|
data/bin/lineprof
DELETED
@@ -1,48 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'bundler/setup'
|
4
|
-
require 'hamlit'
|
5
|
-
require 'lineprof'
|
6
|
-
require 'tempfile'
|
7
|
-
require 'thor'
|
8
|
-
|
9
|
-
class CLI < Thor
|
10
|
-
desc 'render HAML', 'Benchmark render'
|
11
|
-
def render(file)
|
12
|
-
haml = File.read(file)
|
13
|
-
compiled = Hamlit::Engine.new.call(haml)
|
14
|
-
code = [
|
15
|
-
'require "lineprof"',
|
16
|
-
'require "hamlit"',
|
17
|
-
|
18
|
-
'Lineprof.profile(/./) do',
|
19
|
-
'100.times do',
|
20
|
-
compiled,
|
21
|
-
'end',
|
22
|
-
'end',
|
23
|
-
].join("\n")
|
24
|
-
|
25
|
-
file = Tempfile.create('compiled')
|
26
|
-
file.write(code)
|
27
|
-
file.close
|
28
|
-
|
29
|
-
system("bundle exec ruby #{file.path}")
|
30
|
-
end
|
31
|
-
|
32
|
-
desc 'compile HAML', 'Benchmark compile'
|
33
|
-
def compile(file)
|
34
|
-
haml = File.read(file)
|
35
|
-
Lineprof.profile(/./) do
|
36
|
-
100.times { Hamlit::Engine.new.call(haml) }
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def method_missing(*args)
|
43
|
-
return super if args.length > 1
|
44
|
-
render(args.first.to_s)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
CLI.start
|
@@ -1,58 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
require 'hamlit/ruby_expression'
|
3
|
-
|
4
|
-
module Hamlit
|
5
|
-
class StaticAnalyzer < Temple::Filter
|
6
|
-
STATIC_TOKENS = %i[
|
7
|
-
on_tstring_beg on_tstring_end on_tstring_content
|
8
|
-
on_embexpr_beg on_embexpr_end
|
9
|
-
on_lbracket on_rbracket
|
10
|
-
on_qwords_beg on_words_sep on_qwords_sep
|
11
|
-
on_lparen on_rparen
|
12
|
-
on_lbrace on_rbrace on_label
|
13
|
-
on_int on_float on_imaginary
|
14
|
-
on_comma on_sp
|
15
|
-
].freeze
|
16
|
-
|
17
|
-
DYNAMIC_TOKENS = %i[
|
18
|
-
on_ident on_period
|
19
|
-
].freeze
|
20
|
-
|
21
|
-
STATIC_KEYWORDS = %w[
|
22
|
-
true false nil
|
23
|
-
].freeze
|
24
|
-
|
25
|
-
STATIC_OPERATORS = %w[
|
26
|
-
=>
|
27
|
-
].freeze
|
28
|
-
|
29
|
-
def self.static?(code)
|
30
|
-
return false if code.nil? || code.strip.empty?
|
31
|
-
return false if RubyExpression.syntax_error?(code)
|
32
|
-
|
33
|
-
Ripper.lex(code).each do |(_, col), token, str|
|
34
|
-
case token
|
35
|
-
when *STATIC_TOKENS
|
36
|
-
# noop
|
37
|
-
when :on_kw
|
38
|
-
return false unless STATIC_KEYWORDS.include?(str)
|
39
|
-
when :on_op
|
40
|
-
return false unless STATIC_OPERATORS.include?(str)
|
41
|
-
when *DYNAMIC_TOKENS
|
42
|
-
return false
|
43
|
-
else
|
44
|
-
return false
|
45
|
-
end
|
46
|
-
end
|
47
|
-
true
|
48
|
-
end
|
49
|
-
|
50
|
-
def on_dynamic(code)
|
51
|
-
if StaticAnalyzer.static?(code)
|
52
|
-
[:static, eval(code).to_s]
|
53
|
-
else
|
54
|
-
[:dynamic, code]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|