5f8bc82be821519c5e8e171749918d99c617b1c8
galt
  Wed Sep 20 17:15:25 2023 -0700
hgc - Making links work better to support http or https. refs #32257

diff --git src/hg/hgc/wikiTrack.c src/hg/hgc/wikiTrack.c
index 0c78eca..5f23375 100644
--- src/hg/hgc/wikiTrack.c
+++ src/hg/hgc/wikiTrack.c
@@ -1,588 +1,588 @@
 /* Handle details pages for wiggle tracks. */
 
 /* Copyright (C) 2013 The Regents of the University of California 
  * See kent/LICENSE or http://genome.ucsc.edu/license/ for licensing information. */
 
 #include "common.h"
 #include "cart.h"
 #include "hgc.h"
 #include "hCommon.h"
 #include "hgColors.h"
 #include "hgConfig.h"
 #include "obscure.h"
 #include "binRange.h"
 #include "web.h"
 #include "net.h"
 #include "grp.h"
 #include "hui.h"
 #include "htmlPage.h"
 #include "wikiLink.h"
 #include "wikiTrack.h"
 
 
 #define ITEM_SCORE_DEFAULT "1000"
 #define ADD_ITEM_COMMENT_DEFAULT "add comments"
 
 static void colorMenuOutput()
 /* the item color pull-down menu in the create item form */
 {
 hPrintf("<INPUT NAME=\"colorPullDown\" VALUE=\"\" SIZE=1 STYLE=\"display:none;\" >\n");
 
 hPrintf("<SELECT NAME=\"%s\" id='%s' style=\"width:8em; background-color:#000000;\">\n"
     , NEW_ITEM_COLOR, NEW_ITEM_COLOR);
 jsOnEventById("change", NEW_ITEM_COLOR, "updateColorSelectBox();");
 hPrintf("<OPTION SELECTED VALUE = \"#000000\" style=\"background-color:#000000;\" >black</OPTION>\n");
 hPrintf("<OPTION value = \"#0000ff\" style=\"background-color:#0000ff;\" >blue</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#9600c8\" style=\"background-color:#9600c8;\" >purple</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#ff0000\" style=\"background-color:#ff0000;\" >red</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#e67800\" style=\"background-color:#e67800;\" >orange</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#dcdc00\" style=\"background-color:#dcdc00;\" >yellow</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#00b400\" style=\"background-color:#00b400;\" >green</OPTION>\n");
 hPrintf("<OPTION VALUE = \"#8c8c8c\" style=\"background-color:#8c8c8c;\" >gray</OPTION>\n");
 hPrintf("</SELECT>\n");
 }
 
 static char *encodedHgcReturnUrl(int id, char *table)
 /* Return a CGI-encoded hgc URL with hgsid and given id.  Free when done. */
 {
 char retBuf[1024];
 int o = cartUsualInt(cart, "o", winStart);
-safef(retBuf, sizeof(retBuf), "http://%s/cgi-bin/hgc?%s&g=%s&c=%s&o=%d&l=%d&r=%d&db=%s&i=%d",
-    cgiServerNamePort(), cartSidUrlString(cart), table, seqName,
+safef(retBuf, sizeof(retBuf), "http%s://%s/cgi-bin/hgc?%s&g=%s&c=%s&o=%d&l=%d&r=%d&db=%s&i=%d",
+    cgiAppendSForHttps(), cgiServerNamePort(), cartSidUrlString(cart), table, seqName,
 	o, winStart, winEnd, database, id);
 return cgiEncode(retBuf);
 }   
 
 static char *wikiTrackUserLoginUrl(int id, char *table)
 /* Return the URL for the wiki user login page. */
 {
 char *retEnc = encodedHgcReturnUrl(id, table);
 char buf[2048];
 if (! wikiLinkEnabled())
     errAbort("wikiLinkUserLoginUrl called when wiki is not enabled (specified "
              "in hg.conf).");
 safef(buf, sizeof(buf),
       "%s/index.php?title=Special:UserloginUCSC&returnto=%s",
       cfgOptionDefault(CFG_WIKI_URL, NULL), retEnc);
 freez(&retEnc);
 return(cloneString(buf));
 }
 
 void offerLogin(int id, char *loginType, char *table)
 /* display login prompts to the wiki when user isn't already logged in */
 {
 char *wikiHost = wikiLinkHost();
 char *loginUrl = wikiTrackUserLoginUrl(id, table);
 printf("<P>Please login to %s the annotation track.</P>\n", loginType);
 printf("<P>The login page is handled by our "
-       "<A HREF=\"http://%s/\" TARGET=_BLANK>wiki system</A>:\n", wikiHost);
+       "<A HREF=\"http%s://%s/\" TARGET=_BLANK>wiki system</A>:\n", cgiAppendSForHttps(), wikiHost);
 printf("<A HREF=\"%s\"><B>click here to login.</B></A><BR>\n", loginUrl);
 printf("The wiki also serves as a forum for users "
        "to share knowledge and ideas.\n</P>\n");
 freeMem(loginUrl);
 freeMem(wikiHost);
 webIncludeHelpFile("wikiTrackAddCommentHelp", TRUE);
 webIncludeHelpFile("wikiTrack", TRUE);
 }
 
 static void startForm(char *name, char *actionType)
 {
 hPrintf("<FORM ID=\"%s\" NAME=\"%s\" ACTION=\"%s\">\n\n", name, name, hgcName());
 cartSaveSession(cart);
 cgiMakeHiddenVar("g", actionType);
 cgiContinueHiddenVar("c");
 cgiContinueHiddenVar("o");
 hPrintf("\n");
 cgiContinueHiddenVar("l");
 cgiContinueHiddenVar("r");
 hPrintf("\n");
 }
 
 static struct bed *multipleItems(struct wikiTrack *item)
 {
 struct sqlResult *sr;
 char **row;
 struct sqlConnection *wikiConn = wikiConnect();
 char query[1024];
 struct bed *bedList = NULL;
 
 sqlSafef(query, ArraySize(query), "SELECT chrom,chromStart,chromEnd,id FROM %s "
     "WHERE descriptionKey='%s' ORDER BY chrom,chromStart;",
 	WIKI_TRACK_TABLE, item->descriptionKey);
 sr = sqlGetResult(wikiConn, query);
 while ( (row = sqlNextRow(sr)) != NULL)
     {
     int elId = sqlUnsigned(row[3]);
     if (elId == item->id)
 	continue;
     struct bed *bed;
     AllocVar(bed);
     bed->chrom = cloneString(row[0]);
     bed->chromStart = sqlUnsigned(row[1]);
     bed->chromEnd = sqlUnsigned(row[2]);
     bed->score = elId;
     slAddHead(&bedList,bed);
     }
 sqlFreeResult(&sr);
 slSort(&bedList, bedCmpExtendedChr);
 wikiDisconnect(&wikiConn);
 return bedList;
 }
 
 static void displayItem(struct wikiTrack *item, char *userName)
 /* given an already fetched item, get the item description from
  *	the wiki.  Put up edit form(s) if userName is not NULL
  */
 { 
 boolean geneAnnotation = FALSE;
 char *url = cfgOptionDefault(CFG_WIKI_URL, NULL);
 
 if (isNotEmpty(item->geneSymbol) && differentWord(item->geneSymbol,"0"))
     {
     hPrintf("<B>This is a UCSC gene annotation</B><BR>\n");
     geneAnnotation = TRUE;
     }
 else
     hPrintf("<B>This is a genome location annotation, not a gene annotation.</B>\n");
 
 printPosOnChrom(item->chrom, item->chromStart, item->chromEnd,
     item->strand, FALSE, item->name);
 if (geneAnnotation)
     {
     struct bed *itemList = multipleItems(item);
     if (slCount(itemList) > 0)
 	{
 	hPrintf("&nbsp;&nbsp;This gene symbol <B>'%s'</B> is also found in the following "
 	    "locations:<BR>\n", item->name);
 	struct bed *el;
 	for (el = itemList; el; el = el->next)
 	    {
 	    printf("&nbsp;&nbsp;&nbsp;&nbsp;<B>%s:</B> "
 	       "<A HREF=\"%s&db=%s&position=%s%%3A%d-%d\">",
 	       item->name, hgTracksPathAndSettings(), database, el->chrom,
 		el->chromStart+1, el->chromEnd);
 	    printf("%s:%d-%d</A><BR>\n", el->chrom, el->chromStart+1,
 		el->chromEnd);
 	    }
 	}
     }
 hPrintf("<B>Created </B>%s<B> by:&nbsp;</B>", item->creationDate);
 hPrintf("<A HREF=\"%s/index.php/User:%s\" TARGET=_blank>%s</A><BR>\n", url,
     item->owner, item->owner);
 hPrintf("<B>Most recent quick update:&nbsp;</B>%s<BR>\n",
     item->lastModifiedDate);
 
 boolean editor = isWikiEditor(userName);
 
 if ((NULL != userName) &&
 	(editor || (sameWord(userName, item->owner) && !geneAnnotation)))
     {
     hPrintf("<em>(comments for deleted items remain in the wiki, with a "
 	"note<BR>&nbsp;&nbsp;that the item has been deleted.)</em><BR>\n");
     startForm("deleteForm", G_DELETE_WIKI_ITEM);
     char idString[128];
     safef(idString, ArraySize(idString), "%d", item->id);
     cgiMakeHiddenVar("i", idString);
     hPrintf("\n");
     webPrintLinkTableStart();
     webPrintLinkCellStart();
 
     if (editor && (differentWord(userName, item->owner) || geneAnnotation))
 	hPrintf("Editor '%s' has deletion rights&nbsp;&nbsp;", userName);
     else
 	hPrintf("Owner '%s' has deletion rights&nbsp;&nbsp;", item->owner);
 
     webPrintLinkCellEnd();
     webPrintLinkCellStart();
     cgiMakeButton("submit", "DELETE");
     webPrintLinkCellEnd();
     webPrintLinkCellStart();
     hPrintf("&nbsp;(no questions asked)");
     webPrintLinkCellEnd();
     webPrintLinkTableEnd();
     hPrintf("\n</FORM>\n");
     }
 
 hPrintf("<B>View the wiki article "
   "<A HREF=\"%s/index.php/%s\" TARGET=_blank>%s:</A> to see "
 	"existing comments.</B><BR>\n",
        url, item->descriptionKey, item->descriptionKey);
 
 if (NULL != userName)
     hPrintf("<B>Mark this wiki article as <em>"
 	"<A HREF=\"%s/index.php/%s?action=watch\" TARGET=_blank>watched</A>"
 	"</em> to receive email notices of any comment additions.</B><BR>\n",
 	   url, item->descriptionKey);
 
 
 hPrintf("<HR>\n");
 
 if (NULL == userName)
     {
     if (! wikiTrackReadOnly() ) /* read-only option 2012-06-25 */
         offerLogin(item->id, "add comments to items on", WIKI_TRACK_TABLE);
     }
 else if (emailVerified(TRUE)) /* do print message when not verified */
     {
     startForm("addComments", G_ADD_WIKI_COMMENTS);
     char idString[128];
     safef(idString, ArraySize(idString), "%d", item->id);
     cgiMakeHiddenVar("i", idString);
     hPrintf("\n");
     webPrintLinkTableStart();
     /* first row is a title line */
     char label[256];
     safef(label, ArraySize(label),
 	"'%s' quick add comments to item '%s'\n", userName, item->name);
     webPrintWideLabelCell(label, 2);
     webPrintLinkTableNewRow();
     /* second row is initial comment/description text entry */
     webPrintWideCellStart(2, HG_COL_TABLE);
     cgiMakeTextArea(NEW_ITEM_COMMENT, ADD_ITEM_COMMENT_DEFAULT, 3, 70);
     webPrintLinkCellEnd();
     webPrintLinkTableNewRow();
     /*webPrintLinkCellStart(); more careful explicit alignment */
     hPrintf("<TD BGCOLOR=\"#%s\" ALIGN=\"CENTER\" VALIGN=\"TOP\">",
 	    HG_COL_TABLE);
     cgiMakeButton("submit", "add comments");
     hPrintf("\n</FORM>\n");
     webPrintLinkCellEnd();
     /*webPrintLinkCellStart(); doesn't valign center properly */
     hPrintf("<TD BGCOLOR=\"#%s\" ALIGN=\"CENTER\" VALIGN=\"TOP\">",
 	    HG_COL_TABLE);
     hPrintf("\n<FORM ID=\"cancel\" NAME=\"cancel\" ACTION=\"%s\">", hgTracksName());
     cgiMakeButton("cancel", "return to tracks display");
     hPrintf("\n</FORM>\n");
     webPrintLinkCellEnd();
     webPrintLinkTableEnd();
 
     hPrintf("For more extensive edits, please edit the ");
     hPrintf("wiki article <A HREF=\"%s/index.php/%s\" TARGET=_blank>%s</A> "
        "in the wiki editing system.<BR>", url, item->descriptionKey,
 	    item->descriptionKey);
     webIncludeHelpFile("wikiTrackAddCommentHelp", TRUE);
     webIncludeHelpFile("wikiTrack", TRUE);
     }
 }	/*	displayItem()	*/
 
 void outputJavaScript()
 /* java script functions used in the create item form */
 {
 hPrintf("<SCRIPT TYPE=\"text/javascript\">\n");
 
 hPrintf("function updateColorSelectBox() {\n"
 " var form = document.getElementById(\"createItem\");\n"
 " document.createItem.colorPullDown.style.display='inline';\n"
 " document.createItem.colorPullDown.select();\n"
 " document.createItem.colorPullDown.style.display='none';\n"
 " form.%s.style.background = form.%s[form.%s.selectedIndex].value;\n"
 " form.%s.style.color = form.%s[form.%s.selectedIndex].value;\n"
 "}\n", NEW_ITEM_COLOR, NEW_ITEM_COLOR, NEW_ITEM_COLOR,
 	NEW_ITEM_COLOR, NEW_ITEM_COLOR, NEW_ITEM_COLOR);
 hPrintf("</SCRIPT>\n");
 }
 
 void doWikiTrack(char *wikiItemId, char *chrom, int winStart, int winEnd)
 /* handle item clicks on wikiTrack - may create new items */
 {
 char *userName = NULL;
 
 if (wikiTrackEnabled(database, &userName) && sameWord("0", wikiItemId))
     {
     cartWebStart(cart, database, "%s", "User Annotation Track: Create new item");
     if (NULL == userName)
 	{
         if (! wikiTrackReadOnly() ) /* read-only option 2012-06-25 */
             {
             offerLogin(0, "add new items to", WIKI_TRACK_TABLE);
             //cartHtmlEnd();
             }
 	return;
 	}
 
     if (emailVerified(TRUE)) /* do print message when not verified */
 	{
 	outputJavaScript();
 	startForm("createItem", G_CREATE_WIKI_ITEM);
 
 	webPrintLinkTableStart();
 	/* first row is a title line */
 	char label[256];
 	safef(label, ArraySize(label), "Create new item, owner: '%s'\n",
 	    userName);
 	webPrintWideLabelCell(label, 2);
 	webPrintLinkTableNewRow();
 	/* third row is position entry box */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	puts("<B>position:&nbsp;</B>");
 	savePosInTextBox(seqName, winStart+1, winEnd);
 	hPrintf("&nbsp;(size: ");
 	printLongWithCommas(stdout, (long long)(winEnd - winStart));
 	hPrintf(")");
 	webPrintLinkCellEnd();
 	webPrintLinkTableNewRow();
 	/* fourth row is strand selection radio box */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	char *strand = cartUsualString(cart, NEW_ITEM_STRAND, "plus");
 	boolean plusStrand = sameWord("plus",strand) ? TRUE : FALSE;
 	hPrintf("<B>strand:&nbsp;");
 	cgiMakeRadioButton(NEW_ITEM_STRAND, "plus", plusStrand);
 	hPrintf("&nbsp;+&nbsp;&nbsp;");
 	cgiMakeRadioButton(NEW_ITEM_STRAND, "minus", ! plusStrand);
 	hPrintf("&nbsp;-</B>");
 	webPrintLinkCellEnd();
 	webPrintLinkTableNewRow();
 	/* fifth row is item name text entry */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	hPrintf("<B>item name:&nbsp;</B>");
 	cgiMakeTextVar("i", NEW_ITEM_NAME, 18);
 	webPrintLinkCellEnd();
 #ifdef NOT
 	webPrintLinkTableNewRow();
 	/* sixth row is item score text entry */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	hPrintf("<B>item score:&nbsp;</B>");
 	cgiMakeTextVar(NEW_ITEM_SCORE, ITEM_SCORE_DEFAULT, 4);
 	hPrintf("&nbsp;(range:&nbsp;0&nbsp;to&nbsp;%s)", ITEM_SCORE_DEFAULT);
 	webPrintLinkCellEnd();
 #endif
 	webPrintLinkTableNewRow();
 	/* seventh row is item color pull-down menu */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	hPrintf("<B>item color:&nbsp;</B>");
 	colorMenuOutput();
 	webPrintLinkCellEnd();
 	webPrintLinkTableNewRow();
 	/* seventh row is initial comment/description text entry */
 	webPrintWideCellStart(2, HG_COL_TABLE);
 	hPrintf("<B>initial comments/description:</B><BR>");
 	cgiMakeTextArea(NEW_ITEM_COMMENT, NEW_ITEM_COMMENT_DEFAULT, 5, 70);
 	webPrintLinkCellEnd();
 	webPrintLinkTableNewRow();
 	/* seventh row is the submit and cancel buttons */
 	/*webPrintLinkCellStart(); more careful explicit alignment */
 	hPrintf("<TD BGCOLOR=\"#%s\" ALIGN=\"CENTER\" VALIGN=\"TOP\">",
 		HG_COL_TABLE);
 	cgiMakeButton("submit", "create new item");
 	hPrintf("\n</FORM>\n");
 	webPrintLinkCellEnd();
 	/*webPrintLinkCellStart(); doesn't valign center properly */
 	hPrintf("<TD BGCOLOR=\"#%s\" ALIGN=\"CENTER\" VALIGN=\"TOP\">",
 		HG_COL_TABLE);
 	hPrintf("\n<FORM ID=\"cancel\" NAME=\"cancel\" ACTION=\"%s\">", hgTracksName());
 	cgiMakeButton("cancel", "cancel");
 	hPrintf("\n</FORM>\n");
 	webPrintLinkCellEnd();
 	webPrintLinkTableEnd();
 	hPrintf("This entry form starts the comments for this new item.<BR>\n"
 	    "Subsequent edits will be performed in the wiki editing system."
 	    "<BR>\n");
 	webIncludeHelpFile("wikiTrackCreateItemHelp", TRUE);
 	webIncludeHelpFile("wikiTrack", TRUE);
 	}
 
     }
 else
     {
     struct wikiTrack *item = findWikiItemId(wikiItemId);
     cartWebStart(cart, database, "%s (%s) %s", "User Annotation Track", item->name,
 	wikiItemId);
     /* if we can get the hgc clicks to add item id to the incoming data,
      *	then use that item Id here
      */
     displayItem(item, userName);
     }
 
 }	/*	void doWikiTrack()	*/
 
 static void updateLastModifiedDate(int id)
 /* set lastModifiedDate to now() */
 {
 char query[512];
 struct sqlConnection *wikiConn = wikiConnect();
 
 sqlSafef(query, ArraySize(query),
     "UPDATE %s set lastModifiedDate=now() WHERE id='%d'",
 	WIKI_TRACK_TABLE, id);
 sqlUpdate(wikiConn,query);
 wikiDisconnect(&wikiConn);
 }
 
 static void deleteItem(int id)
 /* delete the item with specified id */
 {
 char query[512];
 struct sqlConnection *wikiConn = wikiConnect();
 sqlSafef(query, ArraySize(query), "DELETE FROM %s WHERE id='%d'",
 	WIKI_TRACK_TABLE, id);
 sqlUpdate(wikiConn,query);
 wikiDisconnect(&wikiConn);
 }
 
 void doDeleteWikiItem(char *wikiItemId, char *chrom, int winStart, int winEnd)
 /* handle delete item clicks for wikiTrack */
 {
 char *userName = NULL;
 struct wikiTrack *item = findWikiItemId(wikiItemId);
 
 cartWebStart(cart, database, "%s (%s)", "User Annotation Track, deleted item: ",
 	item->name);
 if (NULL == wikiItemId)
     errAbort("delete wiki item: NULL wikiItemId");
 if (! wikiTrackEnabled(database, &userName))
     errAbort("delete wiki item: wiki track not enabled");
 
 /*	this may be a multiple loci gene symbol annotation */
 struct bed *itemList = multipleItems(item);
 char comments[1024];
 if (slCount(itemList) > 0)
     safef(comments,ArraySize(comments), "This item '''%s''' on assembly %s "
     "at %s:%d-%d (and %d other loci) has been deleted from the wiki track\n\n",
 	item->name, item->db, item->chrom, item->chromStart, item->chromEnd,
 	slCount(itemList));
 else
     safef(comments,ArraySize(comments), "This item '''%s''' on assembly %s "
     "at %s:%d-%d has been deleted from the wiki track\n\n", item->name,
 	item->db, item->chrom, item->chromStart, item->chromEnd);
 
 prefixComments(item, comments, userName, seqName, winStart, winEnd,
     database, NULL, "(deleted item)", NEW_ITEM_CATEGORY);
 deleteItem(sqlSigned(wikiItemId));
 /*	this may be a multiple loci gene symbol annotation */
 if (slCount(itemList) > 0)
     {
     struct bed *el;
     for (el = itemList; el; el = el->next)
 	deleteItem(el->score);
     }
 hPrintf("<BR>\n");
 hPrintf("<FORM ID=\"delete\" NAME=\"delete\" ACTION=\"%s\">", hgTracksName());
 cgiMakeButton("submit", "return to tracks display");
 hPrintf("\n</FORM>\n");
 hPrintf("<BR>\n");
 webIncludeHelpFile("wikiTrack", TRUE);
 }
 
 void doAddWikiComments(char *wikiItemId, char *chrom, int winStart, int winEnd)
 /* handle add comment item clicks for wikiTrack */
 {
 char *userName = NULL;
 struct wikiTrack *item = findWikiItemId(wikiItemId);
 
 cartWebStart(cart, database, "%s (%s)", "User Annotation Track", item->name);
 if (NULL == wikiItemId)
     errAbort("add wiki comments: NULL wikiItemId");
 if (! wikiTrackEnabled(database, &userName))
     errAbort("add wiki comments: wiki track not enabled");
 if (NULL == userName)
     errAbort("add wiki comments: user not logged in ?");
 
 addDescription(item, userName, seqName, winStart, winEnd, cart, database, NULL,
 	NULL, NEW_ITEM_CATEGORY);
 updateLastModifiedDate(sqlSigned(wikiItemId));
 displayItem(item, userName);
 }
 
 void doCreateWikiItem(char *itemName, char *chrom, int winStart, int winEnd)
     /* handle create item clicks for wikiTrack */
 {
 int itemStart = 0;
 int itemEnd = 0;
 char *chrName = NULL;
 char *pos = NULL;
 char *strand = cartUsualString(cart, NEW_ITEM_STRAND, "plus");
 char *class = cartUsualString(cart, NEW_ITEM_CLASS, ITEM_NOT_CLASSIFIED);
 boolean plusStrand = sameWord("plus",strand) ? TRUE : FALSE;
 char descriptionKey[256];
 struct sqlConnection *wikiConn = wikiConnect();
 char *userName = NULL;
 char *color = cartUsualString(cart, NEW_ITEM_COLOR, "#000000");
 int score = 0;
 struct wikiTrack *newItem;
 
 if (! wikiTrackEnabled(database, &userName))
     errAbort("create new wiki item: wiki track not enabled");
 if (NULL == userName)
     errAbort("create new wiki item: user not logged in ?");
 
 #ifdef NOT
 score = sqlSigned(cartUsualString(cart, NEW_ITEM_SCORE, ITEM_SCORE_DEFAULT));
 #endif
 score = 0;
 pos = stripCommas(cartOptionalString(cart, "getDnaPos"));
 if (NULL == pos)
     errAbort("create new wiki item: called incorrectly, without getDnaPos");
 
 hgParseChromRange(database, pos, &chrName, &itemStart, &itemEnd);
 if (NULL == chrName)
     webAbort("Wiki Annotation", "illegal chrom name entered: '%s'<BR>\n"
 	"Note: chrom names are case sensitive.<BR>\n", pos);
 char *realChrName = hgOfficialChromName(database, chrName);
 if (NULL == realChrName)
     webAbort("Wiki Annotation", "illegal chrom name entered: '%s'<BR>\n"
 	"Note: chrom names are case sensitive.<BR>\n", pos);
 if (itemStart > itemEnd)
     {
     int t = itemEnd;
     itemEnd = itemStart;
     itemStart = t;
     }
 
 safef(descriptionKey,ArraySize(descriptionKey),
 	"GenomeAnnotation:%s-%d", database, 0);
 
 AllocVar(newItem);
 newItem->bin = binFromRange(itemStart, itemEnd);
 newItem->chrom = cloneString(realChrName);
 newItem->chromStart = itemStart;
 newItem->chromEnd = itemEnd;
 newItem->name = cloneString(itemName);
 newItem->score = score;
 safef(newItem->strand, sizeof(newItem->strand), "%s", plusStrand ? "+" : "-");
 newItem->db = cloneString(database);
 newItem->owner = cloneString(userName);
 newItem->class = cloneString(class);
 newItem->color = cloneString(color);
 newItem->creationDate = cloneString("0");
 newItem->lastModifiedDate = cloneString("0");
 newItem->descriptionKey = cloneString(descriptionKey);
 newItem->id = 0;
 newItem->geneSymbol = cloneString("0");
 
 wikiTrackSaveToDb(wikiConn, newItem, WIKI_TRACK_TABLE, 1024);
 
 int id = sqlLastAutoId(wikiConn);
 safef(descriptionKey,ArraySize(descriptionKey),
 	"GenomeAnnotation:%s-%d", database, id);
 
 wikiTrackFree(&newItem);
 
 char newItemName[128];
 char query[512];
 if (sameWord(itemName,NEW_ITEM_NAME))
     {
     safef(newItemName, ArraySize(newItemName), "%s-%d", database, id);
     sqlSafef(query, ArraySize(query), "UPDATE %s set creationDate=now(),lastModifiedDate=now(),descriptionKey='%s',name='%s-%d' WHERE id='%d'",
 	WIKI_TRACK_TABLE, descriptionKey, database, id, id);
     
     }
 else
     {
     safef(newItemName, ArraySize(newItemName), "%s", itemName);
     sqlSafef(query, ArraySize(query), "UPDATE %s set creationDate=now(),lastModifiedDate=now(),descriptionKey='%s' WHERE id='%d'",
 	WIKI_TRACK_TABLE, descriptionKey, id);
     }
 sqlUpdate(wikiConn,query);
 wikiDisconnect(&wikiConn);
 
 cartWebStart(cart, database, "%s %s", "User Annotation Track, created new item: ",
 	newItemName);
 
 char wikiItemId[64];
 safef(wikiItemId,ArraySize(wikiItemId),"%d", id);
 struct wikiTrack *item = findWikiItemId(wikiItemId);
 
 addDescription(item, userName, seqName, winStart, winEnd, cart, database, NULL,
 	NULL, NEW_ITEM_CATEGORY);
 displayItem(item, userName);
 }	/*	void doCreateWikiItem()	*/