Annotation of rat/client/parameter.html, revision 1.9

1.1       www         1: <html>
                      2: <!--
                      3: The LearningOnline Network with CAPA
                      4: Parameter Input Window
1.7       www         5: 06/16/00,06/17,11/17,11/18,11/23,11/27,11/28,12/15,12/16,
1.8       www         6: 03/21/01,03/24 Gerd Kortemeyer
1.9     ! harris41    7: 07/24/01 Scott Harrison
1.1       www         8: -->
                      9: <head>
                     10: <title>LON-CAPA</title>
                     11: </head>
                     12: 
                     13: <script>
                     14: 
                     15: var ptype='';
                     16: var pvalue='';
                     17: var preturn='';
                     18: var pcode='';
1.2       www        19: var pscat='';
                     20: var pmarker='';
1.1       www        21: var pname='';
                     22: 
                     23: var svalue;
1.2       www        24: var stype;
                     25: var smarker;
1.1       www        26: 
                     27: var vars=new Array();
                     28: 
1.2       www        29: var cdate=new Date();
                     30: 
                     31: var csec;
                     32: var cmin;
                     33: var chour;
                     34: var cday;
                     35: 
                     36: var months=new Array();
                     37: 
                     38: 
1.1       www        39: function selwrite(text) {
                     40:   this.window.selector.document.write(text);
                     41: }
                     42: 
                     43: function choicestart() {
                     44:   this.window.choices.document.clear();
                     45:   choicewrite('<html><body bgcolor="#FFFFFF">');
                     46: }
                     47: 
                     48: function choiceend() {
                     49:   choicewrite('</body></html>');
                     50:   this.window.choices.document.close();
                     51: }
                     52: 
                     53: function choicewrite(text) {
                     54:   this.window.choices.document.write(text);
                     55: }
                     56: 
                     57: function tablestart(headtext) {
                     58:   choicewrite('<table><tr bgcolor="#AAFFAA"><th colspan=3>'+
                     59:               headtext+'</th></tr>');
                     60: }
                     61: 
                     62: function valline(text,id1,id2) {
                     63:   choicewrite('<tr bgcolor="#AAFFAA"><td>'+text+
                     64:               '</td><td><input type=text size=4 name=val'+
                     65:               id1+'></td><td>incl:<input type=checkbox name=val'+
                     66:               id2+'></td></tr>');
                     67: }
                     68: 
