Diff for /loncom/interface/londocs.pm between versions 1.687 and 1.690

version 1.687, 2022/10/29 14:47:00 version 1.690, 2022/12/31 14:08:59
Line 205  sub validate_supppath { Line 205  sub validate_supppath {
                     $backto .= '&'.$items[$i];                      $backto .= '&'.$items[$i];
                     my $is_hidden;                      my $is_hidden;
                     unless ($got_supp) {                      unless ($got_supp) {
                         my ($supplemental) = &Apache::lonnet::get_supplemental($coursenum,$coursedom);                          my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
                         if (ref($supplemental) eq 'HASH') {                          if (ref($supplemental) eq 'HASH') {
                             if (ref($supplemental->{'hidden'}) eq 'HASH') {                              if (ref($supplemental->{'hidden'}) eq 'HASH') {
                                 %supphidden = %{$supplemental->{'hidden'}};                                  %supphidden = %{$supplemental->{'hidden'}};
Line 3562  sub editor { Line 3562  sub editor {
     }      }
   
     if ((!$allowed) && ($folder =~ /^supplemental_\d+$/)) {      if ((!$allowed) && ($folder =~ /^supplemental_\d+$/)) {
         my ($supplemental) = &Apache::lonnet::get_supplemental($coursenum,$coursedom);          my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
         if (ref($supplemental) eq 'HASH') {          if (ref($supplemental) eq 'HASH') {
             if ((ref($supplemental->{'hidden'}) eq 'HASH') &&              if ((ref($supplemental->{'hidden'}) eq 'HASH') &&
                 (ref($supplemental->{'ids'}) eq 'HASH')) {                  (ref($supplemental->{'ids'}) eq 'HASH')) {
Line 5802  sub handler { Line 5802  sub handler {
             if ($supplementalflag) {              if ($supplementalflag) {
                 ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/);                  ($foldername,$hiddenfolder) = ($pathitems[-1] =~ /^([^:]*)::(|1):::$/);
                 $foldername = &HTML::Entities::decode(&unescape($foldername));                  $foldername = &HTML::Entities::decode(&unescape($foldername));
                 my ($supplemental) = &Apache::lonnet::get_supplemental($coursenum,$coursedom);                  my ($supplemental) = &Apache::loncommon::get_supplemental($coursenum,$coursedom);
                 if (ref($supplemental) eq 'HASH') {                  if (ref($supplemental) eq 'HASH') {
                     my ($suppmap,$suppmapnum);                      my ($suppmap,$suppmapnum);
                     if ($folder eq 'supplemental') {                      if ($folder eq 'supplemental') {
Line 6135  sub handler { Line 6135  sub handler {
                 'stpr' => 'Standard Problem',                  'stpr' => 'Standard Problem',
                 'news' => 'New sub-directory',                  'news' => 'New sub-directory',
                 'crpr' => 'Create Problem',                  'crpr' => 'Create Problem',
                   'swit' => 'Switch Server',
                 'drbx' => 'Drop Box',                  'drbx' => 'Drop Box',
                 'scuf' => 'External Scores (handgrade, upload, clicker)',                  'scuf' => 'External Scores (handgrade, upload, clicker)',
                 'bull' => 'Discussion Board',                  'bull' => 'Discussion Board',
Line 6293  FUFORM Line 6294  FUFORM
 SEDFFORM  SEDFFORM
         my $importcrsresform;          my $importcrsresform;
         my ($numdirs,$pickfile) =           my ($numdirs,$pickfile) = 
             &Apache::loncommon::import_crsauthor_form('crsresimportform','coursepath','coursefile',              &Apache::loncommon::import_crsauthor_form('coursepath','coursefile',
                                                       "resize_scrollbox('contentscroll','1','0');",                                                        "resize_scrollbox('contentscroll','1','0');",
                                                       undef,'res');                                                        undef,'res');
         if ($pickfile) {          if ($pickfile) {
             $importcrsresform=(<<CRSFORM);              $importcrsresform=(<<CRSFORM);
         <a class="LC_menubuttons_link" href="javascript:toggleImportCrsres('res','$numdirs');">          <a class="LC_menubuttons_link" href="javascript:toggleImportCrsres('res');">
         $lt{'imcr'}</a>$help{'Course_Resources'}          $lt{'imcr'}</a>$help{'Course_Resources'}
         <form action="/adm/coursedocs" method="post" name="crsresimportform" onsubmit="return validImportCrsRes();">          <form action="/adm/coursedocs" method="post" name="crsresimportform" onsubmit="return validImportCrsRes();">
         <fieldset id="importcrsresform" style="display: none;">          <fieldset id="importcrsresform" style="display: none;">
Line 6309  SEDFFORM Line 6310  SEDFFORM
         $lt{'title'}: <input type="textbox" name="crsrestitle" value="" $disabled />          $lt{'title'}: <input type="textbox" name="crsrestitle" value="" $disabled />
         </p>          </p>
         <input type="hidden" name="importdetail" value="" />          <input type="hidden" name="importdetail" value="" />
         <input type="submit" name="crsres" value="$lt{'impo'}" $disabled />          <input type="submit" name="crsres" value="$lt{'impo'}" $disabled /><br />
         </fieldset>          </fieldset>
         </form>          </form>
 CRSFORM  CRSFORM
Line 6329  CRSFORM Line 6330  CRSFORM
         { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/sequence.png" alt="'.$lt{impm}.'" onclick="javascript:toggleMap(\'map\');" />' => $importpubform },          { '<img class="LC_noBorder LC_middle" src="/res/adm/pages/sequence.png" alt="'.$lt{impm}.'" onclick="javascript:toggleMap(\'map\');" />' => $importpubform },
         );          );
         if ($pickfile) {          if ($pickfile) {
             push(@importpubforma,{ '<img class="LC_noBorder LC_middle" src="/res/adm/pages/res.png" alt="'.$lt{imcr}.'"  onclick="javascript:toggleImportCrsres(\'res\','."'$numdirs'".');"/>' => $importcrsresform});              push(@importpubforma,{ '<img class="LC_noBorder LC_middle" src="/res/adm/pages/res.png" alt="'.$lt{imcr}.'"  onclick="javascript:toggleImportCrsres(\'res\');" />' => $importcrsresform});
  }   }
  $importpubform = &create_form_ul(&create_list_elements(@importpubforma));   $importpubform = &create_form_ul(&create_list_elements(@importpubforma));
         my $extresourcesform =          my $extresourcesform =
Line 6531  NROSTFORM Line 6532  NROSTFORM
 NWEBFORM  NWEBFORM
   
         my @ids=&Apache::lonnet::current_machine_ids();          my @ids=&Apache::lonnet::current_machine_ids();
         my %select_menus;          my (%select_menus,$rolehomes);
         my $numauthor = 0;          my $numauthor = 0;
         my $numcrsdirs = 0;          my $numcrsdirs = 0;
           my ($showstdprob,$showswitch,$switchlink);
         my $toppath = "/priv/$env{'user.domain'}/$env{'user.name'}";           my $toppath = "/priv/$env{'user.domain'}/$env{'user.name'}"; 
           my $exclude = &Apache::lonnet::priv_exclude();
         if ($env{'user.author'}) {          if ($env{'user.author'}) {
             $numauthor ++;              $numauthor ++;
             $select_menus{'author'}->{'text'} = &Apache::lonnet::plaintext('au');              $select_menus{'author'}->{'text'} = &Apache::lonnet::plaintext('au');
             if (grep(/^\Q$env{'user.home'}\E$/,@ids)) {              if (grep(/^\Q$env{'user.home'}\E$/,@ids)) {
                 my $is_home = 1;                  my $is_home = 1;
                 my %subdirs;                  my %subdirs;
                 &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs);                  &Apache::lonnet::recursedirs($is_home,1,'',$exclude,0,$toppath,'',\%subdirs);
                 $select_menus{'author'}->{'default'} = '/';                   $select_menus{'author'}->{'default'} = '/'; 
                 $select_menus{'author'}->{'select2'}->{'/'} = '/';                  my @ordered = ();
                 my @ordered = ('/');  
                 foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {                  foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {
                     $select_menus{'author'}->{'select2'}->{$relpath} = $relpath;                      $select_menus{'author'}->{'select2'}->{$relpath} = $relpath;
                     push(@ordered,$relpath);                      push(@ordered,$relpath);
                 }                  }
                 $select_menus{'author'}->{'order'} = \@ordered;                  $select_menus{'author'}->{'order'} = \@ordered;
                   $showstdprob = 'block';
             } else {              } else {
                   $rolehomes = '<input type="hidden" name="rolehome_author" value="'.$env{'user.home'}.'" />'."\n";
                 $select_menus{'author'}->{'select2'}->{'switch'} = &mt('Switch server required');                  $select_menus{'author'}->{'select2'}->{'switch'} = &mt('Switch server required');
                 $select_menus{'author'}->{'default'} = 'switch';                  $select_menus{'author'}->{'default'} = 'switch';
                 $select_menus{'author'}->{'order'} = ['switch'];                  $select_menus{'author'}->{'order'} = ['switch'];
                   $showstdprob = 'none';
             }              }
         }          }
         my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',          my %roleshash = &Apache::lonnet::get_my_roles($env{'user.name'},$env{'user.domain'},'userroles',
                                                       ['active'],['ca','aa']);                                                        ['active'],['ca','aa']);
         my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};          my $crshome = $env{'course.'.$env{'request.course.id'}.'.home'};
         my %by_roletype;          my (%by_roletype,%at_home);
         if (keys(%roleshash)) {          if (keys(%roleshash)) {
             foreach my $entry (keys(%roleshash)) {              foreach my $entry (keys(%roleshash)) {
                 my ($auname,$audom,$roletype) = split(/:/,$entry);                  my ($auname,$audom,$roletype) = split(/:/,$entry);
Line 6569  NWEBFORM Line 6574  NWEBFORM
                 $select_menus{$key}->{'text'} = &Apache::lonnet::plaintext($roletype)." ($audom/$auname)";                  $select_menus{$key}->{'text'} = &Apache::lonnet::plaintext($roletype)." ($audom/$auname)";
                 my $rolehome = &Apache::lonnet::homeserver($auname,$audom);                  my $rolehome = &Apache::lonnet::homeserver($auname,$audom);
                 if (grep(/^\Q$rolehome\E$/,@ids)) {                      if (grep(/^\Q$rolehome\E$/,@ids)) {    
                       $at_home{$auname.'___'.$audom} = 1;
                     my $is_home = 1;                      my $is_home = 1;
                     my (%subdirs,@ordered);                      my (%subdirs,@ordered);
                     my $toppath="/priv/$audom/$auname";                      my $toppath="/priv/$audom/$auname";
                     &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs);                      &Apache::lonnet::recursedirs($is_home,1,'',$exclude,0,$toppath,'',\%subdirs);
                     $select_menus{$key}->{'default'} = '/';                      $select_menus{$key}->{'default'} = '/';
                     $select_menus{$key}->{'select2'}->{'/'} = '/';  
                     my @ordered = ('/');  
                     foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {                      foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {
                         $select_menus{$key}->{'select2'}->{$relpath} = $relpath;                          $select_menus{$key}->{'select2'}->{$relpath} = $relpath;
                         push(@ordered,$relpath);                          push(@ordered,$relpath);
                     }                      }
                     $select_menus{$key}->{'order'} = \@ordered;                      $select_menus{$key}->{'order'} = \@ordered;
                 } else {                  } else {
                       $rolehomes .= '<input type="hidden" name="rolehome_coauthor" value="'.$roletype.'='.$audom.'/'.$auname.'='.$rolehome.'" />'."\n";
                     $select_menus{$key}->{'select2'}->{'switch'} = &mt('Switch server required');                      $select_menus{$key}->{'select2'}->{'switch'} = &mt('Switch server required');
                     $select_menus{$key}->{'default'} = 'switch';                      $select_menus{$key}->{'default'} = 'switch';
                     $select_menus{$key}->{'order'} = ['switch'];                      $select_menus{$key}->{'order'} = ['switch'];
Line 6603  NWEBFORM Line 6608  NWEBFORM
                         foreach my $author (sort { lc($a) cmp lc($b) } (keys(%{$by_roletype{$possrole}}))) {                          foreach my $author (sort { lc($a) cmp lc($b) } (keys(%{$by_roletype{$possrole}}))) {
                             unless ($defrole) {                              unless ($defrole) {
                                 $defrole = $author;                                  $defrole = $author;
                                   if ($at_home{$author}) {
                                       $showstdprob = 'block'; 
                                   } else {
                                       $showstdprob = 'none';
                                   }
                             }                              }
                             push(@order,$author.'___'.$possrole);                              push(@order,$author.'___'.$possrole);
                         }                          }
Line 6614  NWEBFORM Line 6624  NWEBFORM
                 my $is_home = 1;                  my $is_home = 1;
                 my %subdirs;                  my %subdirs;
                 my $toppath="/priv/$coursedom/$coursenum";                  my $toppath="/priv/$coursedom/$coursenum";
                 &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs);                  &Apache::lonnet::recursedirs($is_home,1,'',$exclude,0,$toppath,'',\%subdirs);
                 $numcrsdirs = keys(%subdirs);                  $numcrsdirs = keys(%subdirs);
                 $select_menus{'course'}->{'default'} = '/';                  $select_menus{'course'}->{'default'} = '/';
                 $select_menus{'course'}->{'select2'}->{'/'} = '/';                  my @ordered = ();
                 my @ordered = ('/');  
                 foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {                  foreach my $relpath (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {
                     $select_menus{'course'}->{'select2'}->{$relpath} = $relpath;                      $select_menus{'course'}->{'select2'}->{$relpath} = $relpath;
                     push(@ordered,$relpath);                      push(@ordered,$relpath);
                 }                  }
                 $select_menus{'course'}->{'order'} = \@ordered;                  $select_menus{'course'}->{'order'} = \@ordered;
             } else {              } else {
                   $rolehomes .= '<input type="hidden" name="rolehome_course" value="'.$crshome.'" />'."\n";
                 $select_menus{'course'}->{'select2'}->{'switch'} = &mt('Switch server required');                  $select_menus{'course'}->{'select2'}->{'switch'} = &mt('Switch server required');
                 $select_menus{'course'}->{'default'} = 'switch';                  $select_menus{'course'}->{'default'} = 'switch';
                 $select_menus{'course'}->{'order'} = ['switch'];                  $select_menus{'course'}->{'order'} = ['switch'];
Line 6641  NWEBFORM Line 6651  NWEBFORM
             $showtitle = 'inline';              $showtitle = 'inline';
             if (grep(/^\Q$crshome\E$/,@ids)) {              if (grep(/^\Q$crshome\E$/,@ids)) {
                 $is_home = 1;                  $is_home = 1;
                   $showstdprob = 'block';
                 $pickdir .= '<input type="hidden" name="authorrole" value="course" />';                   $pickdir .= '<input type="hidden" name="authorrole" value="course" />'; 
                 my $toppath="/priv/$coursedom/$coursenum'}";                  my $toppath="/priv/$coursedom/$coursenum'}";
                 my %subdirs;                  my %subdirs;
                 &Apache::lonnet::recursedirs($is_home,'priv',$londocroot,$toppath,'',\%subdirs);                  &Apache::lonnet::recursedirs($is_home,1,'',$exclude,0,$toppath,'',\%subdirs);
                 $numcrsdirs = keys(%subdirs);                   $numcrsdirs = keys(%subdirs); 
                 if ($numcrsdirs) {                  if ($numcrsdirs) {
                     $pickdir .= &mt('Directory: ').'<select name="authorpath">'."\n".                      $pickdir .= $lt{'dire'}.' <select name="authorpath">'."\n".
                                  '<option value="/">/</option>'."\n";                                   '<option value="/">/</option>'."\n";
                     foreach my $key (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {                      foreach my $key (sort { lc($a) cmp lc($b) } (keys(%subdirs))) {
                         $pickdir .= '<option value="'.$key.'">'.$key.'</option>'."\n";                          $pickdir .= '<option value="'.$key.'">'.$key.'</option>'."\n";
Line 6656  NWEBFORM Line 6667  NWEBFORM
                 } else {                  } else {
                     $pickdir .= '<input type="hidden" name="authorpath" value="/" />'."\n";                         $pickdir .= '<input type="hidden" name="authorpath" value="/" />'."\n";   
                 }                  }
               } else {
                   $showstdprob = 'none';
                   $rolehomes .= '<input type="hidden" name="rolehome_course" value="'.$crshome.'" />'."\n"; 
                   my @order;
                   $select_menus{'course'}->{'text'} = &mt('Course Resource');
                   $select_menus{'course'}->{'select2'}->{'switch'} = &mt('Switch server required');
                   $select_menus{'course'}->{'default'} = 'switch';
                   $select_menus{'course'}->{'order'} = ['switch'];
                   push(@order,'course');
                   my $defrole = 'course';
                   $pickdir = $lt{'loca'}.
                              &Apache::loncommon::linked_select_forms('courseresform','<br />'.$lt{'dire'},
                                                                      $defrole,'authorrole','authorpath',
                                                                      \%select_menus,\@order,'toggleCrsResTitle();',
                                                                      '','priv').'<br />';
                   $showtitle = 'none';
   
             }              }
         }          }
           if ($showstdprob eq 'none') {
               $showswitch = 'block';
           } else {
               $showswitch = 'none';
           }
   
         my %seltemplate_menus;          my %seltemplate_menus;
         my @files = &Apache::lonhomework::get_template_list('problem');          my @files = &Apache::lonhomework::get_template_list('problem');
Line 6708  NWEBFORM Line 6741  NWEBFORM
         <input type="hidden" name="active" value="bb" />          <input type="hidden" name="active" value="bb" />
         <p>          <p>
         $pickdir          $pickdir
           <div id="newstdproblem" style="display:$showstdprob;">
         <span class="LC_nobreak">$lt{'news'}?&nbsp;          <span class="LC_nobreak">$lt{'news'}?&nbsp;
         <label><input type="radio" name="newsubdir" value="0" onclick="toggleNewsubdir(this.form);" checked="checked" $disabled />No</label>          <label><input type="radio" name="newsubdir" value="0" onclick="toggleNewsubdir(this.form);" checked="checked" $disabled />No</label>
         &nbsp;          &nbsp;
Line 6743  NWEBFORM Line 6777  NWEBFORM
         <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />          <input type="hidden" name="folderpath" value="$env{'form.folderpath'}" />
         <input type="submit" name="newcrs" value="$lt{'crpr'}" $disabled />          <input type="submit" name="newcrs" value="$lt{'crpr'}" $disabled />
         </span>          </span>
           </div>
           <div id="stdprobswitch" style="display:$showswitch;">
           $rolehomes
           <input type="button" name="switchfornewprob" value="$lt{'swit'}" onclick="switchForProb();" />
           </div>
         </fieldset>          </fieldset>
         </form>          </form>
   
Line 7488  sub editing_js { Line 7527  sub editing_js {
     my $backtourl;      my $backtourl;
     my $toplevelmain = &escape(&default_folderpath($coursenum,$coursedom,$navmapref));      my $toplevelmain = &escape(&default_folderpath($coursenum,$coursedom,$navmapref));
     my $toplevelsupp = &supplemental_base();      my $toplevelsupp = &supplemental_base();
       my $showfile_js = &Apache::loncommon::show_crsfiles_js();
     if ($env{'docs.exit.'.$env{'request.course.id'}} =~ /^direct_(.+)$/) {      if ($env{'docs.exit.'.$env{'request.course.id'}} =~ /^direct_(.+)$/) {
         my $caller = $1;          my $caller = $1;
         if ($caller =~ /^supplemental/) {          if ($caller =~ /^supplemental/) {
Line 7921  function toggleCrsResTitle() { Line 7960  function toggleCrsResTitle() {
         } else {          } else {
             document.getElementById('newresource').style.display = 'none';              document.getElementById('newresource').style.display = 'none';
         }          }
     }       }
       if (document.getElementById('newstdproblem')) {
           if (document.courseresform.authorpath.options[document.courseresform.authorpath.selectedIndex].value == 'switch') {
               document.getElementById('newstdproblem').style.display = 'none'; 
               if (document.getElementById('stdprobswitch')) {
                   document.getElementById('stdprobswitch').style.display = 'block'; 
               }
           } else {
               document.getElementById('newstdproblem').style.display = 'block';
               if (document.getElementById('stdprobswitch')) {
                   document.getElementById('stdprobswitch').style.display = 'none';
               }
           }
       }
 }  }
   
 function toggleNewInCourse(form) {  function toggleNewInCourse(form) {
Line 8001  function getExample(width,height,scrolli Line 8053  function getExample(width,height,scrolli
     }      }
 }  }
   
 function toggleImportCrsres(caller,dircount) {  function toggleImportCrsres(caller) {
     var disp = 'none';      var disp = 'none';
     if (document.getElementById('importcrsresform')) {      if (document.getElementById('importcrsresform')) {
         if (caller == 'res') {          if (caller == 'res') {
             var numdirs = parseInt(dircount);  
             var curr = document.getElementById('importcrsresform').style.display;              var curr = document.getElementById('importcrsresform').style.display;
             if (curr == 'none') {              if (curr == 'none') {
                 disp='block';                  disp='block';
                 if (numdirs > 1) {                  populateCrsSelects(document.crsresimportform,'coursepath','coursefile',1,'',1,0,1,1);
                     select1res_changed();  
                 }  
             }              }
         }          }
         document.getElementById('importcrsresform').style.display=disp;          document.getElementById('importcrsresform').style.display=disp;
Line 8019  function toggleImportCrsres(caller,dirco Line 8068  function toggleImportCrsres(caller,dirco
     }      }
     return;      return;
 }  }
   
   $showfile_js
   
   function switchForProb() {
       if (document.courseresform.authorpath.options[document.courseresform.authorpath.selectedIndex].value == 'switch') {
           var url = '/adm/switchserver?otherserver=';
           var newhostid = '';
           var role = '';
           var selloc = document.courseresform.authorrole.options[document.courseresform.authorrole.selectedIndex].value;
           if (selloc == 'author') {
               newhostid = document.courseresform.rolehome_author.value;
               role = "au./&js_escape($env{'user.domain'})/";
           } else if (selloc == 'course') {
               newhostid = document.courseresform.rolehome_course.value;
               role = "&js_escape($env{'request.role'})";
           } else {
               var items = new Array();
               items = selloc.split('___');
               var len = document.courseresform.rolehome_coauthor.length;
               if (null == len) {
                   var currval = document.courseresform.rolehome_coauthor.value;
                   if (null != currval) {
                       var info = new Array();
                       info = currval.split('=');
                       newhostid = info[2];
                       role = info[0]+'./'+info[1];
                   }
               } else {
                   for (var i=0; i<len; i++) {
                       var currval = document.courseresform.rolehome_coauthor[i].value;
                       if (null != currval) {
                           var info = new Array();
                           info = currval.split('=');
                           if ((info[1] == items[1]+'/'+items[0]) && (info[0] == items[2])) {
                               newhostid = info[2];
                               role = info[0]+'./'+info[1];
                               break;
                           }
                       }
                   }
               }
           }
           if (newhostid != '') {
               url += newhostid;
               if (role != '') {
                   url += '&role='+role;
               }
               document.location.href = url;
           }
       }
       return;
   }
   
 function makeims(imsform) {  function makeims(imsform) {
     if ((imsform.uploaddoc.value == '')  || (!imsform.uploaddoc.value)) {      if ((imsform.uploaddoc.value == '')  || (!imsform.uploaddoc.value)) {

Removed from v.1.687  
changed lines
  Added in v.1.690


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