0f3ca3eaf5792df01b7c600a5428d2d0b2809fcd
max
  Fri Sep 20 13:18:01 2024 -0700
Revert "more features to hubtools: search in both parent and subdirs, better docs"

This reverts commit 05e67c59a20a5d00b810a981aef3b00c5bef82e1.

diff --git src/hg/hgTracks/simpleTracks.c src/hg/hgTracks/simpleTracks.c
index e6c9d30..39c2763 100644
--- src/hg/hgTracks/simpleTracks.c
+++ src/hg/hgTracks/simpleTracks.c
@@ -1659,101 +1659,30 @@
     return FALSE;  // Ignore.
 if (chromStart > winEnd || winStart > chromEnd ||
     (!isIns && chromStart == winEnd) ||
     (!isIns && chromEnd == winStart))  // doesn't overlap window?
     return FALSE; // nothing to do
 if (chromStart < winStart) // clip to part overlapping window
     chromStart = winStart;
 if (chromEnd > winEnd)     // which prevents x1,x2 from overflowing when zooming-in makes scale large.
     chromEnd = winEnd;
 *pX1 = round((double)(chromStart-winStart)*scale) + xOff;
 *pX2 = isIns ? (*pX1 + 1) : round((double)(chromEnd-winStart)*scale) + xOff;
 return TRUE;
 }
 
 
-void drawNotches(struct hvGfx* hvg, int x1, int x2, int y, int height, Color color, int startPhase, int endPhase) 
-{
-// do nothing for -1 and 0. Also ignore invalid exonFrame numbers, e.g. 4.
-int w = (int)(height*0.75);
-int halfHeight = (int)(height/2);
-
-if (x2-x1 < 2*w)
-    w = ((x2-x1)/2);
-
-//if ((x2-x1) > 8*height) // TODO: this should use the letter-width somehow...
-    //return;
-
-if ((startPhase==1 || startPhase==2))
-    {
-    struct gfxPoly *poly = gfxPolyNew();
-    switch (startPhase)
-        {
-        case 1 :
-            // a triangle
-            gfxPolyAddPoint(poly, x1, y+halfHeight);
-            gfxPolyAddPoint(poly, x1+w, y);
-            gfxPolyAddPoint(poly, x1+w, y+height);
-            break;
-            
-        case 2 :
-            {
-            // the opposite of a triangle
-            int halfW = (int)(w/2);
-            gfxPolyAddPoint(poly, x1, y);
-            gfxPolyAddPoint(poly, x1, y+height);
-            gfxPolyAddPoint(poly, x1+w, y+height);
-            gfxPolyAddPoint(poly, x1+halfW, y+halfHeight);
-            gfxPolyAddPoint(poly, x1+w, y);
-            break;
-            }
-        }
-
-    hvGfxDrawPoly(hvg,poly,color,TRUE);
-    gfxPolyFree(&poly);
-    }
-
-if (endPhase==1 || endPhase==2)
-    {
-    struct gfxPoly *poly = gfxPolyNew();
-    switch (endPhase)
-        {
-        case 1 :
-            // a triangle
-            gfxPolyAddPoint(poly, x2-w, y);
-            gfxPolyAddPoint(poly, x2+w, y+halfHeight);
-            gfxPolyAddPoint(poly, x2-w, y+height);
-            break;
-            
-        case 2 :
-            {
-            // the opposite of a triangle
-            int halfW = (int)(w/2);
-            gfxPolyAddPoint(poly, x2-w, y);
-            gfxPolyAddPoint(poly, x2-w, y+height);
-            gfxPolyAddPoint(poly, x2, y+height);
-            gfxPolyAddPoint(poly, x2-halfW, y+halfHeight);
-            gfxPolyAddPoint(poly, x2, y);
-            break;
-            }
-        }
-
-    hvGfxDrawPoly(hvg,poly,color,TRUE);
-    gfxPolyFree(&poly);
-    }
-}
-
 void drawScaledBox(struct hvGfx *hvg, int chromStart, int chromEnd,
                    double scale, int xOff, int y, int height, Color color)
 /* Draw a box scaled from chromosome to window coordinates.
  * Get scale first with scaleForPixels. */
 {
 int x1, x2;
 if (scaledBoxToPixelCoords(chromStart, chromEnd, scale, xOff, &x1, &x2))
     {
     int w = x2-x1;
     if (w == 0) // when zoomed out, avoid shinking to nothing
 	w = 1;
     hvGfxBox(hvg, x1, y, w, height, color);
     }
 }
 
