//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// debug alerts through # 10
// scripts.js - jmol command scripts
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "Spt" in the variables below is an abbreviation for "jmol command ScriPT".
//
// Some definitions below are marked "patch". These are temporary corrections
// for problems in Jmol's pre-defined sets/select commands, that are
// documented in select.htm.
//
// One of the problems is "zombie" amino acids. These are standard amino
// acids that are "not (protein,nucleic,hetero)". See examples in select.htm.
//
// Another problem is unbonded atoms. See bugsjmol.htm.

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// A bug in jmol 10.00.34 required that the hover id display
// be used once before the hover command would work.
// This was fixed in 10.00.37.

// Commands that survive load: background, set picking center.
// Commands reset by load: all echo settings, hover format.
// 1atom.pdb is required to display the "loading molecule" echo.
// set echo position must precede font, color.

// Removed for FG 0.97:
// set picking center;\

// was "set picking on" thru Jmol 10.3
var setPickingIdentSpt = "set picking ident;\n";

// INITIAL BACKGROUND CONTROL, ETC.
var view1SptPrefix = "\
load 1atom.pdb;\
spacefill false;\
background white;\
set measurements angstroms;\n\
set echo top center;\
font echo 25 sanserif bold;\
color echo [x" + colorGrayLight + "];\
echo Jmol applet loading completed.;\n\
set echo middle center;\
font echo 25 sanserif bold;\
color echo [x" + colorGrayLight + "];\
echo Now loading the molecule ...;\n\
delay 0.2;\n\
";

// set refreshing false;\n\ BEFORE JMOL.JS


var hoverSpt = "hover %n %r, Chain=%c, Element=%e, Atom=%a;\n";
var labelsIDSpt = " %e %n%r:%c";

// INITIAL SPIN CONTROL, ETC.
var setupSpt = "set spin y 5;\
spin on;\n\
set echo top left;\
font echo 20 sanserif bold;\n\
color echo black;\n" + hoverSpt;

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var defineAnomalousAtomsSpt =

"select not (protein,nucleic,hetero);\n\
define ~anomalous_atoms selected;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var anomalousAtomsView1Spt =

"select ~anomalous_atoms;\n\
color atoms cpk;\n\
dots;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var defineBackboneInvisibleSpt =

// DEFINE ~protein (since proteinSpt uses the results of this Spt!)
// For Jmol 10.3 where calcium is protein.
//"select ((protein,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LYS,LEU,MET,PHE,PRO,SER,THR,TRP,TYR,VAL) and not calcium);\n\
// For Jmol 10.9 where calcium is handled correctly.
"select (protein,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LYS,LEU,MET,PHE,PRO,SER,THR,TRP,TYR,VAL);\n\
define ~protein selected;\n" +

// AMINO ACIDS THAT LACK A BACKBONE ALPHA CARBON (no example known in PDB)
"select ~protein and not within(group, (~protein and *.ca)); \n\
define ~nobackbone_aas selected;\n" +

// AMINO ACIDS LACKING PEPTIDE BONDABLE ATOMS AT ONE END
"select ~protein and not within(group, *.c);\n\
select selected or (~protein and not within(group, *.n));\n\
define ~unbondable_aas selected;\n" +

// AMINO ACIDS NOT CONNECTED TO ANOTHER AMINO ACID VIA A PEPTIDE BOND AT EITHER END (*.N TO *.C)
//		1. N not connected to C
"select (~protein and *.n) and not connected(*.c);\n" +
//		2. Residues containing (N not connected to C) and lacking (C connected to N)
"select (~protein and *.c) and within(group, selected) and not connected(~protein and *.n);\n\
select within(group, selected);\n\
define ~unchained_aas selected;\n" +

// NUCLEOTIDE CHAINS NORMALLY BEGIN AT THE 5' END WITH A NUCLEOTIDE
// LACKING A PHOSPHATE (THE 05* HYDROXY END). JMOL THEREFORE INCLUDES
// THE TERMINAL 05* ATOM IN THE BACKBONE TRACE.

// NUCLEOTIDES THAT LACK A BACKBONE PHOSPHORUS
//		(INCLUDES ALL 5' HYDROXY ENDS)
"select (rna,dna) and not within(group, ((rna,dna) and *.p));\n\
define ~nophosphorus_nucs selected;\n" +

// NO PHOSPHORUS, HAS 03* BUT IT IS NOT BONDED TO P IN ANOTHER NUCLEOTIDE
//		(SO NOT A 5' HYDROXY CHAIN TERMINUS)
//		CASE: A351 CHAIN B IN 1BKX
// In Jmol 11.8.14 w/ 2009 remediation, the old "*.o3*" fails for A351 in 1BKX.
// This appears to be due to remediation since the unremediated 1bkx.pdb
// in my localTestFiles still shows the A351 with *.o3*!
"select ((dna,rna) and *.o3?) and not connected((dna,rna) and *.p);\n\
select selected and ~nophosphorus_nucs;\n\
select within(group, selected);\n\
define ~hydroxy_unchained_nucs selected;\n" +

// RESIDUES LACKING 03* ARE NOT "DNA" in JMOL

// NUCLEOTIDES LACKING CHAIN BONDING ATOMS AT BOTH ENDS,
//		SO CANNOT BE IN A CHAIN, AND CANNOT BE TESTED FOR BEING IN A CHAIN
// By lacking 03*, these are not nucleic!
//"select (dna,rna) and not within(group, *.o3*);\n\
//select selected and ((dna,rna) and not within(group, *.p));\n\
//define ~unbondable_nucs selected;\n" +

// NUCLEOTIDES NOT CONNECTED TO ANOTHER NUCLEOTIDE
//  AT LEAST AT ONE END, VIA O3* TO P (MUST HAVE BOTH O3* and P, BUT SEE
//  ~hydroxy_unchained_nucs ABOVE.)
// EACH SELECTION BELOW, #1 AND #2, SELECTS ALL CHAIN-END RESIDUES.
// BY ANDING THEM, WE SELECT RESIDUES WHICH ARE BOTH THE 3' AND 5' END.
//		1. O3* not connected to P
// In Jmol 11.8.14 w/ 2009 remediation, the old "*.o3*" fails for A351 in 1BKX.
// "*.o3?" gets O3P in SEP and TPO (excluded w/ dna/rna).
// "*.o3'" gets the desired atom.
// "*.o3" gets nothing.
// Note the "and within(group, selected)" which ANDs the selections.
"select ((dna,rna) and *.o3?) and not connected((dna,rna) and *.p);\n" +
//		2. Residues containing (O3* not connected to P) and lacking (P connected to O3*)
"select (((dna,rna) and *.p) and within(group, selected) and not connected((dna,rna) and *.o3?));\n\
select within(group, selected);\n\
define ~unchained_nucs selected;\n" +

// BACKBONE_INVISIBLE RESIDUES
"select ~nobackbone_aas,~unbondable_aas,~unchained_aas;\n\
select selected or ~hydroxy_unchained_nucs,~unchained_nucs;\n\
define ~backbone_invisible selected;\n" +

// DEFINE ~nucleic
"select nucleic and not ~backbone_invisible;\n\
define ~nucleic selected;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// 1. Patch:
//  rare "zombie" standard amino acids are not deemed protein by Jmol 10.00.46.
//  The list of standard amino acids is supposed to be temporary,
//  pending fixes in Jmol, after which
//  we should be able to use simply "(protein)";
// 2. Calcium is deemed protein by Jmol. FIXED Jmol 10.9.x
// 3. "Ligand+" ~backbone_invisible must be excluded.

var proteinSpt = 
"((protein,ALA,ARG,ASN,ASP,CYS,GLN,GLU,GLY,HIS,ILE,LYS,LEU,MET,PHE,PRO," +
"SER,THR,TRP,TYR,VAL) and not ~backbone_invisible)";

// old version for Jmol 10.3
//"SER,THR,TRP,TYR,VAL) and not (calcium, ~backbone_invisible))";
// The above patch fixes composition, polarity, charge and vines.

var clearSpt = "wireframe off; spacefill off;\
cartoon off; rocket off; trace off; backbone off; hbonds off;\
ssbonds off; dots off;\ncolor atoms cpk; color cartoons chain; \
color backbone none; model 1; labels off; \
set hermitelevel 0;\n";
// NOT set cartoonrockets off because then it changes the rocket display
// e.g. when ligands is toggled.

var SSBondsBBSpt = "select " + proteinSpt + ";\n set ssbonds backbone;\n" +
	"ssbonds 0.2; color ssbonds [x" +	colorSSBonds + "];\n";

var hideHydrogensSpt = "restrict not hydrogen;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// including "and (not ligand)" makes the nonstandard residues in 1EVV
// fail to show.
// NOTE that currently ribo-T and deoxyribo-U are not marked as
// non-standard residues. Ribo-T appears in 1EVV as 5MU.

