JFIFxxC      C  " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr# # Authentic Theme (https://github.com/authentic-theme/authentic-theme) # Copyright Ilia Rostovtsev # Licensed under MIT (https://github.com/authentic-theme/authentic-theme/blob/master/LICENSE) # use strict; our ($get_user_level, $xnav, %theme_config, %theme_text, %config, %gconfig, %tconfig, %text, %in, $scriptname, $basic_virtualmin_domain, $basic_virtualmin_menu, $cb, $tb, $title, $cloudmin_no_create_links, $cloudmin_no_edit_buttons, $cloudmin_no_global_links, $current_theme, $done_theme_post_save_server, $mailbox_no_addressbook_button, $mailbox_no_folder_button, $module_index_link, $module_index_name, $nocreate_virtualmin_menu, $nosingledomain_virtualmin_mode, $page_capture, $remote_user, $root_directory, $session_id, $ui_formcount, $theme_ui_post_header_text, $user_module_config_directory, $theme_webprefix); do($ENV{'THEME_ROOT'} . "/authentic-init.pl"); sub theme_header { return if (fetch_content()); if (get_env('script_name') =~ /password_change\.cgi$/) { embed_login_head(); print ""; return; } my $tref = ref($_[0]) eq 'ARRAY'; my $ttitle = $tref ? $_[0]->[0] : $_[0]; embed_header( (($ttitle ne $title ? ($title ? "$ttitle - $title" : $ttitle) : $ttitle), $_[7], theme_debug_mode(), (@_ > 1 ? '1' : '0'), ($tref ? 1 : 0))); my $body_initial = !http_x_request() ? ' data-load-initial="1"' : undef; print '' . "\n"; embed_overlay_prebody() if (!http_x_request()); # Embed branding embed_product_branding() if (!http_x_request() && (!get_env('http_referer') || get_env('http_referer') =~ /(session|pam)_login\.cgi/) && !getvar('theme-goto', 'main', 'unset')); if (@_ > 1 && $_[1] ne 'stripped') { # Print default container print '
' . "\n"; my %this_module_info = &get_module_info(&get_module_name()); print '
' . "\n"; print '
' . "\n"; print $tconfig{'preheader'}; print '
'; print '\n"; if ($_[1]) { print "
", "\"$ttitle\"\n"; } else { my $ts = defined($tconfig{'titlesize'}) ? $tconfig{'titlesize'} : "+2"; print "
", ($ts ? "" : ""), $ttitle, ($ts ? "" : ""); print "
$_[9]\n" if ($_[9]); if ($theme_ui_post_header_text) { print "
$theme_ui_post_header_text
"; } else { print "

"; } print "
\n"; } print "
"; print $_[6]; print "
\n"; print $tconfig{'postheader'}; print '
' . "\n"; print '
' . "\n"; } $miniserv::page_capture = 1; $miniserv::theme_header_captured = 1; } sub theme_footer { my $script_name = $ENV{'SCRIPT_NAME'}; if (index($script_name, 'session_login.cgi') != -1 || index($script_name, 'pam_login.cgi') != -1 || index($script_name, 'password_change.cgi') != -1) { print "
\n"; embed_js_scripts(); print "\n"; print "\n"; } return if (fetch_content()); ((!$miniserv::theme_header_captured && !$miniserv::page_capture) && return); my %this_module_info = &get_module_info(&get_module_name()); for (my $i = 0; $i + 1 < @_; $i += 2) { my $url = $_[$i]; if ($url ne '/' || !$tconfig{'noindex'}) { if ($url eq '/') { $url = "/?cat=$this_module_info{'category'}"; } elsif ($url eq '' && &get_module_name()) { $url = "/" . &get_module_name() . "/" . $this_module_info{'index_link'}; } elsif ($url =~ /^\?/ && &get_module_name()) { $url = "/" . &get_module_name() . "/$url"; } $url = "$theme_webprefix$url" if ($url =~ /^\//); $url = $url . "/" if ($url =~ /[^\/]$/ && $url !~ /.cgi/ && $url !~ /javascript:history/ && $url !~ /[&?]/); print "   ", &text('main_return', $_[$i + 1]), "\n"; } } print "
\n"; embed_port_shell() if (!http_x_request()); embed_footer((theme_debug_mode()), ( (get_module_name() || get_env('request_uri') =~ /\/config.cgi\?/ || get_env('request_uri') =~ /\/uconfig.cgi\?/ || get_env('request_uri') =~ /\/webmin_search.cgi\?/ || get_env('request_uri') =~ /\/tconfig.cgi/ || get_env('request_uri') =~ /\/settings-editor_read.cgi/ || get_env('request_uri') =~ /\/settings-editor_favorites_read.cgi/ || get_env('request_uri') =~ /\/settings-logos.cgi/ || get_env('request_uri') =~ /\/settings-backgrounds.cgi/ ) ? '1' : '0' ), $_[0] ) if (!http_x_request()); embed_pm_scripts(); if ($theme_config{'settings_hide_top_loader'} ne 'true' && get_env('script_name') ne '/session_login.cgi' && get_env('script_name') ne '/pam_login.cgi' && !http_x_request()) { if (!getvar('error-fatal')) { print '
', "\n"; } } # Post-body header overlay embed_overlay_postbody() if (!http_x_request()); print '', "\n"; print '', "\n"; } sub theme_ui_print_header { my ($text, @args) = @_; if (length($text)) { $theme_ui_post_header_text = $text; } &header(@args); } sub theme_popup_prehead { print ''; } sub theme_file_chooser_button { my $chroot = defined($_[3]) ? $_[3] : "/"; my $add = int($_[4]); my $link = "chooser.cgi?add=$add&type=$_[1]&chroot=$chroot&file=\"+encodeURIComponent(ifield.value)"; my $icon = 'fa-fw fa-files-o -cs'; return get_chooser_button_template($link, $icon); } sub theme_user_chooser_button { my $link = "user_chooser.cgi?multi=$_[1]&user=\"+encodeURIComponent(ifield.value)"; my $icon = 'fa-user-o'; return get_chooser_button_template($link, $icon); } sub theme_group_chooser_button { my $link = "group_chooser.cgi?multi=$_[1]&group=\"+encodeURIComponent(ifield.value)"; my $icon = 'fa-group-o'; return get_chooser_button_template($link, $icon); } sub theme_interfaces_chooser_button { my $link = "net/interface_chooser.cgi?multi=$_[1]&interface=\"+encodeURIComponent(ifield.value)"; my $icon = 'fa2 fa2-plus-network'; return get_chooser_button_template($link, $icon); } sub theme_date_chooser_button { return "\n"; } sub theme_popup_window_button { my ($url, $w, $h, $scroll, $fields) = @_; my $scrollyn = $scroll ? "yes" : "no"; my $icon = "fa-files-o -cs"; if ($url =~ /third_chooser|standard_chooser/) { $icon = "fa-world"; } my $rv = ""; return $rv; } sub theme_ui_upload { my ($name, $size, $dis, $tags, $multiple) = @_; $size = &ui_max_text_width($size); return ""; } sub theme_icons_table { my $lt = $theme_config{'settings_right_table_links_type'}; my $sm = $lt eq '1' ? ' small-icons' : undef; my $nl = $lt eq '0' ? 1 : undef; if ($nl) { # Print plain text links print ""; } else { # Print icons my $ff; my $in = scalar(@{ $_[0] }); print "
\n"; for (my $i = 0; $i < @{ $_[0] }; $i++) { &generate_icon($_[2]->[$i], $_[1]->[$i], $_[0]->[$i], ref($_[4]) ? $_[4]->[$i] : $_[4], $_[5], $_[6], $_[7]->[$i], $_[8]->[$i]); $ff .= '
', "\n" if (!$sm); } if ($in < 2) { $ff .= "$ff" x 16; } elsif ($in < 4) { $ff .= "$ff" x 8; } elsif ($in < 8) { $ff .= "$ff" x 4; } elsif ($in < 16) { $ff .= "$ff" x 2; } print "$ff
\n"; } } sub theme_generate_icon { my ($icon, $title, $link, $href, $width, $height, $before, $after) = @_; my $icon_outer = $icon; my $wp = $theme_webprefix; my $lt = $theme_config{'settings_right_table_links_type'}; $icon =~ s/^$wp//g if ($wp); $icon =~ s/\/images//g; $icon =~ s/images//g; my $grayscaled_table_icons = ($theme_config{'settings_right_table_grayscaled_icons'} ne 'false' ? 0 : 1); my $animate_table_icons = ($theme_config{'settings_right_table_animate_icons'} ne 'false' ? 0 : 1); (my $___svg = $icon) =~ s/.gif/.svg/; (!-r $root_directory . "/" . get_module_name() . "/" . $icon_outer) && ($icon_outer = undef); my $mod = get_module_name(); my $images_modules = 'images/modules'; my $root_images = $root_directory . "/$current_theme/$images_modules/"; my $__icon = (-r $root_images . $icon ? $wp . "/$images_modules" . $icon : -r $root_images . $mod . $icon ? $wp . "/$images_modules/" . $mod . $icon : -r $root_images . $mod . $___svg ? $wp . "/$images_modules/" . $mod . $___svg : $icon_outer ? $icon_outer : ($wp . "/images/not_found.svg")); if ($lt eq '1') { print '
'; if ($_[6] || $_[7]) { if ($_[6]) { print "$_[6]\n"; } if ($_[7]) { print "$_[7]\n"; } } print "" . ''; print "$title\n"; print '
'; } else { print '
'; if ($_[6] || $_[7]) { if ($_[6]) { print "$_[6]\n"; } if ($_[7]) { print "$_[7]\n"; } } print "$title" : undef) ) . "\" data-toggle=\"tooltip\" data-placement=\"auto bottom\" data-container=\"body\" " . (string_contains($title, '" . '
'; print "$title
\n"; print "
\n"; } } sub theme_ui_columns_start { my ($heads, $width, $noborder, $tdtags, $title, $sortable) = @_; my ($rv, $i); $sortable = ' dtable-sortable' if ($sortable); my $width_; $width_ = ' w-auto-force" ' if ($width eq 'auto'); $rv .= "" . "\n"; if ($title) { $rv .= "\n"; } if (ref($heads) && scalar(@{$heads})) { $rv .= '' . "\n"; $rv .= '' . "\n"; for ($i = 0; $i < @$heads; $i++) { $rv .= "' . "\n"; } $rv .= '' . "\n"; $rv .= '' . "\n"; } $rv .= '' . "\n"; return $rv; } sub theme_ui_columns_row { my ($cols, $tdtags) = @_; my ($rv, $i); $rv .= '' . "\n"; if (ref($cols)) { for ($i = 0; $i < @$cols; $i++) { $rv .= "' . "\n"; } } $rv .= '' . "\n"; return $rv; } sub theme_ui_columns_header { my ($cols, $tdtags) = @_; my ($rv, $i); $rv .= '' . "\n"; $rv .= '' . "\n"; if (ref($cols)) { for ($i = 0; $i < @$cols; $i++) { $rv .= "' . "\n"; } } $rv .= '' . "\n"; $rv .= '' . "\n"; return $rv; } sub theme_ui_columns_end { my $rv; $rv .= '
$title
[$i] : undef) . ">"; $rv .= ($heads->[$i] eq '' ? '
' : $heads->[$i]); $rv .= '
[$i] : undef) . ">\n"; $rv .= ($cols->[$i] !~ /\S/ ? '
' : $cols->[$i]); $rv .= '
[$i] : undef) . ">"; $rv .= ($cols->[$i] eq '' ? '#' : $cols->[$i]); $rv .= '
' . "\n"; return $rv; } sub theme_ui_help { my ($title) = @_; return ( "" ); } sub theme_hlink { my $mod = $_[2] ? $_[2] : &get_module_name(); my $width = $_[3] || $tconfig{'help_width'} || $gconfig{'help_width'} || 600; my $height = $_[4] || $tconfig{'help_height'} || $gconfig{'help_height'} || 400; return "$_[0]"; } sub theme_ui_link { my ($href, $text, $class, $tags) = @_; return ( "$text"); } sub theme_ui_links_row { my ($links, $nopuncs) = @_; my $link = "$_" : "$_" } @$links; return @$links ? "
" . join("", @$links) . "

\n" : ""; } else { if ($nopuncs == 1) { return @$links ? join(", ", @$links) . "
\n" : ""; } elsif ($nopuncs == 2) { return @$links ? join(" ", @$links) . "
\n" : ""; } else { my $dot = "."; if (scalar(@$links) == 1) { $dot = ""; } return @$links ? join(", ", @$links) . "$dot
\n" : ""; } } } } sub theme_select_all_link { my ($field, $form, $text) = @_; $form = int($form); $text ||= $text{'ui_selall'}; return "$text"; } sub theme_select_invert_link { my ($field, $form, $text) = @_; $form = int($form); $text ||= $text{'ui_selinv'}; return "$text"; } sub theme_select_rows_link { my ($field, $form, $text, $rows) = @_; $form = int($form); my $js = "var sel = { " . join(",", map {"\"" . "e_escape($_) . "\":1"} @$rows) . " }; "; $js .= "for(var i=0; i$text"; } sub theme_ui_form_start { my ($script, $method, $target, $tags, $class) = @_; my $rv; $class = 'ui_form' if (!$class); $rv .= "
\n"; my $b; $rv .= '
'; foreach $b (@$buttons) { if (ref($b)) { $rv .= &ui_submit($b->[1], $b->[0], $b->[3], $b->[4], $b->[5], $b->[6]) . ($b->[2] ? " " . $b->[2] : ""); } elsif ($b) { $rv .= "$b\n"; } else { $rv .= " \n"; } } $rv .= '
'; $rv .= "\n"; } $rv .= "
\n"; if (!$nojs) { # When going back to a form, re-enable any text fields generated by # ui_opt_textbox that aren't in the default state. $rv .= "\n"; } return $rv; } sub theme_ui_textbox { my ($name, $value, $size, $dis, $max, $tags, $class, $nostyle) = @_; my $rv; my $ids; $ids = "_i_$main::ui_textbox_tcalled" if ($main::ui_textbox_tcalled++); $class = $class ? " $class" : ""; my $style = ' style="display: inline; width: auto; max-width: 100%; height: 28px; padding-top: 0; padding-bottom: 2px; vertical-align: middle"'; $style = '' if ($nostyle); $rv .= " 5) { if ($farleft) { $rv .= "" . "\n"; } else { $rv .= "\n"; } } # Left link if ($left) { $rv .= "" . "\n"; } else { $rv .= "\n"; } # Message and inputs $rv .= $msg; $rv .= " " . $inputs if ($inputs); # Right link if ($right) { $rv .= "" . "\n"; } else { $rv .= "\n"; } # Far right link, if needed if (@_ > 5) { if ($farright) { $rv .= "" . "\n"; } else { $rv .= "\n"; } } $rv .= "
" . $below if ($below); $rv .= &ui_form_end() if ($cgi); $rv .= "\n"; return $rv; } sub theme_ui_select { my ($name, $value, $opts, $size, $multiple, $missing, $dis, $tags) = @_; my $rv; $rv .= "\n"; return $rv; } sub theme_ui_radio { my ($name, $val, $opts, $dis) = @_; my ($rv, $o); my $rand = int rand(1e4); foreach $o (@$opts) { my $id = "e_escape($name . "_" . $o->[0]); my $label = $o->[1] || $o->[0]; my $after; if ($label =~ /^([\000-\377]*?)((') ? ' ds-bl-fs' : undef; $rv .= "[0]) . '" '; $rv .= ($o->[0] eq $val ? 'checked ' : ''); $rv .= ($dis ? 'disabled="true" ' : ''); $rv .= 'id="' . $id . '_' . $rand . '" '; $rv .= $o->[2] . ' '; $rv .= '>' . $after . "\n"; } return $rv; } sub theme_ui_yesno_radio { my ($name, $value, $yes, $no, $dis) = @_; $yes = 1 if (!defined($yes)); $no = 0 if (!defined($no)); if ($value =~ /^[0-9,.E]+$/ || !$value) { $value = int($value); } return ui_radio($name, $value, [[$yes, $text{'yes'}], [$no, $text{'no'}]], $dis); } sub theme_ui_oneradio { my ($name, $value, $label, $sel, $tags, $dis) = @_; my $id = "e_escape("${name}_${value}"); my $after; my $rand = int rand(1e4); if ($label =~ /^([^<]*)(<[\000-\377]*)$/) { $label = $1; $after = $2; } $label = trim($label); my $bl = string_ends_with($label, '
') ? ' ds-bl-fs' : undef; my $ret = ""; $ret .= ''; $ret .= "$after\n"; return $ret; } sub theme_ui_checkbox { return theme_ui_checkbox_local(@_); } sub theme_ui_textarea { my ($name, $value, $rows, $cols, $wrap, $dis, $tags) = @_; $cols = &ui_max_text_width($cols, 1); my $ids; $ids = "_t_$main::ui_textarea_tcalled" if ($main::ui_textarea_tcalled++); return ""; } sub theme_ui_submit { my ($label, $name, $dis, $tags, $icon_class, $btn_class_extra) = @_; my ($keys, $class, $icon) = get_button_style($label); if ($icon_class && !$icon) { $icon = ""; } my $ids; $ids = "_s_$main::ui_submit_tcalled" if ($main::ui_submit_tcalled++); my $nbsp; if ($label) { $nbsp = " "; } # Form attr has to be passed directly to input my $form_value = ""; if ($tags && $tags =~ /form=/) { if ($tags =~ s/(form='([^']*)')//) { $form_value = " $1"; } } return "\n" . "\n"; } sub theme_ui_reset { my ($label, $dis) = @_; my $rv; $rv .= '' . "\n"; return $rv; } sub theme_ui_button { my ($label, $name, $dis, $tags, $icon, $type, $btn_class_extra) = @_; my $rv; my $label_safe = &html_escape($label); my $nbsp; if ($label) { $nbsp = " "; } if ($icon) { $label_safe = "$nbsp$label_safe$nbsp"; } $type = "button" if (!$type); $rv .= "' . "\n"; return $rv; } sub theme_ui_date_input { my ($day, $month, $year, $dayname, $monthname, $yearname, $dis) = @_; my $rv; $rv .= ""; $rv .= &ui_textbox($dayname, $day, 3, $dis); $rv .= &ui_select($monthname, $month, [map {[$_, $text{"smonth_$_"}]} (1 .. 12)], 1, 0, 0, $dis); $rv .= &ui_textbox($yearname, $year, 5, $dis); $rv .= ""; return $rv; } sub theme_ui_pre_footer { my $rv; $rv .= '
' . "\n"; $rv .= '
' . "\n"; return $rv; } sub theme_ui_tabs_start { my ($tabs, $name, $sel, $border) = @_; my $rv; $rv .= '' . "\n"; $rv .= '
' . "\n"; $main::ui_tabs_selected = $sel; $rv .= &ui_hidden($name, $sel) . "\n"; return $rv; } sub theme_ui_tabs_end { my ($border) = @_; my $rv; $rv .= '
' . "\n"; return $rv; } sub theme_ui_tabs_start_tab { my ($name, $tab) = @_; my $rv; my $defclass = $tab eq $main::ui_tabs_selected ? 'active' : ''; $rv .= '
' . "\n"; return $rv; } sub theme_ui_tabs_end_tab { my $rv; $rv .= '
' . "\n"; return $rv; } sub theme_ui_hr { my $rv; $rv .= '
' . "\n"; return $rv; } sub theme_ui_alert_box { my ($msg, $class, $style, $new_line, $desc_to_title, $desc_icon) = @_; my ($rv, $type, $tmsg, $fa); if ($class eq "success") { $type = 'alert-success', $tmsg = ($theme_text{'theme_global_success'} . '!'), $fa = 'fa-check-circle'; } elsif ($class eq "info") { $type = 'alert-info', $tmsg = ($theme_text{'theme_global_info'} . '!'), $fa = 'fa-info-circle'; } elsif ($class eq "warn") { $type = 'alert-warning', $tmsg = ($theme_text{'theme_global_warning'} . '!'), $fa = 'fa2 fa2-warning fa-1_15x margined-left--2'; } elsif ($class eq "danger") { $type = 'alert-danger', $tmsg = ($theme_text{'theme_xhred_global_error'} . '!'), $fa = 'fa-bolt'; } elsif ($class eq "danger-fatal") { $type = 'alert-danger-fatal', $tmsg = ($theme_text{'theme_xhred_global_error_fatal'} . '!'), $fa = 'fa-exclamation-triangle'; } my $tmsg_space = " "; if (defined($desc_to_title)) { $tmsg = $desc_to_title || ''; $tmsg_space = '' if (!$tmsg); } if ($desc_icon) { $fa = $desc_icon; } $rv .= '
' . "\n"; $rv .= '' . $tmsg_space . '' . $tmsg . ''; $rv .= ($new_line ? '
' : ($tmsg_space ? ' ' : '')) . "\n"; $msg =~ s/button class="btn/button class="btn btn-tiny/gm; $msg =~ s/input class="ui_submit/input class="ui_submit btn btn-default btn-xs/gm; $rv .= $msg . "\n"; $rv .= '
' . "\n"; return $rv; } sub theme_ui_table_start { my ($heading, $tabletags, $cols, $tds, $rightheading) = @_; if (defined($main::ui_table_cols)) { push(@main::ui_table_cols_stack, $main::ui_table_cols); push(@main::ui_table_pos_stack, $main::ui_table_pos); push(@main::ui_table_default_tds_stack, $main::ui_table_default_tds); } my $colspan = 1; my $rv; $rv .= "
" . "\n"; if (defined($heading) || defined($rightheading)) { $rv .= ""; if (defined($heading)) { $rv .= ""; } if (defined($rightheading)) { $rv .= ""; $colspan++; } $rv .= "\n"; } $rv .= "
$heading$rightheading
" . "\n"; $main::ui_table_cols = $cols || 4; $main::ui_table_pos = 0; $main::ui_table_default_tds = $tds; $rv .= "\n"; return $rv; } sub theme_ui_table_end { my $rv; if ($main::ui_table_cols == 4 && $main::ui_table_pos) { $rv .= &ui_table_row(" ", " "); } if (@main::ui_table_cols_stack) { $main::ui_table_cols = pop(@main::ui_table_cols_stack); $main::ui_table_pos = pop(@main::ui_table_pos_stack); $main::ui_table_default_tds = pop(@main::ui_table_default_tds_stack); } else { $main::ui_table_cols = undef; $main::ui_table_pos = undef; $main::ui_table_default_tds = undef; } $rv .= "
\n"; return $rv; } sub theme_ui_table_row { my ($label, $value, $cols, $tds, $trs) = @_; $cols ||= 1; $tds ||= $main::ui_table_default_tds; my $rv; if ($main::ui_table_pos + $cols + 1 > $main::ui_table_cols && $main::ui_table_pos != 0) { $rv .= "\n"; $main::ui_table_pos = 0; } # Only allow data-* attributes as other, # like width, can have negative effects my ($tds1, $tds2); $tds1 = $tds->[0] if (ref($tds) && $tds->[0] =~ /^data-/); $tds2 = $tds->[1] if (ref($tds) && $tds->[1] =~ /^data-/); my $trtags_attrs = ref($trs) eq 'ARRAY' && $trs->[0] ? " $trs->[0]" : ""; $trtags_attrs .= " data-row-type='ui-table' data-cell-colspan='$cols'"; $trtags_attrs .= ' data-column-span="all" data-column-locked="1"' if ($cols == 2 && !length($label)); my $trtags_class = ref($trs) eq 'ARRAY' && $trs->[1] ? " class='$trs->[1]'" : ""; $rv .= "\n" if ($main::ui_table_pos % $main::ui_table_cols == 0); $rv .= "$label\n" if (defined($label)); $rv .= '' . $value . ''; $main::ui_table_pos += $cols + (defined($label) ? 1 : 0); if ($main::ui_table_pos % $main::ui_table_cols == 0) { $rv .= "\n"; $main::ui_table_pos = 0; } return $rv; } sub theme_ui_table_hr { my $rv; if ($main::ui_table_pos) { $rv .= "\n"; $main::ui_table_pos = 0; } $rv .= " " . "
\n"; return $rv; } sub theme_ui_opt_textbox { my ($name, $value, $size, $opt1, $opt2, $dis, $extra, $max, $tags) = @_; my $dis1 = &js_disable_inputs([$name, (defined($extra) ? @$extra : ())], []); my $dis2 = &js_disable_inputs([], [$name, (defined($extra) ? @$extra : ())]); my $rv; $size = &ui_max_text_width($size); $rv .= &ui_radio($name . "_def", $value eq '' ? 1 : 0, [[1, $opt1, "onClick='$dis1'"], [0, $opt2 || " ", "onClick='$dis2'"]], $dis) . "\n"; my $min_width = $size ? '' : ' min-width: 15%;'; $rv .= ""; # Optional (extra) elements must also be disabled (or enabled) on load if (defined($extra)) { $rv .= ""; } return $rv; } sub theme_ui_checked_columns_row { my ($cols, $tdtags, $checkname, $checkvalue, $checked, $disabled, $tags) = @_; my $rv; $rv .= "\n"; $rv .= "[0] : '') . ">
" . &ui_checkbox($checkname, $checkvalue, undef, $checked, $tags, $disabled, ' thick') . "
\n"; my $i; for ($i = 0; $i < @$cols; $i++) { $rv .= "[$i + 1] : '') . ">"; if ($cols->[$i] !~ /"; } $rv .= ($cols->[$i] !~ /\S/ ? "
" : $cols->[$i]); if ($cols->[$i] !~ /\n"; } sub theme_ui_hidden_start { my ($title, $name, $status, $url) = @_; my $rv; if (!$main::ui_hidden_start_donejs++) { $rv .= &ui_hidden_javascript(); } my $divid = "hiddendiv_$name"; my $openerid = "hiddenopener_$name"; my $defclass = $status ? 'opener_shown' : 'opener_hidden'; $rv .= "\n"; $rv .= "$title
\n"; $rv .= "
\n"; return $rv; } sub theme_ui_hidden_table_start { my ($heading, $tabletags, $cols, $name, $status, $tds, $rightheading) = @_; my $rv; if (!$main::ui_hidden_start_donejs++) { $rv .= &ui_hidden_javascript(); } my $divid = "hiddendiv_$name"; my $openerid = "hiddenopener_$name"; my $defclass = $status ? 'opener_shown' : 'opener_hidden'; my $text = defined($tconfig{'cs_text'}) ? $tconfig{'cs_text'} : defined($gconfig{'cs_text'}) ? $gconfig{'cs_text'} : "f00"; $rv .= "\n"; my $colspan = 1; if (defined($heading) || defined($rightheading)) { $rv .= ""; } if (defined($rightheading)) { $rv .= ""; $colspan++; } $rv .= "\n"; } $rv .= "
"; if (defined($heading)) { $rv .= " $heading$rightheading
\n"; $main::ui_table_cols = $cols || 4; $main::ui_table_pos = 0; $main::ui_table_default_tds = $tds; $rv .= "\n"; return $rv; } sub ui_hidden_table_row_end { return "
\n"; } sub theme_ui_buttons_start { return "
\n\n\n\n\n\n"; } sub theme_ui_buttons_end { return "\n\n\n
\n"; } sub theme_ui_buttons_row { my ($script, $label, $desc, $hiddens, $after, $before) = @_; if (ref($hiddens)) { $hiddens = join("\n", map {&ui_hidden(@$_)} @$hiddens); } return "
\n
\n" . $hiddens . "" . " " . "\n" . "\n" . "
" . ($before ? $before . " " : "") . &ui_submit($label) . ($after ? " " . $after : "") . "" . $desc . "
\n" . "
\n
\n"; } sub theme_ui_radio_table { my ($name, $sel, $rows, $nobold) = @_; return "" if (!$rows || !@$rows); my $rv = "\n"; foreach my $r (@$rows) { $rv .= "\n"; $rv .= "[2]) ? "" : " colspan=2") . ">" . ($nobold ? "" : "") . &ui_oneradio($name, $r->[0], $r->[1], $r->[0] eq $sel, $r->[3]) . ($nobold ? "" : "") . "\n"; if (defined($r->[2])) { $rv .= "\n"; } $rv .= "\n"; } $rv .= "
" . $r->[2] . "
\n"; return $rv; } sub theme_make_date { return theme_make_date_local(@_); } sub theme_nice_size { return theme_nice_size_local(@_); } sub theme_get_webprefix { return theme_get_webprefix_local(@_) if (defined(&theme_get_webprefix_local)); } sub theme_redirect { my $request_uri = navigation_link_clean($ENV{'REQUEST_URI'}); if ($request_uri =~ /noredirect=1/) { head(); return; } my $origin = $ENV{'HTTP_ORIGIN'}; my $referer = navigation_link_clean($ENV{'HTTP_REFERER'}); my $prefix = $theme_webprefix; my $noredir = $gconfig{'webprefixnoredir'}; my $relredir = $gconfig{'relative_redir'}; my ($arg1, $arg2) = (navigation_link_clean($_[0]), navigation_link_clean($_[1])); # Clean redirected links query string if requested if ($request_uri =~ /no-query=string/) { my $nocache = "no-cache=1"; $arg1 =~ s/\.cgi.*/.cgi/; $arg2 =~ s/\.cgi.*/.cgi/; if ($request_uri =~ /\Q$nocache\E/) { $arg1 .= "?" . $nocache; $arg2 .= "?" . $nocache; } } my ($link) = $arg1 || $arg2; my ($url) = $arg2; if (!$relredir) { ($url) = $arg2 =~ /\/\/\S+?(\/.*)/; } $url = "$prefix$url" if ($url && $noredir); theme_redirect_url_alterer(\$url); my ($remote_server_webprefix, $remote_server_linked) = &theme_get_webprefix_local('array'); if ($remote_server_webprefix) { ($link) = $arg2 =~ /:\d+(.*)/; $url = "$remote_server_webprefix$link" if ($url !~ /^$remote_server_webprefix/); } elsif ((string_starts_with($arg1, 'http') && ($arg1 !~ /$origin/ || $referer !~ /$arg1/))) { print "Location: $arg1\n\n"; return; } elsif (string_contains($arg1, '../')) { eval { $main::error_must_die = 1; set_theme_temp_data('redirected', $arg1) if ($arg1 !~ /switch\.cgi/); }; print "Location: $arg1\n\n"; return; } if (!theme_redirect_download($url)) { eval { $main::error_must_die = 1; set_theme_temp_data('redirected', $url) if (!theme_set_redirect_forbidden($url)); }; print "Location: $url\n\n"; } } sub theme_redirect_url_alterer { my ($u) = @_; my ($q) = $u =~ /\.cgi.*(\?)/; my $r = &getvar('navigation-reload'); if ($r) { if ($u !~ /\.cgi/) { if ($u !~ /\/$/) { $$u .= '/'; } $$u .= 'index.cgi'; } my $t = $q ? '&' : '?'; $$u .= "${t}refresh-navigation=1"; } } sub theme_set_redirect_forbidden { my ($url) = @_; if ($url && ($url =~ /\/tunnel\/link\.cgi\//)) { return 1; } return 0; } sub theme_header_redirect_download { my ($url, $delay, $message) = @_; PrintHeader(); print "\n"; print "\n"; print "\n"; print '', "\n"; print "\n"; my $script = '
'; print "\n"; print $script . "\n"; if ($message) { print $message . "\n"; } print "\n"; print ''; } sub theme_redirect_download { if ($_[0] =~ /fetch.cgi/) { my $query = get_env('query_string'); my $show = $query =~ /show=1/ ? 1 : 0; my $delay = $_[0] =~ /unzip=1/ ? 1 : 0; my $zip = $_[0] =~ /.zip/ ? 1 : 0; my $message; if ($delay) { $message = $theme_text{'theme_xhred_download_is_being_prepared'}; } elsif (!$delay && !$show) { $message = $theme_text{'right_download_is_ready'}; } else { $message = $theme_text{'right_file_is_being_prepared'}; } theme_header_redirect_download($_[0], $delay, $message); return 1; } else { return 0; } } sub theme_js_redirect { my ($url, $window) = @_; $window ||= "window"; if ($url =~ /^\//) { # If the URL is like /foo , add webprefix $url = &get_webprefix().$url; } return "\n"; } sub theme_post_save_domain { my ($d) = @_; print '\n"; } sub theme_post_save_domains { print '\n"; } sub theme_post_save_server { my ($s, $action) = @_; if ($action eq 'create' || $action eq 'delete' || !$done_theme_post_save_server++) { print '\n"; } } sub theme_select_domain { my ($s) = @_; print '\n"; } sub theme_select_server { my ($s) = @_; print '\n"; } sub theme_post_change_theme { # Clear module modifications lib_csf_control('unload'); # Remove error handler error_40x_handler(1); } sub theme_post_change_modules { print '\n"; } sub theme_ui_text_color { my ($text, $type) = @_; $type = "warning" if ($type eq "warn"); return "$text\n"; } sub theme_error { my ($iref) = @_; my @err_msg = @{$iref->{'err'}}; my @err_stack = @{$iref->{'stack'}}; my $err_caller = $iref->{'err_caller'}; my $main_header = $main::done_webmin_header; my $main_capture = $miniserv::page_capture ? " captured" : ""; my $err_last_eval = $main::error_last_eval; $err_last_eval =~ s/\n$// if ($err_last_eval); &header($text{'error'}, "") if (!$main_header); my $error_what = ($main::whatfailed ? "$main::whatfailed : " : ""); my $error_message = join(", ", @err_msg); my $main_web = $main::webmin_script_type eq 'web'; my $err_caller_msg_esc = "e_escape(($err_last_eval ? "$err_last_eval : $err_caller" : $err_caller), '"'); if ($err_caller && $main_web) { if ($err_last_eval) { $err_caller = &ui_details({ 'title' => $text{'main_error_details'}, 'content' => $err_caller_msg_esc, 'class' =>'error'}, 1); } else { $err_caller = &ui_help(&html_strip($err_caller_msg_esc)) if ($err_caller); } } my $error = $error_what . $error_message . $err_caller; $error = &html_strip($error_what . $error_message . $err_caller) if (!$main_web); my $get_error_stack = sub { # Show call stack my $error_stack = ""; if ($gconfig{'error_stack'}) { $error_stack = "
" if ($main_header); my $cls_err_caption = " class=\"err-head$main_capture\""; my $cls_err_td = $main_capture ? " class=\"@{[&trim($main_capture)]}\"" : ""; $error_stack .= "
\n" if ($main_capture); $error_stack .= "$text{'error_stack'}\n"; $error_stack .= "$text{'error_file'} "; $error_stack .= "$text{'error_line'}"; $error_stack .= "$text{'error_sub'}\n"; foreach my $stack (@err_stack) { $error_stack .= "\n"; $error_stack .= "$stack->[1]\n"; $error_stack .= "$stack->[2]\n"; $error_stack .= "$stack->[3]\n"; $error_stack .= "\n"; } $error_stack .= "
\n"; } return $error_stack; }; if (!$main_header) { print "
\n"; print "

$error

\n"; print &$get_error_stack(); print "
\n"; if ($ENV{'HTTP_REFERER'} && $main::completed_referers_check) { &footer("javascript:history.back()", $text{'error_previous'}); } } else { print ui_alert_box("$error@{[&$get_error_stack()]}", 'danger-fatal', undef, 1); } } sub theme_ui_page_refresh { return "page_refresh()"; } sub theme_fonts { return embed_css_fonts(1); } sub theme_css_inline { return get_css_inline(@_); } $main::cloudmin_no_create_links = 1; $main::cloudmin_no_edit_buttons = 1; $main::cloudmin_no_global_links = 1; $main::mailbox_no_addressbook_button = 1; $main::mailbox_no_folder_button = 1; $main::basic_virtualmin_menu = 1; $main::basic_virtualmin_domain = 1; $main::nocreate_virtualmin_menu = 1; $main::nosingledomain_virtualmin_mode = 1; 1;