a865b66cfeec6dea62ccdcd5a22c69e9a27335b6
hiram
  Wed Apr 3 12:01:04 2019 -0700
using new browser styles and allow genePred to print refs #18869

diff --git src/hg/hubApi/hubApi.c src/hg/hubApi/hubApi.c
index ac9a8c0..2c9c371 100644
--- src/hg/hubApi/hubApi.c
+++ src/hg/hubApi/hubApi.c
@@ -1,18 +1,19 @@
 /* hubApi - access mechanism to hub data resources. */
 #include "dataApi.h"
 #include "botDelay.h"
+#include "jsHelper.h"
 
 /*
 +------------------+------------------+------+-----+---------+-------+
 | Field            | Type             | Null | Key | Default | Extra |
 +------------------+------------------+------+-----+---------+-------+
 | hubUrl           | longblob         | NO   | PRI | NULL    |       |
 | shortLabel       | varchar(255)     | NO   |     | NULL    |       |
 | longLabel        | varchar(255)     | NO   |     | NULL    |       |
 | registrationTime | varchar(255)     | NO   |     | NULL    |       |
 | dbCount          | int(10) unsigned | NO   |     | NULL    |       |
 | dbList           | blob             | YES  |     | NULL    |       |
 | descriptionUrl   | longblob         | YES  |     | NULL    |       |
 +------------------+------------------+------+-----+---------+-------+
 */
 
@@ -24,58 +25,61 @@
 int botDelay = 0;
 boolean debug = FALSE;	/* can be set in URL debug=1, to turn off: debug=0 */
 #define delayFraction	0.03
 
 /* Global only to this one source file */
 static struct cart *cart;             /* CGI and other variables */
 static struct hash *oldVars = NULL;
 static struct hash *trackCounter = NULL;
 static long totalTracks = 0;
 static boolean measureTiming = FALSE;	/* set by CGI parameters */
 static boolean allTrackSettings = FALSE;	/* checkbox setting */
 static char **shortLabels = NULL;	/* public hub short labels in array */
 // struct hubPublic *publicHubList = NULL;
 static int publicHubCount = 0;
 static char *defaultHub = "Plants";
+// static char *defaultHubUrl = " http://genome-test.gi.ucsc.edu/~hiram/hubs/Plants/hub.txt";
 static char *defaultDb = "ce11";
 static long enteredMainTime = 0;	/* will become = clock1000() on entry */
 		/* to allow calculation of when to bail out, taking too long */
 static long timeOutSeconds = 100;
 static boolean timedOut = FALSE;
 static char *urlPrefix = "";	/* initalized to support self references */
 static struct slName *supportedTypes = NULL;
 	/* will be initialized to a known supported set */
 
 static void initSupportedTypes()
 /* initalize the list of supported track types */
 {
 struct slName *el = newSlName("bed");
 slAddHead(&supportedTypes, el);
 el = newSlName("wig");
 slAddHead(&supportedTypes, el);
 el = newSlName("broadPeak");
 slAddHead(&supportedTypes, el);
 el = newSlName("narrowPeak");
 slAddHead(&supportedTypes, el);
 el = newSlName("bigBed");
 slAddHead(&supportedTypes, el);
 el = newSlName("bigWig");
 slAddHead(&supportedTypes, el);
 el = newSlName("bigNarrowPeak");
 slAddHead(&supportedTypes, el);
 el = newSlName("bigGenePred");
 slAddHead(&supportedTypes, el);
+el = newSlName("genePred");
+slAddHead(&supportedTypes, el);
 // el = newSlName("bigPsl");
 // slAddHead(&supportedTypes, el);
 // el = newSlName("bigBarChart");
 // slAddHead(&supportedTypes, el);
 // el = newSlName("bigInteract");
 // slAddHead(&supportedTypes, el);
 // el = newSlName("bigMaf");
 // slAddHead(&supportedTypes, el);
 // el = newSlName("bigChain");
 // slAddHead(&supportedTypes, el);
 slNameSort(&supportedTypes);
 }
 
 static boolean isSupportedType(char *type)
 /* is given type in the supportedTypes list ? */
