rocketjob_mission_control 6.0.2 → 6.0.6
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/app/controllers/rocket_job_mission_control/application_controller.rb +1 -1
- data/app/helpers/rocket_job_mission_control/application_helper.rb +2 -2
- data/app/models/rocket_job_mission_control/job_sanitizer.rb +5 -0
- data/app/views/rocket_job_mission_control/active_workers/index.html.erb +1 -1
- data/app/views/rocket_job_mission_control/dirmon_entries/_details.html.erb +33 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_exception.html.erb +22 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/_properties.html.erb +28 -0
- data/app/views/rocket_job_mission_control/dirmon_entries/index.html.erb +1 -1
- data/app/views/rocket_job_mission_control/dirmon_entries/show.html.erb +29 -36
- data/app/views/rocket_job_mission_control/jobs/_exceptions.html.erb +1 -1
- data/app/views/rocket_job_mission_control/jobs/index.html.erb +1 -1
- data/app/views/rocket_job_mission_control/servers/index.html.erb +1 -1
- data/lib/rocket_job_mission_control/version.rb +1 -1
- data/test/controllers/rocket_job_mission_control/dirmon_entries_controller_test.rb +13 -13
- data/test/models/rocket_job_mission_control/job_sanitizer_test.rb +9 -0
- metadata +5 -3
- data/app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 64d809575f0731bda365856d8cf93dad699b71f7d5ba574b9d2713270046f8a6
|
4
|
+
data.tar.gz: fe2d64d5aa3eea4da219c672af3c3a014d4f41dacfcc6dc53967fee9b8dc6b21
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 61995bb1057a2fdd7f126c61d0a59ed4c8eed93b526de01c87ce8cecbaa903da056a39ff19d7ea462ffaad20cb86960b7835450d9c9174b824c103429c621558
|
7
|
+
data.tar.gz: 7f5acb288556ec3f6683471c8dbd8fcd75408f39b605e844f2a5892e381ff10abe48ed3d2a945083d7d4d3e0febd87f60bc76ed29fe46840f396028477b3ee11
|
@@ -92,8 +92,8 @@ module RocketJobMissionControl
|
|
92
92
|
"[JSON Hash]\n".html_safe +
|
93
93
|
f.text_field(field_name, value: value ? value.to_json : "", class: "form-control", placeholder: '{"key1":"value1", "key2":"value2", "key3":"value3"}')
|
94
94
|
when "Array"
|
95
|
-
options = value.present? ? Array(value) :
|
96
|
-
f.
|
95
|
+
options = value.present? ? Array(value) : []
|
96
|
+
f.select(field_name, options_for_select(options, options), {include_hidden: true}, {class: "selectize form-control", multiple: true})
|
97
97
|
else
|
98
98
|
"[#{field.type.name}]".html_safe +
|
99
99
|
f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
|
@@ -36,6 +36,11 @@ module RocketJobMissionControl
|
|
36
36
|
target.errors.add(:properties, e.message)
|
37
37
|
value = nil
|
38
38
|
end
|
39
|
+
when "Array"
|
40
|
+
# remove blank entries from rails converted arrays when using multi-select input
|
41
|
+
if !value.blank?
|
42
|
+
value.reject! { |v| v.empty? }
|
43
|
+
end
|
39
44
|
end
|
40
45
|
|
41
46
|
if value.blank? && !value.is_a?(Hash)
|
@@ -20,7 +20,7 @@
|
|
20
20
|
</div>
|
21
21
|
</div>
|
22
22
|
|
23
|
-
<table class='table datatable active-workers-datatable' data-source='<%= active_workers_url(format: 'json') %>' style='width: 100%'>
|
23
|
+
<table class='table datatable active-workers-datatable' data-turbolinks='false' data-source='<%= active_workers_url(format: 'json') %>' style='width: 100%'>
|
24
24
|
<thead>
|
25
25
|
<tr>
|
26
26
|
<th>Worker Name</th>
|
@@ -0,0 +1,33 @@
|
|
1
|
+
<div class='lead'>Details:</div>
|
2
|
+
<div class='row'>
|
3
|
+
<div class='col-md-12 job-status'>
|
4
|
+
<table>
|
5
|
+
<tr>
|
6
|
+
<td><label>State:</label></td>
|
7
|
+
<td>
|
8
|
+
<div class='job-state inline-block'>
|
9
|
+
<div class='left'>State</div>
|
10
|
+
<div class="<%= @dirmon_entry.state %> right"><%= @dirmon_entry.state %></div>
|
11
|
+
</div>
|
12
|
+
</td>
|
13
|
+
</tr>
|
14
|
+
<tr>
|
15
|
+
<td><label>Job Class:</label></td>
|
16
|
+
<td><%= @dirmon_entry.job_class_name %></td>
|
17
|
+
</tr>
|
18
|
+
<tr>
|
19
|
+
<td><label>Pattern:</label></td>
|
20
|
+
<td><%= @dirmon_entry.pattern %></td>
|
21
|
+
</tr>
|
22
|
+
<tr>
|
23
|
+
<td><label>Archive Directory:</label></td>
|
24
|
+
<td><%= @dirmon_entry.archive_directory %></td>
|
25
|
+
</tr>
|
26
|
+
<tr>
|
27
|
+
<td><label>ID:</label></td>
|
28
|
+
<td><%= @dirmon_entry.id %></td>
|
29
|
+
</tr>
|
30
|
+
</table>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<br/>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<div class='lead'>Exception:</div>
|
2
|
+
<div class='row'>
|
3
|
+
<div class='col-md-12'>
|
4
|
+
<table>
|
5
|
+
<tr>
|
6
|
+
<td><label>Exception:</label></td>
|
7
|
+
<td><%= @dirmon_entry.exception.class_name %></td>
|
8
|
+
</tr>
|
9
|
+
<tr>
|
10
|
+
<td><label>Message:</label></td>
|
11
|
+
<td><%= @dirmon_entry.exception.message %></td>
|
12
|
+
</tr>
|
13
|
+
<% if @dirmon_entry.exception.backtrace.present? %>
|
14
|
+
<tr>
|
15
|
+
<td><label>Backtrace:</label></td>
|
16
|
+
<td><%= @dirmon_entry.exception.backtrace.ai(html: true, plain: true) %></td>
|
17
|
+
</tr>
|
18
|
+
<% end %>
|
19
|
+
</table>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<br/>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<div class='lead'>Properties:</div>
|
2
|
+
<div class='row'>
|
3
|
+
<div class='col-md-12'>
|
4
|
+
<table>
|
5
|
+
<% @dirmon_entry.properties.keys.sort.each do |key| %>
|
6
|
+
<%
|
7
|
+
value = @dirmon_entry.properties[key]
|
8
|
+
key = key.to_s.titleize
|
9
|
+
%>
|
10
|
+
<tr>
|
11
|
+
<td><label><%= key %>:</label></td>
|
12
|
+
<% if value.nil? %>
|
13
|
+
<td><label>nil</label></td>
|
14
|
+
<% else %>
|
15
|
+
<td>
|
16
|
+
<% if value.is_a?(String) %>
|
17
|
+
<pre><code><%= simple_format(value) %></code></pre>
|
18
|
+
<% else %>
|
19
|
+
<%= value.ai(html: true, plain: true) %>
|
20
|
+
<% end %>
|
21
|
+
</td>
|
22
|
+
<% end %>
|
23
|
+
</tr>
|
24
|
+
<% end %>
|
25
|
+
</table>
|
26
|
+
</div>
|
27
|
+
</div>
|
28
|
+
<br/>
|
@@ -12,7 +12,7 @@
|
|
12
12
|
</div>
|
13
13
|
</div>
|
14
14
|
|
15
|
-
<table class='table datatable dirmon-datatable' data-source='<%= @data_table_url %>' style='width: 100%'>
|
15
|
+
<table class='table datatable dirmon-datatable' data-turbolinks='false' data-source='<%= @data_table_url %>' style='width: 100%'>
|
16
16
|
<thead>
|
17
17
|
<tr>
|
18
18
|
<th>Name</th>
|
@@ -1,43 +1,36 @@
|
|
1
|
-
<div class='
|
1
|
+
<div class='row'>
|
2
2
|
<div id='job'>
|
3
|
-
<div class='lead'><%= @dirmon_entry.name
|
4
|
-
|
5
|
-
<div class='job-state inline-block'>
|
6
|
-
<div class='left'>status</div>
|
7
|
-
<div class="<%= @dirmon_entry.state %> right"><%= @dirmon_entry.state %></div>
|
8
|
-
</div>
|
9
|
-
|
10
|
-
<div class='btn-toolbar job-actions'>
|
11
|
-
<div class='btn-group'>
|
12
|
-
<% if (@dirmon_entry.disabled? || @dirmon_entry.pending?) && can?(:enable, @dirmon_entry) %>
|
13
|
-
<%= link_to 'Enable', enable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: 'btn btn-default' %>
|
14
|
-
<% end %>
|
15
|
-
<% if @dirmon_entry.enabled? && can?(:disable, @dirmon_entry)%>
|
16
|
-
<%= link_to 'Disable', disable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: 'btn btn-default', data: { confirm: 'Are you sure?' } %>
|
17
|
-
<% end %>
|
18
|
-
</div>
|
3
|
+
<div class='lead'><%= image_tag('rocket_job_mission_control/rocket-icon-64x64.png') %><%= @dirmon_entry.name %>
|
19
4
|
|
5
|
+
<div class='btn-toolbar job-actions'>
|
6
|
+
<div class='btn-group'>
|
7
|
+
<% if @dirmon_entry.may_enable? && can?(:enable, @dirmon_entry) %>
|
8
|
+
<%= link_to 'Enable', enable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: 'btn btn-default', data: {confirm: 'Are you sure you want to enable this Dirmon Entry?'} %>
|
9
|
+
<% end %>
|
10
|
+
<% if @dirmon_entry.may_disable? && can?(:disable, @dirmon_entry) %>
|
11
|
+
<%= link_to 'Disable', disable_dirmon_entry_path(@dirmon_entry.id), method: :put, class: 'btn btn-default', data: {confirm: 'Are you sure you want to disable this Dirmon Entry?'} %>
|
12
|
+
<% end %>
|
13
|
+
</div>
|
20
14
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
15
|
+
<div class='btn-group'>
|
16
|
+
<% if can?(:destroy, @dirmon_entry) %>
|
17
|
+
<%= link_to 'Destroy', dirmon_entry_path(@dirmon_entry), method: :delete, class: 'btn btn-default', data: {confirm: 'Are you sure?'} %>
|
18
|
+
<% end %>
|
19
|
+
</div>
|
20
|
+
<div class='btn-group'>
|
21
|
+
<% if can?(:copy, @dirmon_entry) %>
|
22
|
+
<%= link_to 'Copy', copy_dirmon_entry_path(@dirmon_entry), class: 'btn btn-default' %>
|
23
|
+
<% end %>
|
24
|
+
</div>
|
25
|
+
<div class='btn-group'>
|
26
|
+
<% if can?(:edit, @dirmon_entry) %>
|
27
|
+
<%= link_to 'Edit', edit_dirmon_entry_path(@dirmon_entry), class: 'btn btn-default' %>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
36
30
|
</div>
|
37
31
|
</div>
|
38
|
-
|
39
|
-
<div class='clearfix'></div>
|
40
|
-
|
41
|
-
<%= render partial: 'status', locals: {dirmon_entry: @job} %>
|
42
32
|
</div>
|
43
33
|
</div>
|
34
|
+
<%= render partial: 'details', locals: {dirmon_entry: @dirmon_entry} %>
|
35
|
+
<%= render partial: 'properties', locals: {dirmon_entry: @dirmon_entry} %>
|
36
|
+
<%= render partial: 'exception', locals: {dirmon_entry: @dirmon_entry} if @dirmon_entry.exception %>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<table class='table datatable jobs-datatable' data-source='<%= jobs_url(format: 'json') %>' style='width: 100%'>
|
1
|
+
<table class='table datatable jobs-datatable' data-turbolinks='false' data-source='<%= jobs_url(format: 'json') %>' style='width: 100%'>
|
2
2
|
<thead>
|
3
3
|
<tr>
|
4
4
|
<th>Count</th>
|
@@ -16,7 +16,7 @@
|
|
16
16
|
</div>
|
17
17
|
|
18
18
|
<div class="panel-body">
|
19
|
-
<table class='table datatable jobs-datatable' data-source='<%= @data_table_url %>' style='width: 100%'>
|
19
|
+
<table class='table datatable jobs-datatable' data-turbolinks='false' data-source='<%= @data_table_url %>' style='width: 100%'>
|
20
20
|
<thead>
|
21
21
|
<tr>
|
22
22
|
<% @columns.each do |column| %>
|
@@ -35,7 +35,7 @@
|
|
35
35
|
</div>
|
36
36
|
</div>
|
37
37
|
|
38
|
-
<table class='table datatable servers-datatable' data-source='<%= @data_table_url %>' style='width: 100%'>
|
38
|
+
<table class='table datatable servers-datatable' data-turbolinks='false' data-source='<%= @data_table_url %>' style='width: 100%'>
|
39
39
|
<thead>
|
40
40
|
<tr>
|
41
41
|
<th>Hostname : PID</th>
|
@@ -15,9 +15,9 @@ module RocketJobMissionControl
|
|
15
15
|
|
16
16
|
let :existing_dirmon_entry do
|
17
17
|
RocketJob::DirmonEntry.create!(
|
18
|
-
name: "
|
18
|
+
name: "Existing path test",
|
19
19
|
job_class_name: job_class_name,
|
20
|
-
pattern: "
|
20
|
+
pattern: "existing_path"
|
21
21
|
)
|
22
22
|
end
|
23
23
|
|
@@ -26,9 +26,9 @@ module RocketJobMissionControl
|
|
26
26
|
let :one_dirmon_entry_for_every_state do
|
27
27
|
dirmon_entry_states.collect do |state|
|
28
28
|
RocketJob::DirmonEntry.create!(
|
29
|
-
name: "
|
29
|
+
name: "Test_for_state_#{state}",
|
30
30
|
job_class_name: job_class_name,
|
31
|
-
pattern: "
|
31
|
+
pattern: "path_for_state_#{state}",
|
32
32
|
state: state
|
33
33
|
)
|
34
34
|
end
|
@@ -375,27 +375,27 @@ module RocketJobMissionControl
|
|
375
375
|
json = JSON.parse(response.body)
|
376
376
|
expected_data = {
|
377
377
|
pending: {
|
378
|
-
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.pending.first.id}\">\n <i class=\"fas fa-inbox pending\" style=\"font-size: 75%\" title=\"pending\"></i>\n
|
378
|
+
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.pending.first.id}\">\n <i class=\"fas fa-inbox pending\" style=\"font-size: 75%\" title=\"pending\"></i>\n Test_for_state_pending\n </a>\n",
|
379
379
|
"1" => "RocketJob::Jobs::SimpleJob",
|
380
|
-
"2" => "
|
380
|
+
"2" => "path_for_state_pending",
|
381
381
|
"DT_RowClass" => "card callout callout-pending"
|
382
382
|
},
|
383
383
|
enabled: {
|
384
|
-
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.enabled.first.id}\">\n <i class=\"fas fa-check enabled\" style=\"font-size: 75%\" title=\"enabled\"></i>\n
|
384
|
+
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.enabled.first.id}\">\n <i class=\"fas fa-check enabled\" style=\"font-size: 75%\" title=\"enabled\"></i>\n Test_for_state_enabled\n </a>\n",
|
385
385
|
"1" => "RocketJob::Jobs::SimpleJob",
|
386
|
-
"2" => "
|
386
|
+
"2" => "path_for_state_enabled",
|
387
387
|
"DT_RowClass" => "card callout callout-enabled"
|
388
388
|
},
|
389
389
|
failed: {
|
390
|
-
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.failed.first.id}\">\n <i class=\"fas fa-exclamation-triangle failed\" style=\"font-size: 75%\" title=\"failed\"></i>\n
|
390
|
+
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.failed.first.id}\">\n <i class=\"fas fa-exclamation-triangle failed\" style=\"font-size: 75%\" title=\"failed\"></i>\n Test_for_state_failed\n </a>\n",
|
391
391
|
"1" => "RocketJob::Jobs::SimpleJob",
|
392
|
-
"2" => "
|
392
|
+
"2" => "path_for_state_failed",
|
393
393
|
"DT_RowClass" => "card callout callout-failed"
|
394
394
|
},
|
395
395
|
disabled: {
|
396
|
-
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.disabled.first.id}\">\n <i class=\"fas fa-stop disabled\" style=\"font-size: 75%\" title=\"disabled\"></i>\n
|
396
|
+
"0" => " <a href=\"/dirmon_entries/#{RocketJob::DirmonEntry.disabled.first.id}\">\n <i class=\"fas fa-stop disabled\" style=\"font-size: 75%\" title=\"disabled\"></i>\n Test_for_state_disabled\n </a>\n",
|
397
397
|
"1" => "RocketJob::Jobs::SimpleJob",
|
398
|
-
"2" => "
|
398
|
+
"2" => "path_for_state_disabled",
|
399
399
|
"DT_RowClass" => "card callout callout-disabled"
|
400
400
|
}
|
401
401
|
}
|
@@ -404,7 +404,7 @@ module RocketJobMissionControl
|
|
404
404
|
assert_equal 0, json["draw"]
|
405
405
|
assert_equal 4, json["recordsTotal"]
|
406
406
|
assert_equal 4, json["recordsFiltered"]
|
407
|
-
assert_equal [expected_data[:
|
407
|
+
assert_equal [expected_data[:disabled], expected_data[:enabled], expected_data[:failed], expected_data[:pending]], json["data"]
|
408
408
|
else
|
409
409
|
assert_equal 0, json["draw"]
|
410
410
|
assert_equal 1, json["recordsTotal"]
|
@@ -92,6 +92,15 @@ class JobSanitizerTest < Minitest::Test
|
|
92
92
|
assert_equal 0, @job.errors.count
|
93
93
|
assert_equal({hash_field: {}}, cleansed)
|
94
94
|
end
|
95
|
+
|
96
|
+
it "removes blank entries from rails converted arrays when using multi-select input" do
|
97
|
+
properties = {
|
98
|
+
array: ["", "rf@exp.com", "rm@exp.com", "lb@exp.com"]
|
99
|
+
}
|
100
|
+
cleansed = RocketJobMissionControl::JobSanitizer.sanitize(properties, @job.class, @job, false)
|
101
|
+
assert_equal 0, @job.errors.count
|
102
|
+
assert_equal({array: ["rf@exp.com", "rm@exp.com", "lb@exp.com"]}, cleansed)
|
103
|
+
end
|
95
104
|
end
|
96
105
|
end
|
97
106
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rocketjob_mission_control
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 6.0.
|
4
|
+
version: 6.0.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Michael Cloutier
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2021-
|
14
|
+
date: 2021-11-30 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: access-granted
|
@@ -166,13 +166,15 @@ files:
|
|
166
166
|
- app/views/layouts/rocket_job_mission_control/partials/_header.html.erb
|
167
167
|
- app/views/layouts/rocket_job_mission_control/partials/_sidebar.html.erb
|
168
168
|
- app/views/rocket_job_mission_control/active_workers/index.html.erb
|
169
|
+
- app/views/rocket_job_mission_control/dirmon_entries/_details.html.erb
|
170
|
+
- app/views/rocket_job_mission_control/dirmon_entries/_exception.html.erb
|
169
171
|
- app/views/rocket_job_mission_control/dirmon_entries/_form.html.erb
|
170
172
|
- app/views/rocket_job_mission_control/dirmon_entries/_input_categories.html.erb
|
171
173
|
- app/views/rocket_job_mission_control/dirmon_entries/_input_category_fields.html.erb
|
172
174
|
- app/views/rocket_job_mission_control/dirmon_entries/_output_categories.html.erb
|
173
175
|
- app/views/rocket_job_mission_control/dirmon_entries/_output_category_fields.html.erb
|
176
|
+
- app/views/rocket_job_mission_control/dirmon_entries/_properties.html.erb
|
174
177
|
- app/views/rocket_job_mission_control/dirmon_entries/_sidebar.html.erb
|
175
|
-
- app/views/rocket_job_mission_control/dirmon_entries/_status.html.erb
|
176
178
|
- app/views/rocket_job_mission_control/dirmon_entries/copy.html.erb
|
177
179
|
- app/views/rocket_job_mission_control/dirmon_entries/edit.html.erb
|
178
180
|
- app/views/rocket_job_mission_control/dirmon_entries/index.html.erb
|
@@ -1,26 +0,0 @@
|
|
1
|
-
<div class='row'>
|
2
|
-
<div class='col-md-12'>
|
3
|
-
<div><label>Job Class:</label><%= @dirmon_entry.job_class_name %></div>
|
4
|
-
<div><label>Pattern:</label><%= @dirmon_entry.pattern %></div>
|
5
|
-
<div><label>Archive Directory:</label><%= @dirmon_entry.archive_directory %></div>
|
6
|
-
<div class='id'><label>ID:</label><%= @dirmon_entry.id %></div>
|
7
|
-
</div>
|
8
|
-
</div>
|
9
|
-
|
10
|
-
<div class='lead'>Properties</div>
|
11
|
-
<div class='row'>
|
12
|
-
<div class='col-md-12'>
|
13
|
-
<% @dirmon_entry.properties.keys.sort.each do |name| %>
|
14
|
-
<% value = @dirmon_entry.properties[name] %>
|
15
|
-
<div class='parameters'>
|
16
|
-
<label><%= name.to_s.titleize %>:</label>
|
17
|
-
|
18
|
-
<% if value.is_a?(Array) || value.is_a?(Hash) %>
|
19
|
-
<pre><code><%= pretty_print_array_or_hash(value) %></code></pre>
|
20
|
-
<% else %>
|
21
|
-
<%= value %>
|
22
|
-
<% end %>
|
23
|
-
</div>
|
24
|
-
<% end %>
|
25
|
-
</div>
|
26
|
-
</div>
|