dfd893ed6eb311a9b7c8844db7fec58642083c39
angie
  Fri Jan 9 15:46:14 2015 -0800
New toy CGI hgChooseDb based on PPT mockup and ideas from Ann and Matt: popular species icons and autocomplete search for species, as an alternative to hgGateway's menus.  Uses the new ReactJS/ImmutableJS framework.
hgChooseDb.c has three modes of operation:
- HTML output for simple main page with a <div> container to be filled in by javascript
- cart-based JSON responses to ajax requests from javascript (using hg/lib/cartJson.c)
- no cart; fast JSON responses to species-search autocomplete requests

hgChooseDb.jsx is the React/JSX UI view code, compiled to bundle/reactHgChooseDb.js.
hgChooseDbModel.js is a subclass of js/model/lib/ImModel.js that gets initial state
from the server and then responds to user actions.

diff --git src/lib/common.c src/lib/common.c
index a84f414..4839c61 100644
--- src/lib/common.c
+++ src/lib/common.c
@@ -1386,30 +1386,45 @@
 boolean startsWith(const char *start, const char *string)
 /* Returns TRUE if string begins with start. */
 {
 char c;
 int i;
 
 for (i=0; ;i += 1)
     {
     if ((c = start[i]) == 0)
         return TRUE;
     if (string[i] != c)
         return FALSE;
     }
 }
 
+boolean startsWithNoCase(const char *start, const char *string)
+/* Returns TRUE if string begins with start, case-insensitive. */
+{
+char c;
+int i;
+
+for (i=0; ;i += 1)
+    {
+    if ((c = tolower(start[i])) == 0)
+        return TRUE;
+    if (tolower(string[i]) != c)
+        return FALSE;
+    }
+}
+
 boolean startsWithWord(char *firstWord, char *line)
 /* Return TRUE if first white-space-delimited word in line
  * is same as firstWord.  Comparison is case sensitive. */
 {
 int len = strlen(firstWord);
 int i;
 for (i=0; i<len; ++i)
    if (firstWord[i] != line[i])
        return FALSE;
 char c = line[len];
 return c == 0 || isspace(c);
 }
 
 boolean startsWithWordByDelimiter(char *firstWord,char delimit, char *line)
 /* Return TRUE if first word in line is same as firstWord as delimited by delimit.