1.2       www        69: function datecalc() {
                     70:     var sform=choices.document.forms.sch;
                     71: 
                     72:     cdate.setHours(sform.hours.options[sform.hours.selectedIndex].value);
                     73:     cdate.setMinutes(sform.minutes.options[sform.minutes.selectedIndex].value);
                     74:     cdate.setSeconds(sform.minutes.options[sform.seconds.selectedIndex].value);
                     75:     cdate.setDate(sform.date.options[sform.date.selectedIndex].value);
                     76:     cdate.setMonth(sform.month.options[sform.month.selectedIndex].value);
                     77:     cdate.setFullYear(sform.year.options[sform.year.selectedIndex].value);
                     78: 
                     79:     draw();
                     80: }
                     81: 
                     82: function hour() {
                     83:    var thishour=cdate.getHours();
                     84:     var i; var j;
                     85:     choicewrite('<select name=hours onChange="parent.datecalc();">');
                     86:     for (i=0;i<=23;i++) {
                     87:         choicewrite('<option value='+i);
                     88:         if (i==thishour) {
                     89:             choicewrite(' selected');
                     90:         }
                     91:         choicewrite('>');
                     92:         if (i==12) { choicewrite('noon'); } else {
                     93:            if (i==0) { choicewrite('midnight') } else {
                     94:               
                     95:                  if (i<12) { choicewrite(i+' am'); } else {
                     96:                     j=i-12; choicewrite(j+' pm');
                     97:                  }
                     98:               
                     99:            }
                    100:         }
                    101:         choicewrite('</option>');
                    102:     }
                    103:     choicewrite('</select>');
                    104: }
                    105: 
                    106: function minute() {
                    107:    var thisminutes=cdate.getMinutes();
                    108:     var i;
                    109:     choicewrite('<select name=minutes onChange="parent.datecalc();">');
                    110:     for (i=0;i<=59;i++) {
                    111:         choicewrite('<option value='+i);
                    112:         if (i==thisminutes) {
                    113:             choicewrite(' selected');
                    114:         }
                    115:         choicewrite('>'+i+'</option>');
                    116:     }
                    117:     choicewrite('</select>');
                    118: } 
                    119: 
                    120: function second() {
                    121:    var thisseconds=cdate.getSeconds();
                    122:     var i;
                    123:     choicewrite('<select name=seconds onChange="parent.datecalc();">');
                    124:     for (i=0;i<=59;i++) {
                    125:         choicewrite('<option value='+i);
                    126:         if (i==thisseconds) {
                    127:             choicewrite(' selected');
                    128:         }
                    129:         choicewrite('>'+i+'</option>');
                    130:     }
                    131:     choicewrite('</select>');
                    132: } 
                    133: 
                    134: 
                    135: function date() {
                    136:    var thisdate=cdate.getDate();
                    137:     var i;
                    138:     choicewrite('<select name=date onChange="parent.datecalc();">');
                    139:     for (i=1;i<=31;i++) {
                    140:         choicewrite('<option value='+i);
                    141:         if (i==thisdate) {
                    142:             choicewrite(' selected');
                    143:         }
                    144:         choicewrite('>'+i+'</option>');
                    145:     }
                    146:     choicewrite('</select>');
                    147: }
                    148: 
                    149: function year() {
                    150:    var thisyear=cdate.getFullYear();
                    151:     var i;
                    152:     choicewrite('<select name=year onChange="parent.datecalc();">');
                    153:     for (i=thisyear-25;i<=thisyear+50;i++) {
                    154:         choicewrite('<option value='+i);
                    155:         if (i==thisyear) {
                    156:             choicewrite(' selected');
                    157:         }
                    158:         choicewrite('>'+i+'</option>');
                    159:     }
                    160:     choicewrite('</select>');
                    161: }
                    162: 
                    163: function month() {
                    164:     var thismonth=cdate.getMonth();
                    165:     var i;
                    166:     choicewrite('<select name=month onChange="parent.datecalc();">');
                    167:     for (i=0;i<=11;i++) {
                    168:         choicewrite('<option value='+i);
                    169:         if (i==thismonth) {
                    170:             choicewrite(' selected');
                    171:         }
                    172:         choicewrite('>'+months[i]+'</option>');
                    173:     }
                    174:     choicewrite('</select>');
                    175: }
                    176:     
                    177:     
                    178: function intminute() {
                    179:    var thisminutes=cmins;
                    180:     var i;
                    181:     choicewrite('<select name=minutes onChange="parent.intcalc();">');
                    182:     for (i=0;i<=59;i++) {
                    183:         choicewrite('<option value='+i);
                    184:         if (i==thisminutes) {
                    185:             choicewrite(' selected');
                    186:         }
                    187:         choicewrite('>'+i+'</option>');
                    188:     }
                    189:     choicewrite('</select>');
                    190: } 
                    191: 
                    192: function inthour() {
                    193:    var thishours=chours;
                    194:     var i;
                    195:     choicewrite('<select name=hours onChange="parent.intcalc();">');
                    196:     for (i=0;i<=23;i++) {
                    197:         choicewrite('<option value='+i);
                    198:         if (i==thishours) {
                    199:             choicewrite(' selected');
                    200:         }
                    201:         choicewrite('>'+i+'</option>');
                    202:     }
                    203:     choicewrite('</select>');
                    204: } 
                    205: 
                    206: function intsecond() {
                    207:    var thisseconds=csecs;
                    208:     var i;
                    209:     choicewrite('<select name=seconds onChange="parent.intcalc();">');
                    210:     for (i=0;i<=59;i++) {
                    211:         choicewrite('<option value='+i);
                    212:         if (i==thisseconds) {
                    213:             choicewrite(' selected');
                    214:         }
                    215:         choicewrite('>'+i+'</option>');
                    216:     }
                    217:     choicewrite('</select>');
                    218: } 
                    219: 
                    220: 
                    221: function intday() {
                    222:    var thisdate=cdays;
                    223:     var i;
                    224:     choicewrite('<select name=date onChange="parent.intcalc();">');
                    225:     for (i=0;i<=31;i++) {
                    226:         choicewrite('<option value='+i);
                    227:         if (i==thisdate) {
                    228:             choicewrite(' selected');
                    229:         }
                    230:         choicewrite('>'+i+'</option>');
                    231:     }
                    232:     choicewrite('</select>');
                    233: }
                    234: 
                    235: function intcalc() {
                    236:     var sform=choices.document.forms.sch;
                    237:     svalue=((sform.date.options[sform.date.selectedIndex].value*24+
                    238:              sform.hours.options[sform.hours.selectedIndex].value*1)*60+
                    239:              sform.minutes.options[sform.minutes.selectedIndex].value*1)*60+
                    240:              sform.seconds.options[sform.seconds.selectedIndex].value*1;
                    241:     draw();
                    242: }
                    243: 