var selectNonStandardResiduesSpt =
	"select hetero and (" + proteinSpt + ", nucleic);\n";

var starStub =
	selectNonStandardResiduesSpt +
	// phosphorylated amino acids give 2 crosses unless "not protein"
"select selected and ((phosphorus and not protein), *.ca);\n\
select selected and not ~hidden_jdef;\n";

//var starNonStandardResiduesSpt = starStub + "stars on;\n";
function makeXNonStandardResiduesSpt() // markNonstandard labelNonstandard
{
	var lbl = "x";
	if (labelsID)
		lbl += labelsIDSpt;
	
	return (starStub + makeMarkSelectedSpt(lbl));	
}

//var unStarNonStandardResiduesSpt = starStub + "stars off;\n";

var ballAndStickSpt =  "spacefill 0.6; wireframe 0.2;\n";

var hideBSSpt = "spacefill false; wireframe false;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeHideSidechainsSpt()
{
	var hsss;
	if (allWireframe) // detailed backbones
	{
		hsss = "restrict not sidechains;\n";
	}
	else // backbone traces 'vines'
	{
		hsss =
			"restrict not (nucleic, sidechains);\n" + 
			"select nucleic; trace 0.5; color trace chain;\n" + SSBondsBBSpt;
	}
	// always show sidechains of ~backbone_invisible
	hsss += "select ~backbone_invisible;\n";
	if (allWireframe)
		hsss +=  "wireframe 0.25; spacefill 0.25;\n";
	else
		hsss +=  "wireframe 0.3; spacefill 0.3;\n";

	return hsss;
}

// used in secondary structure rockets
// decommissioned for FGiJ 1.43.
// var patchZombieSpt = "select (*.ca and not protein);\
// old version for Jmol 10.3; reinstated 1.43.
var patchZombieSpt = "select (*.ca and not (protein,calcium));\
spacefill 0.3;\n\
";

// Ensure that non-protein alpha carbons show as spheres in backbone renderings.
// Version used in FGiJ thru 1.42 omitted calcium, but it needs to be excluded.
//var patchZombieChainSpt = "select (*.ca and not protein);\
// Old version for Jmol 10.3; and reinstated in FGiJ 1.43.
var patchZombieChainSpt = "select (*.ca and not (protein,calcium));\
color chain;\
spacefill 0.3;\n\
";

// Ensure that non-protein alpha carbons show as spheres in backbone renderings.
// decommissioned in FGiJ 1.43.
// var patchZombieRainbowSpt = "select (*.ca and not protein);\
// old version for Jmol 10.3; reinstated in FGiJ 1.43.
var patchZombieRainbowSpt = "select (*.ca and not (protein,calcium));\
spacefill 0.5;\n\
";

// CARTOON = RIBBONS
var cartoonSpt = "select (" + proteinSpt + ", ~nucleic);\n" + clearSpt +
"set cartoonRockets off;\
cartoon;\
color cartoon chain;\
select helix;\
cartoon 1.1;\
select sheet;\
cartoon 1.4;"
+ patchZombieChainSpt
+ SSBondsBBSpt;

// THRU FGIJ 1.42:
//var cartoonSpt = "select (" + proteinSpt + ", ~nucleic);\n" + clearSpt +
//	"cartoon; color cartoon chain;\n" + patchZombieChainSpt + SSBondsBBSpt;

// END CARTOON

// including "ligand or" shows the nonstandard residues of 1EVV as "ligands+"
var ligandSelectSpt = "select not (" + proteinSpt + ", nucleic, water);\n" +
	"select selected or ~backbone_invisible;\n";