@@ -2733,51 +2662,51 @@
 *pNewWinStart = *pNewWinEnd - newWinSize;
 }
 
 #define EXONTEXTLEN 256
 
 static void makeExonFrameText(int exonIntronNumber, int numExons, int startPhase, int endPhase, char *buf) 
 /* Write mouseover text that describes the exon's phase into buf[EXONTEXTLEN].
 
    Note that start/end-phases are in the direction of transcription:
    if transcript is on + strand, the start phase is the exonFrame value, and the end phase is the next exonFrame (3' on DNA) value
    if transcript is on - strand, the start phase is the previous (=3' on DNA) exonFrame and the end phase is the exonFrame */
 {
 
 if (startPhase==-1) // UTRs don't have a frame at all
     {
-    safef(buf, EXONTEXTLEN, "<br>untranslated region");
+    safef(buf, EXONTEXTLEN, ", untranslated region");
     }
 else
     {
     char *exonNote = "";
     boolean isNotLastExon = (exonIntronNumber<numExons);
     if (isNotLastExon)
         {
         if (startPhase==endPhase)
-            exonNote = " = in-frame exon";
+            exonNote = ": in-frame exon";
         else
-            exonNote = " = out-of-frame exon";
-        safef(buf, EXONTEXTLEN, "<br><b>Codon Phase:</b> Start %d, End %d%s", startPhase, endPhase, exonNote);
+            exonNote = ": out-of-frame exon";
+        safef(buf, EXONTEXTLEN, ", codon phase: start %d, end %d%s", startPhase, endPhase, exonNote);
         } 
     else
         {
         if (startPhase==0)
-            exonNote = " = in-frame exon";
+            exonNote = ": in-frame exon";
         else
-            exonNote = " = out-of-frame exon";
-        safef(buf, EXONTEXTLEN, "<br><b>Start Codon Phase:</b> %d%s", startPhase, exonNote);
+            exonNote = ": out-of-frame exon";
+        safef(buf, EXONTEXTLEN, ", start codon phase %d%s", startPhase, exonNote);
         }
     }
 }
 
 boolean linkedFeaturesNextPrevItem(struct track *tg, struct hvGfx *hvg, void *item, int x, int y, int w, int h, boolean next)
 /* Draw a mapBox over the arrow-button on an *item already in the window*. */
 /* Clicking this will do one of several things: */
 {
 boolean result = FALSE;
 struct linkedFeatures *lf = item;
 struct simpleFeature *exons = lf->components;
 struct simpleFeature *exon = exons;
 char *nextExonText;
 char *prevExonText;
 long newWinSize = virtWinEnd - virtWinStart;
@@ -2957,286 +2886,35 @@
 	    linkedFeaturesMoveWinStart(xExonStart, bufferToEdge, newWinSize, &newWinStart, &newWinEnd);
 	if (!revStrand)
 	    safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", prevExonText, numExons-exonIx, numExons);
 	else
 	    safef(mouseOverText, sizeof(mouseOverText), "%s (%d/%d)", nextExonText, exonIx+1, numExons);
 	mapBoxJumpTo(hvg, x, y, w, h, tg, virtChromName, newWinStart, newWinEnd, mouseOverText);
 	result = TRUE;
 	break;
 	}
     }
 slFreeList(&exonList);
 slFreeList(&crList);
 return result;
 }
 
