Jump to content

User:Jts1882/taxonomybrowser.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
//---------------------------------------------------------------------------------
//       Taxonomy browser script
//------------------------------------------------------------------------------------
var nLevels = 3;                // this determines how many levels are show in each iteration
var nListLevels = 3;
var nInteractiveLevels = 1;
var debug = false;
var nRun = 1;
var ntt = false; //true;                 // enable create new taxonomy template tool (development only)
var bullets = "nobullets";      // suppress the bullets and place expand/collapse symbols to left: nobullets|bullets
var genus = "";

/**
 * This script adds a tool and dialog using code modified from the following tutorial script
 * 
 * Tutorial script: QuickRC ("Quick Recent Changes")
 *
 * A tutorial user script which adds a "Quick changelog" link to the page skin's
 * toolbox, and when clicked it pops up a dialog with up to 25 recent edits.
 *
 * Demonstrates:
 * - Use of the API
 * - Use of jQuery
 * - Use of ResourceLoader and some of the default modules that come with it
 * - Use of localization
 *
 * (Be bold and improve it!)
 *
 * Authors:
 * Erik Moeller, 2011, public domain
 * Brion Vibber, 2012, public domain
 */

messages = {
    'en': {
        'taxonomy-title': 'Taxonomy template browser',
        'taxonomy-greeting': 'Welcome, $1!',
        'taxonomy-intro': 'The following templates are children of this taxon taxonomy template:',
        'taxonomy-link': 'Taxonomy browser',
        'taxonomy-link2': 'Taxonomy (test)',
        'taxonomy-tooltip': 'Get children for particular taxonomy template',
        'ntt-link': 'Create new template',
        'ntt-tooltip': 'Create new taxonomy template'
    }
};

mw.messages.set(messages.en);
var lang = mw.config.get('wgUserLanguage');
if (lang && lang != 'en' && lang in messages) {
    mw.messages.set(messages[lang]);
}