1.6       www       244: function integereval() {
                    245:    svalue=choices.document.forms.sch.intval.value;
                    246:    svalue=Math.round(svalue);
                    247:    if (pscat=='zeropos') { svalue=Math.abs(svalue); }
                    248:    if ((pscat=='pos') && (svalue==0)) {
                    249:       svalue='';
                    250:    }
                    251:    draw();
                    252: }
                    253: 
                    254: function floateval() {
                    255:    svalue=choices.document.forms.sch.floatval.value;
                    256:    svalue=1.0*svalue;
                    257:    if (pscat=='pos') { svalue=Math.abs(svalue); }
                    258:    if ((pscat=='zeroone') && ((svalue<0) || (svalue>1))) {
                    259:       svalue='';
                    260:    }
                    261:    draw();
                    262: }
                    263: 
                    264: function stringeval() {
                    265:    svalue=choices.document.forms.sch.stringval.value;
                    266:    draw();
                    267: }
                    268: 
1.2       www       269: function intervaldis() {
                    270:     csecs=svalue;
                    271:     cdays=Math.floor(csecs/86400);
                    272:     csecs-=cdays*86400;
                    273:     chours=Math.floor(csecs/3600);
                    274:     csecs-=chours*3600;
                    275:     cmins=Math.floor(csecs/60);
                    276:     csecs-=cmins*60;
                    277:     choicewrite(cdays+' days '+chours+' hours '
                    278:                +cmins+' mins '+csecs+' secs');
                    279: }
                    280:     
                    281:     
                    282:     