-/* this is a take at refactoring linkedFeaturesItemExonMaps */
-static void drawExonMapsNotches(struct track *tg, struct hvGfx *hvg, void *item, double scale,
-    int y, int heightPer, int sItem, int eItem,
-    boolean lButton, boolean rButton, int buttonW, Color color)
-/* Draw mapBoxes over exons and introns labeled with exon/intron numbers, phase information, and draw notches for phases. */
-{
-struct linkedFeatures *lf = item;
-struct simpleFeature *exons = lf->components;
-struct simpleFeature *exon = exons;
-char *exonText, *intronText;
-int numExons = 0;
-int exonIx = 1;
-struct slRef *exonList = NULL, *ref;
-// TODO this exonText (and intronText) setting is just a made-up placeholder.
-// could add a real setting name. Maybe someday extend to exon names (LRG?) instead of just exon numbers
-if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track) || startsWith("net", tg->tdb->track))
-    {
-    exonText   = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText"  , "Block");
-    intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Gap"  ); // what really goes here for chain type?
-    }
-else
-    {
-    exonText   = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText"  , "Exon"  );
-    intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Intron");
-    }
-
-while (exon != NULL)
-/* Make a stupid list of exons separate from what's given. */
-/* It seems like lf->components isn't necessarily sorted. */
-    {
-    refAdd(&exonList, exon);
-    exon = exon->next;
-    }
-/* Now sort it. */
-slSort(&exonList, exonSlRefCmp);
-
-numExons = slCount(exonList);
-boolean revStrand = (lf->orientation == -1);
-int eLast = -1;
-int s = -1;
-int e = -1;
-boolean isExon = TRUE;
-int picStart = insideX;
-int picEnd = picStart + insideWidth;
-if (lButton)
-    picStart += buttonW;
-if (rButton)
-    picEnd -= buttonW;
-
-for (ref = exonList; TRUE; )
-    {
-    exon = ref->val;
-    if (isExon)
-	{
-	s = exon->start;
-	e = exon->end;
-	}
-    else
-	{
-	s = eLast;
-	e = exon->start;
-	}
-    // skip exons and introns that are completely outside the window
-    if (s <= winEnd && e >= winStart)
-	{
-	int sClp = (s < winStart) ? winStart : s;
-	int eClp = (e > winEnd)   ? winEnd   : e;
-
-	int sx = round((sClp - winStart)*scale) + insideX;
-	int ex = round((eClp - winStart)*scale) + insideX;
-
-        // skip regions entirely outside available picture
-        // (accounts for space taken by exon arrows buttons)
-	if (sx <= picEnd && ex >= picStart)
-	    {
-	    // clip it to avail pic
-	    sx = (sx < picStart) ? picStart : sx;
-    	    ex = (ex > picEnd)   ? picEnd   : ex;
-
-	    int w = ex - sx;
-
-	    if (w > 0) // draw exon or intron if width is greater than 0
-		{
-                int exonIntronNumber;
-                char *exonIntronText;
-                int numExonIntrons = numExons;
-                if (isExon)
-                    {
-                    exonIntronText = exonText;
-                    }
-                else
-                    {
-                    exonIntronText = intronText;
-                    --numExonIntrons;  // introns are one fewer than exons
-                    }
-
-                char strandChar;
-                if (!revStrand) {
-                    exonIntronNumber = exonIx;
-                    strandChar = '+';
-                }
-                else {
-                    exonIntronNumber = numExonIntrons-exonIx+1;
-                    strandChar = '-';
-                }
-
-                // we still need to show the existing mouseover text
-                char* existingText = lf->mouseOver;
-                if (isEmpty(existingText))
-                    existingText = lf->name;
-
-                int startPhase = -1;
-                int endPhase = -1;
-                char phaseText[EXONTEXTLEN];
-                phaseText[0] = 0;
-                struct genePred *gp = lf->original;
-                if ((gp != NULL) && gp->exonFrames && isExon)
-                    {
-                    startPhase = gp->exonFrames[exonIx-1];
-                    if (!revStrand) 
-                        endPhase = gp->exonFrames[exonIx];
-                    else 
-                        if (exonIx>1)
-                            endPhase = gp->exonFrames[exonIx-2];
-                    makeExonFrameText(exonIntronNumber, numExons, startPhase, endPhase, phaseText);
-                    }
-
-                // draw mapBoxes for the codons if we are zoomed in far enough
-                struct simpleFeature *codon;
-                struct dyString *codonDy = dyStringNew(0);
-                int codonS, codonE;
-                if (isExon && lf->codons && zoomedToCdsColorLevel)
-                    {
-                    for (codon = lf->codons; codon != NULL; codon = codon->next)
-                        {
-                        codonS = codon->start; codonE = codon->end;
-                        if (codonS <= winEnd && codonE >= winStart)
-                            {
-                            int codonSClp = (codonS < winStart) ? winStart : codonS;
-                            int codonEClp = (codonE > winEnd)   ? winEnd   : codonE;
-
-                            int codonsx = round((codonSClp - winStart)*scale) + insideX;
-                            int codonex = round((codonEClp - winStart)*scale) + insideX;
-
-                            // skip regions entirely outside available picture
-                            // (accounts for space taken by exon arrows buttons)
-                            if (codonsx <= picEnd && codonex >= picStart)
-                                {
-                                // clip it to avail pic
-                                codonsx = (codonsx < picStart) ? picStart : codonsx;
-                                codonex = (codonex > picEnd)   ? picEnd   : codonex;
-
-                                int w = codonex - codonsx;
-                                if (w > 0)
-                                    {
-                                    // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always 
-                                    // prefer a lf->mouseOver over the itemName
-                                    char *oldMouseOver = lf->mouseOver;
-                                    lf->mouseOver = NULL;
-                                    dyStringClear(codonDy);
-                                    if (!isEmpty(existingText))
-                                        dyStringPrintf(codonDy, "%s, ", existingText);
-                                    int codonHgvsIx = (codon->codonIndex - 1) * 3;
-                                    if (codonHgvsIx >= 0)
-                                        dyStringPrintf(codonDy, "<b>cDNA Pos:</b> c.%d-%d<br>", codonHgvsIx + 1, codonHgvsIx + 3);
-                                    dyStringPrintf(codonDy, "<b>Strand:</b> %c<br><b>%s</b> %d of %d%s",
-                                                strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText);
-                                    tg->mapItem(tg, hvg, item, codonDy->string, tg->mapItemName(tg, item),
-                                            sItem, eItem, codonsx, y, w, heightPer);
-                                    // and restore the mouseOver
-                                    lf->mouseOver = oldMouseOver;
-                                    }
-                                }
-                            }
-                        }
-                    }
-                }
-                /*else
-                    {
-                    // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always 
-                    // prefer a lf->mouseOver over the itemName
-                    if (!isEmpty(existingText))
-                        safef(mouseOverText, sizeof(mouseOverText), "%s, W < 0 ?? strand %c, %s %d of %d%s",
-                                existingText, strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText);
-                    else
-                        safef(mouseOverText, sizeof(mouseOverText), "W < 0 ?? strand %c, %s %d of %d%s",
-                                strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText);
-                    char *oldMouseOver = lf->mouseOver;
-                    lf->mouseOver = NULL;
-                    tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item),
-                        sItem, eItem, sx, y, w, heightPer);
-                    // and restore the mouseOver
-                    lf->mouseOver = oldMouseOver;
-                    }
-                */
-
-	    /*if (w > 0) // draw exon or intron if width is greater than 0
-		{
-                char *sep = "";
-                if (!isEmpty(existingText))
-                    sep = ", ";
-
-                safef(mouseOverText, sizeof(mouseOverText), "%s%sstrand %c, %s %d of %d%s", 
-                        existingText, sep, strandChar, exonIntronText, exonIntronNumber, numExonIntrons, phaseText);
-
-                // temporarily remove the mouseOver from the lf, since linkedFeatureMapItem will always 
-                // prefer a lf->mouseOver over the itemName
-                char *oldMouseOver = lf->mouseOver;
-                lf->mouseOver = NULL;
-		tg->mapItem(tg, hvg, item, mouseOverText, tg->mapItemName(tg, item),
-		    sItem, eItem, sx, y, w, heightPer);
-                // and restore the old mouseOver
-                lf->mouseOver = oldMouseOver;
-
-		picStart = ex;  // prevent pileups. is this right? add 1? does it work?
-
-                Color notchColor = lighterColor(hvg, color);
-                Color notchColor2 = lighterColor(hvg, notchColor);
-                struct rgbColor rgb = hvGfxColorIxToRgb(hvg, notchColor2);
-                Color notchColor3 = MAKECOLOR_32_A(rgb.r,rgb.g,rgb.b,0.5);
-                drawNotches(hvg, sx, ex, y, heightPer, notchColor3, startPhase, endPhase);
-		}
-                */
-	    }
-	}
-
-    if (isExon)
-	{
-    	eLast = e;
-	ref = ref->next;
-	if (!ref)
-	    break;
-	}
-    else
-	{
-	exonIx++;
-	}
-    isExon = !isExon;
-
-    if (s > winEnd) // since the rest will also be outside the window
-	break;
-
-    }
-
-slFreeList(&exonList);
-}
-
-/* OLD CODE - under hg.conf control - to be removed one day */
 void linkedFeaturesItemExonMaps(struct track *tg, struct hvGfx *hvg, void *item, double scale,
     int y, int heightPer, int sItem, int eItem,
-    boolean lButton, boolean rButton, int buttonW, Color color)
+    boolean lButton, boolean rButton, int buttonW)
 /* Draw mapBoxes over exons and introns labeled with exon/intron numbers */
 {
-if (cfgOptionBooleanDefault("newExonTooltips", FALSE))
-    drawExonMapsNotches(tg, hvg, item, scale, y, heightPer, sItem, eItem, lButton, rButton, buttonW, color);
-
 struct linkedFeatures *lf = item;
 struct simpleFeature *exons = lf->components;
 struct simpleFeature *exon = exons;
 char *exonText, *intronText;
 int numExons = 0;
 int exonIx = 1;
 struct slRef *exonList = NULL, *ref;
 // TODO this exonText (and intronText) setting is just a made-up placeholder.
 // could add a real setting name. Maybe someday extend to exon names (LRG?) instead of just exon numbers
 if (startsWith("chain", tg->tdb->type) || startsWith("lrg", tg->tdb->track))
     {
     exonText   = trackDbSettingClosestToHomeOrDefault(tg->tdb, "exonText"  , "Block");
     intronText = trackDbSettingClosestToHomeOrDefault(tg->tdb, "intronText", "Gap"  ); // what really goes here for chain type?
     }
 else
@@ -3437,31 +3115,30 @@
 	    break;
 	}
     else
 	{
 	exonIx++;
 	}
     isExon = !isExon;
 
     if (s > winEnd) // since the rest will also be outside the window
 	break;
 
     }
 
 slFreeList(&exonList);
 }
