Diff for /loncom/homework/structuretags.pm between versions 1.508 and 1.512.2.24.2.3

version 1.508, 2012/09/12 05:14:09 version 1.512.2.24.2.3, 2023/07/05 20:57:30
Line 62  use Apache::lonxml; Line 62  use Apache::lonxml;
 use Apache::londefdef;  use Apache::londefdef;
 use Apache::lonenc();  use Apache::lonenc();
 use Apache::loncommon();  use Apache::loncommon();
   use Apache::lonnavmaps;
 use Time::HiRes qw( gettimeofday tv_interval );  use Time::HiRes qw( gettimeofday tv_interval );
   use HTML::Entities();
 use lib '/home/httpd/lib/perl/';  use lib '/home/httpd/lib/perl/';
 use LONCAPA;  use LONCAPA;
     
Line 224  sub end_tex { Line 226  sub end_tex {
 }  }
   
 sub homework_js {  sub homework_js {
       my ($postsubmit,$timeout);
       if (($env{'request.course.id'}) && ($env{'request.state'} ne 'construct')) {
           my $crstype;
           if (&Apache::loncommon::course_type() eq 'Community') {
               $crstype = 'community';
           } else {
               if ($env{'course.'.$env{'request.course.id'}.'.internal.coursecode'}) {
                   $crstype = 'official';
               } elsif ($env{'course.'.$env{'request.course.id'}.'.internal.textbook'}) {
                   $crstype = 'textbook';
               } else {
                   $crstype = 'unofficial';
               }
           }
           $postsubmit = $env{'course.'.$env{'request.course.id'}.'.internal.postsubmit'};
           if ($postsubmit eq '') {
               my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
               $postsubmit = $domdefs{'postsubmit'};
               unless ($postsubmit eq 'off') {
                   $timeout = $domdefs{$crstype.'postsubtimeout'};
               }
           } elsif ($postsubmit eq '0') {
               $postsubmit = 'off';
           } elsif ($postsubmit eq '1') {
               $postsubmit = 'on';
               $timeout = $env{'course.'.$env{'request.course.id'}.'.internal.postsubtimeout'};
               if ($timeout eq '') {
                   my %domdefs = &Apache::lonnet::get_domain_defaults($env{'course.'.$env{'request.course.id'}.'.domain'});
                   $timeout = $domdefs{$crstype.'postsubtimeout'};
               }
           }
           if ($timeout eq '') {
               $timeout = 60;
           }
       } else {
           my %domdefs = &Apache::lonnet::get_domain_defaults($env{'request.role.domain'});
           $postsubmit = $domdefs{'postsubmit'};
           unless ($postsubmit eq 'off') {
               $timeout = 60;
           }
       }
       my $jstimeout = 0;
       if ($timeout) {
           $jstimeout = 1000 * $timeout;
       }
     return &Apache::loncommon::resize_textarea_js().      return &Apache::loncommon::resize_textarea_js().
              &Apache::loncommon::colorfuleditor_js().
            &setmode_javascript().             &setmode_javascript().
  <<'JS';   <<"JS";
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
 function setSubmittedPart (part,prefix) {  function setSubmittedPart (part,prefix) {
Line 241  function setSubmittedPart (part,prefix) Line 289  function setSubmittedPart (part,prefix)
     }      }
 }  }
   
   function disableAutoComplete (id) {
       var field = document.getElementById(id);
       if (field != null && field != undefined){
           if ('autocomplete' in field) {
               field.autocomplete = "off";
           } else {
               field.setAttribute("autocomplete", "off");
           }
       }
   }
   
 function image_response_click (which, e) {  function image_response_click (which, e) {
     init_geometry();      init_geometry();
     if (!e) { e = window.event; } //IE      if (!e) { e = window.event; } //IE
Line 254  function image_response_click (which, e) Line 313  function image_response_click (which, e)
     input_element.value = click;      input_element.value = click;
     img_element.src = '/adm/randomlabel.png?token='+token+'&clickdata='+click;      img_element.src = '/adm/randomlabel.png?token='+token+'&clickdata='+click;
 }  }
   
   var submithandled = 0;
   var keypresshandled = 0;
   var postsubmit = '$postsubmit';
   
   \$(document).ready(function(){
     if (postsubmit != 'off') {
       \$(document).keypress(function(event){
           var keycode = (event.keyCode ? event.keyCode : event.which);
           if ((keycode == '13') && (keypresshandled == 0)) {
               if ( \$( document.activeElement ).hasClass("LC_textline") ) {
                   keypresshandled = 1;
                   var idsArray = \$( document.activeElement ).attr("id").split(/HWVAL_/);
                   if (idsArray.length) {
                       event.preventDefault();
                       var itemsArray = idsArray[1].split(/_/);
                       var buttonId = idsArray[0]+'submit_'+itemsArray[0];
                       \$("#"+buttonId).trigger("click");
                   }
               }
           }
       });
   
       \$(document).delegate('form :submit', 'click', function( event ) {
           if ( \$( this ).hasClass( "LC_hwk_submit" ) ) {
               var buttonId = this.id;
               var timeout = $jstimeout;
               if (submithandled == 0) {
                   submithandled = 1;
                   \$( "#msg_"+buttonId ).css({"display": "inline","background-color": "#87cefa",
                                              "color": "black","padding": "2px"}) ;
                   if (( \$(this.form).attr("id") == "LC_page" ) && (\$('input[name="all_submit"]').length )) {
                       if (buttonId != "all_submit") {
                           \$( ".LC_status_"+buttonId ).hide();
                       }
                       if (( "#"+buttonId+"_pressed" ).length) {
                           \$( "#"+buttonId+"_pressed" ).val( "1" );
                       }
                   } else {
                       \$( ".LC_status_"+buttonId ).hide();
                   }
                   \$(this.form).submit();
                   \$( ".LC_hwk_submit" ).prop( "disabled", true);
                   \$( ".LC_textline" ).prop( "readonly", "readonly");
                   event.preventDefault();
   
                   if (timeout > 0) {
                       setTimeout(function(){
                                          \$( "#msg_"+buttonId ).css({"display": "none"});
                                          if (( \$(this.form).attr("id") == "LC_page" ) && (\$('input[name="all_submit"]').length )) {
                                              if (( "#"+buttonId+"_pressed" ).length) {
                                                  \$( "#"+buttonId+"_pressed" ).val( "" );
                                              }
                                          }
                                          \$( ".LC_hwk_submit" ).prop( "disabled", false);
                                          \$( ".LC_textline" ).prop( "readonly", false);
                                          submithandled = 0;
                                          keypresshandled = 0;
                                        }, timeout);
                   }
                   return true;
               }
           }
       });
     }
   });
   
 // ]]>  // ]]>
 </script>  </script>
 JS  JS