1.1       www       283: function afterproc() {
                    284:   choicewrite('<tr bgcolor="#AAFFAA"><td colspan=3>Error after rounding: '
                    285:              +'<input type=checkbox name=val1></td></tr>');
                    286: }
                    287: 
                    288: function draw() {
                    289:    choicestart();
1.6       www       290:    choicewrite('<form name=sch');
                    291:    if (ptype=='int') {
                    292:       choicewrite(' action="javascript:integereval();"');
                    293:    }
                    294:    if (ptype=='float') {
                    295:       choicewrite(' action="javascript:floateval();"');
                    296:    }
                    297:    if (ptype=='string') {
                    298:       choicewrite(' action="javascript:stringeval();"');
                    299:    }
                    300:    choicewrite('>');
1.1       www       301:    if (ptype=='tolerance') {
1.2       www       302: // 0: pscat
1.1       www       303: // 1: after processing
1.2       www       304:       if (pscat=='default') {
1.1       www       305:          tablestart('Use default value or algorithm of resource');
                    306:       }
1.2       www       307:       if (pscat=='exact') {
1.1       www       308:          tablestart('Accept only exact value, zero tolerance');
                    309:          afterproc();
                    310:       }
1.2       www       311:       if (pscat=='relative_sym') {
1.1       www       312: // 2: percentage
                    313: // 3: open
                    314:          tablestart('Percentage error, symmetric around value');
                    315:          valline('Percentage',2,3);
                    316:          afterproc();
                    317:       }
1.2       www       318:       if (pscat=='relative') {
1.1       www       319: // 2: left
                    320: // 3: open
                    321: // 4: right
                    322: // 5: open
                    323:          tablestart('Percentage error, asymmetric around value');
                    324:          valline('Upper percentage',2,3);
                    325:          valline('Lower percentage',4,5);
                    326:          afterproc();
                    327:       }
1.2       www       328:       if (pscat=='absolute_sym') {
1.1       www       329:          tablestart('Absolute error, symmetric around value');
                    330:          valline('Value',2,3);
                    331:          afterproc();
                    332:       }
1.2       www       333:       if (pscat=='absolute') {
1.1       www       334:          tablestart('Absolute error, asymmetric around value');
                    335:          valline('Upper value',2,3);
                    336:          valline('Lower value',4,5);
                    337:          afterproc();
                    338:       }
1.2       www       339:       if (pscat=='sigdigits') {
1.1       www       340:          tablestart('Agreement on significant digits');
                    341:   choicewrite('<tr bgcolor="#AAFFAA"><td colspan=3>Number of digits: '
                    342:              +'<input type=text size=4 name=val2></td></tr>');
                    343: 
1.6       www       344: choicewrite('<tr bgcolor="#AAFFAA"><td colspan=3>Accept if more digits given: '
1.1       www       345:              +'<input type=checkbox name=val3></td></tr>');
                    346:          
                    347:       }
                    348:    }
                    349: 
                    350:    if (ptype=='date') {
1.2       www       351:      if (pscat=='default') {
                    352:          tablestart('Default value or none');
                    353:          choicewrite('</table>');
                    354:      } else {
                    355:       if (pscat=='start') {
                    356:          tablestart('Starting or opening date and time');
                    357:       }
                    358:       if (pscat=='end') {
                    359:          tablestart('Ending or closing date and time');
                    360:       }
                    361:       if (pscat=='interval') {
                    362:          tablestart('Time interval');
                    363:          choicewrite('<tr bgcolor="#AAFFAA"><td colspan=3>');
                    364:          intervaldis();
                    365:          choicewrite('</td></tr><tr bgcolor="#AAFFAA"><td>Time:'
                    366:          +'</td><td colspan=2>');
                    367:          intday();choicewrite('days ');
                    368:          inthour();choicewrite('hours ');
                    369:          intminute(); choicewrite('mins '); intsecond();
                    370:          choicewrite('secs</td></tr></table>');         
                    371:       } else { 
                    372:          choicewrite('<tr bgcolor="#AAFFAA"><td colspan=3>'
                    373:          +cdate.toString()+
                    374:          '</td></tr><tr bgcolor="#AAFFAA"><td>Date:</td><td colspan=2>');
                    375:          month();date();year();
                    376:          choicewrite('</td></tr><tr bgcolor="#AAFFAA"><td>Time:'
                    377:          +'</td><td colspan=2>');hour();choicewrite('h ');minute();
                    378:          choicewrite('m ');second();
                    379:          choicewrite('s</td></tr></table>');
                    380:       }
                    381:      }
1.1       www       382:    }
                    383: 
1.6       www       384:    if (ptype=='int') {
                    385:       if (pscat=='default') {
                    386:          tablestart('Default value or none');
                    387:          choicewrite('</table>');         
                    388:       } else {
                    389:         if (pscat=='pos') {
                    390:            tablestart('Positive (non-zero) integer');
                    391:         }
                    392:         if (pscat=='zeropos') {
                    393:            tablestart('Positive integer or zero');
                    394:         }
                    395:         if (pscat=='any') {
                    396:            tablestart('Integer');
                    397:         }
                    398:         choicewrite('<tr bgcolor="#AAFFAA"><td>Value:</td><td colspan=2>');
                    399:         choicewrite('<input name=intval size=10 value="'+svalue+
                    400:                     '" name=intval onChange="parent.integereval()">');
                    401:         choicewrite('</td></table>');
                    402:       }
1.1       www       403:    }
                    404: 
1.6       www       405:    if (ptype=='float') {
                    406:       if (pscat=='default') {
                    407:          tablestart('Default value or none');
                    408:          choicewrite('</table>');         
                    409:       } else {
                    410:         if (pscat=='pos') {
                    411:            tablestart('Positive floating point number or zero');
                    412:         }
                    413:         if (pscat=='zeroone') {
                    414:            tablestart('Floating point number between zero and one');
                    415:         }
                    416:         if (pscat=='any') {
                    417:            tablestart('Floating point number');
                    418:         }
                    419:         choicewrite('<tr bgcolor="#AAFFAA"><td>Value:</td><td colspan=2>');
                    420:         choicewrite('<input name=floatval size=10 value="'+svalue+
                    421:                     '" name=floatval onChange="parent.floateval()">');
                    422:         choicewrite('</td></table>');
                    423:       }
1.1       www       424:    }
                    425: 
1.6       www       426:    if (ptype=='string') {
                    427:       if (pscat=='default') {
                    428:          tablestart('Default value or none');
                    429:          choicewrite('</table>');         
                    430:       } else {
                    431:         if (pscat=='any') {
                    432:            tablestart('Text');
                    433:         }
                    434:         choicewrite('<tr bgcolor="#AAFFAA"><td>Value:</td><td colspan=2>');
                    435:         choicewrite('<input name=intval size=20 value="'+svalue+
                    436:                     '" name=stringval onChange="parent.stringeval()">');
                    437:         choicewrite('</td></table>');
                    438:       }
1.1       www       439:    }
                    440: 
                    441:    choicewrite('</table></form>');
                    442:    choiceend();
                    443: }
                    444: 
                    445: function sopt(va,text) {
                    446:    selwrite('<option value="'+va+'"');
1.2       www       447:    if (va==pscat) {
1.1       www       448:      selwrite(' selected');
                    449:    }
                    450:    selwrite('>'+text+'</option>');
                    451: }
                    452: 
                    453: function catchange() {
                    454:    var sform=selector.document.forms.fsel.fcat;
1.2       www       455:    pscat=sform.options[sform.selectedIndex].value;
1.1       www       456:    draw();
                    457: }
                    458: 
                    459: function assemble() {
1.2       www       460:     if ((ptype=='date') && (pscat!='interval')) {
                    461:         svalue=Math.round(cdate.getTime()/1000);
                    462:     }
1.6       www       463:     if (pscat=='default') { svalue=''; }
1.2       www       464:     stype=ptype+'_'+pscat;
1.1       www       465: }
                    466: 
                    467: 
                    468: function init() {
                    469:   var i;
1.2       www       470:   var subs=new Array();
1.1       www       471:   var namevalue=this.window.location.search.split('&');
                    472:   namevalue[0]=namevalue[0].substr(1,namevalue[0].length-1);
                    473: 
                    474:   for (i=0;i<namevalue.length;i++) {
                    475:      var pair=namevalue[i].split('=');
1.3       www       476:      pair[1]=unescape(pair[1]);
1.1       www       477:      if (pair[0]=='value') { pvalue=pair[1]; }
1.2       www       478:      if (pair[0]=='type') { subs=pair[1].split('_');
                    479:                             ptype=subs[0];
                    480:                             pscat=subs[1];
1.9     ! harris41  481:                             if (typeof(subs[2])!="undefined") { pscat+='_'+subs[2]; }
        !           482:                             if ((pscat=='') || (typeof(pscat)=="undefined")) { 
1.6       www       483:                                pscat='default';
                    484:                             }
1.2       www       485:                            }
1.1       www       486:      if (pair[0]=='return') { preturn=pair[1]; }
                    487:      if (pair[0]=='call') { pcode=pair[1]; }
1.2       www       488:      if (pair[0]=='marker') { pmarker=pair[1]; }
1.1       www       489:      if (pair[0]=='name') { pname=pair[1]; }
                    490:   }
                    491: 
                    492:   svalue=pvalue;
1.6       www       493:   if (((ptype=='float') || (ptype=='string') || (ptype=='int')) &&
                    494:       (pscat=='default') && 
1.9     ! harris41  495:       (typeof(svalue)!="undefined") && (svalue!=0) && (svalue!='')) { pscat='any'; }
1.1       www       496: 
                    497:   this.window.selector.document.clear();
                    498:   selwrite('<html><body bgcolor="#FFFFFF">');
                    499: 
1.8       www       500:   selwrite('<form name="fsel"><b>'+pname+'</b><br>');
1.1       www       501:   selwrite('<select name="fcat" onChange="parent.catchange();">');
                    502:   if (ptype=='tolerance') {
                    503:      sopt('default','Default');
                    504:      sopt('exact','Exact Value (no tolerance)');
                    505:      sopt('relative_sym','Relative Tolerance, Symmetric (percent)');
                    506:      sopt('relative','Relative Tolerance (percentages)');
                    507:      sopt('absolute_sym','Absolute Tolerance, Symmetric (value)');
                    508:      sopt('absolute','Absolute Tolerance (values)');
                    509:      sopt('sigdigits','Significant Digits (number)');
                    510:   }
                    511: 
                    512:   if (ptype=='date') {
                    513:      sopt('default','Default');
                    514:      sopt('start','Starting Date');
                    515:      sopt('end','Ending Date');
1.2       www       516:      sopt('interval','Time Interval');
                    517:      
1.9     ! harris41  518:      if ((pvalue!='') && (typeof(pvalue)!="undefined")) {
1.2       www       519:         cdate.setTime(pvalue*1000);
                    520:      }
                    521:  
                    522:      months[0]='January';
                    523:      months[1]='February';
                    524:      months[2]='March';
                    525:      months[3]='April';
                    526:      months[4]='May';
                    527:      months[5]='June';
                    528:      months[6]='July';
                    529:      months[7]='August';
                    530:      months[8]='September';
                    531:      months[9]='October';
                    532:      months[10]='November';
                    533:      months[11]='December';
1.1       www       534:   }
1.2       www       535:    
1.6       www       536:   if (ptype=='int') {
                    537:      sopt('default','Default');
                    538:      sopt('pos','Positive Integer, Not Zero');
                    539:      sopt('zeropos','Positive Integer or Zero');
                    540:      sopt('any','Integer');
1.1       www       541:   }
                    542: 
1.6       www       543:   if (ptype=='float') {
                    544:      sopt('default','Default');
                    545:      sopt('zeroone','Floating Point between 0 and 1');
                    546:      sopt('pos','Positive Floating Point');
                    547:      sopt('any','Floating Point');
1.1       www       548: 
                    549:   }
                    550: 
1.6       www       551:   if (ptype=='string') {
                    552:      sopt('default','Default');
                    553:      sopt('string','String Value');
1.1       www       554:   }
                    555: 
                    556:   selwrite('</select></form>');
                    557: 
1.2       www       558:   selwrite('<a href="javascript:parent.assemble();');
1.1       www       559:   if (preturn!='') {
1.4       www       560:      selwrite(
                    561:       'parent.opener.document.'+preturn+'_value.value=parent.window.svalue;');
                    562:      selwrite(
                    563:       'parent.opener.document.'+preturn+'_type.value=parent.window.stype;');
1.2       www       564:   }
                    565:   if (pmarker!='') {
1.4       www       566:      selwrite(
                    567:      'parent.opener.document.'+preturn+'_marker.value=parent.window.pmarker;');
1.1       www       568:   }
                    569:   if (pcode!='') {
1.4       www       570:      selwrite('parent.opener.'+pcode+'();');
1.1       www       571:   }
1.4       www       572:   selwrite('">Store</a>&nbsp;&nbsp;');
1.5       www       573: 
                    574:   selwrite('<a href="javascript:');
                    575:      selwrite(
                    576:       'parent.opener.document.'+preturn+'_value.value='+"'';");
                    577:   if (pmarker!='') {
                    578:      selwrite(
                    579:      'parent.opener.document.'+preturn+'_marker.value=parent.window.pmarker;');
                    580:   }
                    581:   if (pcode!='') {
                    582:      selwrite('parent.opener.'+pcode+'();');
                    583:   }
                    584:   selwrite('">Delete</a>&nbsp;&nbsp;');
1.4       www       585:  
                    586:   selwrite('<a href="javascript:');
                    587:   if (preturn!='') {
                    588:      selwrite('parent.opener.document.'+preturn+'_value.value='+"'';");
                    589:      selwrite('parent.opener.document.'+preturn+'_type.value='+"'';");
                    590:   }
                    591:   if (pmarker!='') {
                    592:      selwrite('parent.opener.document.'+preturn+'_marker.value='+"'';");
                    593:   }
                    594:   if (pcode!='') {
                    595:      selwrite('parent.opener.'+pcode+'();');
                    596:   }
                    597:   selwrite('">Cancel</a>'); 
1.1       www       598:  
                    599:   selwrite('</body></html>');
                    600:   this.window.selector.document.close();
1.2       www       601:   draw();
1.1       www       602:   
                    603: }
                    604: 
                    605: </script>
                    606: 
1.2       www       607: <frameset rows="120,*" onLoad="init();">
1.1       www       608: <frame name=selector src="empty.html">
                    609: <frame name=choices src="empty.html">
                    610: </frameset>
                    611: 
                    612: 
                    613: 
                    614: </html>

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