lazylead 0.5.2 → 0.7.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +7 -2
- data/.docker/Dockerfile +17 -6
- data/.rubocop.yml +102 -1
- data/.simplecov +1 -1
- data/Guardfile +1 -1
- data/Rakefile +6 -3
- data/bin/lazylead +3 -1
- data/lazylead.gemspec +31 -26
- data/lib/lazylead/cc.rb +21 -20
- data/lib/lazylead/cli/app.rb +8 -3
- data/lib/lazylead/confluence.rb +9 -2
- data/lib/lazylead/email.rb +0 -20
- data/lib/lazylead/exchange.rb +16 -28
- data/lib/lazylead/model.rb +31 -16
- data/lib/lazylead/opts.rb +65 -2
- data/lib/lazylead/postman.rb +13 -17
- data/lib/lazylead/salt.rb +1 -0
- data/lib/lazylead/system/jira.rb +30 -6
- data/lib/lazylead/task/accuracy/accuracy.rb +10 -14
- data/lib/lazylead/task/accuracy/attachment.rb +2 -6
- data/lib/lazylead/task/accuracy/logs.rb +9 -5
- data/lib/lazylead/task/accuracy/onlyll.rb +147 -0
- data/lib/lazylead/task/accuracy/records.rb +1 -1
- data/lib/lazylead/task/accuracy/servers.rb +16 -7
- data/lib/lazylead/task/accuracy/stacktrace.rb +50 -10
- data/lib/lazylead/task/accuracy/testcase.rb +16 -9
- data/lib/lazylead/task/assignment.rb +96 -0
- data/lib/lazylead/task/fix_version.rb +6 -0
- data/lib/lazylead/task/propagate_down.rb +1 -1
- data/lib/lazylead/task/svn/diff.rb +77 -0
- data/lib/lazylead/task/svn/grep.rb +139 -0
- data/lib/lazylead/task/svn/touch.rb +99 -0
- data/lib/lazylead/version.rb +1 -1
- data/lib/messages/illegal_assignee_change.erb +123 -0
- data/lib/messages/illegal_fixversion_change.erb +8 -0
- data/lib/messages/only_ll.erb +107 -0
- data/lib/messages/svn_diff.erb +110 -0
- data/lib/messages/{svn_log.erb → svn_diff_attachment.erb} +19 -9
- data/lib/messages/svn_grep.erb +114 -0
- data/test/lazylead/cc_test.rb +1 -0
- data/test/lazylead/model_test.rb +20 -0
- data/test/lazylead/opts_test.rb +47 -0
- data/test/lazylead/postman_test.rb +8 -5
- data/test/lazylead/smoke_test.rb +13 -0
- data/test/lazylead/smtp_test.rb +1 -4
- data/test/lazylead/system/jira_test.rb +6 -7
- data/test/lazylead/task/accuracy/attachment_test.rb +1 -1
- data/test/lazylead/task/accuracy/logs_test.rb +62 -2
- data/test/lazylead/task/accuracy/onlyll_test.rb +138 -0
- data/test/lazylead/task/accuracy/servers_test.rb +2 -2
- data/test/lazylead/task/accuracy/stacktrace_test.rb +227 -0
- data/test/lazylead/task/accuracy/testcase_test.rb +39 -0
- data/test/lazylead/task/assignment_test.rb +53 -0
- data/test/lazylead/task/duedate_test.rb +3 -10
- data/test/lazylead/task/fix_version_test.rb +1 -0
- data/test/lazylead/task/propagate_down_test.rb +4 -3
- data/test/lazylead/task/savepoint_test.rb +9 -6
- data/test/lazylead/task/svn/diff_test.rb +97 -0
- data/test/lazylead/task/svn/grep_test.rb +103 -0
- data/test/lazylead/task/{touch_test.rb → svn/touch_test.rb} +7 -34
- data/test/test.rb +7 -8
- data/upgrades/sqlite/999.testdata.sql +3 -1
- metadata +141 -55
- data/lib/lazylead/task/touch.rb +0 -119
@@ -92,6 +92,8 @@
|
|
92
92
|
<tr>
|
93
93
|
<th id="key">Key</th>
|
94
94
|
<th id="priority">Priority</th>
|
95
|
+
<th id="from">From</th>
|
96
|
+
<th id="to">To</th>
|
95
97
|
<th id="when">When</th>
|
96
98
|
<th id="who">Who</th>
|
97
99
|
<th id="reporter">Reporter</th>
|
@@ -101,6 +103,12 @@
|
|
101
103
|
<tr>
|
102
104
|
<td><a href='<%= v.issue.url %>'><%= v.issue.key %></a></td>
|
103
105
|
<td><%= v.issue.priority %></td>
|
106
|
+
<td><%= v.last["items"]
|
107
|
+
.select { |h| h["field"] == "Fix Version" }
|
108
|
+
.map { |h| h["fromString"] }
|
109
|
+
.reject(&:blank?)
|
110
|
+
.join(",") %></td>
|
111
|
+
<td><%= v.to %></td>
|
104
112
|
<td><%= DateTime.parse(v.last["created"])
|
105
113
|
.strftime('%d-%b-%Y %I:%M:%S %p') %></td>
|
106
114
|
<td><span style='color: red'><%= v.last["author"]["displayName"] %></span>
|
@@ -0,0 +1,107 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<style> /* CSS styles taken from https://github.com/yegor256/tacit */
|
5
|
+
th {
|
6
|
+
font-weight: 600
|
7
|
+
}
|
8
|
+
|
9
|
+
table tr {
|
10
|
+
border-bottom-width: 2.16px
|
11
|
+
}
|
12
|
+
|
13
|
+
table tr th {
|
14
|
+
border-bottom-width: 2.16px
|
15
|
+
}
|
16
|
+
|
17
|
+
table tr td, table tr th {
|
18
|
+
overflow: hidden;
|
19
|
+
padding: 5.4px 3.6px;
|
20
|
+
line-height: 14px;
|
21
|
+
}
|
22
|
+
|
23
|
+
#summary {
|
24
|
+
text-align: left;
|
25
|
+
}
|
26
|
+
|
27
|
+
.auto {
|
28
|
+
min-width: auto;
|
29
|
+
white-space: nowrap;
|
30
|
+
}
|
31
|
+
|
32
|
+
a {
|
33
|
+
color: #275a90;
|
34
|
+
text-decoration: none
|
35
|
+
}
|
36
|
+
|
37
|
+
a:hover {
|
38
|
+
text-decoration: underline
|
39
|
+
}
|
40
|
+
|
41
|
+
* {
|
42
|
+
border: 0;
|
43
|
+
border-collapse: separate;
|
44
|
+
border-spacing: 0;
|
45
|
+
box-sizing: border-box;
|
46
|
+
margin: 0;
|
47
|
+
max-width: 100%;
|
48
|
+
padding: 0;
|
49
|
+
vertical-align: baseline;
|
50
|
+
font-family: system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
51
|
+
font-size: 13px;
|
52
|
+
font-stretch: normal;
|
53
|
+
font-style: normal;
|
54
|
+
font-weight: 400;
|
55
|
+
line-height: 29.7px
|
56
|
+
}
|
57
|
+
|
58
|
+
html, body {
|
59
|
+
width: 100%
|
60
|
+
}
|
61
|
+
|
62
|
+
html {
|
63
|
+
height: 100%
|
64
|
+
}
|
65
|
+
|
66
|
+
body {
|
67
|
+
background: #fff;
|
68
|
+
color: #1a1919;
|
69
|
+
padding: 36px
|
70
|
+
}
|
71
|
+
</style>
|
72
|
+
<title>Only LL</title>
|
73
|
+
</head>
|
74
|
+
<body>
|
75
|
+
<p>Hi,</p>
|
76
|
+
<p>The LL accuracy labels are cleaned from the following tickets:</p>
|
77
|
+
<table summary="table with tickets triage score">
|
78
|
+
<tr>
|
79
|
+
<th id="key">Key</th>
|
80
|
+
<th id="priority">Priority</th>
|
81
|
+
<th id="reporter">Reporter</th>
|
82
|
+
<th id="violators">Violators</th>
|
83
|
+
<th id="summary">Summary</th>
|
84
|
+
<th id="labels">Labels</th>
|
85
|
+
</tr>
|
86
|
+
<% tickets.each do |t| %>
|
87
|
+
<tr>
|
88
|
+
<td>
|
89
|
+
<div class="auto">
|
90
|
+
<a href="<%= t.issue.url %>"><%= t.issue.key %></a>
|
91
|
+
</div>
|
92
|
+
</td>
|
93
|
+
<td><%= t.issue.priority %></td>
|
94
|
+
<td>
|
95
|
+
<div class="auto"><%= t.issue.reporter.name %></div>
|
96
|
+
</td>
|
97
|
+
<td><%= t.violators.join(', ') %></td>
|
98
|
+
<td><%= t.issue.summary %></td>
|
99
|
+
<td><%= t.issue.labels.join(', ') %></td>
|
100
|
+
</tr>
|
101
|
+
<% end %>
|
102
|
+
</table>
|
103
|
+
<p>Posted by
|
104
|
+
<a href="https://github.com/dgroup/lazylead">lazylead v<%= version %></a>.
|
105
|
+
</p>
|
106
|
+
</body>
|
107
|
+
</html>
|
@@ -0,0 +1,110 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<style>
|
5
|
+
/* CSS styles taken from https://github.com/yegor256/tacit */
|
6
|
+
pre, code, kbd, samp, var, output {
|
7
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
8
|
+
font-size: 14.4px
|
9
|
+
}
|
10
|
+
|
11
|
+
pre code {
|
12
|
+
background: none;
|
13
|
+
border: 0;
|
14
|
+
line-height: 29.7px;
|
15
|
+
padding: 0
|
16
|
+
}
|
17
|
+
|
18
|
+
code, kbd {
|
19
|
+
background: #daf1e0;
|
20
|
+
border-radius: 3.6px;
|
21
|
+
color: #2a6f3b;
|
22
|
+
display: inline-block;
|
23
|
+
line-height: 18px;
|
24
|
+
padding: 3.6px 6.3px 2.7px
|
25
|
+
}
|
26
|
+
|
27
|
+
a {
|
28
|
+
color: #275a90;
|
29
|
+
text-decoration: none
|
30
|
+
}
|
31
|
+
|
32
|
+
a:hover {
|
33
|
+
text-decoration: underline
|
34
|
+
}
|
35
|
+
|
36
|
+
* {
|
37
|
+
border: 0;
|
38
|
+
border-collapse: separate;
|
39
|
+
border-spacing: 0;
|
40
|
+
box-sizing: border-box;
|
41
|
+
margin: 0;
|
42
|
+
max-width: 100%;
|
43
|
+
padding: 0;
|
44
|
+
vertical-align: baseline;
|
45
|
+
font-family: system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
46
|
+
font-size: 13px;
|
47
|
+
font-stretch: normal;
|
48
|
+
font-style: normal;
|
49
|
+
font-weight: 400;
|
50
|
+
line-height: 29.7px
|
51
|
+
}
|
52
|
+
|
53
|
+
html, body {
|
54
|
+
width: 100%
|
55
|
+
}
|
56
|
+
|
57
|
+
html {
|
58
|
+
height: 100%
|
59
|
+
}
|
60
|
+
|
61
|
+
body {
|
62
|
+
background: #fff;
|
63
|
+
color: #1a1919;
|
64
|
+
padding: 36px
|
65
|
+
}
|
66
|
+
|
67
|
+
.commit {
|
68
|
+
min-width: 100%;
|
69
|
+
border-radius: 3.5px;
|
70
|
+
overflow: hidden;
|
71
|
+
display: inline-block;
|
72
|
+
line-height: 15px;
|
73
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
74
|
+
border: 1px solid #BCC6CC;
|
75
|
+
}
|
76
|
+
|
77
|
+
.commit * {
|
78
|
+
padding-left: 4px;
|
79
|
+
font-size: 8px;
|
80
|
+
line-height: 12px;
|
81
|
+
}
|
82
|
+
</style>
|
83
|
+
<title>SVN log</title>
|
84
|
+
</head>
|
85
|
+
<body>
|
86
|
+
<p>Hi,</p>
|
87
|
+
<p>The following file(s) changed since <code><%= since_rev %></code> rev in
|
88
|
+
<a href="<%= svn_url %>"><%= svn_url %></a>:</p>
|
89
|
+
<% stdout.split("------------------------------------------------------------------------").reject(&:blank?).reverse.each do |commit| %>
|
90
|
+
<div class="commit">
|
91
|
+
<% commit.split("\n").reject(&:blank?).each_with_index do |line, index| %>
|
92
|
+
<p style="background: gainsboro;">
|
93
|
+
<% if index.zero? %>
|
94
|
+
<% details = line.split("|").map(&:strip).reject(&:blank?) %>
|
95
|
+
<a href="<%= commit_url %><%= details[0][1..-1] %>"><%= details[0] %></a>
|
96
|
+
by <a href="<%= user %><%= details[1] %>"><%= details[1] %></a>
|
97
|
+
at <span style="color: #275a90;"><%= details[2] %></span>
|
98
|
+
<% end %>
|
99
|
+
<% if index == 1 %>
|
100
|
+
<span style="padding-left: 4px"><%= line %></span>
|
101
|
+
<% end %>
|
102
|
+
</p>
|
103
|
+
<% end %>
|
104
|
+
</div>
|
105
|
+
<% end %>
|
106
|
+
<p>Posted by
|
107
|
+
<a href="https://github.com/dgroup/lazylead">lazylead v<%= version %></a>.
|
108
|
+
</p>
|
109
|
+
</body>
|
110
|
+
</html>
|
@@ -64,7 +64,7 @@
|
|
64
64
|
padding: 36px
|
65
65
|
}
|
66
66
|
|
67
|
-
.commit {
|
67
|
+
.commit, .table-of-contents {
|
68
68
|
min-width: 100%;
|
69
69
|
border-radius: 3.5px;
|
70
70
|
overflow: hidden;
|
@@ -74,26 +74,36 @@
|
|
74
74
|
border: 1px solid #BCC6CC;
|
75
75
|
}
|
76
76
|
|
77
|
-
.commit * {
|
77
|
+
.commit *, .table-of-contents * {
|
78
78
|
padding-left: 4px;
|
79
79
|
font-size: 8px;
|
80
80
|
line-height: 15px;
|
81
81
|
}
|
82
|
+
|
83
|
+
.table-of-contents {
|
84
|
+
border: none;
|
85
|
+
}
|
82
86
|
</style>
|
83
87
|
<title>SVN log</title>
|
84
88
|
</head>
|
85
89
|
<body>
|
86
90
|
<p>Hi,</p>
|
87
|
-
<p>
|
91
|
+
<p>Commit(s) since <code><%= since_rev %></code> revision in <a href="<%= svn_url %>"><%= svn_url %></a>:</p>
|
92
|
+
<div id="table-of-contents" class="table-of-contents">
|
93
|
+
<ul>
|
94
|
+
<% stdout.split("------------------------------------------------------------------------").reject(&:blank?).reverse.each do |commit| %>
|
95
|
+
<% details = commit.split("\n").reject(&:blank?).first.split("|").map(&:strip).reject(&:blank?) %>
|
96
|
+
<li><a href="#<%= details[0] %>"><%= details[0] %></a> by <%= details[1] %> at <%= details[2] %></li>
|
97
|
+
<% end %>
|
98
|
+
</ul>
|
99
|
+
</div>
|
88
100
|
<% stdout.split("------------------------------------------------------------------------").reject(&:blank?).reverse.each do |commit| %>
|
89
101
|
<div class="commit">
|
90
102
|
<% commit.split("\n").reject(&:blank?).each_with_index do |line, index| %>
|
91
103
|
<% if index.zero? %>
|
92
104
|
<% details = line.split("|").map(&:strip).reject(&:blank?) %>
|
93
|
-
<p style="background: gainsboro;">
|
94
|
-
<a href="
|
95
|
-
by <a href="<%= user %><%= details[1] %>"><%= details[1] %></a>
|
96
|
-
at <span style="color: #275a90;"><%= details[2] %></span>
|
105
|
+
<p style="background: gainsboro;" id="<%= details[0] %>"><a href="<%= commit_url %><%= details[0][1..-1] %>"><%= details[0] %></a> by <a href="<%= user %><%= details[1] %>"><%= details[1] %></a> at <span style="color: #275a90;"><%= details[2] %></span>
|
106
|
+
<a href="#table-of-contents">↑</a>
|
97
107
|
</p>
|
98
108
|
<% else %>
|
99
109
|
<% if line.start_with?("+++") || line.start_with?("---") %>
|
@@ -103,12 +113,12 @@
|
|
103
113
|
<% elsif line.start_with?("-") %>
|
104
114
|
<p style="<%= "background: lightsalmon;" %>"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
105
115
|
<% else %>
|
106
|
-
<p style="background: gainsboro;"><%= line.gsub(/[<>]/,'<' => '<', '>' => '>') %></p>
|
116
|
+
<p style="background: gainsboro;"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
107
117
|
<% end %>
|
108
118
|
<% end %>
|
109
119
|
<% end %>
|
110
120
|
</div>
|
111
|
-
<br
|
121
|
+
<br/>
|
112
122
|
<% end %>
|
113
123
|
<p>Posted by
|
114
124
|
<a href="https://github.com/dgroup/lazylead">lazylead v<%= version %></a>.
|
@@ -0,0 +1,114 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<style>
|
5
|
+
/* CSS styles taken from https://github.com/yegor256/tacit */
|
6
|
+
pre, code, kbd, samp, var, output {
|
7
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
8
|
+
font-size: 14.4px
|
9
|
+
}
|
10
|
+
|
11
|
+
pre code {
|
12
|
+
background: none;
|
13
|
+
border: 0;
|
14
|
+
line-height: 29.7px;
|
15
|
+
padding: 0
|
16
|
+
}
|
17
|
+
|
18
|
+
code, kbd {
|
19
|
+
background: #daf1e0;
|
20
|
+
border-radius: 3.6px;
|
21
|
+
color: #2a6f3b;
|
22
|
+
display: inline-block;
|
23
|
+
line-height: 18px;
|
24
|
+
padding: 3.6px 6.3px 2.7px
|
25
|
+
}
|
26
|
+
|
27
|
+
a {
|
28
|
+
color: #275a90;
|
29
|
+
text-decoration: none
|
30
|
+
}
|
31
|
+
|
32
|
+
a:hover {
|
33
|
+
text-decoration: underline
|
34
|
+
}
|
35
|
+
|
36
|
+
* {
|
37
|
+
border: 0;
|
38
|
+
border-collapse: separate;
|
39
|
+
border-spacing: 0;
|
40
|
+
box-sizing: border-box;
|
41
|
+
margin: 0;
|
42
|
+
max-width: 100%;
|
43
|
+
padding: 0;
|
44
|
+
vertical-align: baseline;
|
45
|
+
font-family: system-ui, "Helvetica Neue", Helvetica, Arial, sans-serif;
|
46
|
+
font-size: 13px;
|
47
|
+
font-stretch: normal;
|
48
|
+
font-style: normal;
|
49
|
+
font-weight: 400;
|
50
|
+
line-height: 29.7px
|
51
|
+
}
|
52
|
+
|
53
|
+
html, body {
|
54
|
+
width: 100%
|
55
|
+
}
|
56
|
+
|
57
|
+
html {
|
58
|
+
height: 100%
|
59
|
+
}
|
60
|
+
|
61
|
+
body {
|
62
|
+
background: #fff;
|
63
|
+
color: #1a1919;
|
64
|
+
padding: 36px
|
65
|
+
}
|
66
|
+
|
67
|
+
.commit {
|
68
|
+
min-width: 100%;
|
69
|
+
border-radius: 3.5px;
|
70
|
+
overflow: hidden;
|
71
|
+
display: inline-block;
|
72
|
+
line-height: 15px;
|
73
|
+
font-family: Menlo, Monaco, Consolas, "Courier New", monospace;
|
74
|
+
border: 1px solid #BCC6CC;
|
75
|
+
}
|
76
|
+
|
77
|
+
.commit * {
|
78
|
+
padding-left: 4px;
|
79
|
+
font-size: 8px;
|
80
|
+
line-height: 15px;
|
81
|
+
}
|
82
|
+
</style>
|
83
|
+
<title>SVN log</title>
|
84
|
+
</head>
|
85
|
+
<body>
|
86
|
+
<p>Hi,</p>
|
87
|
+
<p>The following file(s) contain text <code><%= text %></code> in
|
88
|
+
<a href="<%= svn_url %>"><%= svn_url %></a>:</p>
|
89
|
+
<% entries.each do |commit| %>
|
90
|
+
<div class="commit">
|
91
|
+
<p style="background: gainsboro;">
|
92
|
+
<a href="<%= commit_url %><%= commit.rev %>"><%= commit.msg %></a>
|
93
|
+
by <a href="<%= user %><%= commit.author %>"><%= commit.author %></a>
|
94
|
+
at <span style="color: #275a90;"><%= commit.time %></span>
|
95
|
+
</p>
|
96
|
+
<% commit.diff(text.split(",")).each do |line| %>
|
97
|
+
<% if line.start_with?("+++") || line.start_with?("---") %>
|
98
|
+
<p style="background: gainsboro;"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
99
|
+
<% elsif text.split(",").any? { |t| line.include? t } %>
|
100
|
+
<p style="background: #F9F103;"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
101
|
+
<% elsif line.start_with?("+") %>
|
102
|
+
<p style="<%= "background: darkseagreen;" %>"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
103
|
+
<% elsif line.start_with?("-") %>
|
104
|
+
<p style="<%= "background: lightsalmon;" %>"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
105
|
+
<% else %>
|
106
|
+
<p style="background: gainsboro;"><%= line.gsub(/[<>]/, '<' => '<', '>' => '>') %></p>
|
107
|
+
<% end %>
|
108
|
+
<% end %>
|
109
|
+
</div>
|
110
|
+
<% end %>
|
111
|
+
<p>Posted by<a href="https://github.com/dgroup/lazylead">lazylead
|
112
|
+
v<%= version %></a>.</p>
|
113
|
+
</body>
|
114
|
+
</html>
|
data/test/lazylead/cc_test.rb
CHANGED
data/test/lazylead/model_test.rb
CHANGED
@@ -72,5 +72,25 @@ module Lazylead
|
|
72
72
|
)
|
73
73
|
assert_equal "value", ORM::Task.find(171).props["envkey"]
|
74
74
|
end
|
75
|
+
|
76
|
+
test "task properties are parsed despite on wrong config" do
|
77
|
+
CLI::App.new(Log.new, NoSchedule.new).run(
|
78
|
+
home: ".",
|
79
|
+
sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
|
80
|
+
vcs4sql: "upgrades/sqlite",
|
81
|
+
testdata: true
|
82
|
+
)
|
83
|
+
refute ORM::Task.find(260).to_h?
|
84
|
+
end
|
85
|
+
|
86
|
+
test "second ticketing system is found" do
|
87
|
+
CLI::App.new(Log.new, NoSchedule.new).run(
|
88
|
+
home: ".",
|
89
|
+
sqlite: "test/resources/#{no_ext(__FILE__)}.#{__method__}.db",
|
90
|
+
vcs4sql: "upgrades/sqlite",
|
91
|
+
testdata: true
|
92
|
+
)
|
93
|
+
assert_kind_of Jira, ORM::Task.find(270).second_sys
|
94
|
+
end
|
75
95
|
end
|
76
96
|
end
|