Line 264  sub setmode_javascript { Line 390  sub setmode_javascript {
 <script type="text/javascript">  <script type="text/javascript">
 // <![CDATA[  // <![CDATA[
 function setmode(form,probmode) {  function setmode(form,probmode) {
       var initial = form.problemmode.value;
     form.problemmode.value = probmode;      form.problemmode.value = probmode;
     form.submit();      form.submit();
       form.problemmode.value = initial;
 }  }
 // ]]>  // ]]>
 </script>  </script>
Line 291  sub page_start { Line 419  sub page_start {
     $extra_head .= &homework_js().      $extra_head .= &homework_js().
                    &Apache::lonhtmlcommon::dragmath_js("EditMathPopup");                     &Apache::lonhtmlcommon::dragmath_js("EditMathPopup");
     if (&Apache::lonhtmlcommon::htmlareabrowser()) {      if (&Apache::lonhtmlcommon::htmlareabrowser()) {
         my %textarea_args = (          my %textarea_args;
           if (($env{'request.state'} ne 'construct') ||
               ($env{'environment.nocodemirror'})) {
               %textarea_args = (
                                 dragmath => 'math',                                  dragmath => 'math',
                               );                                );
           }
         $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);          $extra_head .= &Apache::lonhtmlcommon::htmlareaselectactive(\%textarea_args);
     }      }
     my $is_task = ($env{'request.uri'} =~ /\.task$/);      my $is_task = ($env{'request.uri'} =~ /\.task$/);
     my $needs_upload;      my ($needs_upload,$partlist);
     my ($symb)= &Apache::lonnet::whichuser();      my ($symb)= &Apache::lonnet::whichuser();
     my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);      my ($map,$resid,$resurl)=&Apache::lonnet::decode_symb($symb);
     if ($is_task) {      if ($is_task) {
Line 315  sub page_start { Line 447  sub page_start {
                     unless ($is_page) {                      unless ($is_page) {
                         $needs_upload = 1;                          $needs_upload = 1;
                     }                      }
                       if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                           my $res = $navmap->getBySymb($symb);
                           if (ref($res)) {
                               $partlist = $res->parts();
                           }
                       }
                 }                  }
             }              }
         } else {          } else {
Line 326  sub page_start { Line 464  sub page_start {
                     if (ref($mapres)) {                      if (ref($mapres)) {
                         $is_page = $mapres->is_page();                          $is_page = $mapres->is_page();
                     }                      }
                     unless ($is_page) {                      if ($is_page) {
                           if ((ref($tagstack) eq 'ARRAY') && ($tagstack->[-1] eq 'problem')) {
                               my $res = $navmap->getBySymb($symb);
                               if (ref($res)) {
                                   $partlist = $res->parts();
                               }
                           }
                       } else {
                         my $res = $navmap->getBySymb($symb);                          my $res = $navmap->getBySymb($symb);
                         if (ref($res)) {                          if (ref($res)) {
                             my $partlist = $res->parts();                              $partlist = $res->parts();
                             if (ref($partlist) eq 'ARRAY') {                              if (ref($partlist) eq 'ARRAY') {
                                 foreach my $part (@{$partlist}) {                                  foreach my $part (@{$partlist}) {
                                     my @types = $res->responseType($part);                                      my @types = $res->responseType($part);
Line 351  sub page_start { Line 496  sub page_start {
             }              }
         }          }
         if ($needs_upload) {          if ($needs_upload) {
             $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js();              $extra_head .= &Apache::lonhtmlcommon::file_submissionchk_js().
                              '<script type="text/javascript" '.
                              'src="/res/adm/includes/file_upload.js"></script>';
         }          }
     }      }
   
Line 370  sub page_start { Line 517  sub page_start {
  "if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".   "if (typeof swmenu != 'undefined') {swmenu.currentURL=null;}\n".
  &Apache::loncommon::browser_and_searcher_javascript().   &Apache::loncommon::browser_and_searcher_javascript().
                 "\n</script>\n";                  "\n</script>\n";
               if ($target eq 'edit') {
                   $extra_head .= &Apache::edit::js_update_linknum();
               }
  }   }
     }      }
   
Line 379  sub page_start { Line 529  sub page_start {
     } elsif (!defined($found{'body'})       } elsif (!defined($found{'body'}) 
      && $env{'request.state'} eq 'construct') {       && $env{'request.state'} eq 'construct') {
  if ($target eq 'web' || $target eq 'edit') {   if ($target eq 'web' || $target eq 'edit') {
         # Breadcrumbs for Construction Space          # Breadcrumbs for Authoring Space
         &Apache::lonhtmlcommon::clear_breadcrumbs();          &Apache::lonhtmlcommon::clear_breadcrumbs();
         &Apache::lonhtmlcommon::add_breadcrumb({          &Apache::lonhtmlcommon::add_breadcrumb({
             'text'  => 'Construction Space',              'text'  => 'Authoring Space',
             'href'  => &Apache::loncommon::authorspace($env{'request.uri'}),              'href'  => &Apache::loncommon::authorspace($env{'request.uri'}),
         });          });
         # breadcrumbs (and tools) will be created           # breadcrumbs (and tools) will be created 
Line 414  sub page_start { Line 564  sub page_start {
         $body_args{'add_entries'}    = \%add_entries;          $body_args{'add_entries'}    = \%add_entries;
         if ( $env{'request.state'} eq   'construct') {          if ( $env{'request.state'} eq   'construct') {
             $body_args{'only_body'}  = 1;              $body_args{'only_body'}  = 1;
           } elsif ($target eq 'web') {
               $body_args{'print_suppress'} = 1;
         }          }
     }      }
     $body_args{'no_auto_mt_title'} = 1;      $body_args{'no_auto_mt_title'} = 1;
Line 453  sub page_start { Line 605  sub page_start {
         }          }
  $form_tag_start.='>'."\n";   $form_tag_start.='>'."\n";
   
  my $symb=&Apache::lonnet::symbread();  
  if ($symb =~ /\S/) {   if ($symb =~ /\S/) {
     $symb=      $symb=
  &HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb));   &HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb));
Line 461  sub page_start { Line 612  sub page_start {
  "\t".'<input type="hidden" name="symb" value="'.$symb.'" />'."\n";   "\t".'<input type="hidden" name="symb" value="'.$symb.'" />'."\n";
  }   }
     }      }
     return ($page_start,$form_tag_start);      return ($page_start,$form_tag_start,$partlist);
 }  }
   
 #use Time::HiRes();  #use Time::HiRes();
Line 492  sub get_resource_name { Line 643  sub get_resource_name {
 }  }
   
 sub setup_rndseed {  sub setup_rndseed {
     my ($safeeval,$target)=@_;      my ($safeeval,$target,$probpartlist)=@_;
     my ($symb)=&Apache::lonnet::whichuser();      my ($symb)=&Apache::lonnet::whichuser();
     my ($questiontype,$set_safespace,$rndseed);      my ($questiontype,$set_safespace,$rndseed,$numtries,$reqtries);
     if ($target eq 'analyze') {      if ($target eq 'analyze') {
         $questiontype = $env{'form.grade_questiontype'};          $questiontype = $env{'form.grade_questiontype'};
     }      }
     unless (defined($questiontype)) {      unless (defined($questiontype)) {
         $questiontype = $Apache::lonhomework::type;          $questiontype = $Apache::lonhomework::type;
     }      }
     if ($env{'request.state'} eq "construct"       if ($Apache::lonhomework::type eq 'randomizetry') {
  || $symb eq ''           my $partfortries = $Apache::inputtags::part;
  || $Apache::lonhomework::type eq 'practice'  #
  || $Apache::lonhomework::history{'resource.CODE'}) {  # Where question type is "randomizetry" for a problem containing
   # a single part (and unless type is explicitly set to not be
   # "randomizetry" for that part), the number of tries used to
   # determine randomization will be for that part, and randomization
   # from calls to &random() in a perl script block before the part tag,
   # will change based on the number of tries, and value of the
   # "randomizeontries" parameter in effect for the single part.
   #
           if (ref($probpartlist) eq 'ARRAY') {
               if ((@{$probpartlist} == 1) && ($probpartlist->[0] ne $partfortries)) {
                   if (&Apache::lonnet::EXT('resource.'.$probpartlist->[0].'.type') eq 'randomizetry') {
                       $partfortries = $probpartlist->[0];
                   } else {
                       $partfortries = '';
                   }
               }
           }
           if ($partfortries ne '') {
               $numtries = $Apache::lonhomework::history{"resource.$partfortries.tries"};
               $reqtries = &Apache::lonnet::EXT("resource.$partfortries.randomizeontries");
           }
       }
       if (($env{'request.state'} eq "construct")
           || ($symb eq '')
           || ($Apache::lonhomework::type eq 'practice')
           || ($Apache::lonhomework::history{'resource.CODE'})
           || (($env{'form.code_for_randomlist'}) && ($target eq 'analyze'))) {
  &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},   &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
  ['rndseed']);   ['rndseed']);
  $rndseed=$env{'form.rndseed'};   $rndseed=$env{'form.rndseed'};
Line 513  sub setup_rndseed { Line 690  sub setup_rndseed {
     if (!$rndseed) {      if (!$rndseed) {
  $rndseed=time;   $rndseed=time;
     }      }
     $env{'form.rndseed'}=$rndseed;              unless ($env{'form.code_for_randomlist'}) {
                   $env{'form.rndseed'}=$rndseed;
               }
  }   }
         if (($env{'request.state'} eq "construct") &&           if ((($env{'request.state'} eq "construct") || ($symb eq '')) &&
             ($Apache::lonhomework::type eq 'randomizetry')) {              ($Apache::lonhomework::type eq 'randomizetry')) {
             my $tries = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};              if ($numtries) {
             if ($tries) {                  if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
                 $rndseed += $tries;                      my $inc = int($numtries/$reqtries);
                       $rndseed += $inc;
                   } else {
                       $rndseed += $numtries;
                   }
             }              }
             $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;              $env{'form.'.$Apache::inputtags::part.'.rndseed'}=$rndseed;
         }          }
Line 541  sub setup_rndseed { Line 724  sub setup_rndseed {
        $rndseed=join(':',&Apache::lonnet::digest($rndseed));         $rndseed=join(':',&Apache::lonnet::digest($rndseed));
             }              }
         }          }
         if ($Apache::lonhomework::history{'resource.CODE'}) {          if (($env{'form.code_for_randomlist'}) && ($target eq 'analyze')) {
               $env{'form.CODE'} = $env{'form.code_for_randomlist'};
               $rndseed=&Apache::lonnet::rndseed();
               undef($env{'form.CODE'});
           } elsif ($Apache::lonhomework::history{'resource.CODE'}) {
    $rndseed=&Apache::lonnet::rndseed();     $rndseed=&Apache::lonnet::rndseed();
  }   }
         $set_safespace = 1;          $set_safespace = 1;