-/* END OLD CODE */
 
 static struct window *makeMergedWindowList(struct window *windows)
 /* Make a copy of the windows list, merging nearby regions on the same chrom
 and which are within some limit (1MB?) of each other. */
 {
 int mergeLimit = 1024*1024;
 struct window *w = windows;
 struct window *resultList = NULL;
 struct window *mergedW = NULL;
 if (!windows)
     errAbort("Unexpected error: windows list NULL in makeMergedWindowList()");
 boolean doNew = TRUE;
 while(TRUE)
     {
     if (doNew)
@@ -4598,31 +4275,32 @@
 		color);
 	    }
 	s = e2;
 	}
     if (e > tallEnd)
 	{
 	s2 = s;
         if (s2 < tallEnd) s2 = tallEnd;
 	if (lf->highlightColor && (lf->highlightMode == highlightOutline))
 	    {
 	    drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight, lf->highlightColor);
 	    drawScaledBox(hvg, s2, e, scale, xOff+1, y+shortOff+1, shortHeight-2, color);
 	    }
 	else
 	    {
-	    drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight, color);
+	    drawScaledBox(hvg, s2, e, scale, xOff, y+shortOff, shortHeight,
+		color);
 	    }
 	e = s2;
 	}
     /* Draw "tall" portion of exon (or codon) */
     if (e > s)
 	{
         if (drawOpt > baseColorDrawOff
         &&  e + 6 >= winStart
         &&  s - 6 <  winEnd
         &&  (e-s <= 3 || !baseColorNeedsCodons))
             baseColorDrawItem(tg, lf, sf->grayIx, hvg, xOff, y, scale, font, s, e, heightPer,
                               zoomedToCodonLevel, qSeq, qOffset, sf, psl, drawOpt, MAXPIXELS, winStart,
                               color);
         else
             {
@@ -4887,32 +4565,31 @@
     int w = x2-textX;
     if (lButton)
         { // if left-button, the label will be on far left, split out a map just for that label.
 	tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
                     s, e, textX, y, insideX-textX, heightPer);
 	textX = insideX + buttonW; // continue on the right side of the left exon button
 	w = x2-textX;
 	}
     if (rButton)
         {
 	w -= buttonW;
         }
 
     if (compat)
 	{  // draw labeled exon/intron maps with exon/intron numbers
-        linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW, color);
-
+	linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW);
 	x2 = x1;
 	w = x2-textX;
 	}
     // if not already mapped, pick up the label
     if (!(lButton && compat))
 	{
         tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
 		s, e, textX, y, w, heightPer);
 	}
     }
 else if (vis == tvSquish)
     {
     int w = x2-textX;
     tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
             s, e, textX, y, w, heightPer);
