06d7be056190c14b85e71bc12523f18ea6815b5e
markd
  Mon Dec 7 00:50:29 2020 -0800
BLAT mmap index support merge with master

diff --git src/hg/hgc/bigBedClick.c src/hg/hgc/bigBedClick.c
index 091bfb3..6d21715 100644
--- src/hg/hgc/bigBedClick.c
+++ src/hg/hgc/bigBedClick.c
@@ -321,50 +321,49 @@
 	    extFieldCrisprOfftargets(NULL, NULL);
         // empty or "0" value in bigBed means that the lookup should not be performed
         continue;
 	}
     off_t offset = atoll(offsetStr);
 
     seekAndPrintTable(detailsUrl, offset, extraFields);
     }
 slPairFreeValsAndList(&detailsUrls);
 }
 
 static void bigBedClick(char *fileName, struct trackDb *tdb,
                      char *item, int start, int end, int bedSize)
 /* Handle click in generic bigBed track. */
 {
-boolean showUrl = FALSE;
 char *chrom = cartString(cart, "c");
 
 /* Open BigWig file and get interval list. */
 struct bbiFile *bbi = bigBedFileOpen(fileName);
 struct lm *lm = lmInit(0);
 int ivStart = start, ivEnd = end;
+char *itemForUrl = item;
 if (start == end)
     {
     // item is an insertion; expand the search range from 0 bases to 2 so we catch it:
     ivStart = max(0, start-1);
     ivEnd++;
     }
 struct bigBedInterval *bbList = bigBedIntervalQuery(bbi, chrom, ivStart, ivEnd, 0, lm);
 
 /* Get bedSize if it's not already defined. */
 if (bedSize == 0)
     {
     bedSize = bbi->definedFieldCount;
-    showUrl = TRUE;
     }
 
 char *scoreFilter = cartOrTdbString(cart, tdb, "scoreFilter", NULL);
 int minScore = 0;
 if (scoreFilter)
     minScore = atoi(scoreFilter);
 
 /* Find particular item in list - matching start, and item if possible. */
 boolean found = FALSE;
 boolean firstTime = TRUE;
 struct bigBedInterval *bb;
 for (bb = bbList; bb != NULL; bb = bb->next)
     {
     if (!(bb->start == start && bb->end == end))
 	continue;
@@ -376,59 +375,75 @@
 	if (!match)
 	    continue;
 	}
 
     found = TRUE;
     if (firstTime)
 	printf("<BR>\n");
     int seq1Seq2Fields = 0;
     // check for seq1 and seq2 in columns 7+8 (eg, pairedTagAlign)
     boolean seq1Seq2 = sameOk(trackDbSetting(tdb, BASE_COLOR_USE_SEQUENCE), "seq1Seq2");
     if (seq1Seq2 && bedSize == 6)
 	seq1Seq2Fields = 2;
     char *fields[bedSize+seq1Seq2Fields];
     char startBuf[16], endBuf[16];
     char *rest = cloneString(bb->rest);
+    char *restFields[256];
+    int restCount = 0;
+    int restBedFields = 0;
+    char **extraFields = NULL;
+    int extraFieldCount = 0;
+    struct slPair *extraFieldPairs = NULL;
+    if (isNotEmpty(rest))
+        {
+        restCount = chopTabs(rest, restFields);
+        restBedFields = bedSize - 3;
+        if (restCount > restBedFields)
+            {
+            extraFields = (restFields + restBedFields);
+            extraFieldCount = restCount - restBedFields;
+            extraFieldPairs = getExtraFields(tdb, extraFields, extraFieldCount);
+            }
+        }
     int bbFieldCount = bigBedIntervalToRow(bb, chrom, startBuf, endBuf, fields,
                                            bedSize+seq1Seq2Fields);
     if (bbFieldCount != bedSize+seq1Seq2Fields)
         {
         errAbort("Disagreement between trackDb field count (%d) and %s fieldCount (%d)",
 		bedSize, fileName, bbFieldCount);
 	}
     struct bed *bed = bedLoadN(fields, bedSize);
     if (bedSize >= 6 && scoreFilter && bed->score < minScore)
 	continue;
-    if (showUrl && (bedSize >= 4))
-        printCustomUrl(tdb, item, TRUE);
+
+    // if there are extra fields, load them up because we may want to use them in URL:
+    itemForUrl = getIdInUrl(tdb, item);
+    printCustomUrlWithFields(tdb, bed->name, bed->name, item == itemForUrl, extraFieldPairs);
+    if (itemForUrl)
+        printIframe(tdb, itemForUrl);
+
     bedPrintPos(bed, bedSize, tdb);
 
     // display seq1 and seq2
     if (seq1Seq2 && bedSize+seq1Seq2Fields == 8)
         printf("<table><tr><th>Sequence 1</th><th>Sequence 2</th></tr>"
 	       "<tr><td> %s </td><td> %s </td></tr></table>", fields[6], fields[7]);
     else if (isNotEmpty(rest))
 	{
-	char *restFields[256];
-	int restCount = chopTabs(rest, restFields);
-	int restBedFields = bedSize - 3;
 	if (restCount > restBedFields)
 	    {
-            char **extraFields = (restFields + restBedFields);
-            int extraFieldCount = restCount - restBedFields;
             int printCount = extraFieldsPrint(tdb,NULL,extraFields, extraFieldCount);
-            struct slPair* extraFieldPairs = getExtraFields(tdb, extraFields, extraFieldCount);
             printAllExternalExtraFields(tdb, extraFieldPairs);
 
             if (printCount == 0)
                 {
                 int i;
                 char label[20];
                 safef(label, sizeof(label), "nonBedFieldsLabel");
                 printf("<B>%s&nbsp;</B>",
                        trackDbSettingOrDefault(tdb, label, "Non-BED fields:"));
                 for (i = restBedFields;  i < restCount;  i++)
                     printf("%s%s", (i > 0 ? "\t" : ""), restFields[i]);
                 printf("<BR>\n");
                 }
 	    }
 	if (sameString(tdb->type, "bigGenePred"))