Line 553  sub setup_rndseed { Line 740  sub setup_rndseed {
         }          }
         unless (($target eq 'analyze') && (defined($rndseed))) {          unless (($target eq 'analyze') && (defined($rndseed))) {
             $rndseed=&Apache::lonnet::rndseed();              $rndseed=&Apache::lonnet::rndseed();
             my $curr_try = $Apache::lonhomework::history{"resource.$Apache::inputtags::part.tries"};              my $curr_try = $numtries;
             if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {              if ($Apache::inputtags::status[-1] eq 'CAN_ANSWER') {
                 $curr_try ++;                  $curr_try ++;
             }              }
Line 561  sub setup_rndseed { Line 748  sub setup_rndseed {
                 $rndseed = $1;                  $rndseed = $1;
             }              }
             if ($curr_try) {              if ($curr_try) {
                 my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");  
                 if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {                  if (($reqtries =~ /^\d+$/) && ($reqtries > 1)) {
                     my $inc = int(($curr_try-1)/$reqtries);                      my $inc = int(($curr_try-1)/$reqtries);
                     $rndseed += $inc;                      $rndseed += $inc;
Line 571  sub setup_rndseed { Line 757  sub setup_rndseed {
             }              }
         }          }
         $set_safespace = 1;          $set_safespace = 1;
           if ($target eq 'grade') {
               $Apache::lonhomework::rawrndseed = $rndseed;
           }
     }      }
     if ($set_safespace) {      if ($set_safespace) {
         if ($safeeval) {          if ($safeeval) {
Line 600  sub problem_edit_action_button { Line 789  sub problem_edit_action_button {
   
 sub problem_edit_buttons {  sub problem_edit_buttons {
    my ($mode)=@_;     my ($mode)=@_;
   # Buttons that save
      my $result = '<div style="float:right">';
      if ($mode eq 'editxml') {
          $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');
          $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');
      } else {
          $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');
          $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');
      }
      $result.="\n</div>\n";
 # Buttons that do not save  # Buttons that do not save
    my $result='<div class="LC_edit_problem_discards">'.     $result .= '<div>'.
               &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);                &problem_edit_action_button('subdiscview','discard','d','Discard Edits and View',1);
    if ($mode eq 'editxml') {     if ($mode eq 'editxml') {
        $result.=&problem_edit_action_button('subedit','edit','e','Edit',1);         $result.=&problem_edit_action_button('subedit','edit','e','Edit',1);
        $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1);         $result.=&problem_edit_action_button('subundo','undoxml','u','Undo',1);
        $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);         if ($env{'environment.nocodemirror'}) {
              $result.=&Apache::lonhtmlcommon::dragmath_button("LC_editxmltext",1);
          }
    } else {     } else {
        $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1);         $result.=&problem_edit_action_button('subeditxml','editxml','x','EditXML',1);
        $result.=&problem_edit_action_button('subundo','undo','u','Undo',1);         $result.=&problem_edit_action_button('subundo','undo','u','Undo',1);
    }     }
    $result.="\n</div>";     $result.="\n</div>";
 # Buttons that save  
    $result.='<div class="LC_edit_problem_saves">';  
    if ($mode eq 'editxml') {  
        $result.=&problem_edit_action_button('subsaveedit','saveeditxml','s','Save and EditXML');  
        $result.=&problem_edit_action_button('subsaveview','saveviewxml','v','Save and View');  
    } else {  
        $result.=&problem_edit_action_button('subsaveedit','saveedit','s','Save and Edit');  
        $result.=&problem_edit_action_button('subsaveview','saveview','v','Save and View');  
    }  
    $result.="\n</div>\n";  
    return $result;     return $result;
 }  }
   
 sub problem_edit_header {  sub problem_edit_header {
     return '<input type="hidden" name="submitted" value="edit" />'.      my ($mode)=@_;
       my $return = '<input type="hidden" name="submitted" value="edit" />'.
  &remember_problem_state('edit').'   &remember_problem_state('edit').'
 <div class="LC_edit_problem_header">          <div class="LC_edit_problem_header">
 <div class="LC_edit_problem_header_title">          <div class="LC_edit_problem_header_title">
 '.&mt('Problem Editing').&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'          '.&mt('Problem Editing').$mode.&Apache::loncommon::help_open_menu('Problem Editing','Problem_Editor_XML_Index',5,'Authoring').'
 </div>'.           </div><div class="LC_edit_actionbar" id="actionbar">'.
 '<input type="hidden" name="problemmode" value="saveedit" />'.           '<input type="hidden" name="problemmode" value="saveedit" />'.
 &problem_edit_buttons().'           &problem_edit_buttons();
 <hr style="clear:both;" />  
 '.&Apache::lonxml::message_location().'      $return .= '</div></div>' . &Apache::lonxml::message_location();
 </div>      $return .= '<link rel="stylesheet" href="/adm/codemirror/codemirror-combined.css" />
 '.      <script type="text/javascript" src="/adm/codemirror/codemirror-compressed-colorful.js"></script>';
        '<table border="0" width="100%"><tr><td bgcolor="#F8F8F8">';  
       $return .= '<script type="text/javascript" src="/adm/jQuery/addons/jquery-scrolltofixed.js"></script>
           <script type="text/javascript">
               // unless internet explorer
               if (!(window.navigator.appName == "Microsoft Internet Explorer" && (document.documentMode || document.compatMode))){
                   $(document).ready(
                       function() {
                           $(\'.LC_edit_actionbar\').scrollToFixed(
                               {
                                   fixed: function(){
                                       //$(this).find(\'.LC_edit_actionbar\').css(\'height\', \'31px\');
                                       $(this).find(\'.LC_edit_actionbar\');
                                   }
                               }
                           );
                       }
                   );
               }
           </script>
           <table id="LC_edit_problem_colorful" border="0" width="100%"><tr><td bgcolor="#F8F8F8">';
       return $return;
 }  }
   
   
 sub problem_edit_footer {  sub problem_edit_footer {
       my $resource = $env{'request.ambiguous'};
     return '</td></tr></table><br />      return '</td></tr></table><br />
 <div class="LC_edit_problem_footer">  <div class="LC_edit_problem_footer">
   <hr />'.    <hr />'.
 &problem_edit_buttons().'  &problem_edit_buttons().'
   <hr style="clear:both;" />    <hr style="clear:both;" />
     <script type="text/javascript">
         restoreState("'.$resource.'");
         restoreScrollPosition("'.$resource.'");
     </script>
 </div>  </div>
 '.  '.
     "\n</form>\n".&Apache::loncommon::end_page();      "\n</form>\n".&Apache::loncommon::end_page();
Line 729  $show_all Line 947  $show_all
 <select name='problemstatus'>  <select name='problemstatus'>
   <option value=''></option>    <option value=''></option>
   ".&option('yes','problemstatus').&mt("Show Feedback")."</option>    ".&option('yes','problemstatus').&mt("Show Feedback")."</option>
   ".&option('no', 'problemstatus').&mt("Don't Show Incorect/Correct Feedback")."</option>    ".&option('no', 'problemstatus').&mt("Don't Show Incorrect/Correct Feedback")."</option>
   ".&option('no_feedback_ever', 'problemstatus').&mt("Don't Show Any Feedback")."</option>    ".&option('no_feedback_ever', 'problemstatus').&mt("Don't Show Any Feedback")."</option>
 </select>  </select>
 </span>  </span>
Line 831  sub initialize_storage { Line 1049  sub initialize_storage {
  }   }
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
     &Apache::lonnet::tmprestore($namespace,'',$domain,$name);      &Apache::lonnet::tmprestore($namespace,'',$domain,$name);
  my ($temp)=keys %Apache::lonhomework::history ;   my ($temp)=keys(%Apache::lonhomework::history);
  &Apache::lonxml::debug("Return message of $temp");   &Apache::lonxml::debug("Return message of $temp");
     } else {      } else {
  %Apache::lonhomework::history=   %Apache::lonhomework::history=
Line 839  sub initialize_storage { Line 1057  sub initialize_storage {
     }      }
   
     #ignore error conditions      #ignore error conditions
     my ($temp)=keys %Apache::lonhomework::history ;      my ($temp)=keys(%Apache::lonhomework::history);
     if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }      if ($temp =~ m/^error:.*/) { %Apache::lonhomework::history=(); }
 }  }
   
Line 847  sub initialize_storage { Line 1065  sub initialize_storage {
   
 =item finalize_storage()  =item finalize_storage()
   
  Stores away the result has to a student's environment   Stores away the result hash to a student's environment;
  checks form.grade_ for specific values, other wises stores   checks form.grade_ for specific values, otherwise stores
  to the running users environment   to the running user's environment.
  Will increment totals for attempts, students, and corrects  
  if running user has student role.          &check_correctness_changes() is called in two circumstances
           in which the results hash is to be stored permanently, for
           grading triggered by a student's submission, where feedback on
           correctness is to be provided to the student.
   
           1. Immediately prior to storing the results hash
   
           To handle the case where a student's submission (and award) were
           stored after history was retrieved in &initialize_storage(), e.g.,
           if a student submitted answers in quick succession (e.g., from
           multiple tabs).  &Apache::inputtags::hidealldata() is called for
           any parts with out-of-order storage (i.e., correct then incorrect,
           where awarded >= 1 when correct).
   
           2. Immediately after storing the results hash
   
           To handle the case where lond on the student's homeserver returns
           delay:N -- where N is the number of transactions between the last
           retrieved in &initialize_storage() and the last stored immediately
           before permanent storage of the current transaction via
           lond::store_handler().  &Apache::grades::makehidden() is called
           for any parts with out-of-order storage (i.e., correct then incorrect,
           where awarded >= 1 when correct).
   
    Will call &store_aggregates() to increment totals for attempts,
    students, and corrects, if running user has student role.
   
 =cut  =cut
   
   
Line 864  sub finalize_storage { Line 1107  sub finalize_storage {
  delete(@Apache::lonhomework::results{@remove});   delete(@Apache::lonhomework::results{@remove});
  my ($symb,$courseid,$domain,$name) =    my ($symb,$courseid,$domain,$name) = 
     &Apache::lonnet::whichuser($given_symb);      &Apache::lonnet::whichuser($given_symb);
           my ($passback,$pbscope,$pbmap,$pbsymb,$pbtype,$crsdef,$ltinum,
               $ltiref,$total,$possible,$dopassback);
  if ($env{'request.state'} eq 'construct'    if ($env{'request.state'} eq 'construct' 
     || $symb eq ''      || $symb eq ''
     || $Apache::lonhomework::type eq 'practice') {      || $Apache::lonhomework::type eq 'practice') {
Line 873  sub finalize_storage { Line 1118  sub finalize_storage {
       $namespace,'',$domain,$name);        $namespace,'',$domain,$name);
     &Apache::lonxml::debug('Construct Store return message:'.$result);      &Apache::lonxml::debug('Construct Store return message:'.$result);
  } else {   } else {
               my ($laststore,$checkedparts,@parts,%postcorrect,%record);
               if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
                   (!$Apache::lonhomework::scantronmode) && (!defined($env{'form.grade_symb'})) &&
                   (!defined($env{'form.grade_courseid'}))) {
                   if (($env{'request.lti.login'}) || ($env{'request.deeplink.login'})) {
                       my ($map)=&Apache::lonnet::decode_symb($symb);
                       $map = &Apache::lonnet::clutter($map);
                       if ($env{'request.lti.login'}) {
                           ($passback,$pbscope,$pbmap,$pbsymb,$ltinum,$ltiref) =
                               &needs_lti_passback($courseid,$symb,$map);
                       } elsif ($env{'request.deeplink.login'}) {
                           ($passback,$pbscope,$pbmap,$pbsymb,$crsdef,$ltinum,$ltiref) =
                               &needs_linkprot_passback($courseid,$symb,$map);
                       }
                   }
                   if ($Apache::lonhomework::history{'version'}) {
                       $laststore = $Apache::lonhomework::history{'version'}.'='.
                                    $Apache::lonhomework::history{'timestamp'};
                   } else {
                       $laststore = '0=0';
                   }
                   %record = &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                   if ($record{'version'}) {
                       my ($newversion,$oldversion,$oldtimestamp);
                       if ($Apache::lonhomework::history{'version'}) {
                           $oldversion = $Apache::lonhomework::history{'version'};
                           $oldtimestamp = $Apache::lonhomework::history{'timestamp'};
                       } else {
                           $oldversion = 0;
                           $oldtimestamp = 0;
                       }
                       if ($record{'version'} > $oldversion) {
                           if ($record{'timestamp'} >= $oldtimestamp) {
                               $laststore = $record{'version'}.'='.$record{'timestamp'};
                               $newversion = $record{'version'} + 1;
                               $checkedparts = 1;
                               foreach my $key (keys(%Apache::lonhomework::results)) {
                                   if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                                       my $part = $1;
                                       if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                                           push(@parts,$part);
                                       }
                                   }
                               }
                               if (@parts) {
                                   my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                                                                                  \%record,\@parts,$newversion,
                                                                                  $oldversion);
                                   if (@parts_to_hide) {
                                       foreach my $part (@parts_to_hide) {
                                           $postcorrect{$part} = 1;
                                           &Apache::inputtags::hidealldata($part);
                                       }
                                   }
                               }
                           }
                       }
                   }
               }
     $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results,      $result=&Apache::lonnet::cstore(\%Apache::lonhomework::results,
     $symb,$courseid,$domain,$name);      $symb,$courseid,$domain,$name,$laststore);
               if ($result =~ /^delay\:(\d+)$/) {
                   my $numtrans = $1;
                   my ($oldversion) = split(/=/,$laststore);
                   if ($numtrans) {
                       my $newversion = $oldversion + 1 + $numtrans;
                       my @possparts;
                       if ($checkedparts) {
                           foreach my $part (@parts) {
                               unless ($postcorrect{$part}) {
                                   push(@possparts,$part);
                               }
                           }
                       } else {
                           foreach my $key (keys(%Apache::lonhomework::results)) {
                               if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                                   my $part = $1;
                                   unless ($postcorrect{$part}) {
                                       if ($Apache::lonhomework::results{$key} eq 'incorrect_attempted') {
                                           push(@possparts,$part);
                                       }
                                   }
                               }
                           }
                       }
                       if (@possparts) {
                           my %newrecord = &Apache::lonnet::restore($symb,$courseid,$domain,$name);
                           my @parts_to_hide = &check_correctness_changes($symb,$courseid,$domain,$name,
                                                                          \%newrecord,\@possparts,$newversion,
                                                                          $oldversion);
                           if (@parts_to_hide) {
                               my $partslist = join(',',@parts_to_hide);
                               &Apache::grades::makehidden($newversion,$partslist,\%newrecord,$symb,$domain,$name,1);
                           }
                       }
                   }
               }
               if ($passback) {
                   foreach my $key (keys(%Apache::lonhomework::results)) {
                       if ($key =~ /^resource\.([^\.]+)\.solved$/) {
                           my $part = $1;
                           if ((($Apache::lonhomework::results{$key} =~ /^correct_/) ||
                               ($Apache::lonhomework::results{$key} eq 'incorrect_attempted')) &&
                               ($Apache::lonhomework::results{"resource.$part.tries"})) {
                               $dopassback = 1;
                               last;
                           }
                       }
                   }
               }
               if (($dopassback) && ($pbscope eq 'resource') && ($pbsymb eq $symb)) {
                   $total = 0;
                   $possible = 0;
                   my $navmap = Apache::lonnavmaps::navmap->new();
                   if (ref($navmap)) {
                       my $res = $navmap->getBySymb($symb);
                       if (ref($res)) {
                           my $partlist = $res->parts();
                           if (ref($partlist) eq 'ARRAY') {
                               foreach my $part (@{$partlist}) {
                                   unless (exists($Apache::lonhomework::results{"resource.$part.solved"})) {
                                       next if ($Apache::lonhomework::record{"resource.$part.solved"} =~/^excused/);
                                       my $weight = &Apache::lonnet::EXT("resource.$part.weight",$symb);
                                       $possible += $weight;
                                       if (($record{'version'}) && (exists($record{"resource.$part.awarded"}))) {
                                           my $awarded = $record{"resource.$part.awarded"};
                                           if ($awarded) {
                                               $total += $weight * $awarded;
                                           }
                                       }
                                   }
                               }
                           }
                       }
                   }
                   foreach my $key (keys(%Apache::lonhomework::results)) {
                       if ($key =~ /^resource\.([^\.]+)\.awarded$/) {
                           my $part = $1;
                           my $weight = &Apache::lonnet::EXT("resource.$part.weight",$symb);
                           $possible += $weight;
                           my $awarded = $Apache::lonhomework::results{$key};
                           if ($awarded) {
                               $total += $weight * $awarded;
                           }
                       }
                   }
               }
     &Apache::lonxml::debug('Store return message:'.$result);      &Apache::lonxml::debug('Store return message:'.$result);
             &store_aggregates($symb,$courseid);              &store_aggregates($symb,$courseid);
               if ($dopassback) {
                   my $scoreformat = 'decimal';
                   if (($env{'request.lti.login'}) || ($env{'request.deeplink.login'})) {
                       if (ref($ltiref) eq 'HASH') {
                           if ($ltiref->{'scoreformat'} =~ /^(decimal|ratio|percentage)$/) {
                               $scoreformat = $1;
                           }
                       }
                   }
                   my ($pbid,$pburl,$pbtype);
                   if ($env{'request.lti.login'}) {
                       $pbid = $env{'request.lti.passbackid'};
                       $pburl = $env{'request.lti.passbackurl'};
                       $pbtype = 'lti';
                   } elsif ($env{'request.deeplink.login'}) {
                       $pbid = $env{'request.linkprotpbid'};
                       $pburl = $env{'request.linkprotpburl'};
                       $pbtype = 'linkprot';
                   }
                   my $ltigrade = {
                                    'ltinum'   => $ltinum,
                                    'lti'      => $ltiref,
                                    'crsdef'   => $crsdef,
                                    'cid'      => $courseid,
                                    'uname'    => $env{'user.name'},
                                    'udom'     => $env{'user.domain'},
                                    'pbid'     => $pbid,
                                    'pburl'    => $pburl,
                                    'pbtype'   => $pbtype,
                                    'scope'    => $pbscope,
                                    'pbmap'    => $pbmap,
                                    'pbsymb'   => $pbsymb,
                                    'format'   => $scoreformat,
                                  };
                   if ($pbscope eq 'resource') {
                       $ltigrade->{'total'} = $total;
                       $ltigrade->{'possible'} = $possible;
                   }
                   push(@Apache::lonhomework::ltipassback,$ltigrade);
               }
  }   }
     } else {      } else {
  &Apache::lonxml::debug('Nothing to store');   &Apache::lonxml::debug('Nothing to store');
Line 884  sub finalize_storage { Line 1314  sub finalize_storage {
     return $result;      return $result;
 }  }
   
   sub needs_lti_passback {
       my ($courseid,$symb,$map) = @_;
       if (($env{'request.lti.passbackid'}) && ($env{'request.lti.passbackurl'})) {
           if ($courseid =~ /^($LONCAPA::match_domain)_($LONCAPA::match_courseid)$/) {
               my ($cdom,$cnum) = ($1,$2);
               my %lti = &Apache::lonnet::get_domain_lti($cdom,'provider');
               if (ref($lti{$env{'request.lti.login'}}) eq 'HASH') {
                   if ($lti{$env{'request.lti.login'}}{'passback'}) {
                       my $itemnum = $env{'request.lti.login'};
                       my ($ltiscope,$ltiuri,$ltisymb) =
                           &LONCAPA::ltiutils::lti_provider_scope($env{'request.lti.uri'},
                                                                  $cdom,$cnum,1);
                       my ($passback,$ltimap);
                       if ($ltiscope eq 'resource') {
                           if ($ltisymb eq $symb) {
                               $passback = 1;
                           }
                       } elsif ($ltiscope eq 'map') {
                           if ($ltiuri eq $map) {
                               $passback = 1;
                               $ltimap = $map;
                           }
                       } elsif ($ltiscope eq 'course') {
                           if (($env{'request.lti.uri'} eq "/$cdom/$cnum") || ($env{'request.lti.uri'} eq '')) {
                               $passback = 1;
                           }
                       }
                       return ($passback,$ltiscope,$ltimap,$ltisymb,$itemnum,$lti{$itemnum});
                   }
               }
           }
       }
       return;
   }
   
   sub needs_linkprot_passback {
       my ($courseid,$symb,$map) = @_;
       if (($env{'request.linkprotpbid'}) && ($env{'request.linkprotpburl'})) {
           if ($courseid =~ /^($LONCAPA::match_domain)_($LONCAPA::match_courseid)$/) {
               my ($cdom,$cnum) = ($1,$2);
               my ($deeplink_symb,$deeplink_map,$deeplink,$passback);
               $deeplink_symb = &Apache::loncommon::deeplink_login_symb($cnum,$cdom);
               if ($deeplink_symb) {
                   if ($deeplink_symb =~ /\.(page|sequence)$/) {
                       $deeplink_map = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[2]);
                       my $navmap = Apache::lonnavmaps::navmap->new();
                       if (ref($navmap)) {
                           $deeplink = $navmap->get_mapparam(undef,$deeplink_map,'0.deeplink');
                       }
                   } else {
                       $deeplink = &Apache::lonnet::EXT('resource.0.deeplink',$deeplink_symb);
                       $deeplink_map = &Apache::lonnet::deversion((&Apache::lonnet::decode_symb($deeplink_symb))[0]);
                   }
                   if (($deeplink ne '') && ($env{'request.linkprot'} ne '')) {
                       my ($itemid,$tinyurl) = split(/:/,$env{'request.linkprot'});
                       if ($itemid =~ /^(\d+)(c|d)$/) {
                           my ($itemnum,$itemtype) = ($1,$2);
                           my ($crsdef,$lti_in_use);
                           if ($itemtype eq 'c') {
                               $crsdef = 1;
                               my %crslti = &Apache::lonnet::get_course_lti($cnum,$cdom,'provider');
                               $lti_in_use = $crslti{$itemnum};
                           } else {
                               my %domlti = &Apache::lonnet::get_domain_lti($cdom,'linkprot');
                               $lti_in_use = $domlti{$itemnum};
                           }
                           my ($state,$others,$listed,$scope,$protect,$display,$target,$exit) = split(/,/,$deeplink);
                           my $passback;
                           if ($scope eq 'resource') {
                               if ($deeplink_symb eq $symb) {
                                   $passback = 1;
                               }
                           } elsif ($scope eq 'map') {
                               if (&Apache::lonnet::clutter($deeplink_map) eq $map) {
                                   $passback = 1;
                               }
                           } elsif ($scope eq 'recurse') {
   #FIXME check if $deeplink_map contains $map
                               $passback = 1;
                           }
                           return ($passback,$scope,$deeplink_map,$deeplink_symb,$crsdef,$itemnum,$lti_in_use);
                       }
                   }
               }
           }
       }
   }
   
   =pod
   
   =item check_correctness_changes()
   
           For all parts for which current results contain a solved status
           of "incorrect_attempted", check if there was a transaction in which
           solved was set to "correct_by_student" in the time since the last
           transaction (retrieved when &initialize_storage() was called i.e.,
           when &start_problem() was called), unless:
           (a) questiontype parameter is set to survey or anonymous survey (+/- credit)
           (b) problemstatus is set to no or no_feedback_ever
           If such a transaction exists, and did not occur after "reset status"
           by a user with grading privileges, then the current transaction is an
           example of an out-of-order transaction (i.e., incorrect occurring after
           correct).  Accordingly, the current transaction should be hidden.
   
   =cut
   
   
   sub check_correctness_changes {
       my ($symb,$courseid,$domain,$name,$record,$parts,$newversion,$oldversion) = @_;
       my @parts_to_hide;
       unless ((ref($record) eq 'HASH') && (ref($parts) eq 'ARRAY')) {
           return @parts_to_hide;
       }
       if (@{$parts}) {
           my $usec;
           if (($env{'user.name'} eq $name) && ($env{'user.domain'} eq $domain) &&
               ($env{'request.course.id'} eq $courseid)) {
               $usec = $env{'request.course.sec'};
           } else {
               $usec = &Apache::lonnet::getsection($domain,$name,$courseid);
           }
           foreach my $id (@{$parts}) {
               next if (($Apache::lonhomework::results{'resource.'.$id.'.type'} =~ /survey/) ||
                        (&Apache::lonnet::EXT("resource.$id.problemstatus",$symb,
                                              $domain,$name,$usec,undef,$courseid) =~ /^no/));
               my $reset;
               for (my $i=$newversion-1; $i>=$oldversion; $i--) {
                   if (($record->{$i.':resource.'.$id.'.regrader'}) &&
                       ($record->{$i.':resource.'.$id.'.tries'} eq '') &&
                       ($record->{$i.':resource.'.$id.'.award'} eq '')) {
                       $reset = 1;
                   } elsif (($record->{$i.":resource.$id.solved"} eq 'correct_by_student') &&
                            ($record->{$i.":resource.$id.awarded"} >= 1)) {
                       unless ($reset) {
                           push(@parts_to_hide,$id);
                           last;
                       }
                   }
               }
           }
       }
       return @parts_to_hide;
   }
   
 =pod  =pod
   
 item store_aggregates()  item store_aggregates()
Line 948  sub store_aggregates { Line 1522  sub store_aggregates {
             }              }
         }          }
     }      }
     if (keys (%aggregate) > 0) {      if (keys(%aggregate) > 0) {
  &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,   &Apache::lonnet::cinc('nohist_resourcetracker',\%aggregate,
                             $cdomain,$cname);                              $cdomain,$cname);
     }      }