var ligandClearSpt = ligandSelectSpt + clearSpt;
var ligandOffSpt = ligandClearSpt;
var ligandSpt = ligandClearSpt + "spacefill; color cpk;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var view1RenderSpt =
	cartoonSpt + ligandSpt + anomalousAtomsView1Spt +
	makeXNonStandardResiduesSpt() +  // needs ~hidden_jdef!
	makeMarkIncompleteSidechainsSpt() +
	makeMarkAnomalousAtomsSpt();

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeView1Spt() // this is also the resetSpt!
{
	var v1 =	
	setupSpt +
	"reset;\n" +
	"select all;\n" +
	"background white;\n" +
	"spin;\n" +
	"slab off;\n" + // in view1Spt
	"center all;\n" +
	"zoom 100;\n" +
	"monitors off;\n" +
	clearSpt +
// defineBackboneInvisibleSpt must precede cartoonSpt, ligandSpt!
	defineBackboneInvisibleSpt + 
	makeDefineHiddenSpt() + // to define ~hidden_jdef in Jmol, for pickCallback!
	defineAnomalousAtomsSpt +
	makeDefineIncompleteSidechainsSpt();

	if (processHeaderBeforeMolView) // for consurf
		v1 += makeEchoMsgSpt("Processing PDB File Header ...",
			"middle center", "25", "[x" + colorGrayLight + "]");

	// for consurf, the real view1 script is from
	// makeConsurfViewSpt() in consurf/scriptsc.js

	else // generic FGiJ initial view
		v1 += view1RenderSpt;

	return v1;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Nonzero hermitelevel makes spinning jerky for large molecules (1igt).
// Although with positive values, thickness goes to ribbons and mouse
// rotation is OK, spinning stays fat and jerky. Still, I liked it better
// than the rocket ridiculous straight planks (cf curved sheet in 1apm).
// And with hermitelevel 0, the only difference between cartoon and
// secondary structure (for strands) is color.
// Larger absolute values of hermitelevel (8) slow rotation without increasing
// thickness.

// secondary structure
var rocketSpt = "select " + proteinSpt + ";\n" + clearSpt +
"\n\
set cartoonrockets on;\
set hermitelevel 4;\
cartoon;\
select selected and not sheet;\
trace 0.3; # winds rope around rocket, connects to ends.;\
select sheet;\
cartoon 1.4 # default is 1.5 width.;" +
	patchZombieSpt +
"select " + proteinSpt + ";\n\
color cartoon structure;\
color trace structure;\n"
+ SSBondsBBSpt;

// ROCKETS: UNTIL FGIJ 1.42:
//var rocketSpt = "select " + proteinSpt + ";\n" + clearSpt +
//"color structure;\
//trace 0.2;\n" +
//	patchZombieSpt +
//"select helix,sheet;\
//rockets;\n" + SSBondsBBSpt;

//color rockets structure;";

// this is necessary when rockets are applied to the whole protein, but not
// when traces are applied.
//select turn;\
//color [x6080ff]";

// trying to make the traces fatter makes rocket heads flap (1d66 only?) and
// the traces don't connect to the rockets
// select not (helix,sheet); trace 0.35;";

// END ROCKETS

var waterOffSpt = "select water;\n" + clearSpt;
var waterSpt = "select water;\n" + clearSpt +
	"spacefill;color cpk;\n";

var polaritySpt = "select all;" + clearSpt +
"select " + proteinSpt + ";\n\
spacefill;\
select hydrophobic;\
color [x" + colorHydrophobic + "];\n\
select " + proteinSpt + " and not hydrophobic;\n\
color [x" + colorPolar + "];\
select ~nucleic;\
cartoon;\
color cartoon chain;"

// PE uses 909090 for gray

function makeChargeSpt()
{
	var acba = // acid, base

"select (asp.od?,glu.oe?);\n\
color [x" + colorAcidic + "];\n\
select (lys.nz,lys.?hz,arg.nh?,arg.?hh?);\n\
color [x" + colorBasic + "];\n\
select (his.ne?,his.he2);\n\
color [x" + colorHisBasic + "];\n\
";

	var incs = // incomplete sidechains
"select arg and not within(group, arg.nh1);\n\
select selected or (arg and not within(group, arg.nh2));\n\
select selected or (lys and not within(group, lys.nz));\n\
select selected or (his and not within(group, his.ne?));\n\
color [x" + colorLightBasic + "];\n\
\n\
select asp and not within(group, asp.od1);\n\
select selected or (asp and not within(group, asp.od2));\n\
select selected or (glu and not within(group, glu.oe2));\n\
select selected or (glu and not within(group, glu.oe2));\n\
color [x" + colorLightAcidic + "];\n\
";

	var cspt = "";
	if (!showPolar)
	{
		cspt =
"select all;" + clearSpt +
"select ~protein;\n" +
"spacefill;\n" +
"color white;\n";

		if (colorChargeOnlyAtoms)
		{
			cspt += acba;

			if (showChargeIncompleteSidechains)
				cspt += incs;
		}
		else // color entire sidechains
		{
			cspt +=
"select lys,arg;\n\
color [x" + colorBasic + "];\n\
select his;\n\
color [x" + colorHisBasic + "];\n\
select asp,glu;\n\
color [x" + colorAcidic + "];\n\
";
		}
	}

	if (showPolar)
		cspt = polaritySpt +
"select acidic;\n\
color [x" + colorAcidic + "];\n\
select basic;\n\
color [x" + colorBasic + "];\n\
select " + proteinSpt + " and backbone;\n\
color [x" + colorBackbone + "];\
";

	cspt +=
"select ~nucleic;\
cartoon;\
color cartoon chain;"

	return cspt;
}

var rainbowSpt = "select (" + proteinSpt + ", ~nucleic);\n" + clearSpt +
"color trace group;\
color backbone group;\
select " + proteinSpt + ";\n\
trace 0.5;\n" +
	patchZombieRainbowSpt +
"select ~nucleic;\
backbone 1.0;\n" + SSBondsBBSpt; // return this to trace when hover/center is fixed.

// When I tried using "center atomno=" (from the picking report)
// centering worked, but there were unwanted changes in zoom.
var centerSpt = "set picking center;";

//select " + twentyAASpt + " or " + proteinSpt + ";\

var compositionSpt = "select all;" + clearSpt +
"spacefill;\
select " + proteinSpt + ";\n\
color [x" + colorProtein + "];\
select dna;\
color [x" + colorDNA + "];\
select rna;\
color [x" + colorRNA + "];" +
	ligandSelectSpt +
"color [x" + colorLigand + "];\
select solvent;\
color [x" + colorSolvent + "];\n";

var hideSpt = "";
 
var allModelsSpt = "select all;" + clearSpt +
"models all;\
backbone;\
color backbone group;";

var slabOffSpt = "slab off;" + hoverSpt;
// both slab and depth go from 0 in the rear

function makeSlabSpt(forceOn)
{
	var sts;
	if (slabThickness == "10")
		sts = "slab 55; depth 45;\n";
	else if (slabThickness == "6")
		sts = "slab 53; depth 47;\n";
	else if (slabThickness == "3")
		sts = "slab 52; depth 49;\n";

	if (forceOn || toggleIsDown[slabIndex])
	{
//		sts += "hover Sorry, can't identify with Slab on;\n";
		sts += "slab on;\n";
	}

	return sts;
}

function makeVineSpt()
// Patches(?):
//
// In 1AL4, DLE (etc.) are hetero and protein. Therefore, restricting
// sidechains to not-hetero excludes the D-AA sidechains.
//
// In 1AL4, residues 1-3 are std AA's but not deemed protein.
// Therefore, selecting (protein and *.ca) fails to show these alpha carbons.
// Therefore, select (*.ca and not calcium).
//
// Patch unbonded!!
// I have included spacefill 0.3 to show sidechain atoms that fail to
// be bonded in Jmol, e.g. all sidechains in 1AL4!

// the select *.ca lines below formerly had "and not calcium"

{
	var vs = 	
"select all;" + clearSpt +
"select " + proteinSpt + ";\n\
set bondmode and;\
backbone 0.3;\
color backbone chain;\
select sidechain;\
select selected or *.ca #patch ;\
set ssbonds sidechain;\
wireframe 0.3;\
spacefill 0.3;\
color cpk;\n\
select *.ca;\
color chain;\n\
select nucleic;\
color cartoon cpk;\
color cpk;\
cartoon;\
color cartoon chain;\n"
	+ ligandSelectSpt + // includes ~backbone_invisible
"color cpk;\
wireframe 0.3;\
spacefill 0.3\n";

if (!top.hydrogensVisible)
	vs += hideHydrogensSpt;

if (!top.sidechainsVisible)
	vs += makeHideSidechainsSpt();

// see also makeWireframeAllSpt() "more detail"

if (useConsurfColors)
	vs += makeConsurfColorsSpt();

	return vs;

}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeJmolScript() // the intitial script for the Jmol applet
{
	// Construct command script for Jmol, maybe including a load command.

	var finalSpt = "";

	if (top.debuggingFG)
		finalSpt += "console;\nset debugscript on;\n"

	finalSpt += view1SptPrefix;

	if (top.pdbURL != "")
	{
		finalSpt += "load " + top.pdbURL + ";" +
			makeView1Spt() + makeEchoPdbIdSpt("black");
	}

	else
		finalSpt += "color echo red;echo Error #1: Cannot obtain PDB file.;";

//	finalSpt += "set refreshing true;\n"; BEFORE JMOL.JS

	finalSpt += makeMessageMarkSpt(messageMarkEndFirstView);

	if (top.debuggingFG || showView1Spt)
//		alert("scripts.js #3 - initial script:\n" + finalSpt);
		showSptInWindow("scripts.js #2 - initial script:\n\n" + finalSpt);

	return finalSpt;

}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function getEchoColor()
{
//	alert("scripts.js #5 entering getEchoColor()");

	var echoColor = "white";

	if (!top.usingFrames)
	{
//		var tognum = toggleIndexFromName["background"];
		if (toggleIsDown[backgroundIndex])
			echoColor = "black";
	}
	else
	{
//		var tognum = top.frameLeft.frameLeftTop.toggleIndexFromName["background"];
//		if (top.frameLeft.frameLeftTop.toggleIsDown[])
//			echoColor = "black";
	}

//	alert("scripts.js #5a getEchoColor() returns " + echoColor);

	return echoColor;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// makeEchoPdbIdSpt(echoColor) makes a script to display the PDB ID code
// at the upper left inside Jmol.
// If echoColor=="", the color is determined automatically to be the opposite
// of the current background.

function makeEchoPdbIdSpt(echoColor)
{
	// PDB code is on top of the unit cell dimensions when unit cell is
	// displayed, so don't show it then.
	if (unitcellOn)
		return "";

	var toshow = top.pdbId;
	if (usingCIF)
		toshow += ".cif";
	var fontsize = "20";

	// Hide PDB filename when it was uploaded, and has a random code name
	// for temporary storage on the CGI server.
	if (top.pdbId.substring(0, 4) == "UPL_")
	{
		toshow = "(Uploaded data)";
		fontsize = "15";	
	}

	if (echoColor == "")
		echoColor = getEchoColor();

	var echoSpt =
"set echo top left;\
font echo " + fontsize + " sanserif bold;\
color echo " + echoColor + ";\
echo \" " + toshow + "\";\n";

	return echoSpt;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeEchoMsgSpt(msg, position, fsize, echoColor)
{
	// PDB code is on top of the unit cell dimensions when unit cell is
	// displayed, so don't show it then.
	if (unitcellOn && position.indexOf("top") != -1)
		return "";

	var toshow = msg;

	var echoSpt =
"set echo " + position + ";\
font echo " + fsize + " sanserif bold;\
color echo " + echoColor + ";\
echo \" " + toshow + "\";\n";

	return echoSpt;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

var centerAllSpt = "center (protein,nucleic);\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

var smallWaterSpt = "select water; spacefill 0.6; wireframe 0.2;\n";

var bigWaterSpt = "select water; spacefill;\n";

var smallLigandSpt = ligandClearSpt // includes clearSpt
		+ "spacefill 0.6; wireframe 0.2;\n";

var bigLigandSpt = ligandClearSpt + "spacefill;\n";

function makeWireframeAllSpt() // more detail
{
	wfa = "select not water;\n" +
	clearSpt + "color cpk; wireframe 0.25; spacefill 0.25; set ssbonds sidechain;\n";

	if (!top.hydrogensVisible)
		wfa += hideHydrogensSpt;

	if (!top.sidechainsVisible)
		wfa += makeHideSidechainsSpt();

	return wfa;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function colorTemperature()
{
	scriptToJmol("select all;color temperature;\
		color cartoons temperature;color backbone temperature;\n");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeSelectSpt() // selects defines ~targ_current
{
	var ss1 =
//		"select all;\n" +
//		"labels off;\n" +
		"select none;\n"; // in makeSelectSpt()

	var ss2 = "# makeSelectSpt();\n";
//	var ss3 = "";
	var is;
	
	for (is = 0; is < selectedChains.length; is++)
	{
		if (selectedChains[is].length > 1)
		{
			if (selectedChains[is] == "Protein")
				ss2 += "select selected or ((" + proteinSpt + ") and not hetero);\n";
			else
				ss2 += "select selected or (~nucleic and not hetero);\n";
		}
		else
			ss2 += "select selected or (:" +
				selectedChains[is] + " and not hetero);\n";
	}
	for (is = 0; is < selectedGroups.length; is++)
	{
		ss2 += "select selected or " +
			selectedGroups[is] + ";\n";
	}
	for (is = 0; is < selectedAtoms.length; is++)
	{
		ss2 += "select selected or atomno=" +
			firstWord(selectedAtoms[is]) + ";\n";
	}

	if (selectedRangeStart != "")
		ss2 += "select selected or " + selectedRangeStart + ";\n";

	for (is = 0; is < selectedRanges.length; is++)
	{
		ss2 += "select selected or " + selectedRanges[is] + ";\n";
	}

	if (selectedFound != "")
		ss2 += "select selected or ((" + selectedFound + ") and not hydrogen);\n";

	if (selectedWater)
		ss2 += "select selected or (water and not hydrogen);\n";

	if (ss2 != "")
		ss2 += "select selected and not ~hidden_jdef;\n";

	ss2 += "define ~targ_current selected;\n";

//	alert("scripts.js #7:\n" + ss1 + ss2);

	return ss1 + ss2;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// for searching: n markselected n labelselected = makeMarkSelectedSpt()
function makeMarkSelectedSpt(mark) // apply mark labels to atoms
{
	// color labels: works only on selected, can color different labels
	// differently in same view.

	// set fontsize: global, works on all labels even when none selected.

		var ss3 =
			"set labeloffset 0 0;\n" +
			"label " + mark + ";\n" +
			"set labelalignment left;\n"; // added for 1.39

		if (contactsShowing && mark == "*")
		{
			if (targetSF)
				ss3 += "set fontsize 20; color labels black;\n";
			else
				ss3 += "set fontsize 16; color labels white;\n"; // or green
		}
		else if (match(currentView, "precontacts") && mark == "*")
		{
			if (preContactsView == "sf")
				ss3 += "set fontsize 20; color labels black;\n";
			else
				ss3 += "set fontsize 16; color labels white;\n";
		}
		else // neither preContacts nor contactsShowing or mark !=  *
		{
			ss3 += "set fontsize 16;\n";
			if (toggleIsDown[backgroundIndex]) // white background
				ss3 += "color labels black;\n";
			else
				ss3 += "color labels white;\n";
		}

//	alert("scripts.js #9 makeMarkSelectedSpt() returns:\n\n" + ss3);
	ss3 = "# BEGIN makeMarkSelectedSpt();\n" + ss3 +
		"# END makeMarkSelectedSpt();\n";

	return ss3;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeFindSpt()
{
	var findSpt = "";

	// guarantee that ~hidden_jdef is defined
	findSpt += makeDefineHiddenSpt();

	if (forceBackgroundBlack)
	{
		findSpt += "background black;\n";
		findSpt += makeEchoPdbIdSpt("white");
		forceBackgroundBlack = false;
	}

	findSpt += "set display selected;\n" +
		"select ("; // in makeSelectSpt()
	var is;

	findSpt += toFind + ");\n";

	// hide hidden halos
	findSpt += "select selected and not ~hidden_jdef;\n";

//	alert("scripts.js #6 makeFindSpt():\n" + findSpt);
	return findSpt;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makePreContactsSpt()
{
	var pcs = "";

	if (preContactsView == "sf")
	{
		pcs +=
		"select all;\n"
		+ clearSpt +
		"color chain;\n"

		+ ligandSelectSpt + 

"color [x" + colorLigand + "];\n\
select solvent; color [x" + colorSolvent + "];\n\
select not (hydrogen, water);\n\
spacefill;\n";

	}
	else // CARTOON
	{
		pcs += cartoonSpt;
	}

//	alert("pre " + preContactsWater);
	if (preContactsWater)
	{
//		alert("during " + preContactsWater);
		pcs += "select water; spacefill;\n";
	}
//	alert("after " + preContactsWater);

	pcs +=
// this contained "slab off" until FGiJ 1.43.
"background black;\n"; // makePreContactsHelp() sets toggle params.

	pcs += makeEchoPdbIdSpt("white");

	return pcs;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeGenerateContactsSpt()
{
	// No contacting atoms remain hidden. Hiding before 'Show Contacts' is
	// to help in selection.

	clearHidden();

	// because form does not exist,
	//	false1 = don't read radio buttons;
	//	false2 = don't read checkboxes
	return (makeDefineContactsSpt() + makeContactsViewSpt(false, false));
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// METALS

// Uncertain: tin (OCA suggests not present; stannous and stannic negative
// at RCSB).

// Not found in the PDB:
// bismuth
// Alkaline earths:
//   radium
// Transition metals:
//   scandium, titanium, niobium, hafnium
// Lanthanides:
//   hafnium, neodymium, promethium, dysprosium, thulium, 
// Actinides:
//   actinium, thorium, protactinium, neptunium, plutonium, americium

// These alkali metals (monovalent: Li, Na, K, Rb, Cs) are present in the
// PDB. Francium is not.

var metalsSpt = 
"(aluminum, barium, beryllium, cadmium, cerium, cesium, calcium, " +
"cesium, chromium, copper, erbium, europium, gadolinium, gallium, gold, " +
"holmium, indium, iridium, iron, lanthanum, lead, lithium, lutetium, " +
"magnesium, manganese, mercury, molybdenum, nickel, " +
"osmium, palladium, platinum, potassium, praseodymium, rhenium, rhodium, " +
"rubidium, ruthenium, samarium, sodium, silver, strontium, " +
"tantalum, technetium, tellurium, terbium, thallium, " +
"tungsten, uranium, vanadium, ytterbium, zinc, zirconium)";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeDefineContactsSpt()
{
// This script is adapted from PE's contsurf.js, namely, the QuickViews
// 'Contact Surface'.
//
// It will make definitions for these terms:
// (NOTE: these terms all used "balled" and "sticked";
//		none use "balls" or "sticks".
//   ---------------------------------------
//   ~contarget           (excludes hydrogen)
//
//   ~outside_contarget   (excludes hydrogen)
//
//   ~bridging_water
//   ~water_bridges (includes ~bridging water and both ends of bridge)
//
//   ~cont_hbonds
//   ~cont_memi
//   ~cont_hphob
//   ~cont_sb
//   ~cont_catpi
//
//
//   ~targ_hbonds
//   ~targ_to_water
//   ~targ_memi
//   ~targ_hphob
//   ~targ_sb
//   ~targ_catpi
//
//   ~close_nonballed NOT IN USE
//   ---------------------------------------

// N.B. IN JMOL, "and model=1" IS OK IN SINGLE MODEL FILES!

	// HIDE EVERYTHING, COLOR CHAIN/SOLVENT/LIGAND
	var cs = "select all;\n" + clearSpt

// DEFINE CONTARGET

	+ makeSelectSpt() +

"select selected and not hydrogen;\n\
define ~contarget (selected and model=1);\n" +

// DEFINE ~outside_contarget

"select not (selected, hydrogen);\n\
define ~outside_contarget (selected and model=1);\n" +

// DEFINE CLOSE_NONBALLED (spacefill 0.15) *NOT IN USE*

// Show close nonsticked, nonbonded water, metal atoms as small balls
// (e.g. HOH 275 at edge of ring in 1HPV).

//"select ~outside_contarget and within(4.5, ~contarget);\n\
//define ~close_nonballed selected;\n" +

// DEFINE LIKELY-BONDED CONTACTING ATOMS

//"select none;\n" + // FOR TESTING

	//--------START NEW SELECTION--------------------

	//    HBONDS = O/N within 3.5A of O/N
	// This rule is bidirectional (inside/outside).
"select (~outside_contarget and (oxygen, nitrogen) and " +
"within(3.5, (~contarget and (oxygen, nitrogen)))); \
define ~cont_hbonds selected;\n" +

	//--------START NEW SELECTION--------------------

	//    METALS AND MISC PART I. Not C/S/H within 3.5A of not C/S/H
	// This rule is bidirectional (inside/outside).
	// It includes e.g. metals bonded to Se/O
	// and Se/O bonded to metals! (Sulfur is handled separately below)
	// Also metals to metals.
	// But it does not include Se-C in either direction, but see hydrophobic below.
"select (~outside_contarget and not (carbon, sulfur, phosphorus) and " +
"within(3.5, (~contarget and not (carbon, sulfur))));\n\
select selected and not ~cont_hbonds;\n" +
//"select none;\n" + // for testing

	//    OUTSIDE METAL-BINDING ATOMS PART II.
	//			= not C/S/P/H within 3.5A of METAL
	// This rule is UNIdirectional.
	// It aims for contacting atoms bound to target metals, such
	// as nitrogen to Fe in Hb, or a metal to metal contact.
	// Without this rule, N's or O's may be excluded in the previous
	// rule b/c of possible hbonding (e.g. bogus N to N bonds between HIS
	// and HEM).
"select selected or (~outside_contarget and not " +
"(carbon, sulfur, phosphorus)) and " +
"within(3.5, (~contarget and " + metalsSpt + "));\n" +

	//    MISCELLANEOUS: OUTSIDE METALS and OTHER ELEMENTS within 4.5A of
	//			ANY TARGET ELEMENT (except H)
	// Includes Se interacting with anything inside.
	// Includes unanticipated elements that lack specific rules.
	// Includes metals to metals.
"select selected or ((~outside_contarget and not " +
"(carbon,oxygen,nitrogen,sulfur,phosphorus)) and within(4.5, ~contarget));\n" +

	//    OUTSIDE SULFURS bonded to TARGET METALS
	// Se was handled in the more generous misc rule above.
"select selected or (~outside_contarget and sulfur and \
within(3.2, ~contarget and " + metalsSpt + "));\n" +

	//		DEFINE CONT_MEMI (MEMI = MEtals or MIscellaneous)
"define ~cont_memi selected;\n" +

	//--------START NEW SELECTION--------------------

	//    HYDROPHOBIC BONDS = C/S/Se within 4.5A of C/S/Se
	// This rule is bidirectional (inside/outside).
	// Note that this excludes Se, but see "outside other elements"
"select (~outside_contarget and (carbon,sulfur,selenium) and " +
"within(4.5, (~contarget and (carbon,sulfur,selenium)))); \
define ~cont_hphob selected;\n" +

	//--------START NEW SELECTION--------------------

	//		SALT BRIDGES
"select (~outside_contarget and (arg.ne,arg.nh?,lys.nz) " +
"and within(4.0, (~contarget and (asp.od?,glu.oe?))));\n\
select selected or (~outside_contarget and (asp.od?,glu.oe?) " +
"and within(4.0, (~contarget and (arg.ne,arg.nh?,lys.nz))));\n\
define ~cont_sb selected;\n" +

	//--------START NEW SELECTION--------------------

	//		CATION PI
	// cations 
"select (~outside_contarget and (lys.ce,lys.nz,arg.cz,arg.cd) " +
"and within(6.0, (~contarget and (trp.cd2,tyr.cd1,phe.cd1))) " +
"and within(6.0, (~contarget and (trp.cz2,tyr.cd2,phe.cd2))) " +
"and within(6.0, (~contarget and (trp.cz3,tyr.cz,phe.cz))));\n" +
"define ~ocatpi0 selected;\n" +

	// pi rings
"select (~outside_contarget and (trp.cd2,tyr.cd1,phe.cd1) " +
"and within(6.0, (~contarget and (lys.ce,lys.nz,arg.cz,arg.cd)))); \
select within(group, selected);\n\
define ~ocatpi1 selected;\n" +

"select ~ocatpi1 and (trp.cz2,tyr.cd2,phe.cd2) " +
"and within(6.0, (~contarget and (lys.ce,lys.nz,arg.cz,arg.cd)));\n\
select within(group, selected);\n\
define ~ocatpi2 selected;\n" +

"select ~ocatpi2 and (trp.cz3,tyr.cz,phe.cz) " +
"and within(6.0, (~contarget and (lys.ce,lys.nz,arg.cz,arg.cd)));\n\
select within(group, selected);\n\
select selected and (trp.cd2,trp.ce?,trp.cz?,trp.ch?, " +
"phe.cg,phe.cd?,phe.ce?,phe.cz, " +
"tyr.cg,tyr.cd?,tyr.ce?,tyr.cz);\n\
select selected or ~ocatpi0;\n\
define ~cont_catpi selected;\n" +

// DEFINE LIKELY-BONDED TARGET ATOMS

	//--------TARGET HBONDED TO NON-WATER OUTSIDE --------------------
"select ~contarget and (oxygen, nitrogen) and " +
"within(3.5, (~outside_contarget and (nitrogen, (oxygen and not water)))); \
define ~targ_hbonds selected;\n" +

	//--------START NEW SELECTION--------------------

	//		DEFINE TARGET TO WATER
"select ~contarget and (oxygen, nitrogen) and " +
"within(3.5, (~outside_contarget and water)); \
define ~targ_to_water selected;\n" +

	//--------START NEW SELECTION--------------------

	//		DEFINE WATER BRIDGES
// First, define bridging water
"select (~outside_contarget and water) and within(3.5, ~targ_to_water) and " +
"within(3.5, ((oxygen, nitrogen) and ~outside_contarget and not water));\
define ~bridging_water selected;\n" +

// Second, define water bridges
// This selection is unusual in that we are not limiting the selected atoms
// to either ~contarget or ~outside_contarget. So we must limit them to
// model=1!
"select ((oxygen, nitrogen) and model=1) and " +
"within(3.5, ~bridging_water) and not water;\
define ~water_bridges (selected or ~bridging_water);\n" +

	//--------START NEW SELECTION--------------------

//"select none;\n" + // for testing only

	//    INSIDE METALS AND MISC PART I. (MISC EXCLUDING HBONDS)
	//			= not C/S/P/H within 3.5A of not C/S/H
	// This rule is bidirectional (inside/outside).
	// It includes e.g. metals bonded to Se/O
	// and Se/O bonded to metals! (Sulfur is handled separately below)
	// But it does not include Se-C in either direction.
"select (~contarget and not (carbon, sulfur, phosphorus)) and " +
"within(3.5, (~outside_contarget and not (carbon, sulfur)));\n" +
"select selected and not (~targ_to_water, ~targ_hbonds);\n" +

	//    INSIDE METALS PART II.
	//			= not C/S/P/H within 3.5A of METAL
	// This rule is UNIdirectional.
	// It aims for target atoms bound to contacting metals, such
	// as nitrogen to Fe in Hb, or a metal to metal contact.
	// Without this rule, N's or O's may be excluded in the previous
	// rule b/c of possible hbonding (e.g. bogus N to N bonds between HIS
	// and HEM).
"select selected or (~contarget and not (carbon, sulfur, phosphorus)) and " +
"within(3.5, (~outside_contarget and " + metalsSpt + "));\n" +

	//    INSIDE METALS and OTHER ELEMENTS within 4.5A of
	//			ANY OTHER OUTSIDE ELEMENT (not C/O/N/S/P/H)
	// Includes Se interacting with anything outside.
"select selected or ((~contarget and not " +
"(carbon,oxygen,nitrogen,sulfur,phosphorus)) " +
"and within(4.5, ~outside_contarget));\n" +

	//    INSIDE SULFURS bonded to OUTSIDE METALS
	// Se was handled in the more generous misc rule above.
"select selected or (~contarget and sulfur and " +
"within(3.2, ~outside_contarget and " + metalsSpt + "));\n" +

	//		DEFINE TARG_MEMI
"define ~targ_memi selected;\n" +

	//--------START NEW SELECTION--------------------

	//    HYDROPHOBIC BONDS
"select (~contarget and (carbon,sulfur,selenium) and " +
"within(4.5, (~outside_contarget and (carbon,sulfur,selenium)))); \
define ~targ_hphob selected;\n" +

	//--------START NEW SELECTION--------------------

	//		SALT BRIDGES
"select (~contarget and (arg.ne,arg.nh?,lys.nz) " +
"and within(4.0, (~outside_contarget and (asp.od?,glu.oe?))));\n\
select selected or (~contarget and (asp.od?,glu.oe?) " +
"and within(4.0, (~outside_contarget and (arg.ne,arg.nh?,lys.nz))));\n\
define ~targ_sb selected;\n" +

	//--------START NEW SELECTION--------------------
	//		CATION PI
	// cations 
"select (~contarget and (lys.ce,lys.nz,arg.cz,arg.cd) " +
"and within(6.0, (~outside_contarget and (trp.cd2,tyr.cd1,phe.cd1))) " +
"and within(6.0, (~outside_contarget and (trp.cz2,tyr.cd2,phe.cd2))) " +
"and within(6.0, (~outside_contarget and (trp.cz3,tyr.cz,phe.cz))));\n" +
"define ~tcatpi0 selected;\n" +

	// pi rings
"select (~contarget and (trp.cd2,tyr.cd1,phe.cd1) " +
"and within(6.0, (~outside_contarget and (lys.ce,lys.nz,arg.cz,arg.cd)))); \
select within(group, selected);\n\
define ~tcatpi1 selected;\n" +

"select ~tcatpi1 and (trp.cz2,tyr.cd2,phe.cd2) " +
"and within(6.0, (~outside_contarget and (lys.ce,lys.nz,arg.cz,arg.cd)));\n\
select within(group, selected);\n\
define ~tcatpi2 selected;\n" +

"select ~tcatpi2 and (trp.cz3,tyr.cz,phe.cz) " +
"and within(6.0, (~outside_contarget and (lys.ce,lys.nz,arg.cz,arg.cd)));\n\
select within(group, selected);\n\
select selected and (trp.cd2,trp.ce?,trp.cz?,trp.ch?, " +
"phe.cg,phe.cd?,phe.ce?,phe.cz, " +
"tyr.cg,tyr.cd?,tyr.ce?,tyr.cz);\n\
select selected or ~tcatpi0;\n\
define ~targ_catpi selected;\n";

	return cs;

}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var contargetDarkCPKSpt =
"select ~contarget and carbon;    color [x" + darkCarbon + "];\n\
select ~contarget and oxygen;     color [x" + darkOxygen + "];\n\
select ~contarget and nitrogen;   color [x" + darkNitrogen + "];\n\
select ~contarget and sulfur;     color [x" + darkSulfur + "];\n\
select ~contarget and phosphorus; color [x" + darkPhosphorus + "];\n\
select ~contarget and water and oxygen; color [x" + darkWater + "];\n\
";

var contactingLightCPKSpt =
"select ~outside_contarget and carbon;    color [x" + lightCarbon + "];\n\
select ~outside_contarget and nitrogen;   color [x" + lightNitrogen + "];\n\
";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Checkbox scripts are those that don't use doViewLink() nor doToggleButton()

function doMolViewSpt(spt) // dmv misnamed: adds hideSpt then does spt
{
	spt += "# BEGIN doMolViewSpt() additions;\n";
//	spt += "set refreshing false;\n"; BEFORE JMOL.JS
	spt += makeHideSpt(); // doMolViewSpt()

	// REINSTATE DOTS
	// restrict anything hides dots, so this must follow the hiding.
//	alert("scripts.js #8 doMolViewSpt():\ncontrolPanel = " + controlPanel);
	if (!consurfNeedsDots())
	{
		if (controlPanel == "consurf")
			spt += "select hetero and not water;\ndots 50;\n";
		else
			spt += makeAnomalousAtomsSpt();
	}
	else
	{
		spt += "select ~consurf_isd_grade0;\ndots;\n";
		if (consurf_isd_mode == "dotssf")
			spt += "color dots [x" + isd_color + "];\n";
	}

	spt += "# END doMolViewSpt() additions;\n";

//	alert("scripts.js #4: doMolViewSpt() generates:\n" + spt)
	scriptToJmol(spt); // doMolViewSpt()
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

// N.B.: ALL or [ALL] for Allose produce a script-stopping error in Jmol.
// ALT produces a script-stopping "variable undefined" error in Jmol, but
// [ALT] is OK. However ALT is thioalanine (1VBT only).

// This list is derived from carbohydrates that occur in PDB files,
// http://bip.weizmann.ac.il/oca-docs/ligandscarb.html
// 1st alphabetic set = monosaccharides.
// 2nd alphabetic set = oligosaccharides.
// 3rd alphabetic set is modified carbohydrates, and sugars missing
//   from the above URL.
// Search for a hetero group w/ entry list and structure:
// http://bip.weizmann.ac.il/oca-bin/ocaids?m=id&ht=ido

var carbohydrateSpt =  // can't use (kills spt) [ALL]
"([AFL],[AGC],[AHR],[ARA],[ARB],[BDF],[BDR],[BGC],[BMA],[FCA], \
[FCB],[FRU],[FUC],[FUL],[GAL],[GLA],[GLB],[GLC],[GUP],[LXC],[MAN], \
[RAA],[RAM],[RIB],[RIP],[XYP],[XYS], \
[CBI],[CT3],[CTR],[CTT],[LAT],[MAB],[MAL],[MLR],[MTT],[SUC],[TRE], \
[ASF],[GCU],[MTL],[NAG],[NAM],[RHA],[SOR],[XYL]) ";

// + = sugar related, included; - = excluded
// + NAG N acetyl D glucosamine
// + NAM napthyl amino alanine = (?) N acetyl muramic acid (3 entries)
// + SOR D sorbitol (7 entries)
// + XYL D xylitol (9 entries)
// + MTL D mannitol (1 entry)
// + XUL D xylulose (1 entry)
// + ASF (only in 1AGM) RCSB says is CHO but is decomposed into monosaccs
//       in the mmCIF, but not in the PDB. Missing info in het dict.
// + GCU D glucuronic acid in 24 entries
// + AGL 4,6-dideoxy-4-amino-alpha-d-glucose (6 entries) agarose
// + G4S d-galactose-4-sulfate (2 entries)
// - sulfated sugars in few entries G4S, IDS, SGN, NGS, GLS, G6S
// - phosphorylated sugars e.g. AFP, AHM, AHG etc.
// - RHA 6-deoxy-mannose-1'-phosphate (occurs only in 1TLP, not on other CHO)
// - ERY is erythromycin (1JZY)
// - GUL is 5 Fluoro Beta L Gulosyl Fluoride  (1QWN, 1QWU)
// - IDO is iodo (1CKT and more)

function hideChecked(cat) // chemical category
{
	// We don't need to make a script here, because reDisplay() will
	// use makeHideSpt() to do the job.

	var ckd, action, catname, catspt, echospt;
	var hcs = "";

	if (cat == "p")
	{
		catname = "protein";
		ckd = document.hideForm.p.checked;
		action = (ckd? " Hidden": " Re-Displayed");
		hideProtein = ckd;
//		catspt = proteinSpt;
	}
	if (cat == "d")
	{
		catname = "DNA";
		ckd = document.hideForm.d.checked;
		action = (ckd? " Hidden": " Re-Displayed");
		hideDNA = ckd;
//		catspt = "DNA";
	}
	if (cat == "r")
	{
		catname = "RNA";
		ckd = document.hideForm.r.checked;
		action = (ckd? " Hidden": " Re-Displayed");
		hideRNA = ckd;
//		catspt = "RNA";
	}
	if (cat == "c")
	{
		catname = "Carbohydrate";
		ckd = document.hideForm.c.checked;
		action = (ckd? " Hidden": " Re-Displayed");
		hideCarbohydrate = ckd;
//		catspt = carbohydrateSpt;
	}
	if (cat == "h")
	{
		catname = "Hydrogen";
		ckd = document.hideForm.h.checked;
		action = (ckd? " Hidden": " Re-Displayed");
		hideHydrogen = ckd;
	}

	echospt = makeEchoSpt(catname + action);

//	if (ckd)
//	{
//		hcs += "restrict not (" + catspt + ");\n";
//		hcs += echospt;
//		doMolViewSpt(hcs);		
//	}
//	else
		reDisplay(echospt, "");
	showHelp("makeHideHelp()");
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var labelContactsSpt =

"select all\n\
labels off\n\
color labels none\n\
set fontsize 14\n" + // for identifying contacts

"select within(group, ~cont_current) and (*.ca or phosphorus)\n\
label %n %r:%c\n\
set labeloffset 1 0\n\
" +

//set labelalignment left\n\

//label %n%r:%c;\n\

"select ~cont_current and (*.ca or phosphorus);\n\
label %n %r:%c;\n\
set labeloffset 1 0;\n\
";

//set labelalignment left\n\


//color labels [x00ff00]\n\


//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var showContactsBackbonesSpt =
"select all; backbone; color backbone chain;\n";

var hideContactsBackbonesSpt =
"select all; backbone off;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
var spinOnSpt = "spin on;\n";
var spinOffSpt = "spin off;\n";

var bgWhiteSpt = "background white;\n";
var bgBlackSpt = "background black;\n";

var qualityOnSpt = "set antialiasdisplay on;\n";
var qualityOffSpt = "set antialiasdisplay off;\n";

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makePreFindSpt()
{
	pfs = "background black; set display selected; select none;\n";

	return pfs;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function seeHalosEasily()
{
	if (toFind == "")
	{
		alert("There are no halos. Please specify some residues\n" +
			"or elements in the slot, then press Enter.");
		return;
	}

	setButtonState("up", backgroundIndex); // Background Black	

	var she = makeEchoPdbIdSpt("white") +
"background black; select all;\n" + clearSpt +
"select " + toFind + ";\n" +
"delay 1;\n" +
"select all; backbone; color backbone chain;\n" +
"select " + toFind + ";\n" +
"delay 1;\n" +
"select all; backbone off;\n" +
"select " + toFind + ";\n" +
"delay 1;\n" +
"select all; backbone;\n" +
"select " + toFind + ";\n" +
"delay 1;\n" +
"select all; backbone off;\n" +
"select " + toFind + ";\n" +
"delay 1;\n" +
"select all; backbone; color backbone chain;\n";

	doMolViewSpt(she);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeContactsViewSpt(readradio, readchecks) // mcv
{
	if (readradio && contactsRadioViews)
	{
		var tren = getRadioValue(top.document.contactsForm.targetRendering);	
		var tcol = getRadioValue(top.document.contactsForm.targetColoring);	
		var cren = getRadioValue(top.document.contactsForm.contactsRendering);	
		var ccol = getRadioValue(top.document.contactsForm.contactsColoring);	

		if (tren == "tsf") targetSF = true; else targetSF = false;
		if (tcol == "tce") targetCPK = true; else targetCPK = false;
		if (cren == "csf") contactingSF = true; else contactingSF = false;
		if (ccol == "cce") contactingCPK = true; else contactingCPK = false;
	}
	// else use existing settings

	if (readchecks)
	{
		backboneContacts = top.document.contactsForm.contactsBackbones.checked;
		hydrogensContacts = top.document.contactsForm.contactsHydrogens.checked;
		labelContacts = top.document.contactsForm.labelContacts.checked;
		if (telAvivMode)
			colorContactsTargetGray = top.document.contactsForm.targetGray.checked;

		showContactsHBonds = top.document.contactsForm.contactsHBonds.checked;		
		showContactsMeMi = top.document.contactsForm.contactsMeMi.checked;		
		showContactsHphob = top.document.contactsForm.contactsHphob.checked;		
		showContactsSB = top.document.contactsForm.contactsSB.checked;		
		showContactsCatPi = top.document.contactsForm.contactsCatPi.checked;		

		showContactsWater = top.document.contactsForm.contactsWater.checked;		
		showWaterBridges = top.document.contactsForm.waterBridges.checked;		

//		if (!contactingSF) // checkbox does not exist when first adding sticks
		if (typeof(document.contactsForm.contactsSticks) != "undefined")
			showContactsSticks = top.document.contactsForm.contactsSticks.checked;
	}

	// HIDE ALL
	var ccv = "select all;\n" + clearSpt;

	// RENDER TARGET
	if (targetSF) // SPACEFILL
	{
		ccv += "select ~contarget;\n";

		if (hydrogensContacts)
			ccv +=
				"select selected or (hydrogen and within(1.1, selected));\n";

		ccv += "define ~targ_current selected;\n";
		ccv += "spacefill;\n";
	}
	else // BALL AND STICK
	{
		ccv += "select none;\n";

		if (showContactsHBonds)
			ccv += "select selected or ~targ_hbonds;\n";
		if (showContactsMeMi)
			ccv += "select selected or ~targ_memi;\n";
		if (showContactsWater)
			ccv += "select selected or ~targ_to_water;\n";
		if (showWaterBridges)
			ccv += "select selected or (~water_bridges and ~contarget);\n";
		if (showContactsHphob)
			ccv += "select selected or ~targ_hphob;\n";
		if (showContactsSB)
			ccv += "select selected or ~targ_sb;\n";
		if (showContactsCatPi)
			ccv += "select selected or ~targ_catpi;\n";
		ccv += "define ~targ_current selected;\n";

		ccv += "spacefill 0.6;\n";

		// show inside wireframe
		if (showContactsSticks)
			ccv += "select within(group, ~targ_current) and not hydrogen;\n";
		else
			ccv += "select ~targ_current;\n"; // for wireframe bondmode and

		if (hydrogensContacts) // hydrogens in wireframe only, and on balled only
			ccv += "select selected or (hydrogen and within(1.1, ~targ_current));\n";

		ccv += "wireframe 0.15;\n";
	}
	
	// COLOR TARGET
	ccv += "select ~contarget;\n";
	if (colorContactsTargetGray)
		ccv += "color [xa0a0a0];\n";
	else if (targetCPK)
		ccv += "color cpk;\n" + contargetDarkCPKSpt;
	else // chain + DRuMS ligand, solvent
	{
		ccv += "color chain;\n" +
		"select water; color [x" + colorSolvent + "];\n" +
		ligandSelectSpt + 
		"color [x" + colorLigand + "];\n";
	}

// =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =  =

	// SELECT CONTACTING
	ccv += "select none;\n";

	if (showContactsHBonds)
		ccv += "select selected or (~cont_hbonds and not water);\n";
	if (showContactsWater)
		ccv += "select selected or (~cont_hbonds and water);\n";
	if (showWaterBridges)
		ccv += "select selected or (~water_bridges and (water,~outside_contarget) and not hydrogen);\n";
	if (showContactsMeMi)
		ccv += "select selected or ~cont_memi;\n";
	if (showContactsHphob)
		ccv += "select selected or ~cont_hphob;\n";
	if (showContactsSB)
		ccv += "select selected or ~cont_sb;\n";
	if (showContactsCatPi)
		ccv += "select selected or ~cont_catpi;\n";
	ccv += "define ~cont_current selected;\n";

	// RENDER CONTACTING
	if (contactingSF) // SPACEFILL
	{
		if (hydrogensContacts)
			ccv += "select selected or (hydrogen and within(1.1, selected));\n";

		ccv += "spacefill;\n";
	}
	else // BALL AND STICK
	{
		ccv += "spacefill 0.45;\n"; // BALLS

		// STICKS
		if (showContactsSticks)
			ccv +=
				"select within(group, ~cont_current) and not hydrogen;\n" +
		// include ~targ_current to show covalent bonds between targ/conts
				"select selected or ~targ_current;\n";
		else
			ccv += "select ~cont_current;\n";

		if (hydrogensContacts) // put hydrogens only on balls! Not on all sticks.
			ccv += 
"select selected or (hydrogen and within(1.1, (~cont_current)));\n";

		ccv += "define ~cont_sticked selected;\n";

		ccv += 
			"set bondmode and;\n" +
			"wireframe 0.15;\n";

		// SS BONDS
		if (showContactsSticks)
			ccv +=
				"select ~cont_sticked or ~contarget;\n" +
				"ssbonds 0.15;\n" +
				"set ssbonds sidechain;\n";
	}

	// COLOR CONTACTING

	ccv += "select ~outside_contarget;\n";
	if (contactingCPK)
	{
		ccv += 
			"color cpk;\n" +
			contactingLightCPKSpt +
			"select ~outside_contarget and water;\n" +
			"color magenta;\n";
	}
	else
	{
		ccv +=
			"color chain;\n" +	
			"select ~outside_contarget and water;\n" +
			"color [x" + colorSolvent + "];\n" +
			ligandSelectSpt + 
			"select selected and ~outside_contarget;\n" +
			"color [x" + colorLigand + "];\n";
	}

	// CHAIN BACKBONES
	if (backboneContacts) ccv +=
		"select all; backbone;\n" +
		"color backbone chain;\n";

	// LABELS?
	if (labelContacts)
		ccv += labelContactsSpt;
	else
		ccv += "select all; labels off;\n";
	// Mark: Target * labels will be added in scriptToJmol()
	
	ccv += makeEchoSpt("");

	// selection for halos is handled in scriptToJmol()

	// Anything hidden after contacts are shown remains hidden.	
	// hiding done in doMolViewSpt().

	if (useConsurfColors)
		ccv += makeConsurfColorsSpt();

	return(ccv);
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeCatPiSBSpt(pollForm)
{
	if (pollForm)
	{
		var catpi = getRadioValue(top.document.catPiSBForm.catPiSB);	
		showCatPi = (catpi == "c");

		var coc = getRadioValue(top.document.catPiSBForm.colorCatPiSB);
		colorCatPiSBChain = (coc == "c");

		showCatPiSBBackbones = top.document.catPiSBForm.backbonesCatPiSB.checked;
	}

	css = "background white\n\
select all;\n" + clearSpt;

	if (showCatPiSBBackbones)
		css +=
"backbone;\n\
color backbone chain;\n";

	if (showCatPi)
		css +=
"select ~cont_catpi, ~targ_catpi;\n\
spacefill 0.6;\n\
select within(group, selected);\n\
wireframe 0.2;\n";

	else
		css +=
"select ~cont_sb, ~targ_sb;\n\
spacefill 0.6;\n\
select within(group, selected);\n\
wireframe 0.2;\n";

	if (colorCatPiSBChain)
	{
		css += "color atoms chain; background black;\n";
		setButtonState("up", backgroundIndex);
	}
	else
	{
		css += "color atoms cpk; background white;\n";
		setButtonState("down", backgroundIndex);
	}

	css += makeEchoPdbIdSpt("");

	if (useConsurfColors)
		css += makeConsurfColorsSpt();

	return css;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeSSBondsSpt(pollForm)
{
	if (pollForm)
	{
//		var catpi = getRadioValue(top.document.SSBondsForm.catPiSB);	
//		showCatPi = (catpi == "c");

		showSSBondsBackbones = top.document.SSBondsForm.backbonesSSBonds.checked;
		showSSBondsLabels = top.document.SSBondsForm.labelsSSBonds.checked;
		connectSSBondsBackbones = top.document.SSBondsForm.connectSSBondsBB.checked;
		hideCysNotSSBonded = top.document.SSBondsForm.hideCysNotSS.checked;
		colorSSBondsChain = top.document.SSBondsForm.colorSSChain.checked;
	}

	css = "background black\n\
select all;\n" + clearSpt;

	// SELECT NOT HIDDEN
"select not ~hidden_jdef;\n";

	// BACKBONES?
	if (showSSBondsBackbones)
		css +=
"backbone;\n\
color backbone chain;\n\
color backbone translucent 5;\n\
if (antialiasdisplay) {color backbone translucent 3};\n\
";

	// FAT SSBONDS
		css += // fatter than SSBondsBBSpt
"ssbonds 1.0;\n";

	// SELECT CYS.SG FOR COLORING
		css +=
"select cys.sg;\n\
color ssbonds none;\n";

	// COLOR SSBONDS BY CHAIN?
	// don't "color ssbonds" else they won't inherit atom (chain) colors
	if (colorSSBondsChain)
	{
		css +=
"color chain;\n";

	}
	else
	{
		css +=
"color [x" +	colorSSBonds + "];\n";

	}

	// DEFINE ~cystine
		css +=
"select cys.sg and connected(cys.sg);\n\
select within(group, selected);\n\
define ~cystine selected;\n\
";

	// SELECT CYS TO SHOW
		if (hideCysNotSSBonded)
			css +=
"select ~cystine;\n";
		else
			css +=
"select cys;\n";

		css +=
"select selected and not ~hidden_jdef;\n";

	// CONNECT SIDECHAINS? (SELECTION ABOVE!)
	if (!connectSSBondsBackbones)
	{
		// WIREFRAME NOT-HIDDEN CYS
		css +=
"set ssbonds sidechain;\n\
wireframe 0.3;\n\
ssbonds 1.0;\n\
";

	}
	else
	{
		// BALL NOT-HIDDEN NOT-SS-BONDED CYS.CA
		css +=
"set ssbonds backbone;\n\
select selected and *.ca and not ~cystine;\n\
spacefill 1.0;\n\
";


//		if (toFind == "")
//			toFind = "CYS.CA";
	}



	css += makeEchoPdbIdSpt("");

	if (useConsurfColors)
		css += makeConsurfColorsSpt();

//	alert("scripts.js #10:\n" + css)
// jmolGetPropertyAsArray() is not in Jmol 11.8.22.
// Jmol 12.0.RC4 fails in FGiJ, so I'm stuck for now.
// alert(jmolGetPropertyAsArray("boundboxInfo"))
// alert(jmolGetPropertyAsArray("bondInfo", "sulfur"))

	return css;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Must be separate from makeSSBondsSpt() b/c labels are a special case in
// in scriptToJmol() in top.js

function makeLabelSSBondsSpt()
{
	var css = "";

	if (!match(currentView, "makessbondsspt"))
		return "";
	
	// LABEL CYSTEINES?
	if (showSSBondsLabels) // assume checkbox has been polled
	{
		if (hideCysNotSSBonded)
			css +=
"select ~cystine;\n";
		else
			css +=
"select cys;\n";

		css +=
"select selected and *.ca and not ~hidden_jdef;\n";

		css +=
'label "Cys %r:%c";\n\
color none;\n\
';

	}

	return css;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Anomalous atoms are atoms that are not (protein,nucleic,hetero).
// These include some alpha carbons for "zombie residues".
// Patches elsewhere guarantee that alpha carbons show up in backbone
// traces. The following script is a more general solution.

function makeAnomalousAtomsSpt()
{
	var	aas = "select ~anomalous_atoms and model=1 and not ~hidden_jdef;\n";

	if (showAnomalous)
	{
		if (anomalousDots)
			aas += "dots;\n"; // don't turn spacefill off, e.g. from zombie CA's
		else
			aas += "dots; spacefill 1.0;\n";
	}
	else
		aas += "dots off;\n";

	return aas;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeMessageMarkSpt(mark)
{
	// jmol does not message back comments even with debugscript on

	var spt = "message " + mark + ";\n";

// for Jmol 10.3:
//		"set debugscript on;\n" +
//		"define " + mark + " none;\n" +
//		"set debugscript off;\n";

	return spt;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeGetPDBFileHeaderSpt()
{
	var ghs =
	makeMessageMarkSpt(messageMarkBeginHeader) + // for debugging only
	"show pdbheader;\n" + makeMessageMarkSpt(messageMarkEndHeader);

	return ghs;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeMarkContactsTargetSpt()
{
	var spt = "";

	if (!labelContacts) // MARK TARGETS WITH *
	{
//		alert("top.js scriptToJmol() 10:" +
//			"\n selectMode = " + selectMode +
//			"\n markContactsTargets = " + markContactsTargets +
//			"\n contactsShowing = " + contactsShowing);

		if (hiddenRangeStart == "") // else leave range start mark from makeHideSpt()
		{
			spt +=
				"select all;\n" +
				"labels off;\n" +
				"select none;\n"; // scriptToJmol()
		}

		if (selectMode != "" || (markContactsTargets && contactsShowing))
		{
			spt += "select ~targ_current;\n"; // in scriptToJmol()
			spt += makeMarkSelectedSpt("*");
		}
	}

	return spt;
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeMarkAnomalousAtomsSpt()
{
	var ics = "";

	var lbl = "?";
	if (labelsID)
		lbl += labelsIDSpt;

	ics +=
"select ~anomalous_atoms and not ~hidden_jdef;\n"
+ makeMarkSelectedSpt(lbl);

	return ics;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeMarkIncompleteSidechainsSpt()
{
	var ics = "";

	var lbl = "s-";
	if (labelsID)
		lbl += labelsIDSpt;

	ics +=
"select ~incomplete_sidechains and not ~hidden_jdef;\n"
+ makeMarkSelectedSpt(lbl);

	return ics;	
}
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
function makeDefineIncompleteSidechainsSpt()
{
// See sidechain_termini.xls excel spreadsheet

// This script assumes that incomplete residues nevertheless have
// alpha carbons or phosphorus atoms on which to hang the labels!

// The script below is ordered
// beta
// gamma
// delta
// epsilon
// zeta
// eta

	var dics =	

// AMINO ACIDS
"select ala and not within(group, ala.cb);\n\
\
select selected or (cys and not within(group, cys.sg));\n\
\
select selected or (ser and not within(group, ser.og));\n\
select selected or (pro and not within(group, pro.cg));\n\
\
select selected or (thr and not within(group, thr.og1));\n\
select selected or (thr and not within(group, thr.cg2));\n\
\
select selected or (val and not within(group, val.cg1));\n\
select selected or (val and not within(group, val.cg2));\n\
\
select selected or (ile and not within(group, ile.cg2));\n\
\
select selected or (asn and not within(group, asn.od1));\n\
select selected or (asn and not within(group, asn.nd2));\n\
\
select selected or (asp and not within(group, asp.od1));\n\
select selected or (asp and not within(group, asp.od2));\n\
\
select selected or (leu and not within(group, leu.cd1));\n\
select selected or (leu and not within(group, leu.cd2));\n\
\
select selected or (ile and not within(group, ile.cd1));\n\
\
select selected or (pro and not within(group, pro.cd));\n\
\
select selected or (gln and not within(group, gln.oe1));\n\
select selected or (gln and not within(group, gln.ne2));\n\
\
select selected or (glu and not within(group, glu.oe1));\n\
select selected or (glu and not within(group, glu.oe2));\n\
\
select selected or (his and not within(group, his.ce1));\n\
select selected or (his and not within(group, his.ne2));\n\
\
select selected or (met and not within(group, met.ce));\n\
\
select selected or (lys and not within(group, lys.nz));\n\
\
select selected or (phe and not within(group, phe.cz));\n\
\
select selected or (arg and not within(group, arg.nh1));\n\
select selected or (arg and not within(group, arg.nh2));\n\
\
select selected or (trp and not within(group, trp.ch2));\n\
\
select selected or (tyr and not within(group, tyr.oh));\n\
\
select selected and *.ca;\n\
define ~incomplete_aa_sidechains selected;\n\
";

// This is an alternative more compact scripting scheme (not used)
// select (cys,ser) and not within(group, (cys.?g, pro.?g));\n\
// select selected or ((thr,val) and not within(group, (thr.?g1,val.?g1)));\n\
// select selected or ((thr,val) and not within(group, (thr.?g2,val.?g2)));\n\

// NUCLEOTIDES
// This code does both RNA and DNA.
// For PDB 2.3 format, the methyl on thymidine was t.c5m.
// In PDB 3.x, it is t.c7. This was causing a spurious "S-" on DT.
// However, in 1EVV, 5MU (5 methyl uracil) may be identical to ribo-T.
// Anyway, Jmol 11.8.14 takes it to be (rna and t) but it has .c5m,
// so I kept that too to avoid incorrectly marking 5MU in 1EVV as S-.

	dics +=

"select a and not within(group, a.n6);\n\
select selected or (a and not within(group, a.n1));\n\
\
select selected or (c and not within(group, c.n4));\n\
select selected or (c and not within(group, c.o2));\n\
\
select selected or (g and not within(group, g.n2));\n\
select selected or (g and not within(group, g.o6));\n\
\
select selected or (t and not within(group, (t.c7, t.c5m)));\n\
select selected or (t and not within(group, t.o4));\n\
\
select selected or (u and not within(group, u.o2));\n\
select selected or (u and not within(group, u.o4));\n\
\
select selected and *.p;\n\
define ~incomplete_nuc_sidechains selected;\n\
";

	dics +=
"select ~incomplete_aa_sidechains or ~incomplete_nuc_sidechains;\n\
define ~incomplete_sidechains selected;\n\
";

	return dics;
}

//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