// Import the jQuery dialog plugin before starting the rest of this script
mw.loader.using(['jquery.ui'], function() {

    function openTaxonBrowserDialog( taxon ) {
        taxon = getDefaultTaxonName(taxon);
		var $dialog = $( '<div id="dialog" ></div>' )
			.html( showTaxonomyBrowserForm(taxon)
		//	+ '<div id="output" class="taxonomy-browser" style="align:left">Tree will appear here</div>'
		//	+ showNewTaxonomyTemplateForm(taxon)
			)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '60%',
				modal: true
			});
	}
    function openCreateTaxonomyTemplateDialog( taxon ) {
        taxon = getDefaultTaxonName(taxon);
		var $dialog = $( '<div></div>' )
			.html(  showNewTaxonomyTemplateForm(taxon) 	)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '50%',
				modal: true
			});
	}
    function renderTaxonomyDialog( output ) {
		var $dialog = $( '<div></div>' )
			.html(
				'<strong>' + mw.message('taxonomy-greeting', mw.user.getName()).escaped() + '</strong> ' 
				+ mw.message('taxonomy-intro').escaped() 
				+ output
			)
			.dialog({
				autoOpen: true,
				title: mw.message('taxonomy-title').plain(),
				width: '60%',
				modal: true
			});
	}
	//------------------------------------ the dialog functions ---------------------------
    function showTaxonomyBrowserForm(taxon) {
    	
        if (bullets == "nobullets") $('<style>ul.nobullets{list-style: none;}</style>').appendTo('head');
    	
    	var text  = "";
		text +=	'<div id="tb" class="taxonomy-browser" style="background-color:#f8f9fa;">';
		text +=		'<div style="border:1px;padding:0.2em;margin:0.5em;" >'
						+ 'Taxon name:&nbsp;<input id="taxonId" type="text" name="taxonname" style="width:200px;" value="'+taxon+'">'
						+ '&nbsp;&nbsp;<input id="gettree" type="submit" value="Get taxonomic tree">'
					    //+ '    <button id="gettree2" >Test</button>'
	                + '</div>\n';
		text +=		'<div style="width:20em;float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;" >'
	                    + '<div style="width:100%;float:left;" title="number of levels in hierarchical tree" >' 
						+	'Levels to display: <input id="levelsId" type="text" name="levels" value="1" style="width:20px;text-align:right;float:right;" ></div>'
	                    + '<div style="width:100%;float:left;" title="do not show extinct taxa"    >' 
	                    +	'Hide extinct taxa: <input id="extinctId" type="checkbox" name="extinct" value="no" style="float:right;"></div>'
	                    + '<div style="width:100%;float:left;" title="bold taxa that would be displayed in automatic taxobox" >' 
	                    +	'Bold displayed taxa: <input id="bolddisplayId" type="checkbox" name="bolddisplay"  value="no" style="float:right;"></div>'
	                    + '<div style="width:100%;float:left;" title="do not show taxa with no children" >' 
	                    +	'Hide childless taxa: <input id="childlessId" type="checkbox" name="childless"  value="no" style="float:right;" ></div>'
	                    + '<div style="width:100%;float:left;" title="link Wikipedia articles" >' 
	                    +	'Link the Wikipedia article: <input id="wikiArticleId" type="checkbox" name="childless"  value="no" style="float:right;" ></div>'
	                    + '<div style="width:100%;float:left;" title="show speciesboxes" >' 
	                    +	'Show speciesboxes: <input id="showSpeciesboxesId" type="checkbox" name="childless" value="yes" checked style="float:right;" ></div>'
	                    + '<div style="width:100%;float:left;" title="show all speciesboxes at genus" >' 
	                    +	'Show speciesboxes (all on genus): <input id="showSpeciesboxesAllId" type="checkbox" name="childless"  value="no" style="float:right;" ></div>'
	                + '</div>\n';
		text +=		'<div style="width:9em;float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;">'
						+ 'Output mode: '
	                    + '<div style="width:100%;float:left;" title="simple listing of set number of levels in taxonomic tree" >' 
						+	'<input id="mode-list"        type="radio" name="mode"       value="list"   >List</div>'
	                    + '<div style="width:100%;float:left;" title="interactive traversing of taxonomic tree" >' 
						+	'<input id="mode-interactive" type="radio" name="mode"       value="interactive"  checked >Interactive</div>'
					+ '</div>\n';
		text +=		'<div style="width:10em;float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;">'
						+ 'Show parameters:'
	                    + '<div style="width:100%;float:left;" title="show rank and show template parameters in tooltip" >' 
						+	'<input id="params-show" type="radio" name="parammode" value="show"  checked >Yes</div>'
	                    + '<div style="width:100%;float:left;" title="" >' 
						+	'<input id="params-hide" type="radio" name="parammode" value="hide"         >No</div>'
					+ '</div>\n';
		text +=		'<div style="width:8em;float:left;border:1px solid #dddddd;padding:0.2em;margin:0.5em;">' //visibility:hidden;">'
						+ 'Search:'
	                    + '<div style="width:100%;float:left;" title="strict matching of parent taxa (excludes variant templates)" >' 
						+	'<input id="search-strict"  type="radio" name="searchtype" value="strict"  checked >Strict</div>'
	                    + '<div style="width:100%;float:left;" title="loose matching of parent taxa (includes variant templates as children)" >' 
						+	'<input id="search-loose"   type="radio" name="searchtype" value="loose"          >Loose</div>'
	                    + '<div style="width:100%;float:left;" title="loose matching of parent taxa (includes variant templates as children)" >' 
						+	'<input id="search-all"   type="radio" name="searchtype" value="all"          >All</div>'
	                    + '<div style="width:100%;float:left;" title="uses same_as= to assign parent templates when parent not set (slow)" >' 
						+	'<input id="search-sameas"  type="radio" name="searchtype" value="sameas"   >Same as</div>'
					+ '</div>\n';
		text +=			'<input id="export-html" type="submit" value="Export tree html">';
		text +=     '<div style="clear:both;">   </div>'; 
		text +=	'</div>\n' ;
		//text += '<div style="clear:both;">   </div>'; 
		// add container for tree
		text += '<div id="output" class="taxonomy-browser" style="clear:both;">   </div>'; 
		text += '<div  class="taxonomy-browser" style="clear:both;"> \
		              <textarea id="html-text" rows="4"  name="html-text" style="width:100%;" ></textarea> \
		              </div>'; 
		return text;
    }
    function showNewTaxonomyTemplateForm(taxon) {
    	var text  = "";
    	text +=	'<div id="tb" class="taxonomy-browser" >'; 
		text +=		'<div style="border:1px;padding:0.2em;margin:0.5em;" >'
					+ 'Taxon name:<input id="ntt-taxon" type="text" name="taxonname" value="'+taxon+'" style="width:250px;">'
					+ '<button id="nnt-createtemplate" >Create new taxonomy template</button><br/>'
	                + '</div>\n';
		text +=		'<div style="width:325px;float:left;border:0px solid #dddddd;padding:0.2em;margin:0.5em;" >'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="parent taxon of taxon" >' 
						+	'<code>parent=</code> <input id="ntt-parent" type="text" name="parent" value="" style="width:250px;float:right;" ></div>'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="rank of taxon" >' 
						+	'<code>rank=</code> <input id="ntt-rank" type="text" name="rank" value="" style="width:250px;float:right;" ></div>'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="name of taxon with redirect to wikipedia article link if necessary" >' 
						+	'<code>link=</code> <input id="ntt-link" type="text" name="link" value="'+taxon+'" style="width:250px;float:right;" ></div>'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="get unset parents from another taxonomy template" >' 
						+	'<code>same as=</code> <input id="ntt-sameas" type="text" name="sameas" value="" style="width:250px;float:right;" ></div>'
	                + '</div>\n';
		text +=		'<div style="width:150px;float:left;border:1px solid #dddddd;padding:0.2em;margin:1em;" >'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="set Yes to indicate extinct taxon"    >' 
	                    +	'<code>extinct=</code> <input id="ntt-extinct" type="checkbox" name="extinct" value="no" style="float:right;"></div>'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="set Yes to always display in taxobox=" >' 
	                    +	'<code>display_always=</code> <input id="ntt-alwaysdisplay" type="checkbox" name="displayalways"  value="no" style="float:right;"></div>'
	                + '</div>\n';
		text +=		'<div style="width:575px;float:left;border:0px solid #dddddd;padding:0.2em;margin:0.5em;" >'
	                    + '<div style="width:100%;padding:0.2em;float:left;" title="reference for taxonomic information" >' 
						//+	'<code>refs=</code> <input id="ntt-refs" type="text" name="refs" value="" style="width:500px;text-align:right;float:right;" ></div>'
						+	'<code>refs=</code> <textarea id="ntt-refs" rows="4"  name="comment" style="width:505px;float:right;" ></textarea></div>'
	                + '</div>\n';
	                
    	text +=	'</div>\n' ;
    	return text;
    }
    function createNewTemplate (taxon) {
        //taxon = prompt("Enter taxon name for new taxonomy template:", getDefaultTaxonName(taxon));

        var link          = $('#ntt-link').val();       // use taxon 
        //alert(link);
        //if (link.includes("|")) link.replace("|","%7c"); 
        //alert(link);
        var parent        = $('#ntt-parent').val();     
        var rank          = $('#ntt-rank').val();        
        var sameas        = $('#ntt-sameas').val();          
        var refs          = $('#ntt-refs').val() ;               
        
        var extinct       = "";
        if ($("#ntt-extinct").prop("checked")) extinct = "yes";              // set to yes or leave empty
        var alwaysdisplay = "";
        if ($("#ntt-alwaysdisplay").prop("checked") ) alwaysdisplay = "yes"; // set to yes or leave empty
 

        var url = 'https://en.wikipedia.org/w/index.php?action=edit&title=Template:taxonomy/'
                   + $('#ntt-taxon').val() 
                   + '&preload=User:Jts1882/Taxonomy/preload'
                   + '&preloadparams%5b%5d=' + link            // link=$1           use taxon 
                   + '&preloadparams%5b%5d=' + parent          // parent=$2
                   + '&preloadparams%5b%5d=' + rank            // rank=$3
                   + '&preloadparams%5b%5d=' + extinct         // extinct=$4
                   + '&preloadparams%5b%5d=' + alwaysdisplay   // display_always=$5
                   + '&preloadparams%5b%5d=' + refs            // refs=$6
                   + '&preloadparams%5b%5d=' + sameas;         // same_as=$7
       
        //window.location = url; //"www.example.com/index.php?id=" + this.id;
        window.open(url, 'window name', 'window settings');
        
        
        // target="_blank">
    }
    function exportTree() {                 // Note this needs a title in the <a> tag to work properly
    	
    	//alert("HTML code of taxonomic tree copied to clipboard");
    	var text = $('#output').html();                   // get content of div containing tree
    	
    	/*<li id="Ranidae-2-1" class="taxon_identifier">
    	   <a href="/wiki/Template:Taxonomy/Ranidae" 
    	      title="parameters: rank=familia parent=Ranoidea link=True frog|Ranidae">Ranidae</a>
    	   <span class="tree-info"> [familia] [12]</span> 
    	   <span class="childbutton" id="Ranidae-2-1-load" style="font-size:120%;"> ⊞ </span> 
    	   <span class="childbutton" id="Ranidae-2-1-collapse" style="font-size:120%;display: none;"> ⊟ </span> 
    	   <span class="childbutton" id="Ranidae-2-1-expand" style="font-size:120%;display: none;"> ⊞ </span>	</li>   	*/
        
        //var title = text.match(/" title[\s]*=[\s]*[\w\s\|\.=\[\]\/"':]*>/g);           // match /" title= ... >/
    	//console.log(title);
    	
    	text = text.replace(/" title[\s]*=[\s]*[\w\s\|\.=\[\]\(\)\/"':]*"/g, "#"); // replace title with #
    	text = text.replace(/<a href="\/wiki\//g, "[[");                     // replace <a> opening with wikitext
    	text = text.replace(/#>/g,'|');                                      // replace the #> with a pipe
    	text = text.replace(/<\/a>/g, ']]');                                 /// replace <a> closing with wikitext

		text = text.replace(/<span class=\"childbutton\"[\w\d\s\|\/\.=_\[\]"':;<>\%\-]*[⊞⊟ ]*<\/span>/g, ""); //remove interactive symbols
    	
    	$('#html-text').val(text);                        // place in textarea
    	
    	$('#html-text').select();                          // Select the text field
    	document.execCommand("copy");                      // Copy the text in the textarea to the clipboard
    }
    
    function getTree(taxon) {
 
        cleanUpAfterPreviousRuns();
		var level = nListLevels;
		var depth = 1;
		
        //taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
		taxon =  $('#taxonId').val();
		
		level =$('#levelsId').val();          // can be changed in getTaxonName
        
        var mode = "LIST";
        if ($("#mode-interactive").prop("checked")) {
        	mode = "INTERACTIVE";
        }
        
        
        nInteractiveLevels=level;  // TODO remove multiple level parameters when two methods combined
        taxon=taxon.replace(/_/g, " ");
        var taxonId = encodeID(taxon, depth, 1); // + '-li';
        
        // note class="bullets" or "nobullets";
        var output = '<br/><ul class="'+ bullets +'">'
                        + '<li class="taxon_identifier" id="' + taxonId + '"><b>' + taxon + '</b>'
                        + '<span class="tree-info"></span>'
                        + '</li>'
                  + '<br/></ul>';
 		
		$('#output').html(output);

        //addChildrenInteractive(taxon, level, mode , depth, taxonId);
        
        // we don't ahve the rank, so first get the rank (needed to get speciesboxes for genus)
    	var search = 'intitle:Taxonomy\\/' + escapeSeq(taxon) + ' insource:/\| *rank *= *[a-zA-Z]+/';
        console.log(search);
        
        
	 	jQuery.getJSON(
			mw.util.wikiScript( 'api' ),
			{ 'format': 'json', 'action': 'query', 	'list': 'search', 'srnamespace' :10, 'srlimit' : 5000, 'srsearch' : search  },
			function( data ) {
                if (data.query == undefined) return;            	// intermittant and seemingly random - not clear why
                var nResults = data.query.searchinfo.totalhits;
                console.log(data.query); 
                
                if (nResults === 0) {
                	console.log ('no results for rank of taxon ' + taxon );
                	addChildrenInteractive(taxon, level, mode , depth, taxonId); // pass without a rank
                }
                else { // so we have some results
                	$.each ( data.query.search , function( index , sr ) {
                		if (sr.title == "Template:Taxonomy/" + taxon ) {
                			console.log(sr.snippet);
                			var match = sr.snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
							if (match && match[1] ) {
								var rank = match[1];
                				console.log ("rank="+rank); 
                				addChildrenInteractive(taxon, level, mode , depth, taxonId, rank);
              				
							}
                		}
                	});
                }
			}
		);

        nRun += 1;
    }

    
    // ----------------------------- utlity functions -------------------------------
    function escapeSeq(taxon) {
    	// Special Regex Characters: ., +*?^$()[]{}|   
    	// Only these four characters require escape sequence inside the bracket list: ^-]\
    	taxon = taxon.replace(" ("," \\("); 
    	taxon = taxon.replace(")","\\)");
    	taxon = taxon.replace("?","\\?");
    	//taxon = taxon.replace("/","\\/");
    	taxon = taxon.replace(/\//g,"\\/");
    	taxon = taxon.replace(".","\\.");
    	
    	return taxon;
    }
    function encodeID(taxon, depth, count) {
    	//taxon = taxon.replace("/","_X_");
    	//taxon = taxon.replace("(","_Y_");
    	//taxon = taxon.replace(")","_Z_");
    	//taxon = taxon.replace(" ","_S_");
    	//taxon = taxon.replace("?","_Q_");
    	taxon = taxon.replace(/\//g, "_X_");
    	taxon = taxon.replace(/\(/g, "_Y_");
    	taxon = taxon.replace(/\)/g, "_Z_");
    	taxon = taxon.replace(/ /g,  "_S_");
    	taxon = taxon.replace(/\?/g, "_Q_");
    	taxon = taxon.replace(/\./g, "_D_");
    	taxon = taxon.replace(/\"/g, "_E_");
    	return taxon+'-'+depth.toString()+'-'+count.toString();
	    //return encodeURIComponent(taxon);
    }
    function decodeID(taxon) {
    	//taxon = taxon.replace("_X_","/");
     	//taxon = taxon.replace("_Y_","(");
   	    //taxon = taxon.replace("_Z_",")");
   	    //taxon = taxon.replace("_S_"," ");
   	    //taxon = taxon.replace("_Q_","?");
    	taxon = taxon.replace(/_X_/g, "/");
     	taxon = taxon.replace(/_Y_/g, "(");
   	    taxon = taxon.replace(/_Z_/g, ")");
   	    taxon = taxon.replace(/_S_/g, " ");
   	    taxon = taxon.replace(/_Q_/g, "?");
   	    taxon = taxon.replace(/_D_/g, ".");
   	    return taxon;
	    //return encodeURIComponent(taxon);
    }    
    function getTaxonName(taxon) {
    	
    	taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
    	var split = taxon.split(" ");
        if (split[1]) {
          var number = parseInt(split[1]);
          //if (number != NaN) nLevels = number;
          if (!isNaN(number)) {
          	 nLevels = number;
          	 nInteractiveLevels= number;  // TODO make decision on level parameters
          	 nListLevels= number;
          }
          taxon = split[0];
        }
        return taxon;
    }
    function getDefaultTaxonName(taxon) {         // get default from page name
    	
    	var page = mw.config.get( 'wgPageName' ) ;

    	if (page.includes("Template:Taxonomy/") ) {
    	   var res = page.split("Template:Taxonomy/");	
    	   taxon = res[1];
    	}
    	else  {
    	    var title = new mw.Title ( page );
    	    var ns = title.getNamespaceId();
    	    if ( ns === 0 && !page.includes(" ") ) 	taxon = page;
    	}
    	return taxon;
    }
    function  getParameterString(index , sr) {
		
		var paramString = "parameters: "; //" [extra info] ";

		var snippet =sr.snippet; // this contains the template code
		
		if (snippet.includes("rank")) {
			//var rank = templateData.match(/rank[\s]*=[\s]*[a-zA-Z]*/); //gets "rank%s=%sclassis"
			var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
			//if (rank && rank[0] ) 	extraInfo  = ' ['+rank[0]+']';
			if (rank && rank[0] ) 	paramString  += rank[0];
		}
		if (snippet.includes("parent")) {
			var parent = snippet.match(/parent[\s]*=[\s]*([a-zA-Z\-\(\)\._ \/\?]*)/);  
			if (parent && parent[0] ) 	paramString  += ' ' + parent[0];
		}
		if (snippet.includes("link")) {
			var link = snippet.match(/link[\s]*=[\s]*([a-zA-Z\-\|#\.\(\)"'&; ]*)/);
			//if (snippet.includes("Ichthyostegalia")) alert(link[0] + '_' + link[1] + '_');
			if (link && link[0] ) 	paramString  += ' ' + link[0];
		}
		if (snippet.includes("extinct")) {
			var extinct = snippet.match(/extinct[\s]*=[\s]*([a-zA-Z ]*)/);
			if (extinct && extinct[0] ) 	paramString  += ' ' + extinct[0];
		}
		if (snippet.includes("always_display")) {
			var always = snippet.match(/always_display[\s]*=[\s]*([a-zA-Z ]*)/);
			if (always && always[0] ) 	paramString  += ' ' + always[0];
		}
		if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	paramString  += ' ' + sameas[0];
		}
		if (snippet.includes("refs")) {
			var refs = snippet.match(/refs[\s]*=[\s]*([a-zA-Z0-9{}| ]*)/);
			var refText = 'refs=[empty]';
			if (refs && refs[1] ) refText =	'refs=[...]';
			paramString  += ' ' + refText;
		}
		//paramString = paramString.replace(/\"/g, '\\\"'); // " already replaced by &quot; in snippet
		return 'title="' + paramString + '" '; 
		//return 'title="' + encodeURI(paramString) + '" ';  // what if " in title string
		
    }   
    function  getSameAs(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	
				return ' [same_as=<a href="/wiki/Template:Taxonomy/' + sameas[1] + '" title="">' + sameas[1] + '</a>]';
		}
		return false;
    }
    function  getExtinct(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("extinct")) {
			var extinct = snippet.match(/extinct[\s]*=[\s]*([a-zA-Z ]*)/);
			if (extinct && extinct[1] ) {
				var value = extinct[1].toLowerCase();
				if (value=="yes" || value=="true") return true;
			}
		}
		return false;
    }
    function  getAlwaysDisplay(index , sr) {
        
        if (!$("#bolddisplayId").prop("checked")) return false;
        
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("always_display")) {
			var alwaysDisplay = snippet.match(/always_display[\s]*=[\s]*([a-zA-Z ]*)/);
			if (alwaysDisplay && alwaysDisplay[1] ) {
				var value = alwaysDisplay[1].toLowerCase();
				if (value=="yes" || value=="true") return true;
			}
		}
		if (snippet.includes("rank")) {
			var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
			if (rank && rank[1] ) {
				var value = rank[1].toLowerCase();
				if (value == 'ordo' || value == 'order' || value == 'classis' || value == 'class'
				    || value == 'kingdom' || value == 'phylum' || value == 'divisio' || value == 'division'
				    || value == 'familia' || value == 'family' || value == 'classis' || value == 'class'
				    ) return true;
			}
		}
		return false;
    }
    function getParent(index , sr) {
		var snippet = sr.snippet; // this contains the template code
		if (snippet.includes("parent")) {
            //if (snippet.includes("Vaccinium")) alert(snippet);
            
			// snippet contains "<span class=\"searchmatch\">parent=Reptiliomorpha</span>" (not with regex search)
            //snippet = snippet.replace("</span>",""); 
			
			//var parent = snippet.match(/parent[\s]*=[\s]*([a-zA-Z\._ \/\?]*)/);  
		    var parent = snippet.match(/parent[\s]*=[\s]*([a-zA-Z\-\(\)\._ \/\?]*)/);  
			if (parent && parent[1] ) {
				return parent[1].trim();
			}
		}
		return false;
    }
    function getLink(index , sr) {
        var snippet = sr.snippet; // this contains the template code
		if (snippet.includes("link")) {
			var link = snippet.match(/link[\s]*=[\s]*([a-zA-Z\-\|#\.\(\)"'&; ]*)/);
			//if (link && link[0] ) 	return link[0];
			if (link && link[1] ) {
				var redirect = link[1].match(/([a-zA-Z\-#\.\(\)"'&; ]*)|(.*)/);
				if (redirect && redirect[1]) return redirect[1];
				return link[1];
				//return link[1];
			}
		} 
    }
    function  getSnippet(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		snippet = snippet.replace('<span class=\"searchmatch\">', "");
		snippet = snippet.replace("</span>",""); 
		return snippet;
    }
    function  getRank(index , sr) {
		var snippet =sr.snippet; // this contains the template code
		if (snippet.includes("rank")) {
		  var rank = snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/); 
		  if (rank && rank[1] ) 	return rank[1];
		}
	/*	if (snippet.includes("same_as") || snippet.includes("same as") ) {
			var sameas = snippet.match(/same[ _]as[\s]*=[\s]*([a-zA-Z]*)/);
			if (sameas && sameas[0] ) 	return sameas[0];
		}*/
		return false; //"unknown rank";
    }
    function formatByRank(name, rank) {
    	// check for genus and species; inlcude should pick up subgenus, species group, etc
        if ( rank && (rank.includes("genus") || rank.includes("species")) ) {
        	name = '<i>' + name + '</i>';
        }
        return name;
    }
    function cleanUpAfterPreviousRuns() {
        if (nRun > 1) {
        	//if (debug) alert ("run number = "+ nRun);
        	$('.taxon_identifier').remove(); 
        }
	}
	
	function InfraGenericRank(rank) {
		switch(rank) {
			case "genus":
			case "subgenus":
		    case "sectio":
		    case "series":
			                return true;
			default:
			    		   	return false;
		}
    } 
	function getTaxonRank(taxon, callback) {

		var search = 'hastemplate:Taxonomy/' + taxon + ' insource:/\| *rank *=[a-zA-Z]+/';

	 	jQuery.getJSON(
			mw.util.wikiScript( 'api' ),
			{ 
				'format': 'json',
				'action': 'query',
				'list': 'search',
				'srnamespace' :10,                        // search in template namespace
				'srlimit' : 500,
				'srsearch' : search  

			},
			function( data ) {

                if (data.query == undefined) {
                	// intermittant and seemingly random - not clear why
                	alert ("undefined data.query: id=" + taxonId);
                	return;
                }
                var nResults = data.query.searchinfo.totalhits;
                console.log(data.query); 
                
                if (nResults === 0) {
                	console.log ('no results for rank of taxon ' + taxon );
                }
                else { // so we have some results
                	$.each ( data.query.search , function( index , sr ) {
                		if (sr.title == "Template:Taxonomy/" + taxon ) {
                			//console.log(sr.snippet);
                			var match = sr.snippet.match(/rank[\s]*=[\s]*([a-zA-Z ]*)/);
							if (match && match[1] ) {
								var rank = match[1];
                				console.log ("rank="+rank); 
                				callback;
                				return(rank);
							}
                		}
                	});
                }
			}
		);
	}
    ///-------------------------------  interactive function (when is this used?)--------------------------------
    function getTreeInteractive(taxon) {

       cleanUpAfterPreviousRuns();

        //taxon = prompt("Enter the parent taxon:", getDefaultTaxonName(taxon));
        taxon = getTaxonName(taxon);
        
 		var output= '<br/><ul><li class="taxon_identifier" id="' + encodeID(taxon) + '-li"><b>' + taxon + '</b></li><br/></ul>';
 		//var output= '<br/><ul><li class="taxon_identifier" id="' + taxon + '-li"><b>' + taxon + '</b></li><br/></ul>';
		
		var level = nInteractiveLevels; // nLevels is globally set at top
		addChildrenInteractive(taxon, level , "INTERACTIVE");  
		renderTaxonomyDialog( output );
        nRun += 1;
    }
    
    function addChildrenInteractive(taxon, level, mode, depth, taxonId, rank, parent) {
       if (level == 0) return;
   
   	    level -= 1;
   	    depth +=1;
	    
	    // perform search using API with one of jQuery's AJAX functions
	    //var search = 'insource:/parent[ ]*=[ ]*' + escapeSeq(taxon) + '[\\s]*/ prefix:Template:Taxonomy/';

        // strict search using RegEx /search terms/
	    var search = 'insource:/parent[ ]*=[ ]*';                          // search for parent
	    if ($("#search-sameas").prop("checked")) {                         // else search for parent or same as
			// insource: /[ps]a[rm]e[n ][ta][s]*[ ]*=[ ]*Archaeplastida/  prefix:Template:Taxonomy/
			search = 'insource: /[ps]a[rm]e[n _][ta][s]*[ ]*=[ ]*';        
	    }
	    search += escapeSeq(taxon) 
	           + '[a-zA-Z0-9 \\.\\/\\?\\\s]*/'             // regex expression for search - we want the name and variants
	           + ' prefix:Template:Taxonomy/';             // restrict search to taxonomy templates
			
		// looser search with "search terms" 
		//            -- this gives 9 children for Reptilomorpha and Reptilomorpha/? instead of 9 and 2
		//            -- but the issue is handling the variant templates (see parent match code below)
		//	    if ($("#search-loose").prop("checked")) {
		//	    	search = 'insource:"parent[ ]+=[ ]+' + escapeSeq(taxon) + '" prefix:Template:Taxonomy/';
		//	    	alert("loose search");
		//	    }
		// not what is wanted: the search wants to retrieve the full name, then decide how to handle it
	    
	    var showParameters = true;
	    if ($("#params-hide").prop("checked")) showParameters = false;
	    var hideExtinct = false;
	    if ($("#extinctId").prop("checked")) hideExtinct = true;
	    var hideChildless = false;
	    if ($("#childlessId").prop("checked")) hideChildless = true;
	    var linkWikiArticle = false;
	    if ($("#wikiArticleId").prop("checked")) linkWikiArticle = true;
	    var showSpeciesboxes = false;
	    var showSpeciesboxesAll = false;
	    if ($("#showSpeciesboxesId").prop("checked")) showSpeciesboxes = true;
	    if ($("#showSpeciesboxesAllId").prop("checked")) showSpeciesboxesAll = true;

	    //TODO Ass [a-zA-Z\/\?\s]*
	    //alert(search);
	    //search ="insource:/parent[ ]*=[ ]*Reptiliomorpha\\/\\?[\\s]*/  prefix:Template:Taxonomy/";
	    
 		jQuery.getJSON(
			mw.util.wikiScript( 'api' ),
			{
				'format': 'json',
				'action': 'query',
				'list': 'search',
				'srnamespace' :10,                        // search in template namespace
				'srlimit' : 500,
			//	'srqiprofile' : 'classic',     
				'srsearch' : search  // uses /regex/

			},
			function( data ) {
                var output = ""; 
                
                if (data.query == undefined) {
                	// intermittant and seemly random - not clear why
                	alert ("undefined data.query: id=" + taxonId);
                	// try again?
                	addChildrenInteractive(taxon, level+1, mode, depth-1 , taxonId, rank, parent);
                	return;
                }
                var nResults = data.query.searchinfo.totalhits;
                //alert ("nResults="+nResults);
                var count = 0;
                
                if (nResults === 0) {
                	// if (debug) alert ('no results for taxon (rank) = ' + taxon + ' (' + rank + ')');
                	// speciesboxes search now launched after the end of the if else results loop

                	output = ' [no child templates]'; // "zero hits: " + taxon;
                	if (hideChildless) {
                		$('#'+taxonId).hide(); // hide taxon
                	}         	
                	else {
                		if (showParameters) $('#'+taxonId+' span.tree-info').append(output); 
                		if (rank != "genus" && rank != "subgenus" && rank != "sectio" && rank != "series") {
                			$('#'+taxonId+'-collapse').html('<span style="color:grey;"> &#8865; </span>').off("click"); // change symbols and disable
                		}
                	}
                }
                else { // so we have some results
                    if (debug && showParameters) $('#'+taxonId+' span.tree-info').append(" [" + nResults + "]"); // number of results; includes variants
                    
                    $('#'+taxonId).append('<ul class="' + bullets + '"></ul>');   // add ul element to contain children
					var listCount = 0;
					
					data.query.search.sort(function(a, b){return a.title>b.title}); // sort on title

					$.each ( data.query.search , function( index , sr ) {
	           
	                    var child = sr.title.replace("Template:Taxonomy/", "");		             
                        var rank = getRank(index , sr);
                        var extinct = getExtinct(index , sr);
                        var link = getLink(index , sr);
                        var parent = getParent(index , sr);
                        var variant = "";
                        var alwaysDisplay = getAlwaysDisplay(index , sr);
                        var sameAs = getSameAs(index , sr);
                        var titleString = ' title=""'; // alt text to display on mouse over [default empty to help export code]
                        if (showParameters) {  
                            //titleString = 'title="rank='+rank+'; parent='+parent+'; always_display='+alwaysDisplay+'" '; 
                            titleString = getParameterString(index , sr); 
                        }
                        if (hideExtinct && extinct) return true; // don't show extinct taxa   
                        
                        if (rank == 'genus' ) genus = child; // a global required for speciesbox searching
                        
                        // select taxa to display
                        //     the search results for Template:Taxonomy/TAXON will also contain variant templates;
                        //     we normally (strict search) don't want to include those under base template name
                        if (1==1 && (!parent || parent!=taxon )) {
                        	if (debug && parent && parent.includes("Vaccinium")) {
                        		alert("parent not matching for child "+child+"\nparent="+parent+"\ntaxon="+taxon); 
                            }
                        	
                        	var accept = false; // we have a parent mismatch
                        	if ($("#search-loose").prop("checked")) {  // if loose match allowed
                        	
                        	    //if (debug) alert("in loose: taxon="+taxon+";parent="+parent);
                        		if (parent && parent.includes(taxon+"/")) {       
                        			accept = true;                     //accept variants - "taxon/variant"
                        			variant = ' [parent='+parent+']';
                        		}
                        	}
                        	if ($("#search-all").prop("checked")) {  // if all matches wanted
                        	    accept = true; 
                        	    variant = ' [parent='+parent+']';
                        	}

                        	if ( sameAs && $("#search-sameas").prop("checked")) { // accept if sameas (any or =taxon)
		                        	accept = true;
		                        	//if (debug) alert('child='+child+': no parent, same_as='+sameAs);
		                    }
                        	if (accept == false)  return true; // skip to next in each loop (equivalent of continue;
                        } // check parents loop
                        
//                        if ($("#search-loose").prop("checked")) {       // if loose match (testing)
//                           // can we exlude reptilomorpha/? if sister reptilomorpha
//                           // skip variant if element at base name exists (unreliable as requires base name before variants)
//                        	if (child.includes("/")) { 
//                        		var value = child.split("/");
//                        		if (value[1] && $('#'+encodeID(value[0],depth)+'-li').length ) {
//                        		//alert('child='+child+'; value1='+value[0]); 
//                        		return true; 
//                        		}
//                            }
//                        }
                        
                        // display the selected child taxa (either matched parents or allowed loose match)
                        count += 1; 
                        var name = formatByRank(child, rank);  // italicise if genus or species rank
                        if (alwaysDisplay) name = '<b>' + name + '</b>';
                        
                        var childId = encodeID(child, depth, count); // + '-li';
	                    output = '<li id="' + childId + '" class="taxon_identifier" >';
	                    if (extinct) output += '†';
	                    output += '<a href="/wiki/' + sr.title + '" ' + titleString + ' target="_blank" >' + name + '</a>';
	                    
	                    output += '<span class="tree-info">'; // span for add information
	                    if (showParameters) {
	                    	if (rank)   output += ' ['+rank+']';
	                    	if (sameAs) output += sameAs;
	                    	if (variant) output += variant;
	                    }

	                    if (linkWikiArticle) {
	                    	if (link == child) {
								output += ' (article: <a href="/wiki/' + child + '" ' + ' target="_blank" >' + name + '</a>)'; // name is formated
							}
							else
							{
								output += ' (links to: <a href="/wiki/' + link + '" ' + ' target="_blank" >' + formatByRank(link, rank); + '</a>';
								output += ' ; redirects from <a href="/wiki/' + child + '" ' + ' target="_blank" >' + name + '</a>'; //keep for debugging
								output += ')';
							}
						}


	                    if (debug) {
	                    	//output += extraText(index , sr); 
	                        //output += " [child="+child+"; parent="+parent+"; taxon="+taxon+ "]";
	                    }
	                    output += '</span>'; // close info span
                        
                        var output2 = "";                               // add the spans with interactive elements
	                    if (level === 0 && mode=="INTERACTIVE") {
	                     	output2 += ' <span class="childbutton" id="' + childId + '-load" style="font-size:120%;"> &#8862; </span>'; // +/- in square &#8862;/&#8863; +/-/x in circle &#8853;/&#8854;/&#8855;
	                     	output2 += ' <span class="childbutton" id="' + childId + '-collapse" style="font-size:120%;display: none;"> &#8863; </span>'; // +/- in square &#8862;/&#8863; +/-/x in circle &#8853;/&#8854;/&#8855;
	                     	output2 += ' <span class="childbutton" id="' + childId + '-expand" style="font-size:120%;display: none;"> &#8862; </span>'; // +/- in square &#8862;/&#8863; +/-/x in circle &#8853;/&#8854;/&#8855;
	                    }
	                    //output += output2; // if interactive elements on right
	                    output += '</li>' ;
	                    
	                    $('#'+taxonId+' > ul').append(output);   // append child li element
	                    listCount += 1;
                        if (bullets == "nobullets") {
	                        $('#'+childId).prepend(output2);         // insert interactive element before (no bullets)
                        } else {
                        	$('#'+childId).append(output2);        // insert interactive element after (with default bullets)
                        }
                        
                        // code for interactive loading, collapsing and expanding tree  
           		        if (level === 0 && mode=="INTERACTIVE") {                     
           		        	//console.log("adding interactive stuff");
           		        	// load children, hide load icon, show collapse icon
           		        	$('#'+childId+'-load').click(function (e) {
								e.preventDefault();
	                            addChildrenInteractive(child, nInteractiveLevels, mode, depth , childId, rank, taxon);  // trigger new run
							    $(this).hide();
							    $('#'+childId+'-collapse').show();
							});	
							// hide children of node; show expand icon
							$('#'+childId+'-collapse').click(function (e) {
								$('#'+childId+' > ul').hide();
								$(this).hide();
								$('#'+childId+'-expand').show();
							});	
							// show children of node, show collapse icon
							$('#'+childId+'-expand').click(function (e) {
								$('#'+childId+' > ul').show();
								$(this).hide();
								$('#'+childId+'-collapse').show();
							});	
           		        }

	                    if (level > 0){                          // if expanding multiple levelss
	                    	console.log("level > 0 for taxon "+taxon);
		                    addChildrenInteractive(child, level, mode, depth , childId, rank, taxon);
						}
					}); // end @each loop
                    
                    if (listCount == 0 ) { // we are here when there are no strict results
                    	                   // e.g.  with Panthera, which has results with "parent=Pantherapsida"
                        console.log("no results with strict matching of " + taxon + ' (' + rank + ')');
                    }
  
					if (showParameters) {
						$('#'+taxonId+' > span.tree-info').append(" [" + count + " child templates]"); // number of results; excludes variants
					}
			    } // end if results 
			    
       		    if (showSpeciesboxesAll ) {  // check speciesboxes at genus level (including infrageneric ranks)
            		if (rank == 'genus' || rank == 'subgenus'  ) { //alway check speciesboxes at genus level
                		//if (debug) alert ('Checking for all speciesboxes associated with this genus');
                		if ($('#'+taxonId + ' ul.speciesboxes').length  ) {
                			//if (debug) alert ('Speciesbox block already exists');
                		} else {
                			//if (debug) alert ("Speciesbox block doesn't exist; will add one");
                			addSpeciesboxes(taxon, level, mode, depth, taxonId, rank, parent); // look for species boxes
                		}
            		}
                 }
			    else if (showSpeciesboxes) { // check speciesboxes even when there are child templates
        			if (rank == 'genus' || rank == 'subgenus' || rank == 'sectio' || rank == 'series' ) {
        				//if (debug) alert ('rank = ' + rank + '; taxon = ' + taxon + '; parent = ' + parent );
           				addSpeciesboxes(taxon, level, mode, depth, taxonId, rank, parent);
       		        }
       		    }

                 
			} // end processing function (data)
		);        
    } // end function addChildrenInteractive()
 
 //------------------------------------function to check species boxes under generic taxa---------------------------------------------
 
   	function addSpeciesboxes(taxon, level, mode, depth, taxonId, rank, parentTaxon) {

        //if (debug) alert ('Call to addSpeciesboxs for taxon (rank) = ' + taxon + ' (' + rank + '); parent = ' + parent );

        var showParameters = true;
	    if ($("#params-hide").prop("checked")) showParameters = false;
	    //var hideExtinct = false;
	    //if ($("#extinctId").prop("checked")) hideExtinct = true;
	    var hideChildless = false;
	    if ($("#childlessId").prop("checked")) hideChildless = true;
	    //var showSpeciesboxes = false;
	    //if ($("#showSpeciesboxesId").prop("checked")) showSpeciesboxes = true;
	    var showSpeciesboxesAll = false;
	    if ($("#showSpeciesboxesAllId").prop("checked")) showSpeciesboxesAll = true;	    
	    
	    // hastemplate:speciesbox insource:Panthera insource:/\| *[gt][ea][nx][uo][sn] *= *Panthera/
	    var search = 'hastemplate:speciesbox'                    // pages with speciesbox template
	                 + ' insource:' + escapeSeq(taxon)           // reduce to pages with taxon before regex inquiry
//	                 + ' insource:' + '/\| *genus *= *Neofelis/'; //search += escapeSeq(taxon) 
//	                 + ' insource:' + '/\| *[gt][ea][nx][uo][sn] *= *' + escapeSeq(taxon) + '/' 
	                 + ' insource:' + '/\| *[gt][ea][nx][uo][sn] *= *' + escapeSeq(taxon) + '[^a-z]/'; // match word, e.g. exclude Mustela from Mus
	                 //+ '[a-zA-Z0-9 \\.\\/\\?\\\s]*/'             // regex expression for search - we want the name and variants
        if (  rank == "genus" && !showSpeciesboxesAll ) {
             //search +=  ' -insource:' + '/\| *parent *= *' + escapeSeq(taxon) +'/';
             search +=  ' -insource:' + '/\| *parent *= *[a-zA-Z]+/';
             console.log(search);
        }
        if ( rank == "subgenus" || rank == "sectio" || rank == 'series' ) {
        	search = 'hastemplate:speciesbox'                    // pages with speciesbox template
	                 + ' insource:' + escapeSeq(taxon)           // reduce to pages with taxon before regex inquiry
	                 + ' insource:' + '/\| *parent *= *' + escapeSeq(taxon) + '[^a-z]/'; // match word, e.g. exclude Mustela from Mus
   		}
        console.log(search);
        



 		jQuery.getJSON(
			mw.util.wikiScript( 'api' ),
			{
				'format': 'json',
				'action': 'query',
				'list': 'search',
				'srnamespace' :0,                        // search in main namespace
				'srlimit' : 500,
			//	'srqiprofile' : 'classic',     
				'srsearch' : search  // uses /regex/

			},
			function( data ) {
                var output = ""; 
                
                if (data.query == undefined) {
                	// intermittant and seemingly random - not clear why
                	alert ("undefined data.query: id=" + taxonId);
                	return;
                }
                var nResults = data.query.searchinfo.totalhits;
                //alert ("nResults="+nResults);
                var count = 0;
                console.log(data.query); //.searchinfo);
                
                if (nResults === 0) {
                	console.log ('no speciesbox results for taxon (rank) = ' + taxon + ' (' + rank + ')');
                	if (rank == 'genus' || rank == 'subgenus' || rank == 'sectio') {
                	   console.log ('No speciesboxes associated with genus ' + taxon)
                	}
                	
                	output = ' [no speciesboxes]'; // "zero hits: " + taxon;
                	if (hideChildless) {
                		$('#'+taxonId).hide(); // hide taxon
                	}         	
                	else {
                		if (showParameters) $('#'+taxonId+' > span.tree-info').append(output); 
//                		$('#'+taxonId+'-collapse').hide(); // hide collapse button  TODO not with genus
                    	$('#'+taxonId+'-collapse').html('<span style="color:grey;"> &#8865; </span>').off("click"); // change symbols and disable

                	}
                }
                else { // so we have some results
                    if (showParameters) $('#'+taxonId+' > span.tree-info').append(" [" + nResults + " speciesboxes]"); // number of results; includes variants
                    
                    if ( showSpeciesboxesAll && rank == "genus"  ) {
                    	//$('#'+taxonId).parent().prepend('<li>speciesboxes for whole genus<ul id="' + rank + '" class="' + bullets + ' speciesboxes"></ul></li>');
                     	$('#'+taxonId).append('<ul class="' + bullets + '"><li>speciesboxes for whole genus<ul id="' + rank + '" class="' + bullets + ' speciesboxes"></ul></li></ul>');
                    } else {
                    	//$('#'+taxonId).append('<ul class="' + bullets + ' speciesboxes">ul block for speciesboxes</ul>');   // add ul element to contain children
                    	$('#'+taxonId).append('<ul class="' + bullets + ' speciesboxes"></ul>');   // add ul element to contain children
                    }
					
					data.query.search.sort(function(a, b){return a.title>b.title});
					
					$.each ( data.query.search , function( index , sr ) {
	           
                        //var rank = getRank(index , sr);
                        //var extinct = getExtinct(index , sr);
                        //if (hideExtinct && extinct) return true; // don't show extinct taxa   (info not available for speciesboxes)
                 
                        // display the selected child taxa 
                        count += 1; 

                    	var child = sr.title.replace(" ", "_");		             
                        var genus = ""; 
                        var species = ""; 
                        var parent = ""; 
                        var binomial = ""; 
                        var comment = "";
                        if ( sr.snippet.search(/taxon *=/) > 0 ) {
                        	var snippet = sr.snippet.replace ('<span class="searchmatch">', ''); // remove highlighting from search snippet
                        	snippet = snippet.replace ('</span>', '');
                        	//var snippetTaxon = snippet.replace(/[\s\S]+taxon *= *(\w+) (\w+)[\s\S]+/, "$1 $2");
                        	var snippetTaxon = snippet.replace(/[\s\S]+taxon *= *(\w+) ([ ×\w]+)[\s\S]+/, "$1 $2");
                            //	snippetTaxon = snippet.replace(/[\s\S]+taxon *= *(\w+ \w+)[\s\S]+/, "$1");
                        	if (snippetTaxon == snippet) {
                        		if (debug) comment = " [taxon not available in search snippet]"; // 
                            } else {
                            	binomial = snippetTaxon;   // should snippetTaxon be checke?
                            }
                        	console.log("taxon=" + snippetTaxon + comment);
                        }
                        else if (sr.snippet.search(/genus *=/) > 0 && sr.snippet.search(/species *=/) > 0 ) { // if speciesbox with genus= and species=
                        	genus =   sr.snippet.replace(/[\s\S]+genus *= *(\w+)[\s\S]+/, "$1");
                        	species = sr.snippet.replace(/[\s\S]+species *= *([\w ×]+)[\s\S]*/, "$1");
                        	binomial = genus + " " + species;
                        	if (species == sr.snippet) {      // if species epithet not available in search snippet
                        		species = "</i>sp.";
                        		comment = " [species epithet not available in search snippet]"; // when species not available in snippet
                        	} 
                        	console.log("taxon(genus+species)=" + genus + " " + species + " " + comment);
						} else {
							comment = " [snippet doesn't contain taxon or genus and species]";
							binomial = "not available";
						}
                    	parent =   sr.snippet.replace(/[\s\S]+parent *= *(\w+[\w \.]*\w+)[\s\S]+/, "$1");
                    	//parent =   sr.snippet.replace(/[\s\S]+parent *= *(\w+)[\s\S]+/, "$1");
                    	if (parent == sr.snippet) {      // if parent not captured
                    	    if (debug) comment += " [no parent or not in snippet]";
                    	} else {
                        	if (debug) comment += " [parent = " + parent + "]";
                    	}

                        var name = sr.title;
                    	if ( binomial == sr.title ) {
                    		binomial = "";                            // don't show if binomial if same as page title 
                    		name = "<i>" + name + "</i>" ;            // italicise page title if binomial
	                   	} else {
                    		binomial = " (<i>" + binomial + "</i>)" ;                // display binomial after page title if different
                    		if ( genus == sr.title ) name = "<i>" + name + "</i>" ;  // italicise page title is monotypic genus
                    	}

                        var titleString = ' title=""';
                        if (showParameters) {
                        	//titleString = ' title="' + encodeURIComponent(sr.snippet) +'"';
                        }

 
                        var childId = sr.title.replace(" ", "_") + "_SPECIES"; // + '-li';
	                    output = '<li id="' + childId + '" class="taxon_identifier" >';
	                    //if (extinct) output += '†';                                             // cannot know extinct status for speciesbox
	                    output += '<a href="/wiki/' + sr.title + '" ' + titleString + ' target="_blank" >' + name + '</a>'; 

	                    output += '<span class="tree-info" style="color:grey;" >'; // span for add information
	                    output += binomial;
	                    if (debug) {
	                    	//output += extraText(index , sr); 
	                    	output += comment;
	                    }
	                    output += '</span>'; // close info span
	                    output += '</li>' ;
	                    
						if (rank == "subgenus" || rank == "sectio" || rank == 'series' ) {
	                        $('#'+taxonId+' > ul.speciesboxes').append(output);   // append child li element
	                    } else {
	                        $('#'+taxonId+'  ul.speciesboxes').append(output);   // append child li element
	                    }
					});
					if (showParameters) {
						//$('#'+rank).parent().prepend(" [" + count + " ???]"); // number of results; excludes variants
					}
			    }
			} // end processing function (data)
		);	
   		
   	} // end function addChildrenInteractive()


    // ----------------- document ready - add functions to tool menu ------------------
	$(document).ready( function() {
		
       // alert("hello")   // my test that the page is loading
		
		//  mw.util.addPortletLink( portletId, href, text, id, tooltip, accesskey, nextnode );
		// Add a link to the toolbox
		var link = mw.util.addPortletLink(
			'p-tb',
			'#',
			mw.message('taxonomy-link').plain(),
			't-prettylinkwidget',
			mw.message('taxonomy-tooltip').plain(),
			'/'
			//'#t-whatlinkshere'    // this places it at the top of the tools
		);
		if (debug) {
			var link2 = mw.util.addPortletLink('p-tb', '#', mw.message('taxonomy-link2').plain(), 't-prettylinkwidget', mw.message('taxonomy-tooltip').plain());
		}
		if (ntt) {
			var link3 = mw.util.addPortletLink('p-tb', '#', mw.message('ntt-link').plain(), 't-prettylinkwidget', mw.message('ntt-tooltip').plain()	);
		}
		// Create a jQuery object for this link so that we get to use jQuery awesomeness 
		//        like .click() for binding functions to events and methods like e.preventDefault();
		$(link).click( function( e ) {
			e.preventDefault(); // Avoid the browser going to '#'
			//getChildren("Felidae");  // get children for prompted taxon
			//getTreeList("Plantae");  // get more than one level of tree 
			if (nRun >1 ) {
				$('.taxonomy-browser').remove(); // remove previous instances of form and output divs (prevents multiple IDs)
			}
			openTaxonBrowserDialog( "Fagaceae" );
			$('#gettree').click( function( e ) {
				e.preventDefault();
				getTree("Plantae");
			});
			$('#export-html').click( function( e ) {
				e.preventDefault();
				exportTree();
			});				
		});
		if (debug) {
			$(link2).click( function( e ) {
			e.preventDefault();// Avoid the browser going to '#'
			//getTreeInteractive("Carnivora");  // get more than one level of tree
			getTreeInteractive("Tetrapoda");  // get more than one level of tree
			});
		}
		if (ntt) {
			$(link3).click( function( e ) {
				e.preventDefault();// Avoid the browser going to '#'
				openCreateTaxonomyTemplateDialog( "Miodocus" );
				$('#nnt-createtemplate').click( function( e ) {
					e.preventDefault();
					createNewTemplate("Miodocus");
				});
			});
		}
	});

});