Line 976  sub checkout_msg { Line 1550  sub checkout_msg {
 <p class="LC_warning">$lt{'warning'}</p>  <p class="LC_warning">$lt{'warning'}</p>
 <form name="checkout" method="post" action="$uri">  <form name="checkout" method="post" action="$uri">
 <input type="hidden" name="doescheckout" value="yes" />  <input type="hidden" name="doescheckout" value="yes" />
 <input type="button" name="checkoutbutton" value="$lt{'checkout'}" onClick="javascript:if (confirm('$lt{'checkout?'}')) { document.checkout.submit(); }" />  <input type="button" name="checkoutbutton" value="$lt{'checkout'}" onclick="javascript:if (confirm('$lt{'checkout?'}')) { document.checkout.submit(); }" />
 </form>  </form>
 ENDCHECKOUT  ENDCHECKOUT
 }  }
Line 1007  sub firstaccess_msg { Line 1581  sub firstaccess_msg {
     my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});      my $uri = &Apache::lonenc::check_encrypt($env{'request.uri'});
     my $buttontext = &mt('Show Resource');      my $buttontext = &mt('Show Resource');
     my $timertext = &mt('Start Timer?');      my $timertext = &mt('Start Timer?');
       my $shownsymb = &HTML::Entities::encode(&Apache::lonenc::check_encrypt($symb),'\'"<>&');
     $result .= (<<ENDCHECKOUT);      $result .= (<<ENDCHECKOUT);
 <form name="markaccess" method="post" action="$uri">  <form name="markaccess" method="post" action="$uri">
 <input type="hidden" name="markaccess" value="yes" />  <input type="hidden" name="markaccess" value="yes" />
 <input type="button" name="accessbutton" value="$buttontext" onClick="javascript:if (confirm('$timertext')) { document.markaccess.submit(); }" />  <input type="hidden" name="symb" value="$shownsymb" />
   <input type="button" name="accessbutton" value="$buttontext" onclick="javascript:if (confirm('$timertext')) { document.markaccess.submit(); }" />
 </form>  </form>
 ENDCHECKOUT  ENDCHECKOUT
     return $result;      return $result;