@@ -656,72 +660,78 @@
     {
     hPrintf("    <li><ul>\n");
     trackSettings(tdb, countTracks); /* show all settings */
     hPrintf("    </ul></li>\n");
     }
 else if (tdb->subtracks)
     {
     showSubTracks(NULL, db, tdb, countTracks, chromName, chromSize, NULL);
     }
 return;
 }	/*	static void countOneTdb(char *db, struct trackDb *tdb,
 	 *	struct hash *countTracks, char *chromName,
 	 *	unsigned chromSize)
 	 */
 
-static unsigned largestChrom(char *db, char **nameReturn)
+static unsigned largestChrom(char *db, char **nameReturn, int *chromCount)
 /* return the length and get the chrom name for the largest chrom
  * from chromInfo table.  For use is sample getData URLs
  */
 {
 char query[1024];
 struct sqlConnection *conn = hAllocConn(db);
 sqlSafef(query, sizeof(query), "select chrom,size from chromInfo order by size desc limit 1");
 struct sqlResult *sr = sqlGetResult(conn, query);
 char **row = sqlNextRow(sr);
 unsigned length = 0;
 if (row)
    {
    *nameReturn = cloneString(row[0]);
    length = sqlLongLong(row[1]);
    }
 sqlFreeResult(&sr);
+if (chromCount)
+    {
+    sqlSafef(query, sizeof(query), "select count(*) from chromInfo");
+    *chromCount = sqlQuickNum(conn, query);
+    }
 hFreeConn(&conn);
 return length;
 }
 
 static void hubTrackList(struct trackHub *hub, struct trackDb *topTrackDb, struct trackHubGenome *genome)
 /* process the track list in a hub to show all tracks */
 {
 hPrintf("    <li><ul>\n");
 if (topTrackDb)
     {
     struct hash *countTracks = hashNew(0);
     struct trackDb *tdb = NULL;
     for ( tdb = topTrackDb; tdb; tdb = tdb->next )
 	{
 	char *bigDataIndex = NULL;
 	char *relIdxUrl = trackDbSetting(topTrackDb, "bigDataIndex");
 	if (relIdxUrl != NULL)
 	    bigDataIndex = trackHubRelativeUrl(genome->trackDbFile, relIdxUrl);
         char *defaultGenome = NULL;
         if (isNotEmpty(genome->name))
 	    defaultGenome = genome->name;
         char *chromName = NULL;
         unsigned chromSize = 0;
+	int chromCount = 0;
         if (isEmpty(genome->twoBitPath))
-            chromSize = largestChrom(defaultGenome, &chromName);
+            chromSize = largestChrom(defaultGenome, &chromName, &chromCount);
 	else
 	    hPrintf("    <li>twoBitPath %s genome %s</li>\n", genome->twoBitPath, defaultGenome);
 	hubCountOneTdb(hub, defaultGenome, tdb, bigDataIndex, countTracks, chromName, chromSize, defaultGenome);
 	if (timeOutReached())
 	    break;
 	}	/*	for ( tdb = topTrackDb; tdb; tdb = tdb->next )	*/
     hPrintf("    <li>%d different track types</li>\n",countTracks->elCount - 1);
     /* add this single genome count to the overall multi-genome counts */
     if (countTracks->elCount)
 	{
         hPrintf("        <li><ol>\n");
 	struct hashEl *hel, *helList = hashElListHash(countTracks);
 	slSort(&helList, hashElCmpIntValDesc);
 	for (hel = helList; hel; hel = hel->next)
 	    {
@@ -918,36 +928,40 @@
 /* skip the first leading slash to simplify chopByChar parsing */
 tmp += 1;
 int wordCount = chopByChar(tmp, '/', words, MAX_PATH_INFO);
 if (wordCount < 1)
     return NULL;
 
 struct hashEl *hel = hashLookup(apiFunctionHash, words[0]);
 return hel;
 }
 
 static void tracksForUcscDb(char *db)
 /* scan the specified database for all tracks */
 {
 struct hash *countTracks = hashNew(0);
 char *chromName = NULL;
-unsigned chromSize = largestChrom(db, &chromName);
-hPrintf("<h4>Tracks in UCSC genome: '%s', longest chrom: %s:%u</h4>\n", db, chromName, chromSize);
+int chromCount = 0;
+unsigned chromSize = largestChrom(db, &chromName, &chromCount);
+char countString[64];
+sprintLongWithCommas(countString, chromCount);
+char sizeString[64];
+sprintLongWithCommas(sizeString, chromSize);
+hPrintf("<h4>Tracks in UCSC genome: '%s', chrom count: %s, longest chrom: %s : %s</h4>\n", db, countString, chromName, sizeString);
 struct trackDb *tdbList = obtainTdb(NULL, db);
 struct trackDb *tdb;
 hPrintf("<ul>\n");
-hPrintf("<li>%s:%u</li>\n", chromName, chromSize);
 for (tdb = tdbList; tdb != NULL; tdb = tdb->next )
     {
     countOneTdb(db, tdb, countTracks, chromName, chromSize, NULL);
     if (timeOutReached())
 	break;
     }
 int trackCount = ptToInt(hashFindVal(countTracks, "track count"));
 /* elCount - 1 since the 'track count' element isn't a track */
 hPrintf("    <li>%d total tracks counted, %d different track types</li>\n", trackCount, countTracks->elCount - 1);
 if (countTracks->elCount)
     {
     hPrintf("        <ol>\n");
     struct hashEl *hel, *helList = hashElListHash(countTracks);
     slSort(&helList, hashElCmpIntValDesc);
     for (hel = helList; hel; hel = hel->next)
@@ -1095,51 +1109,53 @@
     if (hel)	/* have valid command */
 	{
         hPrintDisable();
         /* could check botDelay here to see if 459 status is advised */
 	puts("Content-Type:application/json");
 	puts("\n");
         void (*apiFunction)(char **) = hel->val;
         (*apiFunction)(words);
 	return;
 	}
      else
 	commandError = TRUE;
     }
 
 /* could check botDelay here to see if 459 status is advised */
-puts("Content-Type:text/html");
-puts("\n");
+// puts("Content-Type:text/html");
+// puts("\n");
 
 (void) hubPublicDbLoadAll();
 
 struct dbDb *dbList = ucscDbDb();
 char **ucscDbList = NULL;
 int listSize = slCount(dbList);
 AllocArray(ucscDbList, listSize);
 struct dbDb *el = dbList;
 int ucscDataBaseCount = 0;
 int maxDbNameWidth = 0;
 for ( ; el != NULL; el = el->next )
     {
     ucscDbList[ucscDataBaseCount++] = el->name;
     if (strlen(el->name) > maxDbNameWidth)
 	maxDbNameWidth = strlen(el->name);
     }
 maxDbNameWidth += 1;
 
-cartWebStart(cart, database, "UCSC JSON API interface");
+webStartJWest(cart, database, "UCSC JSON API interface");
+
+hPrintf("<div class='container-fluid gbPage'>\n");
 
 if (debug)
     {
     hPrintf("<ul>\n");
     hPrintf("<li>hgBotDelay: %d</li>\n", botDelay);
     char *envVar = getenv("BROWSER_HOST");
     hPrintf("<li>BROWSER_HOST:%s</li>\n", envVar);
     envVar = getenv("CONTEXT_DOCUMENT_ROOT");
     hPrintf("<li>CONTEXT_DOCUMENT_ROOT:%s</li>\n", envVar);
     envVar = getenv("CONTEXT_PREFIX");
     hPrintf("<li>CONTEXT_PREFIX:%s</li>\n", envVar);
     envVar = getenv("DOCUMENT_ROOT");
     hPrintf("<li>DOCUMENT_ROOT:%s</li>\n", envVar);
     envVar = getenv("HTTP_HOST");
     hPrintf("<li>HTTP_HOST:%s</li>\n", envVar);
@@ -1151,58 +1167,72 @@
     hPrintf("<li>SCRIPT_NAME:%s</li>\n", envVar);
     envVar = getenv("SCRIPT_URI");
     hPrintf("<li>SCRIPT_URI:%s</li>\n", envVar);
     envVar = getenv("SCRIPT_URL");
     hPrintf("<li>SCRIPT_URL:%s</li>\n", envVar);
     envVar = getenv("SERVER_NAME");
     hPrintf("<li>SERVER_NAME:%s</li>\n", envVar);
     envVar = getenv("PATH_INFO");
     if (isNotEmpty(envVar))
        hPrintf("<li>PATH_INFO:'%s'</li>\n", envVar);
     else
        hPrintf("<li>PATH_INFO:&lt;empty&gt;</li>\n");
     hPrintf("</ul>\n");
     }
 
-char *goOtherHub = cartUsualString(cart, "goOtherHub", defaultHub);
+char *goOtherHub = cartUsualString(cart, "goOtherHub", "");
 char *goUcscDb = cartUsualString(cart, "goUcscDb", "");
-char *otherHubUrl = cartUsualString(cart, "urlHub", defaultHub);
-char *goPublicHub = cartUsualString(cart, "goPublicHub", defaultHub);
+char *otherHubUrl = cartUsualString(cart, "urlHub", "");
+char *goPublicHub = cartUsualString(cart, "goPublicHub", "");
 char *hubDropDown = cartUsualString(cart, "publicHubs", defaultHub);
 char *urlDropDown = urlFromShortLabel(hubDropDown);
-char *ucscDb = cartUsualString(cart, "ucscGenomes", defaultDb);
+char *ucscDb = cartUsualString(cart, "ucscGenome", defaultDb);
 char *urlInput = urlDropDown;	/* assume public hub */
+if (debug)
+    {
+    hPrintf("<ul>\n");
+    hPrintf("<li>goOtherHub: '%s'</li>\n", goOtherHub);
+    hPrintf("<li>goUcscDb: '%s'</li>\n", goUcscDb);
+    hPrintf("<li>otherHubUrl: '%s'</li>\n", otherHubUrl);
+    hPrintf("<li>goPublicHub: '%s'</li>\n", goPublicHub);
+    hPrintf("<li>hubDropDown: '%s'</li>\n", hubDropDown);
+    hPrintf("<li>urlDropDown: '%s'</li>\n", urlDropDown);
+    hPrintf("<li>ucscDb: '%s'</li>\n", ucscDb);
+    hPrintf("<li>urlInput: '%s'</li>\n", urlInput);
+    hPrintf("</ul>\n");
+    }
 if (sameWord("go", goOtherHub))	/* requested other hub URL */
     urlInput = otherHubUrl;
 else if (isEmpty(otherHubUrl))
     otherHubUrl = urlInput;
 
+skipLeadingChars
 if (commandError)
   {
   hPrintf("<h3>ERROR: no such command: '%s/%s' for endpoint '%s'</h3>", words[0], words[1], pathInfo);
   }
 
 long lastTime = clock1000();
 struct trackHub *hub = errCatchTrackHubOpen(urlInput);
 if (measureTiming || debug)
     {
     long thisTime = clock1000();
     if (debug)
        hPrintf("<em>hub open time: %ld millis</em><br>\n", thisTime - lastTime);
     }
 
-hPrintf("<p>Please refer to <a href='../../goldenPath/help/api.html'>API help</a> documentation for more discussion.</p>\n");
+hPrintf("<h3>Please refer to <a href='../../goldenPath/help/api.html'>API help</a> documentation for more information about data data API operation.</h3>\n");
 
 if (debug)
     showCartDump();
 
 hPrintf("<h2>Explore hub or database assemblies and tracks</h2>\n");
 
 hPrintf("<form action='%s' name='hubApiUrl' id='hubApiUrl' method='GET'>\n\n", urlPrefix);
 
 hPrintf("<b>Select public hub:&nbsp;</b>");
 #define JBUFSIZE 2048
 #define SMALLBUF 256
 char javascript[JBUFSIZE];
 struct slPair *events = NULL;
 safef(javascript, sizeof(javascript), "this.lastIndex=this.selectedIndex;");
 slPairAdd(&events, "focus", cloneString(javascript));
@@ -1210,77 +1240,83 @@
 cgiMakeDropListClassWithIdStyleAndJavascript("publicHubs", "publicHubs",
     shortLabels, publicHubCount, hubDropDown, NULL, "width: 400px", events);
 
 hWrites("&nbsp;");
 hButton("goPublicHub", "go");
 
 hPrintf("<br>Or, enter a hub URL:&nbsp;");
 hPrintf("<input type='text' name='urlHub' id='urlHub' size='60' value='%s'>\n", otherHubUrl);
 hWrites("&nbsp;");
 hButton("goOtherHub", "go");
 
 hPrintf("<br>Or, select a UCSC database name:&nbsp;");
 maxDbNameWidth *= 9;  // 9 should be font width here
 char widthPx[SMALLBUF];
 safef(widthPx, sizeof(widthPx), "width: %dpx", maxDbNameWidth);
-cgiMakeDropListClassWithIdStyleAndJavascript("ucscGenomes", "ucscGenomes",
+cgiMakeDropListClassWithIdStyleAndJavascript("ucscGenome", "ucscGenome",
     ucscDbList, ucscDataBaseCount, ucscDb, NULL, widthPx, events);
 hWrites("&nbsp;");
 hButton("goUcscDb", "go");
 
 boolean depthSearch = cartUsualBoolean(cart, "depthSearch", FALSE);
 hPrintf("<br>\n&nbsp;&nbsp;");
 hCheckBox("depthSearch", cartUsualBoolean(cart, "depthSearch", FALSE));
 hPrintf("&nbsp;perform full bbi file measurement : %s (will time out if taking longer than %ld seconds)<br>\n", depthSearch ? "TRUE" : "FALSE", timeOutSeconds);
 hPrintf("\n&nbsp;&nbsp;");
 allTrackSettings = cartUsualBoolean(cart, "allTrackSettings", FALSE);
 hCheckBox("allTrackSettings", allTrackSettings);
 hPrintf("&nbsp;display all track settings for each track : %s<br>\n", allTrackSettings ? "TRUE" : "FALSE");
 
-hPrintf("<br>\n</form>\n");
+hPrintf("<br>\n");
+// if (debug)
+//    cgiMakeHiddenVar("debug", "1");
+hPrintf("</form>\n");
 
 hPrintf("<p>\n");
 if (sameWord("go", goUcscDb))	/* requested UCSC db track list */
     {
     tracksForUcscDb(ucscDb);
     }
 else
     {
     hPrintf("<h4>Examine %s at: %s</h4>\n", sameWord("go",goPublicHub) ? "public hub" : "other hub", urlInput);
     hPrintf("<ul>\n");
     hPrintf("<li>%s</li>\n", hub->shortLabel);
     hPrintf("<li>%s</li>\n", hub->longLabel);
     if (isNotEmpty(hub->defaultDb))
         hPrintf("<li>%s - default database</li>\n", hub->defaultDb);
     hPrintf("</ul>\n");
 
     genomeList(hub);
     }
 
 if (timedOut)
     hPrintf("<h1>Reached time out %ld seconds</h1>", timeOutSeconds);
 if (measureTiming || debug)
     hPrintf("<em>Overall total time: %ld millis</em><br>\n", clock1000() - enteredMainTime);
 
 hPrintf("</p>\n");
+hPrintf("</div> <!-- end this page contents -->\n");
 
-cartWebEnd();
+webIncludeFile("inc/jWestFooter.html");
+webEndJWest();
+// cartWebEnd();
 }	/*	void doMiddle(struct cart *theCart)	*/
 
 /* Null terminated list of CGI Variables we don't want to save
  * permanently. */
-static char *excludeVars[] = {"Submit", "submit", "goOtherHub", "goPublicHub", "goUcscDb", "ucscGenomes", "publicHubs", NULL,};
+static char *excludeVars[] = {"Submit", "submit", "goOtherHub", "goPublicHub", "goUcscDb", "ucscGenome", "publicHubs", "clade", NULL,};
 
 int main(int argc, char *argv[])
 /* Process command line. */
 {
 enteredMainTime = clock1000();
 cgiSpoof(&argc, argv);
 measureTiming = TRUE;
 verboseTimeInit();
 /* similar delay system as in DAS server */
 botDelay = hgBotDelayTimeFrac(delayFraction);
 if (botDelay > 0)
     {
     if (botDelay > 2000)
         {
 	hogExit();