Diff for /loncom/interface/lonnavmaps.pm between versions 1.65 and 1.66

version 1.65, 2002/10/04 15:38:22 version 1.66, 2002/10/04 20:34:04
Line 841  sub new_handle { Line 841  sub new_handle {
     $r->print("<h3>$date</h3>\n");      $r->print("<h3>$date</h3>\n");
     $r->rflush();      $r->rflush();
     if ($navmap->{LAST_CHECK}) {      if ($navmap->{LAST_CHECK}) {
  $r->print('<img src="/adm/lonMisc/chat.gif"> New discussion since '.          $r->print('<img src="/adm/lonMisc/chat.gif"> New discussion since '.
   timeToHumanString($navmap->{LAST_CHECK}).                    timeToHumanString($navmap->{LAST_CHECK}).
   '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>');                     '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>'); 
     } else {      } else {
  $r->print('<img src="/adm/lonMisc/chat.gif"> Discussions'.          $r->print('<img src="/adm/lonMisc/chat.gif"> Discussions'.
   '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>');                     '<br><img src="/adm/lonMisc/feedback.gif"> New message (click to open)<p>'); 
     }      }
     #if (($currenturl=~/^\/res/) &&      #if (($currenturl=~/^\/res/) &&
     #    ($currenturl!~/^\/res\/adm/)) {      #    ($currenturl!~/^\/res\/adm/)) {
Line 882  sub new_handle { Line 882  sub new_handle {
     my $hurryUpColor = "#FFCCCC";      my $hurryUpColor = "#FFCCCC";
   
     my %statusIconMap =       my %statusIconMap = 
  ( $res->NETWORK_FAILURE    => '',          ( $res->NETWORK_FAILURE    => '',
   $res->NOTHING_SET        => '',            $res->NOTHING_SET        => '',
   $res->CORRECT            => 'navmap.correct.gif',            $res->CORRECT            => 'navmap.correct.gif',
   $res->EXCUSED            => 'navmap.correct.gif',            $res->EXCUSED            => 'navmap.correct.gif',
   $res->PAST_DUE_NO_ANSWER => 'navmap.wrong.gif',            $res->PAST_DUE_NO_ANSWER => 'navmap.wrong.gif',
   $res->PAST_DUE_ANSWER_LATER => 'navmap.wrong.gif',            $res->PAST_DUE_ANSWER_LATER => 'navmap.wrong.gif',
   $res->ANSWER_OPEN        => 'navmap.wrong.gif',            $res->ANSWER_OPEN        => 'navmap.wrong.gif',
   $res->OPEN_LATER         => '',            $res->OPEN_LATER         => '',
   $res->TRIES_LEFT         => 'navmap.open.gif',            $res->TRIES_LEFT         => 'navmap.open.gif',
   $res->INCORRECT          => 'navmap.wrong.gif',            $res->INCORRECT          => 'navmap.wrong.gif',
   $res->OPEN               => 'navmap.open.gif' );            $res->OPEN               => 'navmap.open.gif' );
   
     my %condenseStatuses =      my %condenseStatuses =
  ( $res->NETWORK_FAILURE    => 1,          ( $res->NETWORK_FAILURE    => 1,
   $res->NOTHING_SET        => 1,            $res->NOTHING_SET        => 1,
   $res->CORRECT            => 1 );            $res->CORRECT            => 1 );
   
     my %filterHash;      my %filterHash;
     # Figure out what we're not displaying      # Figure out what we're not displaying
Line 912  sub new_handle { Line 912  sub new_handle {
     $currenturl=~s/^[^\/]+//;      $currenturl=~s/^[^\/]+//;
     my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl);      my $queryAdd = "postdata=" . &Apache::lonnet::escape($currenturl);
   
     $r->print("$currenturl<br/>");      $r->print('<a href="navmaps?condition=1&filter=">Show All Resources</a><br /><br />');
       
   
     # Begin the HTML table      # Begin the HTML table
     # four cols: resource + indent, chat+feedback, icon, text string      # four cols: resource + indent, chat+feedback, icon, text string
     $r->print('<table cellspacing="3" cellpadding="0" bgcolor="#FFFFFF">' ."\n");      $r->print('<table cellspacing="3" cellpadding="0" bgcolor="#FFFFFF">' ."\n");
   
     my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, 0);      my $condition = 0;
       if ($ENV{'form.condition'}) {
    $condition = 1;
       }
   
       my $mapIterator = $navmap->getIterator(undef, undef, \%filterHash, $condition);
     my $curRes = $mapIterator->next();      my $curRes = $mapIterator->next();
     undef $res; # so we don't accidentally use it later      undef $res; # so we don't accidentally use it later
     my $indentLevel = -1;      my $indentLevel = -1;
Line 944  sub new_handle { Line 948  sub new_handle {
   
         if (ref($curRes) && $curRes->src()) {          if (ref($curRes) && $curRes->src()) {
   
     # Step one: Decide which parts to show              # Step one: Decide which parts to show
     my @parts = @{$curRes->parts()};              my @parts = @{$curRes->parts()};
     my $multipart = scalar(@parts) > 1;              my $multipart = scalar(@parts) > 1;
     my $condensed = 0;              my $condensed = 0;
                   
             if ($curRes->is_problem()) {              if ($curRes->is_problem()) {
  # Is it multipart?                  # Is it multipart?
   
  if ($multipart) {                  if ($multipart) {
     # If it's multipart, see if part 0 is "open"                      # If it's multipart, see if part 0 is "open"
     # if it is, display all parts, if it isn't,                      # if it is, display all parts, if it isn't,
     # just display first                      # just display first
     if (!$curRes->opendate("0")) {                      if (!$curRes->opendate("0")) {
  @parts = ("0"); # just display the zero-th part                          @parts = ("0"); # just display the zero-th part
     } else {   $condensed = 1;
  # Otherwise, only display part 0 if we want to                       } else {
  # attach feedback or email information to it                          # Otherwise, only display part 0 if we want to 
  if ($curRes->hasDiscussion() || $curRes->getFeedback()) {                          # attach feedback or email information to it
     shift @parts;                          if ($curRes->hasDiscussion() || $curRes->getFeedback()) {
  } else {                              shift @parts;
     # If there's discussion or feedback, that counts                          } else {
     # as a difference, so display the parts.                              # If there's discussion or feedback, that counts
                                   # as a difference, so display the parts.
     # Now, we decide whether to condense the                              
     # parts due to similarity                              # Now, we decide whether to condense the
     my $status = $curRes->status($parts[1]);                              # parts due to similarity
     my $due = $curRes->duedate($parts[1]);                              my $status = $curRes->status($parts[1]);
     my $open = $curRes->opendate($parts[1]);                              my $due = $curRes->duedate($parts[1]);
     my $statusAllSame = 1;                              my $open = $curRes->opendate($parts[1]);
     my $dueAllSame = 1;                              my $statusAllSame = 1;
     my $openAllSame = 1;                              my $dueAllSame = 1;
     for (my $i = 2; $i < scalar(@parts); $i++) {                              my $openAllSame = 1;
  if ($curRes->status($parts[$i]) != $status){                              for (my $i = 2; $i < scalar(@parts); $i++) {
     $statusAllSame = 0;                                  if ($curRes->status($parts[$i]) != $status){
  }                                      $statusAllSame = 0;
  if ($curRes->duedate($parts[$i]) != $due ) {                                  }
     $dueAllSame = 0;                                  if ($curRes->duedate($parts[$i]) != $due ) {
  }                                      $dueAllSame = 0;
  if ($curRes->opendate($parts[$i]) != $open) {                                  }
     $openAllSame = 0;                                  if ($curRes->opendate($parts[$i]) != $open) {
  }                                      $openAllSame = 0;
     }                                  }
                                   }
     # $allSame is true if all the statuses were                              
     # the same. Now, if they are all the same and                              # $allSame is true if all the statuses were
     # match one of the statuses to condense, or they                              # the same. Now, if they are all the same and
     # are all open with the same due date, or they are                              # match one of the statuses to condense, or they
     # all OPEN_LATER with the same open date, display the                              # are all open with the same due date, or they are
     # status of the first non-zero part (to get the 'correct'                              # all OPEN_LATER with the same open date, display the
     # status right, since 0 is never 'correct' or 'open').                              # status of the first non-zero part (to get the 'correct'
     if (($statusAllSame && defined($condenseStatuses{$status})) ||                              # status right, since 0 is never 'correct' or 'open').
  ($dueAllSame && $status == $curRes->OPEN && $statusAllSame)||                              if (($statusAllSame && defined($condenseStatuses{$status})) ||
  ($openAllSame && $status == $curRes->OPEN_LATER && $statusAllSame) ){                                  ($dueAllSame && $status == $curRes->OPEN && $statusAllSame)||
  @parts = ($parts[1]);                                  ($openAllSame && $status == $curRes->OPEN_LATER && $statusAllSame) ){
  $condensed = 1;                                  @parts = ($parts[1]);
     }                                  $condensed = 1;
  }                              }
     }                          }
  }                      }
                   }
   
             } else {              } else {
                 @parts[0] = "0"; # this is to get past foreach loop below                  @parts[0] = "0"; # this is to get past foreach loop below
Line 1010  sub new_handle { Line 1015  sub new_handle {
                  # with only one part without loss                   # with only one part without loss
             }              }
   
     # Step two: Show the parts              # Display one part, in event of network error.
               # If this is a single part, we can at least show the correct
               # status, but if it's multipart, we're lost.
               if ($curRes->{RESOURCE_ERROR}) {
                   @parts = ("0");
               }
   
               # Step two: Show the parts
             foreach my $part (@parts) {              foreach my $part (@parts) {
   
  my $deltalevel = 0; # for inserting the branch icon                  my $deltalevel = 0; # for inserting the branch icon
                                   
                 # For each thing we're displaying...                  # For each thing we're displaying...
   
Line 1034  sub new_handle { Line 1046  sub new_handle {
                 if ($isNewBranch) {                  if ($isNewBranch) {
                     $newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">";                      $newBranchText = "<img src=\"/adm/lonIcons/branch.gif\" border=\"0\">";
                     $isNewBranch = 0;                      $isNewBranch = 0;
     $deltalevel = 1;                      $deltalevel = 1;
                 }                  }
   
                 # links to open and close the folders                  # links to open and close the folders
Line 1043  sub new_handle { Line 1055  sub new_handle {
   
                 my $icon = "<img src=\"/adm/lonIcons/html.gif\" alt=\"\" border=\"0\" />";                  my $icon = "<img src=\"/adm/lonIcons/html.gif\" alt=\"\" border=\"0\" />";
                 if ($curRes->is_problem()) {                   if ($curRes->is_problem()) { 
     if ($part eq "0" || $condensed) {                      if ($part eq "0" || $condensed) {
  $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border=\"0\" />';                           $icon = '<img src="/adm/lonIcons/problem.gif" alt="" border=\"0\" />'; 
     } else {                      } else {
  $icon = $indentString;                          $icon = $indentString;
     }                      }
                 }                  }
   
                 # Display the correct icon, link to open or shut map                  # Display the correct icon, link to open or shut map
Line 1056  sub new_handle { Line 1068  sub new_handle {
                     my $nowOpen = !defined($filterHash{$mapId});                      my $nowOpen = !defined($filterHash{$mapId});
                     $icon = $nowOpen ?                      $icon = $nowOpen ?
                         "folder_closed.gif" : "folder_opened.gif";                          "folder_closed.gif" : "folder_opened.gif";
     $icon = "<img src=\"/adm/lonIcons/$icon\" alt=\"\" border=\"0\" />";                      $icon = "<img src=\"/adm/lonIcons/$icon\" alt=\"\" border=\"0\" />";
                     $linkopen = "<a href=\"/adm/navmaps?filter=";                      $linkopen = "<a href=\"/adm/navmaps?filter=";
                     $linkopen .= $nowOpen ?                       $linkopen .= ($nowOpen xor $condition) ? 
                         addToFilter(\%filterHash, $mapId) :                          addToFilter(\%filterHash, $mapId) :
                         removeFromFilter(\%filterHash, $mapId);                          removeFromFilter(\%filterHash, $mapId);
                     $linkopen .= "&$queryAdd\">";                      $linkopen .= "&condition=$condition&$queryAdd\">";
                     $linkclose = "</a>";                      $linkclose = "</a>";
                                           
                 }                  }
Line 1075  sub new_handle { Line 1087  sub new_handle {
                     }                      }
                 }                  }
   
  # FIRST ROW: The resource indentation, branch icon, and name                  # FIRST COL: The resource indentation, branch icon, and name
                 $r->print("  <tr><td align=\"left\" valign=\"top\">\n");                  $r->print("  <tr><td align=\"left\" valign=\"bottom\">\n");
   
                 # print indentation                  # print indentation
                 for (my $i = 0; $i < $indentLevel - $deltalevel; $i++) {                  for (my $i = 0; $i < $indentLevel - $deltalevel; $i++) {
Line 1085  sub new_handle { Line 1097  sub new_handle {
   
                 $r->print("  ${newBranchText}${linkopen}$icon${linkclose}\n");                  $r->print("  ${newBranchText}${linkopen}$icon${linkclose}\n");
   
    my $nonLinkedText = "";
   
                 if ($curRes->is_problem() && $part != "0" && !$condensed) {                   if ($curRes->is_problem() && $part != "0" && !$condensed) { 
     $partLabel = " (Part $part)";                       $partLabel = " (Part $part)"; 
     $title = "";                      $title = "";
  }                  }
                   if ($multipart && $condensed) {
                 $r->print("  <a href=\"$link\">$title$partLabel</a></td>");                      $nonLinkedText = ' (' . $curRes->countParts() . ' parts)';
                   }
  my $discussionHTML = ""; my $feedbackHTML = "";  
                   $r->print("  <a href=\"$link\">$title$partLabel</a> $nonLinkedText");
  # SECOND ROW: Is there text or feedback?  
  if ($curRes->hasDiscussion()) {                  if ($curRes->{RESOURCE_ERROR}) {
     $discussionHTML = $linkopen .                      $r->print(&Apache::loncommon::help_open_topic ("Navmap_Host_Down",
  '<img border="0" src="/adm/lonMisc/chat.gif" />' .                                                    '<font size="-1">Host down</font>'));
  $linkclose;                      }
  }  
                   my $discussionHTML = ""; my $feedbackHTML = "";
  if ($curRes->getFeedback()) {  
     my $feedback = $curRes->getFeedback();                  # SECOND COL: Is there text or feedback?
     foreach (split(/\,/, $feedback)) {                  if ($curRes->hasDiscussion()) {
  if ($_) {                      $discussionHTML = $linkopen .
     $feedbackHTML .= '&nbsp;<a href="/adm/email?display='                          '<img border="0" src="/adm/lonMisc/chat.gif" />' .
  . &Apache::lonnet::escape($_) . '">'                          $linkclose;
  . '<img src="/adm/lonMisc/feedback.gif" '                  }
  . 'border="0" /></a>';  
  }                  if ($curRes->getFeedback()) {
     }                      my $feedback = $curRes->getFeedback();
  }                      foreach (split(/\,/, $feedback)) {
                           if ($_) {
  $r->print("<td align=\"left\">$discussionHTML$feedbackHTML</td>");                              $feedbackHTML .= '&nbsp;<a href="/adm/email?display='
                                   . &Apache::lonnet::escape($_) . '">'
  # Is this the first displayed part of a multi-part problem                                  . '<img src="/adm/lonMisc/feedback.gif" '
  # that has not been condensed, so we should suppress these two                                  . 'border="0" /></a>';
  # columns?                          }
  my $firstDisplayed = !$condensed && $multipart && $part eq "0";                      }
                   }
  # THIRD ROW: Problem status icon  
  if ($curRes->is_problem() &&                  $r->print("<td align=\"left\" valign=\"bottom\">$discussionHTML$feedbackHTML</td>");
     !$firstDisplayed) {  
     my $icon = $statusIconMap{$curRes->status($part)};  
     if ($icon) {  
  $r->print("<td width=\"50\" align=\"right\">$linkopen<img src=\"/adm/lonIcons/$icon\" border=\"0\" />$linkclose</td>\n");  
     } else {  
  $r->print("<td></td>\n");  
     }  
  } else { # not problem, no icon  
     $r->print("<td></td>\n");  
  }  
   
   # FOURTH ROW: Text description                  # Is this the first displayed part of a multi-part problem
  $r->print("<td $colorizer align=\"right\">\n");                  # that has not been condensed, so we should suppress these two
                   # columns?
                   my $firstDisplayed = !$condensed && $multipart && $part eq "0";
   
                   # THIRD ROW: Problem status icon
                   if ($curRes->is_problem() &&
                       !$firstDisplayed) {
                       my $icon = $statusIconMap{$curRes->status($part)};
                       if ($icon) {
                           $r->print("<td valign=\"bottom\" width=\"50\" align=\"right\">$linkopen<img src=\"/adm/lonIcons/$icon\" border=\"0\" />$linkclose</td>\n");
                       } else {
                           $r->print("<td></td>\n");
                       }
                   } else { # not problem, no icon
                       $r->print("<td></td>\n");
                   }
   
                   # FOURTH ROW: Text description
                   $r->print("<td $colorizer align=\"right\" valign=\"bottom\">\n");
                                   
                 if ($curRes->kind() eq "res" &&                  if ($curRes->kind() eq "res" &&
                     $curRes->is_problem() &&                      $curRes->is_problem() &&
     !$firstDisplayed) {                      !$firstDisplayed) {
                     $r->print (getDescription($curRes, $part));                      $r->print (getDescription($curRes, $part));
                 }                  }
   
  $r->print("</td></tr>\n");                  $r->print("</td></tr>\n");
             }              }
         }          }
         $curRes = $mapIterator->next();          $curRes = $mapIterator->next();
Line 1220  sub getDescription { Line 1242  sub getDescription {
         return "Opens: " . timeToHumanString($res->opendate($part));          return "Opens: " . timeToHumanString($res->opendate($part));
     }      }
     if ($status == $res->OPEN) {      if ($status == $res->OPEN) {
  if ($res->duedate()) {          if ($res->duedate()) {
     return "Due: $status " . timeToHumanString($res->duedate($part));              return "Due: $status " . timeToHumanString($res->duedate($part));
  } else {          } else {
     return "Open, no due date";              return "Open, no due date";
  }          }
     }      }
     if ($status == $res->PAST_DUE_ANSWER_LATER) {      if ($status == $res->PAST_DUE_ANSWER_LATER) {
         return "Answer opens: " . timeToHumanString($res->answerdate($part));          return "Answer opens: " . timeToHumanString($res->answerdate($part));
Line 1236  sub getDescription { Line 1258  sub getDescription {
         return "Answer available";          return "Answer available";
     }      }
     if ($status == $res->EXCUSED) {      if ($status == $res->EXCUSED) {
  return "Excused by instructor";          return "Excused by instructor";
     }      }
     if ($status == $res->TRIES_LEFT) {      if ($status == $res->TRIES_LEFT) {
  my $tries = $res->tries();          my $tries = $res->tries();
  my $maxtries = $res->maxtries();          my $maxtries = $res->maxtries();
  my $triesString = "($tries of $maxtries tries used)";          my $triesString = "($tries of $maxtries tries used)";
  if ($res->duedate()) {          if ($res->duedate()) {
     return "Due: $status " . timeToHumanString($res->duedate($part)) .              return "Due: $status " . timeToHumanString($res->duedate($part)) .
  " $triesString";                  " $triesString";
  } else {          } else {
     return "No due date $triesString";              return "No due date $triesString";
  }          }
     }      }
 }  }
   
Line 1258  sub timeToHumanString { Line 1280  sub timeToHumanString {
     my ($time) = @_;      my ($time) = @_;
     # zero, '0' and blank are bad times      # zero, '0' and blank are bad times
     if ($time) {      if ($time) {
  return localtime($time);          return localtime($time);
     } else {      } else {
  return 'Never';          return 'Never';
     }      }
 }  }
   
Line 1328  sub new { Line 1350  sub new {
     if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},      if (!(tie(%parmhash, 'GDBM_File', $self->{PARM_HASH_FILE},
               &GDBM_READER(), 0640)))                &GDBM_READER(), 0640)))
     {      {
  untie $self->{PARM_HASH};          untie $self->{PARM_HASH};
         return undef;          return undef;
     }      }
     $self->{PARM_HASH} = \%parmhash;      $self->{PARM_HASH} = \%parmhash;
Line 1481  sub hasDiscussion { Line 1503  sub hasDiscussion {
     if (!defined($self->{DISCUSSION_TIME})) { return 0; }      if (!defined($self->{DISCUSSION_TIME})) { return 0; }
   
     return $self->{DISCUSSION_TIME}->{$symb} >      return $self->{DISCUSSION_TIME}->{$symb} >
    $self->{LAST_CHECK};             $self->{LAST_CHECK};
 }  }
   
 # Private function: Does the given resource (as a symb string) have  # Private function: Does the given resource (as a symb string) have
Line 1898  sub next { Line 1920  sub next {
         $self->{RECURSIVE_ITERATOR} =          $self->{RECURSIVE_ITERATOR} =
           Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource,             Apache::lonnavmaps::iterator->new ($self->{NAV_MAP}, $firstResource, 
                      $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN},                       $finishResource, $self->{FILTER}, $self->{ALREADY_SEEN},
      $self->{CONDITION});                                               $self->{CONDITION});
     }      }
   
     return $self->{HERE};      return $self->{HERE};
Line 1971  sub new { Line 1993  sub new {
   
     # Store this new resource in the parent nav map's cache.      # Store this new resource in the parent nav map's cache.
     $self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self;      $self->{NAV_MAP}->{RESOURCE_CACHE}->{$self->{ID}} = $self;
       $self->{RESOURCE_ERROR} = 0;
   
     # A hash that can be used by two-pass algorithms to store data      # A hash that can be used by two-pass algorithms to store data
     # about this resource in. Not used by the resource object      # about this resource in. Not used by the resource object
Line 2271  sub countParts { Line 2294  sub countParts {
     my $self = shift;      my $self = shift;
           
     my $parts = $self->parts();      my $parts = $self->parts();
       
     if (scalar(@{$parts}) == 1) { return 1;}      if ($self->{RESOURCE_ERROR}) {
           return 0;
       }
   
       if (scalar(@{$parts}) < 2) { return 1;}
   
     return scalar(@{$parts}) - 1;      return scalar(@{$parts}) - 1;
 }  }
Line 2286  sub extractParts { Line 2313  sub extractParts {
     $self->{PARTS} = [];      $self->{PARTS} = [];
   
     # Retrieve part count      # Retrieve part count
     foreach (split(/\,/,&Apache::lonnet::metadata($self->src(),       my $metadata = &Apache::lonnet::metadata($self->src(), 'allpossiblekeys');
                                                   'allpossiblekeys'))) {      if (!$metadata) {
           $self->{RESOURCE_ERROR} = 1;
           $self->{PARTS} = [];
           return;
       }
   
       foreach (split(/\,/,$metadata)) {
         if ($_ =~ /^parameter\_(.*)\_opendate$/) {          if ($_ =~ /^parameter\_(.*)\_opendate$/) {
             push @{$self->{PARTS}}, $1;              push @{$self->{PARTS}}, $1;
         }          }
     }      }
   
           
     # Is this possible to do in one line? - Jeremy      # Is this possible to do in one line? - Jeremy
     my @sortedParts = sort @{$self->{PARTS}};      my @sortedParts = sort @{$self->{PARTS}};
Line 2566  sub getNext { Line 2600  sub getNext {
         $next = $self->{NAV_MAP}->getById($next);          $next = $self->{NAV_MAP}->getById($next);
   
         # Don't remember it if we've already seen it or if          # Don't remember it if we've already seen it or if
  # the student doesn't have browse priviledges          # the student doesn't have browse priviledges
  my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);          my $browsePriv = &Apache::lonnet::allowed('bre', $self->src);
         if (!defined($alreadySeenHash) ||          if (!defined($alreadySeenHash) ||
             !defined($alreadySeenHash->{$next->{ID}}) ||              !defined($alreadySeenHash->{$next->{ID}}) ||
     ($browsePriv ne '2' && $browsePriv ne 'F')) {              ($browsePriv ne '2' && $browsePriv ne 'F')) {
                 push @branches, $next;                  push @branches, $next;
             }              }
     }      }

Removed from v.1.65  
changed lines
  Added in v.1.66


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