Line 1045  sub init_problem_globals { Line 1621  sub init_problem_globals {
     @Apache::inputtags::importlist = ();      @Apache::inputtags::importlist = ();
     @Apache::inputtags::previous=();      @Apache::inputtags::previous=();
     @Apache::inputtags::previous_version=();      @Apache::inputtags::previous_version=();
       $Apache::inputtags::leniency='';
     $Apache::structuretags::printanswer='No';      $Apache::structuretags::printanswer='No';
     @Apache::structuretags::whileconds=();      @Apache::structuretags::whileconds=();
     @Apache::structuretags::whilebody=();      @Apache::structuretags::whilebody=();
     @Apache::structuretags::whileline=();      @Apache::structuretags::whileline=();
     $Apache::lonhomework::scantronmode=0;      $Apache::lonhomework::scantronmode=0;
       $Apache::lonhomework::randomizetrypart=0;
     undef($Apache::lonhomework::name);      undef($Apache::lonhomework::name);
     undef($Apache::lonhomework::default_type);      undef($Apache::lonhomework::default_type);
     undef($Apache::lonhomework::type);      undef($Apache::lonhomework::type);
Line 1060  sub reset_problem_globals { Line 1638  sub reset_problem_globals {
     undef(%Apache::lonhomework::history);      undef(%Apache::lonhomework::history);
     undef(%Apache::lonhomework::results);      undef(%Apache::lonhomework::results);
     undef($Apache::inputtags::part);      undef($Apache::inputtags::part);
       undef($Apache::inputtags::leniency);
     if ($type eq 'Task') {      if ($type eq 'Task') {
         undef($Apache::inputtags::slot_name);          undef($Apache::inputtags::slot_name);
       } elsif ($type eq 'problem') {
           undef($Apache::lonhomework::rawrndseed);
     }      }
 #don't undef this, lonhomework.pm takes care of this, we use this to   #don't undef this, lonhomework.pm takes care of this, we use this to 
 #detect if we try to do 2 problems in one file  #detect if we try to do 2 problems in one file
Line 1070  sub reset_problem_globals { Line 1651  sub reset_problem_globals {
     undef($Apache::lonhomework::default_type);      undef($Apache::lonhomework::default_type);
     undef($Apache::lonhomework::type);      undef($Apache::lonhomework::type);
     undef($Apache::lonhomework::scantronmode);      undef($Apache::lonhomework::scantronmode);
       undef($Apache::inputtags::randomizetrypart);
     undef($Apache::lonhomework::ignore_response_errors);      undef($Apache::lonhomework::ignore_response_errors);
     undef(@Apache::functionplotresponse::callscripts);      undef(@Apache::functionplotresponse::callscripts);
     &Apache::lonhomework::reset_show_problem_status();      &Apache::lonhomework::reset_show_problem_status();
Line 1163  sub start_problem { Line 1745  sub start_problem {
     my $resource_due;      my $resource_due;
   
     my $name= &get_resource_name($parstack,$safeeval);      my $name= &get_resource_name($parstack,$safeeval);
     my ($result,$form_tag_start,$slot_name,$slot);      my ($result,$form_tag_start,$slot_name,$slot,$probpartlist,$firstaccres);
   
     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||      if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
         $target eq 'tex') {          $target eq 'tex') {
         if ($env{'form.markaccess'}) {          if ($env{'form.markaccess'}) {
             my @interval=&Apache::lonnet::EXT("resource.0.interval");              my @interval=&Apache::lonnet::EXT("resource.0.interval");
             &Apache::lonnet::set_first_access($interval[1]);              my ($timelimit) = ($interval[0] =~ /^(\d+)/);
               my $is_set = &Apache::lonnet::set_first_access($interval[1],$timelimit);
               unless (($is_set eq 'ok') || ($is_set eq 'already_set')) {
                   $firstaccres = $is_set;
               }
         }          }
   
         ($status,$accessmsg,$slot_name,$slot) =          ($status,$accessmsg,$slot_name,$slot) =
Line 1179  sub start_problem { Line 1765  sub start_problem {
   
     if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'      if ($target eq 'web' || $target eq 'webgrade' || $target eq 'tex'
  || $target eq 'edit') {   || $target eq 'edit') {
  ($result,$form_tag_start) =   ($result,$form_tag_start,$probpartlist) =
     &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,      &page_start($target,$token,$tagstack,$parstack,$parser,$safeeval,
  $name);   $name);
       } elsif (($target eq 'grade') && ($Apache::lonhomework::type eq 'randomizetry')) {
           my ($symb)= &Apache::lonnet::whichuser();
           if ($symb ne '') {
               my $navmap = Apache::lonnavmaps::navmap->new();
               if (ref($navmap)) {
                   my $res = $navmap->getBySymb($symb);
                   if (ref($res)) {
                       $probpartlist = $res->parts();
                   }
               }
           }
     }      }
   
     if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';}      if ($target eq 'tex' and $env{'request.symb'} =~ m/\.page_/) {$result='';}
Line 1190  sub start_problem { Line 1787  sub start_problem {
     if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||      if ($target eq 'web' || $target eq 'grade' || $target eq 'answer' ||
  $target eq 'tex') {   $target eq 'tex') {
   
           my ($symb) = &Apache::lonnet::whichuser();
  #handle rand seed in construction space   #handle rand seed in construction space
  my $rndseed=&setup_rndseed($safeeval,$target);          if (($env{'request.state'} eq 'construct') || ($symb eq '')) {
  my ($symb)=&Apache::lonnet::whichuser();              my $partorder=&Apache::lonnet::metadata($env{'request.uri'},'partorder');
               if ($partorder ne '') {
                   @{$probpartlist} = split(/,/,$partorder);
               }
           }
    my $rndseed=&setup_rndseed($safeeval,$target,$probpartlist);
           if (($target eq 'grade') && &Apache::response::submitted()) {
               if ($Apache::lonhomework::type eq 'randomizetry') {
                   $Apache::lonhomework::results{'resource.0.rndseed'}=$rndseed;
               } else {
                   my @parts;
                   if (ref($probpartlist) eq 'ARRAY') {
                       @parts = @{$probpartlist};
                   }
                   unless (@parts) {
                       $Apache::lonhomework::results{'resource.0.rndseed'}=$Apache::lonhomework::rawrndseed;
                   }
               }
           }
   
  if ($env{'request.state'} ne "construct" &&    if ($env{'request.state'} ne "construct" && 
     ($symb eq '' || $Apache::lonhomework::type eq 'practice')) {      ($symb eq '' || $Apache::lonhomework::type eq 'practice')) {
               my $rndseedval = $rndseed;
               if (($symb eq '') && ($Apache::lonhomework::type eq 'randomizetry')) {
                   $rndseedval = $env{'form.rndseed'};
               }
     $form_tag_start.='<input type="hidden" name="rndseed" value="'.      $form_tag_start.='<input type="hidden" name="rndseed" value="'.
  $rndseed.'" />'.   $rndseedval.'" />'.
     '<input type="submit" name="resetdata"      '<input type="submit" name="resetdata"
                              value="'.&mt('New Problem Variation').'" />';                               value="'.&mt('New Problem Variation').'" />';
     if (exists($env{'form.username'})) {      if (exists($env{'form.username'})) {
Line 1219  sub start_problem { Line 1839  sub start_problem {
                 $form_tag_start.=&practice_problem_header();                  $form_tag_start.=&practice_problem_header();
             }              }
     $form_tag_start.='<hr />';      $form_tag_start.='<hr />';
         } elsif (($env{'request.state'} ne "construct") &&          }
                  ($Apache::lonhomework::type eq 'randomizetry') &&          if (($env{'request.state'} ne "construct") &&
                  ($status eq 'CAN_ANSWER')) {              ($Apache::lonhomework::type eq 'randomizetry') &&
             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");              ($status eq 'CAN_ANSWER')) {
             my $problemstatus = &get_problem_status($Apache::inputtags::part);              my @parts;
             $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries);              if (ref($probpartlist) eq 'ARRAY') {
                   @parts = @{$probpartlist};
               }
               unless (@parts) {
                   my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
                   my $problemstatus = &get_problem_status($Apache::inputtags::part);
                   $form_tag_start.=&randomizetry_problem_header($problemstatus,$reqtries,$symb);
               }
         }          }
   
  my $expression='$external::datestatus="'.$status.'";';   my $expression='$external::datestatus="'.$status.'";';
Line 1261  sub start_problem { Line 1888  sub start_problem {
  } elsif ($status eq 'UNCHECKEDOUT') {   } elsif ($status eq 'UNCHECKEDOUT') {
     $msg.=&checkout_msg();      $msg.=&checkout_msg();
  } elsif ($status eq 'NOT_YET_VIEWED') {   } elsif ($status eq 'NOT_YET_VIEWED') {
                       if ($firstaccres) {
                           $msg .= '<p class="LC_error">'.
                                   &mt('A problem occurred when trying to start the timer.').'</p>';
                       }
     $msg.=&firstaccess_msg($accessmsg,$symb);      $msg.=&firstaccess_msg($accessmsg,$symb);
  } elsif ($status eq 'NOT_IN_A_SLOT') {   } elsif ($status eq 'NOT_IN_A_SLOT') {
     $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work");      $msg.=&Apache::bridgetask::add_request_another_attempt_button("Sign up for time to work");
Line 1336  sub start_problem { Line 1967  sub start_problem {
                     $result.= '<input type="submit" name="resetdata" '.                      $result.= '<input type="submit" name="resetdata" '.
                               'value="'.&mt('New Problem Variation').'" />'.                                'value="'.&mt('New Problem Variation').'" />'.
                               &practice_problem_header().'<hr />';                                &practice_problem_header().'<hr />';
                   } elsif ($Apache::lonhomework::type eq 'randomizetry') {
                       my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");
                       my $problemstatus = &get_problem_status($Apache::inputtags::part);
                       $result.=&randomizetry_problem_header($problemstatus,$reqtries);
                 }                  }
     }      }
     # if we are viewing someone else preserve that info      # if we are viewing someone else preserve that info
Line 1399  sub end_problem { Line 2034  sub end_problem {
  my $id = $Apache::inputtags::part;   my $id = $Apache::inputtags::part;
  my $weight = &Apache::lonnet::EXT("resource.$id.weight");   my $weight = &Apache::lonnet::EXT("resource.$id.weight");
  my $packages=&Apache::lonnet::metadata($env{'request.uri'},'packages');   my $packages=&Apache::lonnet::metadata($env{'request.uri'},'packages');
  my @packages = split /,/,$packages;   my @packages = split(/,/,$packages);
  my $allow_print_points = 0;   my $allow_print_points = 0;
  foreach my $partial_key (@packages) {   foreach my $partial_key (@packages) {
     if ($partial_key=~m/^part_0$/) {      if ($partial_key=~m/^part_0$/) {
Line 1537  sub end_problem { Line 2172  sub end_problem {
     }      }
  }   }
         if ($target eq 'web') {          if ($target eq 'web') {
            $result.=&Apache::functionplotresponse::init_script();              $result.=&Apache::functionplotresponse::init_script();
               if ($Apache::lonhomework::default_type eq 'randomizetry') {
                   my ($symb) = &Apache::lonnet::whichuser();
                   if ((($env{'request.state'} eq 'construct') || ($symb eq '')) &&
                       ($status eq 'CAN_ANSWER')) {
                       unless (@Apache::inputtags::partlist > 1) {
                           $result.= <<"ENDJS";
   <script type="text/javascript">
   // <![CDATA[
       \$(document).ready(function() {
            \$('#LC_randomizetry_header').css('display','block');
       });
   // ]]>
   </script>
   ENDJS
                       }
                   }
               }
         }          }
  if ($target eq 'grade') {   if ($target eq 'grade') {
     &Apache::lonhomework::showhash(%Apache::lonhomework::results);      &Apache::lonhomework::showhash(%Apache::lonhomework::results);
Line 1631  sub end_library { Line 2283  sub end_library {
      && ($#$tagstack eq 0 && $$tagstack[0] eq 'library')        && ($#$tagstack eq 0 && $$tagstack[0] eq 'library') 
      && $env{'request.state'} eq "construct") {       && $env{'request.state'} eq "construct") {
  $result.='</form>'.&Apache::loncommon::end_page({'discussion' => 1});   $result.='</form>'.&Apache::loncommon::end_page({'discussion' => 1});
       } elsif ($target eq 'meta') {
           $result.=&Apache::response::meta_response_order();
     }      }
     if ( $#$tagstack eq 0 && $$tagstack[0] eq 'library') {      if ( $#$tagstack eq 0 && $$tagstack[0] eq 'library') {
  &reset_problem_globals('library');   &reset_problem_globals('library');
Line 2058  sub end_while { Line 2712  sub end_while {
     }      }
     $return = &Apache::run::run($code,$safeeval);      $return = &Apache::run::run($code,$safeeval);
  }   }
  if ($error) {          if ($error) {
     &Apache::lonxml::error('<pre>'.&mt('Code ran too long. It ran for more than').' '.$Apache::lonnet::perlvar{'lonScriptTimeout'}.' '.&mt('seconds occurred while running &lt;while&gt; on line').' '.$line.'</pre>');              &Apache::lonxml::error(
  }                  '<pre>'
                  .&mt('Code ran too long. It ran for more than [_1] seconds.',
                           $Apache::lonnet::perlvar{'lonScriptTimeout'})
                  .&mt('This occurred while running &lt;while&gt; on line [_1].',
                           $line)
                  .'</pre>');
           }
     } elsif ($target eq "edit") {      } elsif ($target eq "edit") {
  $result.= &Apache::edit::tag_end($target,$token,'');   $result.= &Apache::edit::tag_end($target,$token,'');
     }      }
Line 2107  sub start_randomlist { Line 2767  sub start_randomlist {
  }   }
  if (@randomlist) {   if (@randomlist) {
     my @idx_arr = (0 .. $#randomlist);      my @idx_arr = (0 .. $#randomlist);
     &Apache::structuretags::shuffle(\@idx_arr);              if ($env{'form.code_for_randomlist'}) {
                   &Apache::structuretags::shuffle(\@idx_arr,$target);
                   undef($env{'form.code_for_randomlist'});
               } else {
                   &Apache::structuretags::shuffle(\@idx_arr);
               }
     my $bodytext = '';      my $bodytext = '';
     my $show=$#randomlist;      my $show=$#randomlist;
     my $showarg=&Apache::lonxml::get_param('show',$parstack,$safeeval);      my $showarg=&Apache::lonxml::get_param('show',$parstack,$safeeval);
Line 2127  sub start_randomlist { Line 2792  sub start_randomlist {
                     }                      }
                 }                  }
             }              }
     for(0 .. $show) {      for my $i (0 .. $show) {
  $bodytext .= "$randomlist[ $idx_arr[$_] ]";   $bodytext .= "$randomlist[ $idx_arr[$i] ]";
     }      }
     &Apache::lonxml::newparser($parser,\$bodytext);      &Apache::lonxml::newparser($parser,\$bodytext);
  }   }
Line 2146  sub start_randomlist { Line 2811  sub start_randomlist {
 }  }
   
 sub shuffle {  sub shuffle {
     my $a=shift;      my ($a,$target) = @_;
     my $i;      my $i;
     if (ref($a) eq 'ARRAY' && @$a) {      if (ref($a) eq 'ARRAY' && @$a) {
  &Apache::response::pushrandomnumber();   &Apache::response::pushrandomnumber(undef,$target);
  for($i=@$a;--$i;) {   for($i=@$a;--$i;) {
     my $j=int(&Math::Random::random_uniform() * ($i+1));      my $j=int(&Math::Random::random_uniform() * ($i+1));
     next if $i == $j;      next if $i == $j;
Line 2233  sub start_part { Line 2898  sub start_part {
     my $id= &Apache::lonxml::get_id($parstack,$safeeval);      my $id= &Apache::lonxml::get_id($parstack,$safeeval);
     $Apache::inputtags::part=$id;      $Apache::inputtags::part=$id;
     push(@Apache::inputtags::partlist,$id);      push(@Apache::inputtags::partlist,$id);
       $Apache::inputtags::leniency='';
     @Apache::inputtags::response=();      @Apache::inputtags::response=();
     @Apache::inputtags::previous=();      @Apache::inputtags::previous=();
     @Apache::inputtags::previous_version=();      @Apache::inputtags::previous_version=();
Line 2242  sub start_part { Line 2908  sub start_part {
     my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);      my $hidden=&Apache::loncommon::check_if_partid_hidden($Apache::inputtags::part);
     my $newtype=&Apache::lonnet::EXT("resource.$id.type");      my $newtype=&Apache::lonnet::EXT("resource.$id.type");
     if ($newtype) { $Apache::lonhomework::type=$newtype; }      if ($newtype) { $Apache::lonhomework::type=$newtype; }
       if ($Apache::lonhomework::type eq 'randomizetry') {
           my $rndseed=&setup_rndseed($safeeval,$target);
           if (($target eq 'grade') && &Apache::response::submitted()) {
               $Apache::lonhomework::results{"resource.$id.rndseed"}=$rndseed;
           }
       } elsif (($target eq 'grade') && &Apache::response::submitted()) {
           $Apache::lonhomework::results{"resource.$id.rndseed"}=$Apache::lonhomework::rawrndseed;
       }
     my $in_order_show=&ordered_show_check();      my $in_order_show=&ordered_show_check();
     my $expression='$external::part=\''.$Apache::inputtags::part.'\';';      my $expression='$external::part=\''.$Apache::inputtags::part.'\';';
     $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';      $expression.='$external::type=\''.$Apache::lonhomework::type.'\';';
Line 2292  sub start_part { Line 2966  sub start_part {
     }      }
     my $weight = &Apache::lonnet::EXT("resource.$id.weight");      my $weight = &Apache::lonnet::EXT("resource.$id.weight");
     my $allkeys=&Apache::lonnet::metadata($env{'request.uri'},'packages');      my $allkeys=&Apache::lonnet::metadata($env{'request.uri'},'packages');
     my @allkeys = split /,/,$allkeys;      my @allkeys = split(/,/,$allkeys);
     my $allow_print_points = 0;      my $allow_print_points = 0;
     foreach my $partial_key (@allkeys) {      foreach my $partial_key (@allkeys) {
  if ($partial_key=~m/^part_(.*)$/) {   if ($partial_key=~m/^part_(.*)$/) {
Line 2314  sub start_part { Line 2988  sub start_part {
  } elsif ($target eq 'web') {   } elsif ($target eq 'web') {
                     if ($status eq 'CAN_ANSWER') {                      if ($status eq 'CAN_ANSWER') {
                         my $problemstatus = &get_problem_status($Apache::inputtags::part);                           my $problemstatus = &get_problem_status($Apache::inputtags::part); 
                         my $probrandomize = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].type");  
                         my $probrandtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::partlist[0].randomizeontries");  
                         my $num = scalar(@Apache::inputtags::partlist)-1;                          my $num = scalar(@Apache::inputtags::partlist)-1;
                         if ($probrandomize eq 'randomizetry') {                          if ((($Apache::lonhomework::default_type eq 'randomizetry') ||
                             if (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") ne 'randomizetry') {                               ($Apache::lonhomework::randomizetrypart)) &&
                                 $result .= &randomizetry_part_header($problemstatus,'none',$num);                              ($Apache::lonhomework::type ne 'randomizetry')) {
                             } else {                              $result .= &randomizetry_part_header($problemstatus,'none',$num);
                                 my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");                          } elsif ($Apache::lonhomework::type eq 'randomizetry') {
                                 if ($probrandtries ne $reqtries) {                              $Apache::lonhomework::randomizetrypart = 1;
                                     $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);                              my $reqtries = &Apache::lonnet::EXT("resource.$id.randomizeontries");
                                 }  
                             }  
                         } elsif (&Apache::lonnet::EXT("resource.$Apache::inputtags::part.type") eq 'randomizetry') {  
                             my $reqtries = &Apache::lonnet::EXT("resource.$Apache::inputtags::part.randomizeontries");  
                             $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);                              $result .= &randomizetry_part_header($problemstatus,$reqtries,$num);
                         }                          }
                     }                      }
Line 2382  sub end_part { Line 3050  sub end_part {
     $gradestatus='';      $gradestatus='';
  }   }
  $result.=$gradestatus;   $result.=$gradestatus;
  if ($$tagstack[-2] eq 'td' and $target eq 'tex') {$result.='\end{minipage}';}           if ($$tagstack[-2] eq 'td' and $target eq 'tex') {
               if (not $env{'form.problem_split'}=~/yes/) {
                   $result.='\end{minipage}';
               }
           }
     } elsif ($target eq 'edit') {      } elsif ($target eq 'edit') {
  $result.=&Apache::edit::end_table();   $result.=&Apache::edit::end_table();
     } elsif ($target eq 'modified') {      } elsif ($target eq 'modified') {
Line 2390  sub end_part { Line 3062  sub end_part {
     }      }
     pop @Apache::inputtags::status;      pop @Apache::inputtags::status;
     $Apache::inputtags::part='';      $Apache::inputtags::part='';
       $Apache::inputtags::leniency='';
     $Apache::lonhomework::type = $Apache::lonhomework::default_type;      $Apache::lonhomework::type = $Apache::lonhomework::default_type;
     return $result;      return $result;
 }  }
Line 2540  sub end_startouttext { Line 3213  sub end_startouttext {
     if ($target eq 'edit') {      if ($target eq 'edit') {
  my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;   my $areaid = 'homework_edit_'.$Apache::lonxml::curdepth;
  $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);   $text=&Apache::lonxml::get_all_text("endouttext",$parser,$style);
  $result.=&Apache::edit::start_table($token)."<tr><td>".&mt('Text Block')."</td>"          $result.=&Apache::edit::start_table($token)."<tr><td>".&Apache::loncommon::insert_folding_button()
                    ." ".&mt('Text Block')."</td>"
                  .'<td><span class="LC_nobreak">'.&mt('Delete?').' '                   .'<td><span class="LC_nobreak">'.&mt('Delete?').' '
                  .&Apache::edit::deletelist($target,$token)                   .&Apache::edit::deletelist($target,$token)
                  .'</span></td>'                   .'</span></td>'
          .'<td align="left"><span id="math_'.$areaid.'" />'           .'<td><span id="math_'.$areaid.'">';
  .&Apache::lonhtmlcommon::dragmath_button($areaid,1)   if ($env{'environment.nocodemirror'}) {
  .'<span></td>'      $result.=&Apache::lonhtmlcommon::dragmath_button($areaid,1);
    } else {
       $result.='&nbsp;';
    }
    $result.='</span></td>'
  .'<td>'   .'<td>'
  .&Apache::edit::insertlist($target,$token)   .&Apache::edit::insertlist($target,$token)
  .'</td>'   .'</td>'
          .'<td align="right" valign="top">' .           .'<td class="LC_edit_problem_latexhelper">' .
          &Apache::loncommon::helpLatexCheatsheet().           &Apache::loncommon::helpLatexCheatsheet().
  &Apache::edit::end_row().   &Apache::edit::end_row().
                  &Apache::edit::start_spanning_row()."\n".                   &Apache::edit::start_spanning_row()."\n".
Line 2641  sub practice_problem_header { Line 3319  sub practice_problem_header {
 }  }
   
 sub randomizetry_problem_header {  sub randomizetry_problem_header {
     my ($problemstatus,$reqtries) = @_;      my ($problemstatus,$reqtries,$symb) = @_;
     my ($header,$text);      my ($header,$text);
     if ($reqtries > 1) {      if ($reqtries > 1) {
         $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);          $header = &mt('New Problem Variation After Every [quant,_1,Try,Tries]',$reqtries);
Line 2661  sub randomizetry_problem_header { Line 3339  sub randomizetry_problem_header {
             $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');              $text = &mt('A new variation will be generated after each try until correct or tries limit is reached.');
         }          }
     }      }
     return '<span class="LC_info"><h3>'.$header.'</h3></span>'.      if (($env{'request.state'} eq "construct") || ($symb eq '')) {
            '<span class="LC_info">'.$text.'</span><hr />';          return '<div class="LC_info" id="LC_randomizetry_header" style="display:none">'.
                  '<h3>'.$header.'</h3><span class="LC_info">'.$text.'</span><hr /></div>';
       } else {
           return '<h3 class="LC_info">'.$header.'</h3>'.
                  '<span class="LC_info">'.$text.'</span><hr />';
       }
 }  }
   
 sub randomizetry_part_header {  sub randomizetry_part_header {
Line 2670  sub randomizetry_part_header { Line 3353  sub randomizetry_part_header {
     my ($header,$text);      my ($header,$text);
     if ($reqtries eq 'none') {      if ($reqtries eq 'none') {
         $header = &mt('No Question Variation');          $header = &mt('No Question Variation');
         $text = &mt('For this question there will no new variation after a try.');          $text = &mt('For this question there will be no new variation after a try.');
     } elsif ($reqtries > 1) {      } elsif ($reqtries > 1) {
         $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);          $header = &mt('New Question Variation After Every [quant,_1,Try,Tries]',$reqtries);
         if (($problemstatus eq 'no') ||          if (($problemstatus eq 'no') ||

Removed from v.1.508  
changed lines
  Added in v.1.512.2.24.2.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>