admin_tools_ennder 1.3.20
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 +7 -0
- data/Changelog +158 -0
- data/MIT-LICENSE +20 -0
- data/README.md +89 -0
- data/Rakefile +2 -0
- data/TODO +0 -0
- data/app/controllers/admin_dev_infos_controller.rb +46 -0
- data/app/controllers/admin_gems_controller.rb +24 -0
- data/app/controllers/admin_inflexions_controller.rb +6 -0
- data/app/controllers/admin_menu_controller.rb +2 -0
- data/app/controllers/admin_routes_controller.rb +21 -0
- data/app/controllers/admin_send_file_controller.rb +8 -0
- data/app/controllers/admin_translations_controller.rb +21 -0
- data/app/controllers/admin_url_infos_controller.rb +7 -0
- data/app/controllers/application_controller.rb +10 -0
- data/app/controllers/commands_controller.rb +152 -0
- data/app/controllers/gmm_controller.rb +27 -0
- data/app/controllers/processus_controller.rb +8 -0
- data/app/helpers/application_helper.rb +11 -0
- data/app/metal/metal_processus_liste.rb +13 -0
- data/app/models/command.rb +5 -0
- data/app/views/admin_dev_infos/index.html.erb +7 -0
- data/app/views/admin_dev_infos/show.html.erb +43 -0
- data/app/views/admin_gems/_gem_infos.html.erb +46 -0
- data/app/views/admin_gems/index.html.erb +3 -0
- data/app/views/admin_inflexions/index.html.erb +41 -0
- data/app/views/admin_menu/index.html.erb +29 -0
- data/app/views/admin_routes/index.html.erb +64 -0
- data/app/views/admin_send_file/index.html.erb +7 -0
- data/app/views/admin_translations/index.html.erb +128 -0
- data/app/views/admin_url_infos/index.html.erb +91 -0
- data/app/views/commands/_execute_results.html.erb +10 -0
- data/app/views/commands/execute.html.erb +10 -0
- data/app/views/commands/executed.html.erb +12 -0
- data/app/views/commands/index.html.erb +24 -0
- data/app/views/commands/new.html.erb +15 -0
- data/app/views/commands/show.html.erb +10 -0
- data/app/views/common/_error_messages.html.erb +10 -0
- data/app/views/common/_top_menu.html.erb +2 -0
- data/app/views/gmm/index.html.erb +34 -0
- data/app/views/processus/index.html.erb +9 -0
- data/config/routes.rb +75 -0
- data/db/migrate/20100422173622_create_commands.rb +13 -0
- data/db/migrate/rails_before_5/20100422173622_create_commands.rb +13 -0
- data/lib/admin_tools_ennder.rb +77 -0
- data/lib/admin_tools_ennder/engine.rb +7 -0
- data/lib/gtm.rb +75 -0
- data/lib/tasks/admin_tools_ennder_tasks.rake +11 -0
- data/test/admin_tools_ennder_test.rb +8 -0
- data/test/test_helper.rb +3 -0
- metadata +95 -0
@@ -0,0 +1,91 @@
|
|
1
|
+
<%= render :partial => 'common/top_menu' %>
|
2
|
+
|
3
|
+
Infos sur la page courante (pour l'instant on ne peut pas changer la page)<br/>
|
4
|
+
|
5
|
+
<p>
|
6
|
+
<b>host</b> - The hostname used for this request.<br/>
|
7
|
+
[<span id="host"><%=h request.host %></span>]
|
8
|
+
</p>
|
9
|
+
|
10
|
+
<p>
|
11
|
+
<b>referer</b> - The full URL from the page calling this page.<br/>
|
12
|
+
[<%=h request.referer %>]
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
<b>domain</b> - The hostname without the first part (usually "www").<br/>
|
17
|
+
[<%=h request.domain %>]
|
18
|
+
</p>
|
19
|
+
|
20
|
+
<p>
|
21
|
+
<b>format</b> - The content type requested by the client.<br/>
|
22
|
+
[<%=h request.format %>]
|
23
|
+
</p>
|
24
|
+
|
25
|
+
<p>
|
26
|
+
<b>method</b> - The HTTP method used for the request.<br/>
|
27
|
+
[<%=h request.method %>]
|
28
|
+
</p>
|
29
|
+
|
30
|
+
<p>
|
31
|
+
<b>get?, post?, put?, delete?, head?</b> - Returns true if the HTTP method is get/post/put/delete/head.<br/>
|
32
|
+
[<%=h request.get? %>]<br/>
|
33
|
+
[<%=h request.post? %>]<br/>
|
34
|
+
[<%=h request.put? %>]<br/>
|
35
|
+
[<%=h request.delete? %>]<br/>
|
36
|
+
[<%=h request.head? %>]
|
37
|
+
</p>
|
38
|
+
|
39
|
+
<p>
|
40
|
+
<b>xhr?</b> - Returns true if the request is an AJAX request.<br/>
|
41
|
+
[<%=h request.xhr? %>]
|
42
|
+
</p>
|
43
|
+
|
44
|
+
<p>
|
45
|
+
<b>headers</b> - Returns a hash containing the headers associated with the request.<br/>
|
46
|
+
[<%=h request.headers %>]
|
47
|
+
</p>
|
48
|
+
|
49
|
+
<p>
|
50
|
+
<b>port</b> - The port number (integer) used for the request.<br/>
|
51
|
+
[<%=h request.port %>]
|
52
|
+
</p>
|
53
|
+
|
54
|
+
<p>
|
55
|
+
<b>protocol</b> - The protocol used for the request.<br/>
|
56
|
+
[<%=h request.protocol %>]
|
57
|
+
</p>
|
58
|
+
|
59
|
+
<p>
|
60
|
+
<b>query_string</b> - The query string part of the URL - everything after "?".<br/>
|
61
|
+
[<%=h request.query_string %>]
|
62
|
+
</p>
|
63
|
+
|
64
|
+
<p>
|
65
|
+
<b>remote_ip</b> - The IP address of the client.<br/>
|
66
|
+
[<%=h request.remote_ip %>]
|
67
|
+
</p>
|
68
|
+
|
69
|
+
<p>
|
70
|
+
<b>url</b> - The entire URL used for the request.<br/>
|
71
|
+
[<%=h request.url %>]
|
72
|
+
</p>
|
73
|
+
|
74
|
+
<p>
|
75
|
+
<b>request_uri</b>/<b>fullpath</b>(Rails 3) - Returns the full local request URL.<br/>
|
76
|
+
<% if Rails::VERSION::MAJOR < 3 %>
|
77
|
+
[<%=h request.request_uri %>]
|
78
|
+
<% else %>
|
79
|
+
[<%=h request.fullpath %>]
|
80
|
+
<% end %>
|
81
|
+
</p>
|
82
|
+
|
83
|
+
<p>
|
84
|
+
<b>ssl?</b> - Returns true if it's an HTTPS / SSL request.<br/>
|
85
|
+
[<%=h request.ssl? %>]
|
86
|
+
</p>
|
87
|
+
|
88
|
+
<p>
|
89
|
+
<b>subdomains</b> - Returns an array of subdomains that you could use as part of your authentication scheme.<br/>
|
90
|
+
[<%=h request.subdomains %>]
|
91
|
+
</p>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= link_to 'Retour au menu', :controller => :admin_menu %><br/>
|
2
|
+
<br/>
|
3
|
+
<%= link_to 'Nouvelle', new_command_path %> |
|
4
|
+
<%= link_to 'Historique des commandes', commands_path %> |
|
5
|
+
<%= link_to 'Executer', execute_command_path(@command) %>
|
6
|
+
|
7
|
+
<p>
|
8
|
+
<b>Commande à executer :</b>
|
9
|
+
<%=@command.execute %>
|
10
|
+
</p>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<%= link_to 'Retour au menu', :controller => :admin_menu %><br/>
|
2
|
+
<br/>
|
3
|
+
<%= link_to 'Autre', new_command_path %> |
|
4
|
+
<%= link_to 'Historique des commandes', commands_path %> |
|
5
|
+
<%= link_to 'Executer', execute_command_path(@command) %>
|
6
|
+
|
7
|
+
<p>
|
8
|
+
<b>Command executée :</b>
|
9
|
+
<%=h @command.execute %>
|
10
|
+
</p>
|
11
|
+
|
12
|
+
<%= render :partial => 'execute_results' %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<%= render :partial => 'common/top_menu' %>
|
2
|
+
|
3
|
+
<%= link_to 'Nouvelle commande', new_command_path %><br/>
|
4
|
+
<br/>
|
5
|
+
[<%= @commands_nb %>] commande(s)<br/>
|
6
|
+
|
7
|
+
<br/>
|
8
|
+
<%#= will_paginate @commands %><br/>
|
9
|
+
|
10
|
+
<table>
|
11
|
+
<tr>
|
12
|
+
<th>Commande</th>
|
13
|
+
<th>Executée à</th>
|
14
|
+
<th>actions</th>
|
15
|
+
</tr>
|
16
|
+
|
17
|
+
<% for _command in @commands %>
|
18
|
+
<tr>
|
19
|
+
<td><%=h _command.execute %></td>
|
20
|
+
<td><%=h _command.created_at %></td>
|
21
|
+
<td><%= link_to 'Voir', _command %> | <%= link_to 'Supprimer', _command, :confirm => 'Êtes vous sur(e)?', :method => :delete %> | <%= link_to 'Executer', execute_command_path(_command) %> </td>
|
22
|
+
</tr>
|
23
|
+
<% end %>
|
24
|
+
</table>
|
@@ -0,0 +1,15 @@
|
|
1
|
+
<%= link_to 'Historique des commandes', commands_path %>
|
2
|
+
<br/>
|
3
|
+
<%= form_for(@command) do |f| %>
|
4
|
+
<%= render :partial => '/common/error_messages', :locals => {:model => @command} %>
|
5
|
+
<p>
|
6
|
+
<%= f.text_field :execute %>
|
7
|
+
</p>
|
8
|
+
<p>
|
9
|
+
<%= f.submit 'Execute' %>
|
10
|
+
</p>
|
11
|
+
<% end %>
|
12
|
+
|
13
|
+
<hr>
|
14
|
+
|
15
|
+
<%= render :partial => 'execute_results' %>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<%= link_to 'Retour au menu', :controller => :admin_menu %><br/>
|
2
|
+
<br/>
|
3
|
+
<%= link_to 'Autre', new_command_path %> |
|
4
|
+
<%= link_to 'Historique des commandes', commands_path %> |
|
5
|
+
<%= link_to 'Executer', execute_command_path(@command) %>
|
6
|
+
|
7
|
+
<p>
|
8
|
+
<b>Commande déjà exécutée :</b>
|
9
|
+
<%=h @command.execute %>
|
10
|
+
</p>
|
@@ -0,0 +1,10 @@
|
|
1
|
+
<% if model && model.errors.any? -%>
|
2
|
+
<div id="errorExplanation">
|
3
|
+
<h2><%= pluralize(model.errors.count, "erreur") %> a empêché cet enregistrement d'être sauvegardé :</h2>
|
4
|
+
<ul>
|
5
|
+
<% model.errors.full_messages.each do |msg| %>
|
6
|
+
<li><%= msg %></li>
|
7
|
+
<% end %>
|
8
|
+
</ul>
|
9
|
+
</div>
|
10
|
+
<% end -%>
|
@@ -0,0 +1,34 @@
|
|
1
|
+
<%= render :partial => 'common/top_menu' %>
|
2
|
+
|
3
|
+
<table border="2">
|
4
|
+
<thead>
|
5
|
+
<th>Model classes</th>
|
6
|
+
<th>Relation type</th>
|
7
|
+
<th>Relation</th>
|
8
|
+
</thead>
|
9
|
+
<%
|
10
|
+
@all_models.keys.sort.each_with_index{ |name, i|
|
11
|
+
relations = @all_models[name]
|
12
|
+
-%>
|
13
|
+
<tr>
|
14
|
+
<td colspan="3">[<%= i %>] <b><%= name %></b></td>
|
15
|
+
</tr>
|
16
|
+
<%
|
17
|
+
relations.each { |type, relations_of_type|
|
18
|
+
next if relations_of_type.empty?
|
19
|
+
-%>
|
20
|
+
<tr>
|
21
|
+
<td></td><td colspan="2"><%= type %> [<%= relations_of_type.size %>]</td>
|
22
|
+
</tr>
|
23
|
+
<%
|
24
|
+
relations_of_type.each { |r|
|
25
|
+
-%>
|
26
|
+
<tr>
|
27
|
+
<td></td><td><b><%= "#{type} :#{r.name}".html_safe %></b></td><td><%= r.inspect %></td>
|
28
|
+
</tr>
|
29
|
+
<%
|
30
|
+
}
|
31
|
+
} # relations.each
|
32
|
+
} # @all_models.keys.sort
|
33
|
+
-%>
|
34
|
+
</table>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= render :partial => 'common/top_menu' %>
|
2
|
+
|
3
|
+
<%= javascript_include_tag 'prototype' %>
|
4
|
+
|
5
|
+
<h1>Liste des Processus</h1>
|
6
|
+
|
7
|
+
<pre id="processus" style="width:100%; overflow:scroll">Collecte des informations...</pre>
|
8
|
+
|
9
|
+
<%= periodically_call_remote :url => '/admin/processus_liste', :update => 'processus', :frequency => 1, :method => :get %>
|
data/config/routes.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
|
3
|
+
if Rails::VERSION::MAJOR >= 4
|
4
|
+
begin
|
5
|
+
# puts "Engine admin_tools_ennder, config/routes.rb : [#{Rails.application.routes.routes.size}] route(s)"
|
6
|
+
|
7
|
+
_routes = Rails.application.routes
|
8
|
+
_nb_routes_avant = _routes.routes.size
|
9
|
+
|
10
|
+
_routes.draw do
|
11
|
+
resources :commands do
|
12
|
+
member do
|
13
|
+
get 'execute'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
#Le menu
|
18
|
+
match 'admin/menu' => 'admin_menu#index', :via => [:get]
|
19
|
+
match 'admin' => 'admin_menu#index', :via => [:get]
|
20
|
+
|
21
|
+
#Les outils
|
22
|
+
match 'admin/inflexions' => 'admin_inflexions#index', :via => [:get]
|
23
|
+
match 'admin/translations' => 'admin_translations#index', :via => [:get]
|
24
|
+
match 'admin/routes' => 'admin_routes#index', :via => [:get]
|
25
|
+
match 'admin/gems' => 'admin_gems#index', :via => [:get]
|
26
|
+
match 'admin/dev_infos' => 'admin_dev_infos#index', :via => [:get]
|
27
|
+
match 'admin/dev_infos/:id' => 'admin_dev_infos#show', :via => [:get]
|
28
|
+
match 'admin/url_infos' => 'admin_url_infos#index', :via => [:get]
|
29
|
+
match 'admin/commands' => 'commands#index', :via => [:get]
|
30
|
+
match 'admin/send_file' => 'admin_send_file#index', :via => [:get]
|
31
|
+
match 'admin/processus_liste' => 'processus#index', :via => [:get]
|
32
|
+
match 'admin/gmm' => 'gmm#index', :via => [:get]
|
33
|
+
end
|
34
|
+
|
35
|
+
puts "Engine admin_tools_ennder, config/routes.rb, Rails 4 : route(s) #{_nb_routes_avant} -> #{_routes.routes.size}"
|
36
|
+
rescue
|
37
|
+
puts "Engine admin_tools_ennder, config/routes.rb, Rails 4 : exception : #{$!}"
|
38
|
+
end
|
39
|
+
else
|
40
|
+
begin
|
41
|
+
# puts "Engine admin_tools_ennder, config/routes.rb : [#{Rails.application.routes.routes.size}] route(s)"
|
42
|
+
|
43
|
+
_routes = Rails.application.routes
|
44
|
+
_nb_routes_avant = _routes.routes.size
|
45
|
+
|
46
|
+
_routes.draw do
|
47
|
+
resources :commands do
|
48
|
+
member do
|
49
|
+
get 'execute'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
#Le menu
|
54
|
+
match 'admin/menu' => 'admin_menu#index'
|
55
|
+
match 'admin' => 'admin_menu#index'
|
56
|
+
|
57
|
+
#Les outils
|
58
|
+
match 'admin/inflexions' => 'admin_inflexions#index'
|
59
|
+
match 'admin/translations' => 'admin_translations#index'
|
60
|
+
match 'admin/routes' => 'admin_routes#index'
|
61
|
+
match 'admin/gems' => 'admin_gems#index'
|
62
|
+
match 'admin/dev_infos' => 'admin_dev_infos#index'
|
63
|
+
match 'admin/dev_infos/:id' => 'admin_dev_infos#show'
|
64
|
+
match 'admin/url_infos' => 'admin_url_infos#index'
|
65
|
+
match 'admin/commands' => 'commands#index'
|
66
|
+
match 'admin/send_file' => 'admin_send_file#index'
|
67
|
+
match 'admin/processus_liste' => 'processus#index'
|
68
|
+
match 'admin/gmm' => 'gmm#index'
|
69
|
+
end
|
70
|
+
|
71
|
+
puts "Engine admin_tools_ennder, config/routes.rb, Rails 3 : route(s) #{_nb_routes_avant} -> #{_routes.routes.size}"
|
72
|
+
rescue
|
73
|
+
puts "Engine admin_tools_ennder, config/routes.rb, Rails 3 : exception : #{$!}"
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
|
2
|
+
module AdminToolsEnnder
|
3
|
+
# :stopdoc:
|
4
|
+
LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
|
5
|
+
PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
|
6
|
+
|
7
|
+
@debug = false
|
8
|
+
if @debug
|
9
|
+
puts " admin_tools_ennder LIBPATH=#{LIBPATH}"
|
10
|
+
puts " PATH=#{PATH}"
|
11
|
+
end if
|
12
|
+
# :startdoc:
|
13
|
+
|
14
|
+
# Returns the version string for the library.
|
15
|
+
#
|
16
|
+
def self.version
|
17
|
+
@version ||= File.read(path('VERSION')).strip
|
18
|
+
end
|
19
|
+
|
20
|
+
# Returns the library path for the module. If any arguments are given,
|
21
|
+
# they will be joined to the end of the libray path using
|
22
|
+
# <tt>File.join</tt>.
|
23
|
+
#
|
24
|
+
def self.libpath( *args, &block )
|
25
|
+
rv = args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
|
26
|
+
if block
|
27
|
+
begin
|
28
|
+
$LOAD_PATH.unshift LIBPATH
|
29
|
+
rv = block.call
|
30
|
+
ensure
|
31
|
+
$LOAD_PATH.shift
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
puts " self.libpath ->#{rv}" if @debug
|
36
|
+
return rv
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the lpath for the module. If any arguments are given,
|
40
|
+
# they will be joined to the end of the path using
|
41
|
+
# <tt>File.join</tt>.
|
42
|
+
#
|
43
|
+
def self.path( *args, &block )
|
44
|
+
rv = args.empty? ? PATH : ::File.join(PATH, args.flatten)
|
45
|
+
if block
|
46
|
+
begin
|
47
|
+
$LOAD_PATH.unshift PATH
|
48
|
+
rv = block.call
|
49
|
+
ensure
|
50
|
+
$LOAD_PATH.shift
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
puts " self.path ->#{rv}" if @debug
|
55
|
+
return rv
|
56
|
+
end
|
57
|
+
|
58
|
+
# Utility method used to require all files ending in .rb that lie in the
|
59
|
+
# directory below this file that has the same name as the filename passed
|
60
|
+
# in. Optionally, a specific _directory_ name can be passed in such that
|
61
|
+
# the _filename_ does not have to be equivalent to the directory.
|
62
|
+
#
|
63
|
+
def self.require_all_libs_relative_to( fname, dir = nil )
|
64
|
+
dir ||= ::File.basename(fname, '.*')
|
65
|
+
puts " self.require_all_libs_relative_to, dir=#{dir}" if @debug
|
66
|
+
search_me = ::File.expand_path(
|
67
|
+
::File.join(::File.dirname(fname), dir, '**', '*.rb'))
|
68
|
+
|
69
|
+
puts " search_me=#{search_me}" if @debug
|
70
|
+
Dir.glob(search_me).sort.each {|rb|
|
71
|
+
puts " require #{rb}" if @debug
|
72
|
+
require rb
|
73
|
+
}
|
74
|
+
end
|
75
|
+
end # module AdminToolsEnnder
|
76
|
+
|
77
|
+
AdminToolsEnnder.require_all_libs_relative_to(__FILE__)
|
data/lib/gtm.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
# Load any model classes
|
2
|
+
Dir[Rails.root.to_s + '/app/models/**/*.rb'].each do |file|
|
3
|
+
begin
|
4
|
+
# puts "loading #{file}"
|
5
|
+
require file
|
6
|
+
rescue
|
7
|
+
Rails.logger.error "GTM: Error loading #{file}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
models = ActiveRecord::Base.descendants.map(&:name)
|
12
|
+
|
13
|
+
models.each do |model|
|
14
|
+
print model
|
15
|
+
print ' '
|
16
|
+
end
|
17
|
+
|
18
|
+
=begin
|
19
|
+
class Class
|
20
|
+
def extend?(klass)
|
21
|
+
not superclass.nil? && ( superclass == klass || superclass.extend? klass )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def models
|
26
|
+
Module.constants.select do |constant_name|
|
27
|
+
constant = eval constant_name
|
28
|
+
if (
|
29
|
+
! constant.nil? &&
|
30
|
+
constant.is_a? Class &&
|
31
|
+
constant.extend? ActiveRecord::Base
|
32
|
+
)
|
33
|
+
constant
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def all_models
|
39
|
+
# must eager load all the classes...
|
40
|
+
Dir.glob("#{RAILS_ROOT}/app/models/**/*.rb") do |model_path|
|
41
|
+
begin
|
42
|
+
require model_path
|
43
|
+
rescue
|
44
|
+
# ignore
|
45
|
+
end
|
46
|
+
end
|
47
|
+
# simply return them
|
48
|
+
ActiveRecord::Base.send(:subclasses)
|
49
|
+
end
|
50
|
+
|
51
|
+
def load_models_in_development
|
52
|
+
if Rails.env == "development"
|
53
|
+
load_models_for(Rails.root)
|
54
|
+
Rails.application.railties.engines.each do |r|
|
55
|
+
load_models_for(r.root)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def load_models_for(root)
|
61
|
+
Dir.glob("#{root}/app/models/**/*.rb") do |model_path|
|
62
|
+
begin
|
63
|
+
require model_path
|
64
|
+
rescue
|
65
|
+
# ignore
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
Rails.application.eager_load! unless Rails.configuration.cache_classes
|
71
|
+
|
72
|
+
def list_models
|
73
|
+
Dir.glob("#{Rails.root}/app/models/*.rb").map{|x| x.split("/").last.split(".").first.camelize}
|
74
|
+
end
|
75
|
+
=end
|