@@ -4925,31 +4602,31 @@
     int trackPastTabX = (withLeftLabels ? trackTabWidth : 0);
     tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
                 s, e, trackPastTabX, y, insideX - trackPastTabX, heightPer);
     /* Depending on which button mapboxes we drew, draw the remaining mapbox. */
     if (lButton)
         {
         geneMapBoxX += buttonW;
         geneMapBoxW -= buttonW;
         }
     if (rButton)
 	{
         geneMapBoxW -= buttonW;
 	}
     if (compat)
 	{  // draw labeled exon/intron maps with exon/intron numbers
-	linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW, color);
+	linkedFeaturesItemExonMaps(tg, hvg, item, scale, y, heightPer, s, e, lButton, rButton, buttonW);
 	if (!lButton)
 	    {
 	    int w = x1 - geneMapBoxX;
 	    if (w > 0)
 		tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
 		    s, e, geneMapBoxX, y, w, heightPer);
 	    }
 	if (!rButton)
 	    {
 	    int w = geneMapBoxX + geneMapBoxW - x2;
 	    if (w > 0)
 		tg->mapItem(tg, hvg, item, tg->itemName(tg, item), tg->mapItemName(tg, item),
 		    s, e, x2, y, w, heightPer);
 	    }
 	}
@@ -13413,31 +13090,30 @@
 char *table = tg->table;
 int bedSize = tg->bedSize; /* field count of bed part */
 boolean useItemRgb = bedItemRgb(tg->tdb);
 struct customTrack *ct = tg->customPt;
 
 if (ct == NULL)
     conn = hAllocConn(database);
 else
     {
     conn = hAllocConn(CUSTOM_TRASH);
     table = ct->dbTableName;
     bedSize = ct->fieldCount - 2;
     useItemRgb = bedItemRgb(ct->tdb);
     }
 sr = hRangeQuery(conn, table, chromName, winStart, winEnd, NULL, &rowOffset);
-
 while ((row = sqlNextRow(sr)) != NULL)
     {
     el = bedDetailLoadAsLf(row, rowOffset, bedSize, useItemRgb);
     slAddHead(&list, el);
     }
 slReverse(&list);
 sqlFreeResult(&sr);
 hFreeConn(&conn);
 tg->items = list;
 }
 
 void loadProtVar(struct track *tg)
 /* Load UniProt Variants with labels */
 {
 struct protVarPos *list = NULL, *el;