Bug 35212: Correct mismatched label on identity provider entry form
[koha.git] / koha-tmpl / intranet-tmpl / prog / en / modules / admin / identity_providers.tt
1 [% USE raw %]
2 [% USE Asset %]
3 [% USE Branches %]
4 [% USE Categories %]
5 [% PROCESS 'i18n.inc' %]
6 [% SET footerjs = 1 %]
7 [% INCLUDE 'doc-head-open.inc' %]
8 <title>[% FILTER collapse %]
9     [% IF op == 'add_form' %]
10         [% t("New identity provider") | html %] &rsaquo;
11     [% ELSIF op == 'edit_form' %]
12         [% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %] &rsaquo;
13     [% END %]
14     [% t("Identity providers") | html %] &rsaquo;
15     [% t("Administration") | html %] &rsaquo;
16     [% t("Koha") | html %]
17 [% END %]</title>
18 [% INCLUDE 'doc-head-close.inc' %]
19 </head>
20
21 <body id="admin_identity_providers" class="admin">
22 [% INCLUDE 'header.inc' %]
23 [% INCLUDE 'prefs-admin-search.inc' %]
24
25 [% WRAPPER 'sub-header.inc' %]
26     [% WRAPPER breadcrumbs %]
27         [% WRAPPER breadcrumb_item %]
28             <a href="/cgi-bin/koha/admin/admin-home.pl">Administration</a>
29         [% END %]
30
31         [% IF op == 'add_form' %]
32             [% WRAPPER breadcrumb_item %]
33                 <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
34             [% END %]
35             [% WRAPPER breadcrumb_item bc_active= 1 %]
36                 <span>New identity provider</span>
37             [% END %]
38
39         [% ELSIF op == 'edit_form' %]
40             [% WRAPPER breadcrumb_item %]
41                 <a href="/cgi-bin/koha/admin/identity_providers.pl">Identity providers</a>
42             [% END %]
43             [% WRAPPER breadcrumb_item bc_active= 1 %]
44                 [% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %]
45             [% END %]
46
47         [% ELSE %]
48             [% WRAPPER breadcrumb_item bc_active= 1 %]
49                 <span>Identity providers</span>
50             [% END %]
51         [% END %]
52     [% END #/ WRAPPER breadcrumbs %]
53 [% END #/ WRAPPER sub-header.inc %]
54
55 <div class="main container-fluid">
56     <div class="row">
57         <div class="col-sm-10 col-sm-push-2">
58             <main>
59
60 [% FOREACH m IN messages %]
61     <div class="dialog [% m.type | html %]" id="identity_provider_action_result_dialog">
62         [% SWITCH m.code %]
63         [% CASE 'error_on_update' %]
64             <span>An error occurred trying to open the identity provider for editing. The passed ID is invalid.</span>
65         [% CASE 'error_on_insert' %]
66             <span>An error occurred when adding a new identity provider.</span>
67         [% CASE 'success_on_update' %]
68             <span>Identity provider updated successfully.</span>
69         [% CASE 'success_on_insert' %]
70             <div>Identity provider added successfully.</div>
71             <div>You will need to restart Koha for the provider to work.</div>
72         [% CASE %]
73             <span>[% m.code | html %]</span>
74         [% END %]
75     </div>
76 [% END %]
77
78     <div class="dialog message" id="identity_provider_delete_success" style="display: none;"></div>
79     <div class="dialog alert"   id="identity_provider_delete_error"   style="display: none;"></div>
80
81 [% IF op == 'add_form' %]
82     <h1>New identity provider</h1>
83
84         <form action="/cgi-bin/koha/admin/identity_providers.pl" id="add" name="add" class="validated" method="post">
85             <input type="hidden" name="op" value="add" />
86             <fieldset class="rows">
87                 <legend id="identity_provider_basic">Basic configuration</legend>
88                 <ol>
89                     <li>
90                         <label for="code" class="required">Code: </label>
91                         <input type="text" name="code" id="code" size="60" class="required" required="required" />
92                         <span class="required">Required</span>
93                         <div class="hint">Code that identifies this provider. Only alphanumeric and "_" characters are allowed</div>
94                     </li>
95                     <li>
96                         <label for="description" class="required">Description: </label>
97                         <input type="text" name="description" id="description" size="60" class="required" required="required" />
98                         <span class="required">Required</span>
99                         <div class="hint">User friendly name of this provider</div>
100                     </li>
101                     <li>
102                         <label for="protocol">Protocol: </label>
103                         <select name="protocol" id="protocol">
104                             <option value="OAuth">OAuth</option>
105                             <option value="OIDC">OIDC</option>
106                             <!-- Not implemented yet
107                             <option value="LDAP">LDAP</option>
108                             <option value="CAS">CAS</option>
109                             -->
110                         </select>
111                         <div class="hint">Choose the protocol this external identity provider uses</div>
112                     </li>
113                 </ol>
114             </fieldset>
115
116             <fieldset class="rows">
117                 <legend id="identity_provider_advanced">Advanced configuration</legend>
118                 <ol>
119                     <li>
120                         <label for="config" class="required json">Configuration: </label>
121                         <textarea name="config" id="config" class="required" cols="75" rows="10"></textarea>
122                         <span class="required">Required</span>
123                         <div class="hint">Provider's main configuration. <button class="more btn btn-ligth" data-target="config"><i class="fa fa-caret-down"></i> More</button></div>
124                         <div class="hint more-config" style="display: none">
125                             <div>This configuration differs for each protocol.</div>
126                             <div>It is recommended to add the default configuration, and then replace with appropriate values</div>
127                         </div>
128                         <div class="hint">
129                             <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default OAuth configuration</button>
130                         </div>
131                     </li>
132                     <li>
133                         <label for="mapping" class="required json">Mapping: </label>
134                         <textarea name="mapping" id="mapping" class="required" cols="75" rows="10"></textarea>
135                         <span class="required">Required</span>
136                         <div class="hint">Map provider's result to Koha patron's fields. <button class="more btn btn-ligth" data-target="mapping"><i class="fa fa-caret-down"></i> More</button></div>
137                         <div class="hint more-mapping" style="display: none">
138                             <div>It is recommended to add the default mapping, and then modify to suit this provider's response</div>
139                             <div>Keys represent Koha's fields, and values represent the keys in provider's result</div>
140                             <div>For nested values in provider's results, you can use dot separation.</div>
141                             <div>For example, <i>firstname: "users.0.name"</i> will match the 'name' attribute of the first object in the array named 'users', and place it in 'firstname' field</div>
142                             <div>If you plan to use auto register feature, either <i>userid</i> or <i>cardnumber</i> must be present in this mapping</div>
143                         </div>
144                         <div class="hint">
145                             <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default OAuth mapping</button>
146                         </div>
147                     </li>
148                     <li>
149                         <label for="matchpoint">Matchpoint: </label>
150                         <select name="matchpoint" id="matchpoint">
151                             <option value="email">Email</option>
152                             <option value="userid">User ID</option>
153                             <option value="cardnumber">Card number</option>
154                         </select>
155                         <div class="hint">Koha patron's field that will be used to match provider's user with Koha's</div>
156                         <div class="hint">It must be present in mapping</div>
157                     </li>
158                     <li>
159                         <label for="icon_url">Icon URL: </label>
160                         <input type="text" name="icon_url" id="icon_url" size="60" />
161                     </li>
162                 </ol>
163             </fieldset>
164
165             <fieldset class="rows">
166                 <legend id="identity_provider_domain">Domain configuration</legend>
167                 <ol>
168                     <li>
169                         <label for="domain" class="required">Domain: </label>
170                         <input type="text" name="domain" id="domain" class="required" size="60" />
171                         <span class="required">Required</span>
172                         <div class="hint">Use &ast; for any domain. You can add new domains later on the dedicated admin page.</div>
173                     </li>
174                     <li>
175                         <label for="default_library_id">Default library: </label>
176                         <select id="default_library_id" name="default_library_id" class="mandatory">
177                             [% PROCESS options_for_libraries libraries => Branches.all( unfiltered => 1, do_not_select_my_library => 1 ) %]
178                         </select>
179                         <span class="required">Required</span>
180                         <div class="hint">Use this library for the patron on auto register</div>
181                     </li>
182                     <li>
183                         <label for="default_category_id">Default category: </label>
184                         [% SET categories = Categories.all() %]
185                         <select name="default_category_id" id="default_category_id" class="mandatory">
186                             [% FOREACH category IN categories %]
187                                 <option value="[% category.categorycode | html %]">[% category.description | html %]</option>
188                             [% END %]
189                         </select>
190                         <span class="required">Required</span>
191                         <div class="hint">Use this category for the patron on auto register</div>
192                     </li>
193                     <li>
194                         <label for="allow_opac">Allow OPAC: </label>
195                         <select name="allow_opac" id="allow_opac">
196                             <option value="1">Yes</option>
197                             <option value="0" selected="selected">No</option>
198                         </select>
199                         <div class="hint">Allow OPAC access to users from this domain to login with this identity provider.</div>
200                     </li>
201                     <li>
202                         <label for="allow_staff">Allow staff: </label>
203                         <select name="allow_staff" id="allow_staff">
204                             <option value="1">Yes</option>
205                             <option value="0" selected="selected">No</option>
206                         </select>
207                         <div class="hint">Allow staff access to users from this domain to login with this identity provider.</div>
208                     </li>
209                     <li>
210                         <label for="auto_register">Auto register: </label>
211                         <select name="auto_register" id="auto_register">
212                             <option value="1">Yes</option>
213                             <option value="0" selected="selected">No</option>
214                         </select>
215                         <div class="hint">Allow users to auto register on login.</div>
216                     </li>
217                     <li>
218                         <label for="update_on_auth">Update on login: </label>
219                         <select name="update_on_auth" id="update_on_auth">
220                             <option value="1">Yes</option>
221                             <option value="0" selected="selected">No</option>
222                         </select>
223                         <div class="hint">Update user data on login.</div>
224                 </ol>
225             </fieldset>
226
227             <fieldset class="action">
228                 <input type="submit" value="Submit" />
229                 <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
230             </fieldset>
231         </form>
232
233 [% END %]
234
235 [% IF op == 'edit_form' %]
236     <h1>[% tx("Modify identity provider '{id_provider}'", {id_provider = identity_provider.code}) | html %]</h1>
237
238         <form action="/cgi-bin/koha/admin/identity_providers.pl" id="edit_save" name="edit_save" class="validated" method="post">
239             <input type="hidden" name="op" value="edit_save" />
240             <input type="hidden" name="identity_provider_id" value="[%- identity_provider.identity_provider_id | html -%]" />
241             <fieldset class="rows">
242                 <legend id="identity_provider_basic">Basic configuration</legend>
243                 <ol>
244                     <li>
245                         <label for="code" class="required">Code: </label>
246                         <input type="text" name="code" id="code" size="60" class="required" required="required" value="[%- identity_provider.code | html -%]"/>
247                         <span class="required">Required</span>
248                         <div class="hint">Code that identifies this provider. Only alphanumeric and "_" characters are allowed</div>
249                     </li>
250                     <li>
251                         <label for="description" class="required">Description: </label>
252                         <input type="text" name="description" id="description" size="60" class="required" required="required" value="[%- identity_provider.description | html -%]"/>
253                         <span class="required">Required</span>
254                         <div class="hint">User friendly name of this provider</div>
255                     </li>
256                     <li>
257                         <label for="protocol">Protocol: </label>
258                         <select name="protocol" id="protocol">
259                         [% IF identity_provider.protocol == 'OAuth' %]
260                             <option value="OAuth" selected="selected">OAuth</option>
261                             <option value="OIDC">OIDC</option>
262                             <!-- Not implemented yet
263                             <option value="LDAP">LDAP</option>
264                             <option value="CAS">CAS</option>
265                             -->
266                         [% ELSE %]
267                             <option value="OAuth">OAuth</option>
268                             <option value="OIDC" selected="selected">OIDC</option>
269                             <!-- Not implemented yet
270                             <option value="LDAP">LDAP</option>
271                             <option value="CAS">CAS</option>
272                             -->
273                         [% END %]
274                         </select>
275                         <div class="hint">Choose the protocol this external identity provider uses</div>
276                     </li>
277                 </ol>
278             </fieldset>
279
280             <fieldset class="rows">
281                 <legend id="identity_provider_advanced">Advanced configuration</legend>
282                 <ol>
283                     <li>
284                         <label for="config" class="required json">Configuration: </label>
285                         <textarea name="config" id="config" class="required" cols="75" rows="10">[%- identity_provider.config | html -%]</textarea>
286                         <span class="required">Required</span>
287                         <div class="hint">Provider's main configuration. <button class="more btn btn-ligth" data-target="config"><i class="fa fa-caret-down"></i> More</button></div>
288                         <div class="hint more-config" style="display: none">
289                             <div>This configuration differs for each protocol.</div>
290                             <div>It is recommended to add the default configuration, and then replace with appropriate values</div>
291                         </div>
292                         <div class="hint">
293                             <button class="btn btn-ligth defaults" data-default-target="config" id="default-config">Add default [%- identity_provider.protocol | html -%] configuration</button>
294                         </div>
295                     </li>
296                     <li>
297                         <label for="mapping" class="required json">Mapping: </label>
298                         <textarea name="mapping" id="mapping" class="required" cols="75" rows="10">[%- identity_provider.mapping | html -%]</textarea>
299                         <span class="required">Required</span>
300                         <div class="hint">Map provider's result to Koha patron's fields. <button class="more btn btn-ligth" data-target="mapping"><i class="fa fa-caret-down"></i> More</button></div>
301                         <div class="hint more-mapping" style="display: none">
302                             <div>It is recommended to add the default mapping, and then modify to suit this provider's response</div>
303                             <div>Keys represent Koha's fields, and values represent the keys in provider's result</div>
304                             <div>For nested values in provider's results, you can use dot separation.</div>
305                             <div>For example, <i>firstname: "users.0.name"</i> will match the 'name' attribute of the first object in the array named 'users', and place it in 'firstname' field</div>
306                             <div>If you plan to use auto register feature, either <i>userid</i> or <i>cardnumber</i> must be present in this mapping</div>
307                         </div>
308                         <div class="hint">
309                             <button class="btn btn-ligth defaults" data-default-target="mapping" id="default-mapping">Add default [%- identity_provider.protocol | html -%] mapping</button>
310                         </div>
311                     </li>
312                     <li>
313                         <label for="matchpoint">Matchpoint: </label>
314                         <select name="matchpoint" id="matchpoint">
315                             [%- IF identity_provider.matchpoint == 'email'      -%]
316                                 <option value="email" selected="selected">Email</option>
317                             [%- ELSE -%]
318                                 <option value="email">Email</option>
319                             [%- END -%]
320                             [%- IF identity_provider.matchpoint == 'userid'     -%]
321                                 <option value="userid" selected="selected">User id</option>
322                             [%- ELSE -%]
323                                 <option value="userid">User id</option>
324                             [%- END -%]
325                             [%- IF identity_provider.matchpoint == 'cardnumber' -%]
326                                 <option value="cardnumber" selected="selected">Card number</option>
327                             [%- ELSE -%]
328                                 <option value="cardnumber">Card number</option>
329                             [%- END -%]
330                         </select>
331                         <div class="hint">Koha patron's field that will be used to match provider's user with Koha's</div>
332                         <div class="hint">It must be present in mapping</div>
333                     </li>
334                     <li>
335                         <label for="icon_url">Icon URL: </label>
336                         <input type="text" name="icon_url" id="icon_url" size="60"  value="[%- identity_provider.icon_url | html -%]"/>
337                     </li>
338                 </ol>
339             </fieldset>
340             <fieldset class="action">
341                 <input type="submit" value="Submit" />
342                 <a class="cancel" href="/cgi-bin/koha/admin/identity_providers.pl">Cancel</a>
343             </fieldset>
344         </form>
345
346 [% END %]
347
348 [% IF op == 'list' %]
349
350     <div id="toolbar" class="btn-toolbar">
351         <a class="btn btn-default" id="new_identity_provider" href="/cgi-bin/koha/admin/identity_providers.pl?op=add_form"><i class="fa fa-plus"></i> New identity provider</a>
352     </div>
353
354     <h1>Identity providers</h1>
355     <div class="page-section">
356         <table id="identity_providers">
357             <thead>
358                 <tr>
359                     <th>Code</th>
360                     <th>Description</th>
361                     <th>Protocol</th>
362                     <th data-class-name="actions noExport">Actions</th>
363                 </tr>
364             </thead>
365         </table>
366     </div>
367 [% END %]
368
369             <div id="delete_confirm_modal" class="modal" tabindex="-1" role="dialog" aria-labelledby="delete_confirm_modal_label" aria-hidden="true">
370                 <div class="modal-dialog">
371                     <div class="modal-content">
372                         <div class="modal-header">
373                             <button type="button" class="closebtn" data-dismiss="modal" aria-hidden="true">×</button>
374                             <h3 id="delete_confirm_modal_label">Confirm deletion of identity provider</h3>
375                         </div>
376                         <div class="modal-body">
377                             <div id="delete_confirm_dialog"></div>
378                         </div>
379                         <div class="modal-footer">
380                             <a href="#" class="btn btn-default" id="delete_confirm_modal_button" role="button" data-toggle="modal">Delete</a>
381                             <button class="btn btn-default" data-dismiss="modal" aria-hidden="true">Close</button>
382                         </div>
383                     </div> <!-- /.modal-content -->
384                 </div> <!-- /.modal-dialog -->
385             </div> <!-- #delete_confirm_modal -->
386
387             </main>
388         </div> <!-- /.col-sm-10.col-sm-push-2 -->
389
390         <div class="col-sm-2 col-sm-pull-10">
391             <aside>
392                 [% INCLUDE 'admin-menu.inc' %]
393             </aside>
394         </div> <!-- /.col-sm-2.col-sm-pull-10 -->
395      </div> <!-- /.row -->
396
397
398 [% MACRO jsinclude BLOCK %]
399     [% Asset.js("js/admin-menu.js") | $raw %]
400     [% INCLUDE 'datatables.inc' %]
401     <script>
402         $(document).ready(function() {
403
404             var identity_providers_url = '/api/v1/auth/identity_providers';
405             window.identity_providers = $("#identity_providers").kohaTable({
406                 "ajax": {
407                     "url": identity_providers_url
408                 },
409                 'language': {
410                     'emptyTable': '<div class="dialog message">'+_("There are no identity providers defined.")+'</div>'
411                 },
412                 "columnDefs": [ {
413                     "targets": [0,1,2],
414                     "render": function (data, type, row, meta) {
415                         if ( type == 'display' ) {
416                             if ( data != null ) {
417                                 return data.escapeHtml();
418                             }
419                             else {
420                                 return "Default";
421                             }
422                         }
423                         return data;
424                     }
425                 } ],
426                 "columns": [
427                     {
428                         "data": "code",
429                         "searchable": true,
430                         "orderable": true
431                     },
432                     {
433                         "data": "description",
434                         "searchable": true,
435                         "orderable": true
436                     },
437                     {
438                         "data": "protocol",
439                         "searchable": true,
440                         "orderable": true
441                     },
442                     {
443                         "data": function( row, type, val, meta ) {
444                             var result = '<a class="btn btn-default btn-xs" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?op=edit_form&amp;identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa-solid fa-pencil" aria-hidden="true"></i> '+_("Edit")+'</a>'+"\n";
445                             result += '<a class="btn btn-default btn-xs delete_identity_provider" role="button" href="#" data-toggle="modal" data-target="#delete_confirm_modal" data-auth-provider-id="'+ encodeURIComponent(row.identity_provider_id) +'" data-auth-provider-code="'+ encodeURIComponent(row.code.escapeHtml()) +'"><i class="fa fa-trash-can" aria-hidden="true"></i> '+_("Delete")+'</a>'+"\n";
446                             result += '<a class="btn btn-default btn-xs edit_domains" role="button" href="/cgi-bin/koha/admin/identity_providers.pl?domain_ops=1&amp;identity_provider_id='+ encodeURIComponent(row.identity_provider_id) +'"><i class="fa fa-cog" aria-hidden="true"></i> '+_("Manage domains")+'</a>';
447                             return result;
448                         },
449                         "searchable": false,
450                         "orderable": false
451                     }
452                 ],
453                 createdRow: function (row, data, dataIndex) {
454                     if ( data.debug ) {
455                         $(row).addClass('debug');
456                     }
457                 },
458             });
459
460             $('#identity_providers').on( "click", '.delete_identity_provider', function () {
461                 var identity_provider_id   = $(this).data('auth-provider-id');
462                 var identity_provider_code = decodeURIComponent($(this).data('auth-provider-code'));
463
464                 $("#delete_confirm_dialog").html(
465                     _("You are about to delete the '%s' identity provider.").format(identity_provider_code)
466                 );
467                 $("#delete_confirm_modal_button").data('auth-provider-id', identity_provider_id);
468                 $("#delete_confirm_modal_button").data('auth-provider-code', identity_provider_code);
469             });
470
471             $("#delete_confirm_modal_button").on( "click", function () {
472
473                 var identity_provider_id   = $(this).data('auth-provider-id');
474                 var identity_provider_code = $(this).data('auth-provider-code');
475
476                 $.ajax({
477                     method: "DELETE",
478                     url: identity_providers_url+"/"+identity_provider_id
479                 }).success(function() {
480                     window.identity_providers.api().ajax.reload(function (data) {
481                         $("#identity_provider_action_result_dialog").hide();
482                         $("#identity_provider_delete_success").html(_("Server '%s' deleted successfully.").format(identity_provider_code)).show();
483                     });
484                 }).fail(function () {
485                     $("#identity_provider_delete_error").html(_("Error deleting server '%s'. Check the logs.").format(identity_provider_code)).show();
486                 }).done(function () {
487                     $("#delete_confirm_modal").modal('hide');
488                 });
489             });
490
491             $.validator.addMethod('json', function(value, element) {
492                 if (this.optional(element) && value === '') return true;
493                 try {
494                     JSON.parse(value)
495                 } catch (error) {
496                     return false;
497                 }
498                 return true;
499             }, _("Not a valid JSON"));
500
501             $.validator.addMethod('alphanum', function(value, element) {
502                 if (this.optional(element) && value === '') return true;
503                 return /^[a-zA-Z0-9_]+$/.test(value);
504             }, _("Value must have alphanumeric characters or '_'"));
505
506             $('#config, #mapping').each(function() {
507                 $(this).rules('add', {
508                     required: true,
509                     json: true
510                 });
511             });
512
513             $('button.more').on('click', function(event) {
514                 event.preventDefault();
515                 var target = $(this).hide().data('target');
516                 $('.more-'+target).show();
517             });
518
519             $('#code').rules('add', {
520                 alphanum: true,
521                 required: true
522             });
523
524             var defaults = {
525                 OIDC: {
526                     config: {
527                         key: "<enter client id>",
528                         secret: "<enter client secret>",
529                         well_known_url: "<enter openid configuration endpoint>",
530                         scope: "openid email"
531                     },
532                     mapping: {
533                         email: "email",
534                         firstname: "given_name",
535                         surname: "family_name"
536                     }
537                 },
538                 OAuth: {
539                     config: {
540                         key: "<enter client id>",
541                         secret: "<enter client secret>",
542                         authorize_url: "<enter authorization endpoint>",
543                         token_url: "<enter token endpoint>",
544                         userinfo_url: "<enter user info endpoint (optional)>",
545                         scope: "email"
546                     },
547                     mapping: {
548                         email: "email",
549                         firstname: "given_name",
550                         surname: "family_name"
551                     }
552                 }
553             };
554
555             $('#protocol').on('change', function() {
556                 var protocol = $(this).val();
557                 $('#default-config').html(_("Add default %s configuration").format(protocol));
558                 $('#default-mapping').html(_("Add default %s mapping").format(protocol));
559             });
560
561             $('button.defaults').on('click', function(event) {
562                 event.preventDefault();
563                 var target = $(this).data('defaultTarget');
564                 if($('#'+target).val() !== '' && !confirm(_("Are you sure you want to replace current %s contents?").format(target))) {
565                     return;
566                 }
567                 var protocol = $('#protocol').val();
568                 $('#'+target).val(JSON.stringify(defaults[protocol][target], null, 2));
569             })
570         });
571     </script>
572 [% END %]
573
574 [% INCLUDE 'intranet-bottom.inc' %]