<<

Generating Interactive Protein Structure Tutorial Using WebGL and HTML5 ______

______Elizabeth Montes April 25, 2014 CS 698 – Master’s Project in Computer Science California State University San Marcos (CSUSM)

Master’s Project Committee Members: Dr. Xiaoyu Zhang, CSUSM Department of Computer Science Dr. Ahmad Hadaegh, CSUSM Department of Computer Science Dr. Sajith Jayasinghe, CSUSM Department of Chemistry and Biochemistry

ii

DEDICATIONS I dedicate this project to the memory of my mother who has been an inspirational

human being and a great example of strength, courage, passion and love; to my father

who is a great example of hard work and loyalty to his family; and to my siblings who

are always there for me and who have become my strength in these past years; and to

my nieces and nephews who always fill me with joy.

iii ACKNOWLEDGEMENTS I would like to thank each and every committee member for their dedication of

time, advice, supervision, feedback and encouragement required for the completion of

this project. This project would not be possible if not were for their guidance,

encouragement and expertise.

iv

ABSTRACT

Proteins are large biological molecules of long polymers of amino acid residues, typically containing thousands of atoms and consisting of a uniform repetitive backbone and variable side chains attached to each residue. They fold into complex

3D structures to perform a vast array of functions within living organisms. In order to help students to better understand the protein structures, it is important that the student can visualize the details of 3D structures, and manipulate them interactively to focus on aspects of interest. Recent developments in web technologies such as WebGL and

HTML5, available in a wide range of browser on different platforms, made them the perfect choice to build cross-platform interactive tutorials for learning protein structures. This project, WebGL and HTML5 Interactive Protein Structure Tutorial

Generator (WHIPSTG: http://montes.co.nf/whipst.html), made it possible for biochemistry or biology professors to easily generate web tutorials that can facilitate students’ learning of protein structures. The generated tutorials allow the user to interact with protein visualization in 3D, answer true/false questions and multiple- choice questions, and read text. WHIPSTG uses GLmol – a 3D molecular viewer based on WebGL and JavaScript – to visualize and interactively manipulate the 3D protein. For the scope of this project, GLmol has been modified to include functionality for highlighting amino acids and highlighting a part of a protein sequence. I developed a web interface that provides the user with a short introduction about the project, the ability to easily generate an interactive tutorial and various examples of generated tutorials.

v

Table of Contents DEDICATIONS ...... iii ACKNOWLEDGEMENTS ...... iv ABSTRACT ...... v 1. INTRODUCTION...... 1 2. BACKGROUND ...... 3 2.1 WebGL ...... 3 2.2 HTML5 ...... 3 2.3 JavaScript ...... 4 2.3.1 Three.js ...... 4 2.3.2 jQuery ...... 4 2.3.3 jQuery UI ...... 5 2.4 Related Work ...... 6 3. DESIGN ...... 7 3.1 Web Interface Description ...... 7 3.2 Tutorial Description ...... 8 3.3 Web Interface View ...... 11 3.3.1 Web Interface Mapping Diagram ...... 11 3.3.2 Web Interface ...... 12 3.3.3 WHIPSTG Interaction with the User ...... 25 3.3.4 WHIPSTG Data Flow ...... 29 3.3.5 Widget Information ...... 31 3.4 Tutorial View ...... 36 3.4.1 Tutorial Mapping Diagram ...... 36 3.4.2 Tutorial Website Flow ...... 37 4. IMPLEMENTATION ...... 39 4.1 Web Interface Implementation ...... 39 4.2 Tutorial Implementation ...... 50 5. TEST CASES ...... 65 5.1 Test Case Create a WHIPSTG Tutorial ...... 65 5.2 Test Case GLmol Highlight Amino Acids PDB ID 2POR ...... 74 5.3 Test Case GLmol Highlight Sequence PDB ID 2POR ...... 79 5.4 Negative Test Case WHIPSTG Missing Information ...... 82 5.5 Negative Test Case GLmol Highlight Amino acids PDB ID 1111 ...... 85 6. CONCLUSION AND FUTURE WORK ...... 88 7. REFERENCES ...... 89 APPENDICES...... 92 1. whipst. ...... 92 2. file.html ...... 99 3. whipst.js ...... 103 4. GLmol.js ...... 118 5. widgetFunctionality.js ...... 131 vi

6. whipst. ...... 133 7. simple.css...... 141 8. left.css ...... 145 9. right.css ...... 151

vii

List of Figures Figure 1 Web Interface ...... 8 Figure 2 WHIPSTG Simple Layout ...... 9 Figure 3 WHIPSTG Left Layout ...... 10 Figure 4 WHIPSTG Right Layout ...... 11 Figure 5 WHIPSTG Web Interface Mapping Diagram ...... 12 Figure 6 Web Interface Welcome Tab ...... 13 Figure 7 WHIPSTG Tab ...... 14 Figure 8 Fill Out True False Question Widget ...... 16 Figure 9 Adding GLmol Widgets ...... 17 Figure 10 Title and Save File ...... 18 Figure 11 WHIPSTG Help Tab ...... 20 Figure 12 WHIPSTG Simple Tab ...... 21 Figure 13 WHIPSTG Left Tab ...... 22 Figure 14 WHIPSTG Right Tab ...... 23 Figure 15 WHIPSTG GLHAA Tab ...... 24 Figure 16 WHIPSTG GLHS Tab ...... 25 Figure 17 WHIPSTG Use Case Diagram ...... 29 Figure 18 WHIPSTG Data Flow Diagram...... 31 Figure 19 True False Question Widget ...... 32 Figure 20 Multiple Choice Question Widget ...... 33 Figure 21 GLmol Widget ...... 34 Figure 22 GLmol Highlight Amino Acids Widget ...... 35 Figure 23 GLmol Highlight Sequence Widget ...... 35 Figure 24 Text Widget ...... 36 Figure 25 WHIPSTG Tutorial Mapping Diagram ...... 37 Figure 26 ShortTutorial.html Website Uses Simple Template ...... 38 Figure 27 Test Case Create a Tutorial Welcome Tab ...... 66 Figure 28 Test Case Create a Tutorial WHIPSTG Tab ...... 67 Figure 29 Test Case Create a Tutorial Enter Title ...... 68 Figure 30 Test Case Create a Tutorial Enter Text ...... 69 Figure 31 Test Case Create a Tutorial False Question ...... 70 Figure 32 Test Case Create a Tutorial Multiple Choice Question ...... 71 Figure 33 Test Case Create a Tutorial GLmol Widgets ...... 72 Figure 34 Test Case Create a Tutorial Save File ...... 73 Figure 35 Test Case GLmol Highlight Amino Acids PDB ID 2POR Browser Display .... 74 Figure 36 Test Case GLmol Highlight Amino Acids PDB ID 2POR Highlight Valine .... 75 Figure 37 Test Case GLmol Highlight Amino Acids PDB ID 2POR Highlight E, L, and I ...... 76 Figure 38 Test Case GLmol Highlight Amino Acids PDB ID 2POR Rotate and Zoom .... 77 Figure 39 Test Case GLmol Highlight Amino Acids PDB ID 2POR Side Chains ...... 78 Figure 40 Test Case GLmol Highlight Amino Acids PDB ID 2POR Valine Side Chain .. 79 Figure 41 Test Case GLmol Highlight Sequence PDB ID 2POR Navigate Link ...... 80 Figure 42 Test Case GLmol Highlight Sequence PDB ID 2POR Highlight Sequence ...... 81 Figure 43 Test Case GLmol Highlight Sequence PDB ID 2POR Rotate ...... 82 Figure 44 Negative Test Case WHIPSTG Missing Widget Info all Widgets ...... 83

viii

Figure 45 Negative Test Case WHIPSTG Missing Widget Info Error Messages ...... 84 Figure 46 Negative Test Case WHIPSTG No Widgets Error Message ...... 85 Figure 47 Negative Test Case GLmol Highlight Amino Acids Save File ...... 86 Figure 48 Negative Test Case GLmol Highlight Amino Acids Widget Error Message .... 87

ix

1. INTRODUCTION

Biochemistry is the study of living organisms and of the molecular basis of the transformations that occur in living cells. It is an important field because it “…has become the foundation for understanding all biological processes. It has provided explanations for the causes of many diseases in humans, animals and plants [22].” Much of biochemistry deals with structures such as proteins. Proteins are large biological molecules of long polymers of amino acid residues, typically containing thousands of atoms and consisting of a uniform repetitive backbone and variable side chains attached to each residue. They fold into complex 3D structures to perform a vast array of functions within living organisms. In order to help students to better understand the protein structures, it is important that the student can visualize the details of 3D structures, and manipulate them interactively to focus on aspects of interest.

Bioinformatics is a scientific field that develops methods for storing, retrieving organizing and analyzing biological data. This field provides molecular graphic systems that are used for visualizing macromolecules, such as protein structures.

The purpose of this project, WebGL and HTML5 Interactive Protein Structure Tutorial

Generator or WHIPSTG, is to generate an interactive tutorial for learning protein structures. WHIPSTG provides an interactive web interface that allows the user to determine what contents will be on the interactive tutorial. The interactive tutorial, which is the output of this project, provides protein visualization using GLmol; a web based molecular graphic system. The WHIPSTG project utilizes GLmol (WebGL based), HTML5, Cascading Style

Sheets (CSS), jQuery UI and jQuery TE. The web interface contents are created using

HTML5 and styled using CSS. The drag and drop functionality is applied from jQuery UI, see Background below for more information. A text editor from jQuery TE is included as one of the widgets. The tutorial uses HTML5 and CSS for displaying contents on the web and JavaScript to load visualization capabilities from GLmol. The tabs to show the GLmol widgets are created using jQuery UI.

Before the creation of this project, Dr. Jayasinghe used a tutorial showing text and

Jmol 3D protein structure visualization. Jmol [9] is a molecular graphic system that requires the use of Java plugin and has several limitations. This tutorial was coded by hand, so their implementation required many hours. These features allow the improvement of the tutorial thereof. So, the project presented in this paper (WHIPSTG) provides a generator for creating an interactive tutorial that adds several features to the previous tutorial. These are the true or false questions and multiple choice questions. In addition, it also has the last tutorial functions: display text and include 3D protein visualization but instead of using Jmol uses GLmol to load the protein. Moreover, it uses WebGL and

HTML5 to load 3D protein visualization and eliminate the need of using plugins.

Therefore, WHIPSTG improves the previous tutorial by adding more features and eliminating the use of plugins.

The outline of the rest of the paper is detailed next:

 Chapter 2 describes background ideas used by WHIPSTG.

 Chapter 3 describes the design of WHIPSTG.

 Chapter 4 explains implementation of WHIPSTG in detail.

2

 Chapter 5 demonstrates the functionality of WHIPSTG by providing several

test cases.

 Chapter 6 concludes the report and discusses future work.

 The appendix section at the end contains the code of the contributions of this

project.

2. BACKGROUND There are five major technologies utilized in the WHIPSTG implementation, including WebGL, GLmol, HTML5, JavaScript and jQuery UI. At the end of this chapter, a description of related work is provided as well.

2.1 WebGL WebGL is a cross-platform, royalty-free web standard for a low-level 3D graphics

API based on OpenGL ES 2.0, exposed throughout the HTML5 as

Document Object Model Interfaces [19]. Semantically, WebGL is very similar to OpenGL

ES 2.0. The specification is very close to the OpenGL ES 2.0 specification, with some concessions made for what developers expect out of memory-managed languages such as

JavaScript. WebGL allows browsers to implement and run 3D content without the need of a plugin. WebGL Working Group vendors are major browsers vendors such as Apple

(), (Chrome), Mozilla (), and (Opera).

2.2 HTML5

HTML5 is a work in progress that will be the new standard for HTML in the near future. HTML5 is cooperation between the Consortium (W3C) and the

Web Hypertext Application Technology Working Group (WHATWG). WHATWG was

3 working with web forms and applications, and W3C was working with XHTML 2.0. In

2006, they decided to cooperate and create a new version of HTML [7].

Some rules of HTML5 were established: a) new features should be based on

HTML, CSS, DOM, and JavaScript, b) reduce the need for external plugins (like flash), ) better error handling, d) more markup to replace scripting, e) HTML5 should be device independent, f) the development process should be visible to the public [7].

Also, new features were included in HTML5: a) the element for 2D drawing, b) the

,
"; 313 str_footer += writeFooter(objects, nameTemplate); 314 str = str_header + str_tab_list + str_left + str_right + str_footer; 315 }else{ 316 simple_str += writeFooter(objects, nameTemplate); 317 str = simple_str; 318 }

48

Once that the “str” variable holds the final file contents, we check the flag that indicates there is no missing information. If everything is correct, we check if a title has been entered for the tutorial (line 321 below). If there is no title written by the user, we perform a call to downloadFile function(filename, str) (line 323 below). The first parameter is the name of the file to be downloaded and the second parameter is the “str” variable. On the other hand, if the user specifies a title name, we call the downloadFile function, but this time we enter titlePage+“.html” value to name the file for downloading purposes (line 327 below). For example, if the user enters “Short Tutorial” as the title, the file name is “ShortTutorial.html” instead of “file.html.”

If flag variable returns a false value, this means that there is missing information in some or all of the widgets. So, a message indicating there is missing information is displayed to the user via an alert box (line 331 below).

320 if(flag){ 321 if(titlePage.length == 0){ 322 $("#buttonMsg").html("Look for file in Downloads folder."); 323 downloadFile("file.html", str); 324 }else{ 325 titlePage = titlePage.replace(/\s/g, ''); //Remove space in file 326 $("#buttonMsg").html("Look for file in Downloads folder."); 327 downloadFile(titlePage+".html", str); 328 } 329 } 330 else { 331 alert("Please add items to the 'Add your items here' area \n or correct 'Required errors'"); 332 } 333 return flag;

Previously, we have described functions draggable, sortable, and save contained in this file. At the end of this file, there are eight writing functions: one for each of the six widgets, one for the header and one for the footer. Their functionalities are very similar

49 and there is no need to explain all of them. So, here we will explain how the writeTrueFalse function works.

The writeTrueFalse function defines a variable “str” (line 336 below) that is concatenated with values throughout the function (line 337 below). Then, the function returns the “str” variable containing the dynamic html code (line 347 below).

334 function writeTrueFalse(count){ 335 var number = parseInt(count); 336 var str = ''; 337 str += '\n'; 338 str += '\n'; 339 str += '\n'; 340 str += '\n'; 341 str += '

\n'; 342 str += '\n'; 343 str += '
NumQuestionYour answerResult/Explanation
1 ' + $("#tfq"+count).val() + '\n'; 344 str += 'True\n'; 345 str += 'False\n'; 346 str += '


\n'; 347 return str; 348 }

Thus, the basic functionality of the writing functions is to add html code to string variables, and then return those strings containing the html code that define the widget.

We have described the writeTrueFalse function above, and the remaining writing functions have its same functionality.

4.2 Tutorial Implementation

As Figure 15 shows, there are ten files in the tutorial implementation. There is the output file of WHIPSTG system, “file.html”. There are four CSS files “simple.css”,

“left.css”, “right.css” and “tabs.css”. There are five JavaScript files:

50

“widgetFuncionality.js”, “GLmol.js”, “Three49custom.js”, “jquery-1.7.min.js”, and

“jquery-ui-1.8.9.js". The jQuery and Three.js files are detailed in the Background chapter of this paper; the rest will be detailed next.

The “file.html” file (appendix 2) is the output of the WHIPSTG system. This file uses the simple template because it provides a link to CSS file “simple.css” (line 10 below).

The included file could be also, “left.css” which loads the left template and “right.css” which loads the right template. This will change according to the template selected by the user.

10

Some files are also included at the bottom of the page. The jQuery library is included and is used for selecting objects from the Document Object Model (DOM) (line 147 below). The Three.js library is included and is required so that GLmol can run properly

(line 148 below). The “GLmol.js” file is also included (line 149 below). Then, the

“widgetFunctionality.js” file is included and this is required so that the widgets can run properly (line 150 below). Last, the jQuery UI library is included and is required for the tabs in the left and right templates (line 151 below).

147 148 149 150 151

The code segment above contains html code that will always be generated and written to the file “file.html”. However, there are html code contents that define the widgets which

51 sometimes could be omitted and sometimes repeated. Next, we will explain what html code segment defines each widget.

The text widget contains a paragraph tag

which encloses the text that should be displayed on the page (line 18 below). The html code for a text widget looks like the code segment below.

18

Protein structure is the biomolecular structure of a protein molecule. Proteins are polymers 19 -specifically polypeptides - sequences formed from various L-α-amino acids. Each unit of a protein 20 is called an amino acid residue because it is the residue of every amino acid that forms the protein 21 by losing a water molecule. 22

The true false question widget comprises four input fields that are invisible which objective is to pass the information from the html file to the corresponding JavaScript file

(lines 23 – 26 below). Also, it encompasses a table for displaying the question (line 34 below), one radio button to select true (line 36 below), one radio button to select false

(line 37 below), and a result or explanation message (line 39 below). The two input radio buttons call the function isTrueFalse when the onchange event is triggered.

23 24 25 26 27

28 29 30 31 32 33 34 35 39 40 41
NumQuestionYour answerResult/Explanation
1 The basic monomers of proteins are amino acids. 36 True 37 False

52

38



The multiple choice question widget comprises eight input text fields that are invisible but needed to pass information from the html page to the JavaScript file (lines 42 – 50 below). There are four input radio buttons one in each row of the table. They call the function multipleChoice to check the correctness of the answer when the onchange event is triggered (line 58, 62, 66 and 68). There is an explanation message that is displayed when the user answers the question and shows a message according to the user’s answer

(line 59, 63, 67 and 69).

42 43 44 45 46 47 48 49 50 51

52 53 54 55 56 57 58 59 60 61 62 63 64

53

65

66 67 68 69 70 71
How many different amino acids are used in making proteins??
AnswerExplanation
A12
B 32
C 20
D 22

The GLmol widget comprises the following html code. There are divs and spans with assigned ids that define a place in the document where the object will be placed. The ids are used by JavaScript to create the content dynamically.

The id of several divs and their reason to be in the code segment are listed next:

 glmol5 - unique id for the GLmol object (line 72 below),

 glmol5_src - holds the source from the PDB file (line 73 below),

 glmol5_infobox - defines the about tab info (line 74 below),

 glmol5_inInfoBox - holds the information of the about tab (line 76 below),

 glmol5_srcbox – defines the load tab (line 78 below),

 glmol5_srccontents - hold the contents of the load tab (line 80 below).

 glmol5_viewbox – defines the view tab (line 82 below)

 glmol5_viewcontents – holds the contents of the view tab (line 84 below)

 glmol5_options – shows the options rotate, translate, zoom, slab, and reset (line

86 below)

 glmol5_loading – shows the loading message (line 87 below)

 glmol5_pdbTitle – shows the title of the loaded molecule (line 88 below).

72

73
74
75 About 76 77

54

78

79 Load 80 81
82
83 View 84 85
86
87
88
89
90

Similarly, the GLmol highlighting amino acids widget also contains divs with assigned ids. The ids for this widget and their reason for their definition are listed next:

 glmol6 – unique id of the GLmol object (line 92 below),

 glmol6_src – holds the source of the PDB file (line 93 below),

 glmol6_options – shows rotate, translate, zoom and slab (line 118 below),

 glmol6_loading – shows the loading message (line 119 below), and

 glmol6_pdbTitle – shows the title of loaded molecule (line 120 below).

For the highlighting abilities to be included twenty checkboxes are placed in the widget to select the amino acids (lines 95 – 114 below). There is also an html div that has a checkbox to select if the user wants to show the side chains of the protein sequence or not (line 116 below). Also, there is a highlight button that will send the request for highlighting (line 117 below).

92

93
94
95 A
96 R
113 Y

55

114 V
115

116
Side chains
117 118
.
119
120
.
121
122

Similarly, the GLmol highlighting sequence has divs and spans as the previous GLmol widgets. The id names followed for their reason to be in the html code are listed next:

 glmol10 – unique id of GLmol widget (line 124 below),

 glmol10_src – holds the source of PDB file (line 125 below),

 glmol10_highlight – turns on or off highlighting (line 126 below),

 glmol10_hgcolor – color for highlighting (line 128 below),

 glmol10_seqHigh – holds the sequence of loaded molecule (line 134 below),

 glmol10_options – shows rotate, translate, zoom and slab (line 137 below),

 glmol10_loading – shows the loading message (line 138 below),

 glmol10_pdbTitle - shows the title of loaded molecule (line 139 below).

This widget is composed of a select menu with four colors that the user can choose from to highlight the sequence (line 128 below). Also, a text area contains the protein sequence for selection (line 134 below). Likewise, a button to highlight the sequence is defined (line 136 below).

124

125
126
ON-OFF 127 Highlight color 128 134 135
136 137
.
138
139
.
140
141

Previously, we have defined the html code that defines the widgets. Now, we will explain the JavaScript code needed to define the GLmol widgets. First, we take the id for the GLmol widget, which is the first id of each code segment. For this example, we will use the id “glmol5.” First, we define a variable “strId” and assign the id value to the variable (line 153 below). Then, we declare a new GLmol object by passing the parameters strId and true (line 154 below). Then, we call the download function by passing the parameters pdb id of the protein and the GLmol object created previously (line

155 and 156).

153 var strId = "glmol5"; 154 var glmol5 = new GLmol(strId, true); var query = window.location.search.substring(1); 155 if (query == '') download('pdb:2POR',glmol5); 156 else download(query, glmol5);

When we are defining the GLmol widget with tabs, we call the addGLmolObject function and we passed the GLmol object on line 154 as a parameter (line 157 below). The addGLmolObject function defines everything needed for showing the tabs with dynamic html.

157 addGLmolObject(glmol5);

57

Similarly, for the GLmol highlighting widgets, we assign the definition of the defineRepCheckHighlight function to the defineRepresentation function (line 162 below).

The defineRepresentation function calls the functions for coloring and drawing the atoms contained in the atom list array. The defineRepCheckHighlight function contains the same functions as defineRepresentation. However, it adds extra calls to highlighting functions before drawing the atoms.

162 glmol6.defineRepresentation = glmol6.defineRepCheckHighlight;

The style of the three templates is defined by cascading style sheets. In style sheets, we assign CSS properties to html tags such as p, h3, body and header, etc. As mentioned before, there are three templates defined by style sheets in this project which are explained next.

The “simple.css” file (appendix 7) shows a style sheet for the simple template. This template includes values in style such as color, background, width, height and position.

Similarly, the “left.css” file (appendix 8) shows a style sheet for the left template.

Using this style sheet, the tutorial displays tabs on the left side that include GLmol widgets. On the right side, the true false question, multiple choice question and text are displayed in the order they are in the middle area in WHIPSTG tab. The right side is scrollable if needed.

On the other hand, the “right.css” file (appendix 9) shows a style sheet for the right template. Using this style sheet, the tutorial displays tabs on the right side that include

GLmol widgets. On the left side, the true false question, multiple choice question and text are displayed in the order they are in the middle area in WHIPSTG tab. The left side is scrollable if needed.

58

We have described the html file, and now we will describe the required functions in

“widgetFunctionality.js” file. This file is responsible for functions that add interactivity to the tutorial.

The function isTrueFalse checks whether the selected response is right or wrong each time the radio buttons are changed (line 79 below). If the response is right, a message displaying a check mark and the word “Correct” is shown in the corresponding cell in the table (line 80 below). If the response is wrong, an x mark and the word “Incorrect” is shown in the corresponding cell in the table (line 83 below).

73 function isTrueFalse(name, count){ 74 var value = $("#correctValue"+count).val(); 75 var msgId = $("#answerid"+count).val(); 76 var msg1 = $("#msg1"+count).val(); 77 var msg2 = $("#msg2"+count).val(); 78 if(value == "True") { value = "true"; } if(value == "False") { value = "false"; } 79 if(value == name.value){ 80 $("#" + msgId).html(" Correct. " + msg1); 81 } 82 else{ 83 $("#" + msgId).html(" Incorrect. " + msg2); 84 } 85 }

Similarly, the multipleChoice function checks if the selected input is the right answer for the four options A, B, C or D. For example, if the correct answer is A, then an explanation is displayed in the corresponding cell in the table (line 91 below). For example, if option B is incorrect, and explanation indicating so is displayed in the corresponding cell in the table (line 106 below).

87 function multipleChoice(name, count){ 88 var value = $("#cValue").val(); 89 if(name.id == value){ 90 if( name.id == "A" ) 91 {$("#displayMsg1"+count).html("" + $("#fcExplanation").val()); } 59

92 else if( name.id == "B" ) 93 { $("#displayMsg2"+count).html("" + $("#scExplanation").val());} 94 else if( name.id == "C" ) 95 { $("#displayMsg3"+count).html("" + $("#tcExplanation").val()); } 96 else if ( name.id == "D" ) 97 {$("#displayMsg4"+count).html("" + $("#fourExplanation").val());} 98 var names = document.getElementsByName(name.name); 99 for(var i = 0; i < names.length; ++i) 100 names[i].disabled=true; 101 } 102 else{ 103 if( name.id == "A" ) 104 { $("#displayMsg1"+count).html("" + $("#fcExplanation").val());} 105 else if( name.id == "B" ) 106 { $("#displayMsg2"+count).html("" + $("#scExplanation").val()); } 107 else if( name.id == "C" ) 108 { $("#displayMsg3"+count).html("" + $("#tcExplanation").val());} 109 else if( name.id == "D" ) 110 { $("#displayMsg4"+count).html("" + $("#fourExplanation").val()); } 111 } 112 }

The “GLmol.js” file has been modified for its use in this project (appendix 4). The modifications performed allow the highlighting of amino acids, and the highlighting of a part of the protein sequence.

The highlightAminoacid function loops through an array containing the twenty amino acid names as three letter codes (line 1987 below). Then, it checks if the checkbox corresponding to each amino acid is selected (see line 1989). Every time a checkbox is selected, the function loops through all atoms in the protein and searches for the selected amino acid (line 1995 below). If the atom is found in the atom list, the atom color is assigned the value for the amino acid stored in the array this.aminoColors (line 1996 below). Also, the background for the checkbox is colored with the same color the atom is highlighted (line 1997 below). If nothing is selected, no changes are performed. If a

60 previously checked checkbox has been unchecked, the current checkbox background color is cleared (line 2000 below).

1984 GLmol.prototype.highlightAminoacids = function(all){ 1985 var idHeader = "#" + this.id + "_"; 1986 var name=""; 1987 for( var i in this.aminoNames ){ 1988 name = this.aminoNames[i]; 1989 if( $(idHeader + name).attr('checked') ) { 1990 var atomlist = all; 1991 for(var i in atomlist) { 1992 var atom = this.atoms[atomlist[i]]; 1993 if (atom == undefined) continue; 1994 if (atom.hetflag) continue; 1995 if($(idHeader + name).val() == atom.resn) { 1996 atom.color = this.aminoColor[atom.resn]; 1997 $(idHeader + name + "_bc").css("background-color", this.aminoColors[atom.resn]); 1998 } 1999 } 2000 } else{ $(idHeader + name + "_bc").css("background-color", "transparent"); } 2001 } 2002 };

The highlightSequenceOLC function highlights a part of the sequence that the user selects (line 1944 below). The protein sequence value is obtained from the text area with id “this.id + ‘_seqHigh’” using jQuery id selector “#” and is stored in a variable “element”

(line 1945 below). Then, we check if the sequence is empty or not. If it is not empty, we call the function getResiFromSequence and assign its returned value to a variable resiNo

(line 1948 below). The variable resiNo should contain an array of residue numbers of the atoms that have been selected from the sequence. So, we loop through the resiNo array and call the function getSerialByResi to get the serial number of each residue number and store it into a passed by reference array named seriales (line 1951 below). The function returns an array "seriales" that holds the serial numbers of the atoms selected from the sequence (line 1954 below).

1944 GLmol.prototype.highlightSequenceOLC = function(color){

61

1945 var element = $('#' + this.id + '_seqHigh'); 1946 if(element.length) { 1947 var seriales = []; 1948 var resiNo = this.getResiFromSequence(element[0]); 1949 1950 for(var k in resiNo){ 1951 this.getSerialByResi(seriales, k, resiNo[k],color); 1952 } 1953 } 1954 return seriales; 1955 };

We will describe the getResiFromSequence function next. The function fills the resi_numbers array by pushing the contents of a function findResiSequenceNumbers into it (see line 1903 below). The resi_numbers array contains a map of the chain and the resi number, for example chain A is mapped with resi number 1. The function creates a variable k which purpose is to iterate through every amino acid in the sequence (line 1905 below). The function loops through this two-dimensional array (lines 1906 and 1907 below) and also increments k in each iteration (line 1917 below). Now, we have a mapping in such way that we have k, chain and resi number. For example, in iteration 0 we will have 0, chain A, and resi number 1 in a map representation. This means the first value, 0, is the serial number of the current atom in chain A with resi number 1. So, k also serves for checking the start position and the end position of the sequence selection. We check if k is in the selection interval and if it is we assign the current chain and the current resi number to an array resi_map (line 1912 and 1915). This array maps the resi numbers with the chains of the amino acids that are selected from the sequence. For example, if an atom in chain B with resi number 20 is selected, the array will contain entry {B: 20}. The function returns the resi_map array (line 1921).

1893 GLmol.prototype.getResiFromSequence = function(element){ 1894 if(element.selectionStart != undefined){ //works on chrome and mozilla 1895 var startPos = element.selectionStart;

62

1896 var endPos = element.selectionEnd; 1897 var selText = element.value.substring(startPos, endPos); 1898 1899 var resiNumbers = {}; 1900 var resi_map = {}; 1901 1902 var resi_numbers = new Array(); 1903 resi_numbers.push(this.findResiSequenceNumbers()); 1904 1905 var k = 0; //k iterates through every amino acid in sequence 1906 for(var i in resi_numbers[0]){ 1907 for(var j in resi_numbers[0][i]){ 1908 var current_resi = j; 1909 var current_chain = resi_numbers[0][i][j]; 1910 1911 if(k == startPos && (selText.length == 1)){ 1912 resi_map[current_resi] = current_chain; 1913 } 1914 if(k >= startPos && k < endPos){ 1915 resi_map[current_resi] = current_chain; 1916 } 1917 ++k; 1918 } 1919 } 1920 } 1921 return resi_map; 1922 };

The function findResiSequenceNumbers calls the mapChainSize function that returns a map of the chain and the chain size of every atom in the protein sequence and stores them in variable seqChain, i.e. { A : 94 } (line 1870 below). The size of the chain is the number of amino acids that a chain contains; this is not the total number of amino acids.

The function iterates through seqChain, and inside the loop we assign the current chain size into a variable l (line 1879 below). We loop from 0 to l to map resi numbers to the current chain and store them in an array named numbers (line 1881 below). Outside of the loop, we push the numbers array into array resi_numbers (line 1883). Finally, the function returns the resi_numbers array that holds the residue numbers of the protein sequence (line

1886).

63

1868 GLmol.prototype.findResiSequenceNumbers = function(){ 1869 var seq_length = this.protein.sequence.length; 1870 var seqChain = this.mapChainSize(); 1871 var resi_numbers = []; 1872 var numbers = {}; 1873 for(var i in seqChain){ 1874 var current_chain = i; 1875 var current_chain_size = seqChain[i]; 1876 1877 //get the new length and assign it to seq_length 1878 var new_length = seq_length - current_chain_size; 1879 var l = seq_length - new_length; 1880 for(var j = 0; j < l; ++j){ 1881 numbers[j+1] = current_chain; 1882 } 1883 resi_numbers.push(numbers); 1884 numbers = {}; 1885 } 1886 return resi_numbers; 1887 };

Next we will describe the getSerialByResi function (line 1928 below). The function loops through all the atoms in the protein, and checks to see if each atom’s chain and atom’s residue number is equal to the values passed by value resiNum and chain_value (line 1932). If they are equal, the atom color is assigned the value of the passed by value variable color (line 1933). Also, the atom serial number is pushed into the seriales array which is passed by reference (line 1934 below). Since the seriales array is passed by reference, the function does not return a value.

1928 GLmol.prototype.getSerialByResi = function(seriales, resiNum, chain_value, color){ 1929 for(var i in this.atoms){ 1930 if (this.atoms[i] == undefined) continue; 1931 if (this.atoms[i].hetflag) continue; 1932 if(this.atoms[i].chain == chain_value && this.atoms[i].resi == resiNum){ 1933 this.atoms[i].color = color; 1934 seriales.push(this.atoms[i].serial); 1935 } 1936 } 1937 };

64

This chapter covered the Implementation. The next chapter will provide several test cases to test the functionality of WHIPSTG and contributions made to GLmol.

5. TEST CASES This chapter provides various WHIPSTG and GLmol test cases to demonstrate how they work. For GLmol, the test case will show the modifications made to GLmol mentioned previously on this paper. The first section of this chapter will explain how to create a WHIPSTG tutorial.

5.1 Test Case Create a WHIPSTG Tutorial This test case demonstrates the steps required to create a tutorial including the six widgets at least once using the simple template.

Step 1: Navigate browser to WHIPSTG site. (http://montes.co.nf/whipst.html)

65

Figure 27 Test Case Create a Tutorial Welcome Tab

Step 1 Confirmation: Browser should display the Welcome tab similar to Figure 27 above.

Step 2: Click on WHIPSTG tab in browser.

66

Figure 28 Test Case Create a Tutorial WHIPSTG Tab Step 2 Confirmation: Browser should display the WHIPSTG tab similar to Figure 28. By looking at Figure 28 or at the browser, one can easily identify the left area, middle area, the top right area and the top bottom area. The left area contains the six widgets, the middle area accepts an optional tutorial title, the top right area has a trash container and the template selection, and finally the top bottom area has a reset button and a save file button.

Step 3: Enter “Simple Tutorial” as the title in the middle area.

67

Figure 29 Test Case Create a Tutorial Enter Title

Step 3 Confirmation: The WHIPSTG tab in the browser should look like Figure 29.

Step 4: Drag a Text widget into middle area, and enter the information below:

Protein structure is the biomolecular structure of a protein molecule. Proteins are polymers -specifically polypeptides - sequences formed from various L-α-amino acids. Each unit of a protein is called an amino acid residue because it is the residue of every amino acid that forms the protein by losing a water molecule.

68

Figure 30 Test Case Create a Tutorial Enter Text Step 4 Confirmation: The WHIPSTG tab in the browser should look like Figure 30.

Step 5: Drag a True False Question widget into the middle area.

 Question: The basic monomers of proteins are amino acids.  Correct Answer: Select true  Explanation Correct: Great! Keep up the good work!  Explanation Incorrect: That’s not right! Keep on studying!

69

Figure 31 Test Case Create a Tutorial False Question

Step 5 Confirmation: The WHIPSTG tab in browser should look like Figure 31.

Step 6: Drag a Multiple Choice Question widget into the middle area. Enter the required information, for example:  Question: How many different amino acids are used in making proteins?  A: 12  Explanation: Incorrect. 12 is too low.  B: 32  Explanation: Incorrect. 32 is too high.  C: 20  Explanation: Great job!  D: 22  Explanation: Incorrect. 22 is close but not right.  Correct Value: Select C from the select menu.

70

Figure 32 Test Case Create a Tutorial Multiple Choice Question Step 6 Confirmation: The WHIPSTG tab should look like Figure 32 in the browser.

Step 7: Drag a GLmol widget into the middle area. Enter PDB Id “2POR.”

Step 8: Drag a GLmol Highlighting Amino Acids widget into the middle area. Enter PDB Id “2POS.”

Step 9: Drag a GLmol Highlight Sequence widget into the middle area. Enter PDB Id “2DHB.”

71

Figure 33 Test Case Create a Tutorial GLmol Widgets Step 7, 8 and 9 Confirmation: The WHIPSTG tab should look like Figure 33 in the browser.

Step 10: Select the simple template from the Template section in the top right area of the screen.

Step 11: Click on save file to save the tutorial in your computer.

72

Figure 34 Test Case Create a Tutorial Save File

Step 10 and 11 Confirmation: The WHIPSTG tab should look like Figure 34. The tutorial has been saved as SimpleTutorial.html in the Downloads folder. Navigate in a web browser to http://montes.co.nf/whipst.html and click on the Simple tab to interact with this tutorial using the simple template.

Step 12: Go back to Step 10 and select the left template instead. Then, click on save file. You will see a screen similar to Figure 34 in your browser, but now the file should be saved as LeftTutorial.html. Navigate to http://montes.co.nf/whipst.html and click on the Left tab to interact with this tutorial using the left template.

Step 13: Go back to Step 10 and select the left template instead. Then, click on save file. You will see a screen similar to Figure 34 in your browser, but now the file should be saved as RightTutorial.html. Navigate to http://montes.co.nf/whipst.html and click on the Right tab to interact with this tutorial using the right template.

73

5.2 Test Case GLmol Highlight Amino Acids PDB ID 2POR This test case will demonstrate the highlighting amino acids functionality added to

GLmol. The webpage shown in Figure 35 was generated using WHIPSTG with a simple tab.

Step 1: Navigate to http://montes.co.nf/testcase/GLHAA.html

Figure 35 Test Case GLmol Highlight Amino Acids PDB ID 2POR Browser Display

Step 1 Confirmation: Figure 35 shows that the web page contains a 3D visualization for protein structure 2POR. The widget has an html div on the left that contains:  a box with the twenty amino acids represented by their one letter code,  a checkbox that serves to check the amino acid and to display the highlighting color of the amino acid, and  a button to highlight the checked amino acids. The widget also contains another html div on the bottom right corner that has a group of four radio buttons and a button:  rotate radio button turns on rotation capabilities started by clicking and performed by moving the mouse,  translate radio button turns on translation capabilities performed by clicking and dragging the visualization up, down, left or right,  zoom turns on zoom capabilities,  slab, and the  reset view button resets the view of the 3D visualization.

Step 2: Check the Valine (V) amino acid, and click on the button “Highlight.”

74

Figure 36 Test Case GLmol Highlight Amino Acids PDB ID 2POR Highlight Valine

Step 2 Confirmation: The result should look like Figure 36. When an amino acid is checked and Highlight button is clicked, the amino acid is highlighted in the protein visualization showing its locations in the structure. Also, the checkbox is highlighted with the same color to indicate what color corresponds to each amino acid.

Step 3: The user can check more than one amino acid. Select E, L and I amino acids and click on Highlight.

75

Figure 37 Test Case GLmol Highlight Amino Acids PDB ID 2POR Highlight E, L, and I Step 3 Confirmation: The result of Step 3 should look like Figure 37. The four amino acids are highlighted. However the protein orientation can block the view of some amino acids. For this, we can perform rotation and translation to make them viewable. We will do this in the next step.

Step 4: Rotate by clicking down in the protein and moving the mouse down and a little to the right. Also, zoom in using the mouse.

76

Figure 38 Test Case GLmol Highlight Amino Acids PDB ID 2POR Rotate and Zoom Step 4 Confirmation: The result should look like Figure 38. The four amino acids are easily identified and their positions in the structure chain are recognized.

Step 5: Click on the reset view button at the bottom right. Also, click on the Side chains checkbox at the bottom left and then click on Highlight.

77

Figure 39 Test Case GLmol Highlight Amino Acids PDB ID 2POR Side Chains

Step 9 Confirmation: The result should look like Figure 39. The side chains of the protein are shown.

Step 10: Zoom in to see the direction of Valine side chain.

78

Figure 40 Test Case GLmol Highlight Amino Acids PDB ID 2POR Valine Side Chain

Step 10 Confirmation: The result should look like Figure 40. The side chain pointing up out of Valine is visible.

5.3 Test Case GLmol Highlight Sequence PDB ID 2POR This test case will demonstrate the highlighting sequence functionality added to

GLmol. WHIPSTG will be used for creating the tutorial that will contain the visualization of protein 2POR in this case.

Step 1: Navigate to http://montes.co.nf/testcase//GLHS.html

79

Figure 41 Test Case GLmol Highlight Sequence PDB ID 2POR Navigate Link Step 1 Confirmation: The browser should display protein structure 2POR similar to Figure 41. The GLmol Highlight Sequence widget contains an html div on the top of the widget and has:  a checkbox that turns ON and OFF the highlighting sequence functionality,  a select menu that selects the color of the highlighted sequence, and a  button that calls a function to select the sequence. It has another html div on the bottom right of the widget described in the previous section on Step 1 Confirmation.

Step 2: Check the ON/OFF checkbox to turn ON highlighting the sequence functionality. Then select the first line of the sequence: EVKLSGDARMGVMYNG DDWNFSSRSRVLFTMSGTTDSGLEFGASFKAHESVGAETGEDGTVFLSGAFGKI. After making the selection, click on select sequence.

80

Figure 42 Test Case GLmol Highlight Sequence PDB ID 2POR Highlight Sequence Step 6 Confirmation: The widget should look like Figure 42 above. The widget displays all the atoms that have been selected from the sequence in their specific location. The default color is white, but there are more options in the color menu. The color options are white, yellow, red and lime green.

Step 7: Select the lime green color by selecting it from the color menu. Click on select sequence.

Step 8: Rotate the highlighted sequence by clicking anywhere in the widget and moving the mouse right or left to explore the part of the sequence.

81

Figure 43 Test Case GLmol Highlight Sequence PDB ID 2POR Rotate Step 8 Confirmation: Figure 43 shows a possible view of the structure once it is rotated. 5.4 Negative Test Case WHIPSTG Missing Information This test case will demonstrate how WHIPSTG behaves when the user interacts with

WHIPSTG tab. In particular, this test case will cover what happens when the user drags widgets into the middle are and attempts to save the tutorial. Also, it will cover what happens when there are no widgets in the middle area and the user attempts to save the tutorial.

Step 1: Perform Step 1 and Step 2 in Section 5.1.

Step 2: Drag a true false question widget, drag a multiple choice question widget, drag a GLmol widget, drag a GLmol highlight amino acids widget, and drag a GLmol highlight sequence widget into the middle area.

82

Figure 44 Negative Test Case WHIPSTG Missing Widget Info all Widgets Step 2 Confirmation: The browser should look like Figure 44. The middle area has to contain one instance of every widget, a total of six widgets.

Step 3: Click on Save File.

83

Figure 45 Negative Test Case WHIPSTG Missing Widget Info Error Messages Step 3 Confirmation: Figure 45 above shows that instead of saving the file to the computer, a pop up alert appears along with red text next to the input fields. The pop up alert says: “Please add items to the ‘Add your items here’ area or correct ‘Required’ errors.” In this case, it means to fix the “Required” errors before saving. The “Required” errors are displayed next to the input fields of every widget. The user has to fill out the information to fix the errors.

Step 4: Click on the reset button to delete all the six widgets added previously. Step 5: Click on Save File.

84

Figure 46 Negative Test Case WHIPSTG No Widgets Error Message Step 4 and 5 Confirmation: The browser should look like Figure 46 above. The file did not save because there are no items in the middle area. Instead a pop up alert showed up with a message: “Please add items to the ‘Add your items here’ area or correct ‘Required’ errors.” In this case, it appeared because there are no items in the middle area.

5.5 Negative Test Case GLmol Highlight Amino acids PDB ID 1111 This test case will demonstrate how WHIPSTG behaves when entering an invalid PDB

Id in the GLmol Highlight Amino Acids widget in the WHIPSTG Tab, and how GLmol handles that invalid PDB id.

Step 1: Perform Step 1 and Step 2 in Section 5.1.

Step 2: Drag a GLmol Highlight Amino Acids widget and enter PDB Id ‘1111’ into PDBID input field. 85

Step 3: Click on save file to save a tutorial with a GLmol Highlight Amino Acids widget with protein 1111.

Figure 47 Negative Test Case GLmol Highlight Amino Acids Save File Step 2 and 3: The browser should look like Figure 47. In this figure, we can see that WHIPSTG saved a file even though “1111” is invalid.

Step 4: Open file.html to see how GLmol processed the invalid input.

86

Figure 48 Negative Test Case GLmol Highlight Amino Acids Widget Error Message

Step 4 Confirmation: The GLmol Highlighting Amino Acids Widget should look like Figure 48. GLmol does not recognize the PDB Id ‘1111’. So, it displays a message saying: Loading structure from server… It may take a while. If you believe something went wrong, please make sure PDB ID is correct. Please also make sure that WebGL is enabled in your browser.  : sorry. IE doesn’t support WebGL.  Firefox (version 4 or later): try force enable WebGL.  Chrome: try force enable WebGL.  Safari: have to enable WebGL manually.

The message is very self-explanatory. If this is the first time someone is running WebGL in her browser, she might be tempted to force enable WebGL in her browser. On the other hand, if she already knows that her browser runs WebGL, she might want to check that the PDB ID is correct. This demonstrates how GLmol behaves when handling invalid data. Since it is a GLmol feature, the same behavior applies when using the other two GLmol widgets.

87

6. CONCLUSION AND FUTURE WORK

This project has successfully achieved to create a teaching tool to generate an interactive website tutorial that will help in teaching and learning about protein structures.

The generator tool reduces the time to create an interactive website so that biology or biochemistry professors teach lessons about protein structures. The tutorial interactivity will help students be more engaged and more experimental in learning about proteins.

Even though the website interface provides good functionality and examples, there are several aspects in which it could be improved.

One feature that can be supported in the future is drag and drop capabilities in a touch device. The library used for this purpose, jQuery UI, responds to mouse events. Thus, it limits the drag and drop functionality to only desktops or laptops. There is a plug-in,

Touch Punch, that translates mouse events into touch events but it is not very effective. On the other hand, “The jQuery Foundation” are working on resolving this issue and they plan to add this functionality at the end of 2014. This feature can be taken into account only if the generator tool might want to be used in mobile devices.

Another possible feature that may be added is responsive . Responsive web design aims to provide an optimal view experience across many devices. A website that implements this design applies several rules according to the screen resolution of the website to target more devices. For example, with a responsive design a webpage applies different CSS style sheets according to the screen size during the event of resizing the window.

Another improvement is to make the tutorial more interactive so that the students have a greater experience while learning. The true false question and the multiple-choice

88 widgets have a low level of interactivity that could be improved significantly. For the scope of this project, our main goal was to create a web interface that generated a tutorial website that students could use. For this reason, interactivity has been kept at a basic level for the tutorial.

Subsequently, it would be useful that the generated tutorial could be sent to the user’s e-mail address instead of saving the file to the computer. This could come in handy if students are assigned to create a tutorial in class using the school’s computers and they would like a copy of their tutorial. They could access the tutorial from their personal computer, tablet or mobile device at home.

Also, the text widget uses a jQuery TE text editor. The textarea in this widget exceeds the height of the text widget if the user enters a long text. This problem could be possibly resolved by making the text area scrollable or making the widgtes resizable.

Lastly, other widgets could be added to integrate other types of questions into the tutorial website. HTML5 provides drag and drop capabilities. So, it would be useful to integrate a type of question to match a concept with its definition by dragging and dropping.

7. REFERENCES 1. " Studio 3." Aptana. http://aptana.com/products/studio3 (accessed October 10, 2013). 2. "Best Screen Size & Screen Resolution to Design Websites | Is There A Standard Size? What Is The Most Common Dimension?." Hobo. http://www.hobo- web.co.uk/best-screen-size/ (accessed April 13, 2014). 3. Castaño-Muñoz, Jonatan, Josep M. Duart, and Teresa Sancho-Vinuesa. "The Internet in face-to-face higher education: Can interactive learning improve academic achievement?." British Journal of Educational Technology 45, no. 1 (2014): 149-159. 4. "CSS Tutorial." CSS Tutorial. http://www.w3schools.com/css/default.asp (accessed October 10, 2013). 5. "Documentation." Welcome to the Worldwide Protein Data Bank.

89

http://www.wwpdb.org/docs.html (accessed November 14, 2013). 6. "GLmol - Molecular Viewer on WebGL/Javascript." GLmol - Molecular Viewer on WebGL/Javascript. http://webglmol.sourceforge.jp/index-en.html (accessed May 3, 2014). 7. "HTML5 Introduction." HTML5 Introduction. http://www.w3schools.com/html/html5_intro.asp (accessed May 2, 2014). 8. "JavaScript Tutorial." JavaScript Tutorial. http://www.w3schools.com/js/ (accessed May 3, 2014). 9. "Jmol: an open-source Java viewer for chemical structures in 3D." Jmol: an open- source Java viewer for chemical structures in 3D. http://www.jmol.org/ (accessed May 3, 2014). 10. "jQuery." jQuery. http://jquery.com/ (accessed May 2, 2014). 11. "jQuery Tutorial." jQuery Tutorial. http://www.w3schools.com/jquery/default.asp (accessed October 10, 2013). 12. "jQuery UI." jQuery UI. http://jqueryui.com/ (accessed May 3, 2014). 13. "mrdoob/three.js." GitHub. ://github.com/mrdoob/three.js/ (accessed May 3, 2014). 14. Pan, Yi. Algorithmic and artificial intelligence methods for protein bioinformatics. Hoboken, N.J.: J. Wiley & Sons, 2013. 15. Panzenböck , Mathias . "Hackworthy." : Save/download data generated in JavaScript. http://hackworthy.blogspot.com/2012/05/savedownload-data-generated-in.html (accessed May 5, 2014). 16. "PDB identification code." - Proteopedia, life in 3D. http://proteopedia.org/wiki/index.php/PDB_identification_code (accessed May 3, 2014). 17. Roberts, Matt. "Stygian Vision - Random thoughts from a random guy." Creating a jQuery Sortable Trash Bin to Remove Items. http://stygianvision.net/updates/jquery- sortable-remove-item/ (accessed April 22, 2014). 18. "Style Your jQuery-UI Tabs - Web Development is Easy!." Style Your jQuery-UI Tabs - Web Development is Easy!. http://www.webdeveasy.com/style-your-jquery-ui- tabs/ (accessed May 3, 2014). 19. "The - a non-profit industry consortium to develop, publish and promote open standard, royalty-free media authoring and acceleration standards for desktop and handheld devices, combined with conformance qualification programs for platform and." WebGL. http://www.khronos.org/webgl/ (accessed May 3, 2014). 20. "Tired of hunting." website dimensions. http://www.websitedimensions.com/ (accessed May 3, 2014). 21. "Understanding PDB Data: Looking at Structures." RCSB PDB-101. http://www.rcsb.org/pdb/101/static101.do?p=education_discussion/Looking-at- Structures/intro.html (accessed May 3, 2014). 22. "What is Biochemistry?." Home Page. https://www.mcgill.ca/biochemistry/about- us/information/biochemistry (accessed May 3, 2014). 23. "What is jQuery TE?." jQuery Text Editor. http://jqueryte.com/ (accessed May 3, 2014). 24. "WebGL." Mozilla Developer Network. https://developer.mozilla.org/en- US/docs/Web/WebGL (accessed May 3, 2014).

90

25. "WebGL." RealTime Rendering. http://www.realtimerendering.com/blog/tag/webgl 26. "WebGL Specification." WebGL Specification. https://www.khronos.org/registry/webgl/specs/1.0/ (accessed May 3, 2014). 27. Wikimedia Foundation. "Data URI Scheme." Wikipedia. http://en.wikipedia.org/wiki/Data_URI_scheme#JavaScript (accessed May 3, 2014). 28. Wikimedia Foundation. "WebGL." Wikipedia. http://en.wikipedia.org/wiki/WebGL (accessed May 3, 2014).

91

APPENDICES

1. whipst.html This appendix contains the code for file “whipst.html,” which is responsible for providing a web interface to this project.

1 2 3 4 WHIPSTG 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19

20

Generating Interactive Protein Structure Tutorial Using WebGL and HTML5

21
22
23 49
50

51 INTRODUCTION
52 Biochemistry is the study of living organisms and of molecular basis for the transformation that occur
53 in living cells. Much of Biochemistry deals with large structures such as proteins. Protein molecules
54 are long polymers typically containing several thousand of atoms, composed of a uniform repetitive
55 backbone with a particular sidechain attached to each residue. One problem that arises in learning about
56 proteins is the hardship to visualize the little details of structures of such magnitude. This is where
57 Bioinformatics – the application of computer science that utilizes software to solve problems in
58 visualization – comes in. Using a visualization tool to display a protein in 3D helps protein elements
59 such as amino acids to stand out and be identified quickly. WebGL and HTML5 Interactive Protein Structure
60 Tutorial or WHIPSTG aims to facilitate the learning of protein structures by creating a website tutorial
61 that allows the user to interact with a protein visualization in 3D, true false questions, multiple-choice
62 questions, and to display text to the tutorial. WHIPSTG uses GLmol – a 3D molecular viewer based on WebGL
63 and JavaScript – that allows the user to manipulate the 3D protein. For the scope of this project, GLmol
64 has been slightly modified to include functionality for highlighting amino acids, highlighting a part of
65 a protein sequence and for embedding multiple GLmol instances into a webpage. 66

67


68
69
70
71
72
73
74
75
76
77
    78
  • 79 80
  • 81
  • 93

    82 83

  • 84
  • 85 86
  • 87
  • 88 89
  • 90
  • 91 92
  • 93
  • 94 95
  • 96
97
98
99 100 101
102
    103
  • Add your items here
  • 104
105
106
107 Trash 108
    109
    110
    111 Template
    112
    113
    114 115
    116 117 118
    119
    120
    121
    122

    What is WHIPSTG?

    123
    124

    125 WHIPSTG is a tool that allows the user to create a tutorial for students that are learning about
    126 protein structures.The tutorial is a webpage that displays the content provided by the user. The
    127 tutorial has interactive widgets that allows for manipulation of 3D protein structures, answering
    128 of true false questions, and also answering to multiple- choice questions.

    94

    129

    130
    131

    What are the WHIPSTG Components?

    132
    133

    The screen is divided in three parts: the left area, the middle area, and the right area. In the left
    134 area there are six widgets:
    135

      136
    • True False Question
    • 137
    • Multiple Choice Questions
    • 138
    • GLmol
    • 139
    • Glmol Highlight Amino Acids
    • 140
    • Glmol Highlight Sequence
    • 141
    • Text
    • 142
    143 The middle area contains the contents that the tutorial will have. Initially, it only shows a prompt to
    144 enter a title to name the tutorial to be created The right side has an area where widgets entered erroneously
    145 will be dropped and deleted. It also has a Template area to choose a template. There are also two buttons at the
    146 bottom right of the page: one is to reset the middle area contents and the other one to save the file. 147

    148
    149

    What information is required by widgets?

    150
    151

    152

      153
    • True False Question 154
        155
      • Question - A true false question is a statement that is either true or false.
      • 156
      • Correct Answer - This is the correct answer of the question. For example, true.
      • 157
      • Explanation Correct - This is a message to be displayed when the person using the tutorial selects 158 the correct answer. For example,
        the user might want to encourage the person using the tutorial with 159 a message like: “Great job! Keep
        up the good work!”
      • 160
      • Explanation Incorrect - This is a message to be displayed when the person using the tutorial selects 161 the incorrect answer. In this case,
        the user might want to encourage the person using the tutorial to 162 keep studying. For example, the user might use a message
        like: “Not quite right! Please review Chapter 163 2, Section 3 of our textbook!” 164
      • 165
      166
    • 167
    168
      169
    • Multiple Choice Question 170
        171
      • Question - A multiple-choice question is a type of question that provides a question and four possible

        95

        172 answers in which only one answer is correct.

      • 173
      • A - This is the first answer choice.
      • 174
      • Explanation - This is an explanation for the A answer. If answer A is correct or incorrect, what 175 message does the user want to give to the person using the tutorial? Consider a positive or 176 negative message.
      • 177
      • B - This is the second answer choice. Write it in the input field provided.
      • 178
      • Explanation - This is an explanation for the B answer. If answer B is correct or incorrect, what 179 message does the user want to give to the person using the tutorial? Consider a positive or negative 180 message.
      • 181
      • C - This is the third answer choice. Write it in the input field provided.
      • 182
      • Explanation - This is an explanation for the C answer. If answer C is correct or incorrect, what 183 message does the user want to give to the person using the tutorial? Consider a positive or negative 184 message.
      • 185
      • D - This is the fourth answer choice. Write it in the input field provided.
      • 186
      • Explanation - This is an explanation for the D answer. If answer D is correct or incorrect, what 187 message does the user want to give to the person using the tutorial? Consider a positive or negative 188 message.
      • 189
      • Correct Value - This is the correct value of the question.
      • 190
      191
    • 192
    193
      194
    • GLmol 195
        196
      • PDB Id - This is the id of the protein structure that will be displayed on the tutorial.
      • 197
      198
    • 199
    200
      201
    • GLmol Highlight Amino Acids 202
        203
      • PDB Id - This is the id of the protein structure will be displayed on the tutorial.
      • 204
      205
    • 206
    207
      208
    • GLmol Highlight Sequence 209
        210
      • PDB Id - This is the id of the protein structure will be displayed on the tutorial.
      • 211

      96

      212

    • 213
    214
      215
    • Text 216
        217
      • This is some text that the user wants to display in the tutorial, for example, text describing a 218 protein structure or a set of
        instructions to perform during the tutorial.
      • 219
      220
    • 221
    222

    223
    224

    What is a tutorial?

    225
    226

    A tutorial is a website created by WHIPSTG. The tutorial contains several interactive widgets.

    227
    228

    How to create a tutorial?

    229
    230

    231 Click on a widget from the left area and drag it into the middle area. The widget will change to ask for information. 232 Fill out all the information as needed. The widgets can be sorted. Once you are satisfied with the contents you chose, 233 click on save file. You should see a file in your downloads folder. 234 235

    236
    237

    How to delete an unnecessary widget?

    238
    239

    To delete a widget, drag it from the middle area and drop it into the trash area.

    240
    241

    How to delete all widgets?

    242
    243

    To delete all widgets in the middle area, click on the reset button.

    244
    245

    How do the templates look?

    246
    247

    The Simple, Left and Right Tabs on this web page display websites that use the Simple, Left and Right templates respectively.

    248
    249

    What do I do if the tutorial I created does not work?

    250
    251

    252 First of all, I suggest that you check that all the files are read from the hosting site.
    253 The files needed for the website tutorial to run are:
    254

      255
    • simple.css
    • 256
    • left.css
    • 97

      257

    • right.css
    • 258
    • tabs.css
    • 259
    • Three49custom.js
    • 260
    • Query-1.7.min.js
    • 261
    • GLmol.js
    • 262
    • widgetFunctionality.js
    • 263
    • jquery-ui-1.8.9.js
    • 264
    265 266 The files live on a hosting site http://montes.co.nf/css/
    267 You can find them by adding the file name after css/ For example, to see the simple.css file
    268 you can write http://montes.co.nf/css/simple.css

    269 270 If for any reason, you still have problems, you can reach me at [email protected] 271

    272
    273
    274
    275
    276 277
    278
    279 280
    281
    282 283
    284
    285 286
    287
    288 289
    290
    291
    292 © Copyright CSUSM - Elizabeth Montes
    All Rights Reserved 2014 293
    294 295 296 297 308 309

    2. file.html This appendix contains the code for the file “file.html.” This html file defines the interactive widgets and includes the files needed for its proper execution. This file is the output of the system presented on this paper.

    1 2 3 4 5 6 7 8 9 10 11 12 13

    14
    15

    Simple Tutorial

    16
    17 18

    Protein structure is the biomolecular structure of a protein molecule. Proteins are polymers 19 -specifically polypeptides - sequences formed from various L-α-amino acids. Each unit of a protein 20 is called an amino acid residue because it is the residue of every amino acid that forms the protein 21 by losing a water molecule. 22

    23 24 25 26 27 28 29 30

    99

    31

    32 33 34 35 39 40 41
    NumQuestionYour answer Result/Explanation
    1 The basic monomers of proteins are amino acids. 36 True 37 False 38


    42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
    How many different amino acids are used in making proteins??
    AnswerExplanation
    A12
    B 32
    C 20
    D 22

    72

    100

    73

    74
    75 About 76 77
    78
    79 Load 80 81
    82
    83 View 84 85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95 A
    96 R
    97 N
    98 D
    99 C
    100 Q
    101 E
    102 G
    103 H
    104 I
    105 L
    106 K
    107 M
    108 F
    109 P
    110 S

    101

    111 T
    112 W
    113 Y
    114 V
    115

    116
    Side chains
    117 118
    .
    119
    120
    .
    121
    122
    123
    124
    125
    126
    ON-OFF 127 Highlight color 128 134 135
    136 137
    .
    138
    139
    .
    140
    141
    142
    143
    144

    © Copyright by CSUSM - Elizabeth Montes

    145
    146
    147 148 149 150 151 152 169 170

    3. whipst.js This appendix shows contents of the file “whipst.js,” which handles the interactivity of the web interface. This file is responsible for the dragging and sorting capabilitites in the middle area, for generating the widgets contents by calling the appropriate writing function, and for saving the file to the computer.

    1 /* 2 * : Elizabeth Montes 3 * Year: 2013- 2014 4 */ 5 //When the document loads have everything initialized 6 $(function(){ 7 var idName = ""; 8 9 //get the id of the draggable 10 $("li").mousedown(function(){ 11 idName = this.id; 12 }); 13 14 var counter = 0; 15 16 // This function makes the widgets (they have the class boxes) draggable 17 $(".boxes").draggable({ 18 appendTo: "body", 19 cursor: "crosshair", 20 cursorAt: { top: 56, left: 56 }, 21 helper: "clone", 22 revert: "invalid", 23 connectToSortable: ".sortableList",

    103

    24 stop: function(event,ui){ 25 counter++; 26 } 27 }); 28 29 //This function makes sortList sortable. 30 $("#sortList").sortable({ 31 tolerance: 'pointer', 32 items: "li:not(.placeholder),li:not(.notSortable)", 33 dropOnEmpty: true, 34 connectWith: '.trash', 35 appendTo: "#sortList", 36 sort: function(event, ui){ 37 $(this).removeClass("ui-state-default"); 38 }, 39 beforeStop: function(event, ui){ 40 newItem = ui.item; 41 }, 42 receive: function(event, ui){ 43 current = idName + counter; 44 if($(this).find(".placeholder").length > 0){ 45 promptInformation($(newItem), current); 46 $(this).find(".placeholder").remove(); 47 }else{ 48 promptInformation($(newItem), current); 49 } 50 } 51 }); 52 53 //Sortable to hold the trash 54 $(".trash").sortable({ 55 items: "li:not(.notTrash)", 56 receive: function(event, ui){ 57 $(".trash").each(function(){ 58 $(this).find('li').each(function(){ 59 $(this).css("display","none"); 60 }); 61 }); 62 } 63 }); 64 65 /* 66 * This function prompts the user for information according to the selected widget. 67 * Parameters: 68 * elem - item that will be passed from receive to stop event in $("#sortList").sortable() 69 * current - current id. This is a unique id that avoids conflict between widgets ids 70 * */ 71 function promptInformation(elem, current){ 72 73 switch(current){ 74 case "trueFalseQuestion"+counter: 75 elem.addClass("tempclass");

    104

    76 elem.html('
            ;' + 77 '           ' + 78 '' + 79 '
    ' + 80 '        ' + 81 '
    ' + 85 '   ' + 86 '' + 87 '
    ' + 88 '' + 89 '' + 90 '
    '); 91 elem.css({width:"600px",height: '120px'}); 92 $(".tempclass").attr("id","trueFalseQuestion"+counter); 93 $("#trueFalseQuestion"+counter).removeClass("tempclass"); 94 if(elem) 95 break; 96 case "multipleChoiceQuestion"+counter: 97 elem.addClass("tempclass"); 98 elem.append('
           ' + 99 '' + 100 '
    ' + 101 '' + 103 '' + 104 '
    ' + 105 '' + 106 '' + 107 '
    ' + 108 '' + 110 '' + 111 '
    ' + 112 '' + 113 '' + 114 '
    ' + 115 '

    105

    116 '      ' + 117 '' + 118 '
    ' + 119 '' + 120 '' + 121 '
    ' + 122 '' + 124 '' + 125 '
    ' + 126 '' + 127 '' + 128 '
    ' + 129 '' + 130 ''); 136 $(".tempclass").attr("id","multipleChoiceQuestion"+counter); 137 $("#multipleChoiceQuestion"+counter).removeClass("tempclass"); 138 elem.css({width:"600px",height:"260px"}); 139 break; 140 case "glmolwidget1_"+counter: 141 elem.addClass("tempclass"); 142 elem.append('
    ' + 144 '' + 145 '
    '); 146 elem.css({width:"600px", height:"40px"}); 147 $(".tempclass").attr("id","glmolwidget1_"+counter); 148 $("#glmolwidget1_"+counter).removeClass("tempclass"); 149 break; 150 case "glmolwidget2_"+counter: 151 elem.addClass("tempclass"); 152 elem.append('
    ' + 154 '' + 155 ''); 156 elem.css({width:"600px", height:"40px"}); 157 $(".tempclass").attr("id","glmolwidget2_"+counter); 158 $("#glmolwidget2_"+counter).removeClass("tempclass"); 159 break; 160 case "glmolwidget3_"+counter: 161 elem.addClass("tempclass");

    106

    162 elem.append('
    ' + 164 '' + 165 ''); 166 elem.css({width:"600px", height:"40px"}); 167 $(".tempclass").attr("id","glmolwidget3_"+counter); 168 $("#glmolwidget3_"+counter).removeClass("tempclass"); 169 break; 170 case "paragraphText"+counter: 171 elem.addClass("tempclass"); 172 elem.append('' + 173 ''); 174 elem.css({width:"600px", height:"200px"}); 175 $("#txtInfo"+counter).jqte(); //create the jqte text area 176 177 $(".tempclass").attr("id","paragraphText"+counter); 178 $("#paragraphText"+counter).removeClass("tempclass"); 179 console.log($(this)); 180 break; 181 } 182 } 183 }); 184 185 //This functions clears sortableList 186 function reset(){ 187 $(".sortableList").empty(); 188 } 189 190 //This functions saves the file tutorial to computer 191 function save(){ 192 193 var flag = false; 194 var len, pos, num; 195 var objects = new Array(); 196 var str_header = ""; 197 var str_left = ""; 198 var str_footer = ""; 199 var str_right = ""; 200 var str_tab_list = ""; 201 var str = ""; 202 var simple_str = ""; 203 var titlePage = $("#pageTitle").val(); 204 var nameTemplate = $('input[name="template"]:checked').val(); 205 206 if(nameTemplate == "left" || nameTemplate == "right"){ 207 str_right += "

    "; 312 str_left += "
    "; //this closes section left that begun on writeHeader()

    109

    313 str_footer += writeFooter(objects, nameTemplate); 314 str = str_header + str_tab_list + str_left + str_right + str_footer; 315 }else{ 316 simple_str += writeFooter(objects, nameTemplate); 317 str = simple_str; 318 } 319 320 if(flag){ 321 if(titlePage.length == 0){ 322 $("#buttonMsg").html("Look for file in Downloads folder."); 323 downloadFile("file.html", str); 324 }else{ 325 titlePage = titlePage.replace(/\s/g, ''); //Remove space in file 326 $("#buttonMsg").html("Look for file in Downloads folder."); 327 downloadFile(titlePage+".html", str); 328 } 329 } 330 else { 331 alert("Please add items to the 'Add your items here' area \n or correct 'Required errors'"); 332 } 333 return flag; 334 } 335 /* VALIDATION FUNCTIONS */ 336 function required(name, num){ 337 if(!$("#"+ name + num).val().length){ 338 $("#"+ name + "msg" + num).html("Required"); 339 }else{ 340 $("#"+ name + "msg" + num).html(" "); 341 } 342 } 343 344 function clearmcmsg(num){ 345 $("#mcqmsg"+num).html(" "); 346 $("#mcamsg"+num).html(" "); 347 $("#mcaexpmsg"+num).html(" "); 348 $("#mcbmsg"+num).html(" "); 349 $("#mcbexpmsg"+num).html(" "); 350 $("#mccmsg"+num).html(" "); 351 $("#mccexpmsg"+num).html(" "); 352 $("#mcdmsg"+num).html(" "); 353 $("#mcdmsg"+num).html(" "); 354 $("#mcdexpmsg"+num).html(" "); 355 $("#mccvmsg"+num).html(" "); 356 } 357 358 function mcqValid(num){ 359 360 if (!$("#mcq"+num).val().length || !$("#mca"+num).val().length || !$("#mcaexp"+num).val().length 361 || !$("#mcb"+num).val().length || !$("#mcbexp"+num).val().length || !$("#mcc"+num).val().length 362 || !$("#mccexp"+num).val().length || !$("#mcd"+num).val().length || !$("#mcdexp"+num).val().length){ 363 364 required("mcq", num);

    110

    365 required("mca", num); 366 required("mcaexp", num); 367 required("mcb",num); 368 required("mcbexp", num); 369 required("mcc",num); 370 required("mccexp", num); 371 required("mcd",num); 372 required("mcdexp", num); 373 required("mccv",num); 374 return false; 375 } 376 //at this point everything is true, clear required messages 377 clearmcmsg(num); 378 return true; 379 } 380 381 function tfValid(num){ 382 if(!$("#tfexpc"+num).val().length || !$("#tfq"+num).val().length || !$("#tfexpi"+num).val().length 383 || !$("#tfcv"+num).val().length) 384 { 385 required("tfq",num); 386 required("tfexpc",num); 387 required("tfexpi",num); 388 required("tfcv", num); 389 390 return false; 391 } 392 //at this point everything is true, clear required messages 393 $("#tfqmsg"+num).html(" "); 394 $("#tfexpcmsg"+num).html(" "); 395 $("#tfexpimsg"+num).html(" "); 396 $("#tfcvmsg"+num).html(" "); 397 return true; 398 } 399 400 function gl1Valid(num){ 401 if(!$("#pdbid1_"+num).val().length){ 402 $("#pdbid1msg_"+num).html("Required"); 403 return false; 404 }else{ 405 if(!$("#pdbid1_"+num).val().match(/^[1-9][A-Za-z0-9]{3}$/)){ 406 $("#pdbid1msg_"+num).html("Wrong PDB Id"); 407 return false; 408 } 409 } 410 $("#pdbid1msg_"+num).html(" "); 411 return true; 412 } 413 414 function gl2Valid(num){ 415 if(!$("#pdbid2_"+num).val().length){ 416 $("#pdbid2msg_"+num).html("Required"); 417 return false; 418 } else{ 111

    419 if(!$("#pdbid2_"+num).val().match(/^[1-9][A-Za-z0-9]{3}$/)){ 420 $("#pdbid2msg_"+num).html("Wrong PDB Id"); 421 return false; 422 } 423 } 424 $("#pdbid2msg_"+num).html(" "); 425 return true; 426 } 427 428 function gl3Valid(num){ 429 if(!$("#pdbid3_"+num).val().length){ 430 $("#pdbid3msg_"+num).html("Required"); 431 return false; 432 } else{ 433 if(!$("#pdbid3_"+num).val().match(/^[1-9][A-Za-z0-9]{3}$/)){ 434 $("#pdbid3msg_"+num).html("Wrong PDB Id"); 435 return false; 436 } 437 } 438 $("#pdbid3msg_"+num).html(" "); 439 return true; 440 } 441 442 function txtValid(num){ 443 if(!$("#txtInfo"+num).val().length){ 444 $("#txtInfomsg"+num).html("Required"); 445 return false; 446 } 447 $("#txtInfomsg"+num).html(" "); 448 return true; 449 } 450 451 /* FUNCTIONS THAT RETURN STRING WITH TUTORIAL HTML CODE */ 452 function writeHeader(title, name){ 453 var str = ''; 454 str += '\n\n'; 455 str += '' + title + ''; 456 str += '\n'; 457 str += '\n\n'; 458 str += '\n'; 459 460 if(name == "simple"){ 461 str += '\n'; 462 str += '\n

    ' + title + '

    '; 463 }else if(name == "left"){ 464 str += '\n'; 465 str += ' \n'; 466 str += '\n

    ' + title + '

    ';

    112

    467 str += '

    \n
    \n'; 468 }else if(name == "right"){ 469 str += '\n'; 470 str += ' \n'; 471 str += '\n

    ' + title + '

    '; 472 str += '
    \n
    \n'; 473 } 474 return str; 475 } 476 477 function writeFooter(objects,name){ 478 var str = ''; 479 480 if(name == "left" || name == "right"){ 481 str += '
    \n
    \n'; 482 } 483 484 str += '
    \n

    © Copyright by CSUSM - Elizabeth Montes

    \n
    '; 485 str += ' \n'; 486 str += ' \n'; 487 str += ' \n'; 488 str += ' \n'; 489 str += ' \n '; 490 str += ' \n'; 497 str += '\n'; 498 return str; 499 } 500 501 function writeParagraph(count){ 502 var parContent = "

    "; 503 parContent += $("#txtInfo" + count).val() + "

    \n"; 504 return parContent; 505 } 506 507 function writeTrueFalse(count){ 508 var number = parseInt(count); 509 var str = ''; 510 str += '\n'; 511 str += '\n';

    113

    512 str += '\n'; 513 str += '\n'; 514 str += '

    \n'; 515 str += '\n'; 516 str += '
    NumQuestionYour answerResult/Explanation
    1 ' + $("#tfq"+count).val() + '\n'; 517 str += 'True\n'; 518 str += 'False\n'; 519 str += '


    \n'; 520 return str; 521 } 522 523 function writeMultipleChoice(count){ 524 var number = parseInt(count); 525 var str = ''; 526 str += '\n'; 527 str += '\n'; 528 str += '\n'; 529 str += '\n'; 530 str += '\n'; 531 str += '\n'; 532 str += '\n'; 533 str += '\n'; 534 str += ''; 535 str += '\n'; 536 str += '\n'; 537 str += '\n'; 539 str += '\n'; 542 str += '\n'; 545 str += '\n';

    114

    546 str += '

    \n'; 548 str += '
    ' + $("#mcq"+count).val() + '?
    AnswerExplanation
    A' + $("#mca"+count).val() + '
    \n'; 540 str += 'B ' + $("#mcb"+count).val() + '
    \n'; 543 str += 'C ' + $("#mcc"+count).val() + '
    D ' + $("#mcd"+count).val() + '

    \n'; 549 return str; 550 } 551 552 function writeGLmolObject(id, name, num){ 553 var str = ''; 554 555 if(name == "left" || name == "right"){ 556 str += '
    '; 557 } 558 559 str += '
    \n'; 560 str += '
    \n'; 561 str += '
    \n'; 562 str += 'About\n'; 563 str += '\n'; 564 str += '
    \n'; 565 str += '
    \n'; 566 str += 'Load\n'; 567 str += '\n'; 568 str += '
    \n'; 569 str += '
    \n'; 570 str += 'View\n'; 571 str += '\n'; 572 str += '
    \n'; 573 str += '
    .
    \n'; 574 str += '
    \n'; 575 str += '
    .
    \n'; 576 str += '
    \n'; 577 str += '
    \n'; 578 579 if(name == "left" || name == "right"){ 580 str += '
    \n'; 581 }else{ 582 str += '
    '; 583 } 584 585 return str; 586 } 587 588 function writeGLmolhighlightaminoacid(id, name, num){ 589 var str = ''; 590 if(name == "left" || name == "right"){ 591 str += '
    '; 592 } 593 594 str += '
    \n'; 595 str += '
    \n'; 596 str += '
    \n';

    115

    597 str += 'A
    \n'; 598 str += 'R
    \n'; 599 str += 'N
    \n'; 600 str += 'D
    \n'; 601 str += 'C
    \n'; 602 str += 'Q
    \n'; 603 str += 'E
    \n'; 604 str += 'G
    \n'; 605 str += 'H
    \n'; 606 str += 'I
    \n'; 607 str += 'L
    \n'; 608 str += 'K
    \n'; 609 str += 'M
    \n'; 610 str += 'F
    \n'; 611 str += 'P
    \n'; 612 str += 'S
    \n'; 613 str += 'T
    \n'; 614 str += 'W
    \n'; 615 str += 'Y
    \n'; 616 str += 'V
    \n'; 617 str += '

    \n'; 618 str += '
    '; 619 str += 'Side chains
    '; 620 str += '\n'; 621 str += '
    .
    \n'; 622 str += '
    \n'; 623 str += '
    .
    \n'; 624 str += '
    \n'; 625 str += '
    \n'; 626 627 if(name == "left" || name == "right"){ 628 str += '
    \n'; 629 }else{ 630 str += '
    '; 631 } 632

    116

    633 return str; 634 } 635 636 function writeGLmolhighlightsequence(id, name, num){ 637 var str = ''; 638 if(name == "left" || name == "right"){ 639 str += '

    '; 640 } 641 642 str += '
    \n'; 643 str += '
    \n'; 644 str += '
    ON-OFF\n'; 645 str += 'Highlight color \n'; 650 str += '
    \n'; 651 str += '\n'; 652 str += '
    .
    \n'; 653 str += '
    \n'; 654 str += '
    .
    \n'; 655 str += '
    \n'; 656 str += '
    '; 657 658 if(name == "left" || name == "right"){ 659 str += '
    \n'; 660 }else{ 661 str += '
    '; 662 } 663 664 return str; 665 } 666 667 /* Returns a string with the glmol object declaration. This string should be written to the contents.js file. 668 * Parameters: id - a string to represent the name of glmol object to be created (must be unique) 669 * file - the name of the protein file to be downloaded. ie. 2POR (this is grabbed using $("#pdbid1_"+num).val()) 670 * flag - represents the type of widget that will be written in the document. 1 is for the glmol widget with tabs 671 * 2 is for either one of the highlighting options (amino acids or sequence) 672 * */ 673 function glmolObject(id, file, flag){ 674 var str = "\n var strId = \""+ id + "\"; \n var " + id + " = new GLmol(strId, true); "; 675 str += "var query = window.location.search.substring(1); \n"; 676 str += "if (query == '') download('pdb:" + file + "'," + id + ");\n else download(query, " + id + "); \n"; 677 678 if(flag == 1){ str += "addGLmolObject(" + id + "); "; }

    117

    679 else if (flag == 2){ str += id + ".defineRepresentation = " + id + ".defineRepCheckHighlight; "; } 680 else {alert("Please enter a flag number onto glmolObjectsTabs() in generator.js file. Thanks.");}; 681 return str; 682 } 683 684 function downloadFile (filename, data) { 685 if (!showSave) { 686 alert("Your browser does not support saving JavaScript generated data to files."); 687 return; 688 } 689 690 showSave(data,filename,"text/plain"); 691 }

    4. GLmol.js This appendix describes some of the code that is in the file “GLmol.js” located at http://montes.co.nf/js/GLmol.js. The code shown in this appendix defines my contributions to “GLmol.js”.

    135 //colors for GL purposes 136 this.aminoColor = { 137 'ALA': 0x330000,'ARG': 0x000066,'ASN': 0x33FFFF,'ASP':0x990066, 138 'CYS': 0x99CC33,'GLN': 0x9999FF,'GLU': 0xCC6666,'GLY':0x993333, 139 'HIS': 0x00FF66,'ILE': 0xCC00CC,'LEU': 0x993333, 'LYS': 0x660066, 140 'MET': 0xCCCC99,'PHE': 0xCC99FF,'PRO': 0x663300,'SER': 0x0000CC, 141 'THR':0x6600CC ,'TRP': 0x009999,'TYR': 0xFF99FF,'VAL': 0xCC0000 }; 142 143 //colors used for css purposes 144 this.aminoColors = { 145 'ALA': '#330000','ARG': '#000066','ASN': '#33FFFF','ASP':'#990066', 146 'CYS': '#99CC33','GLN': '#9999FF','GLU': '#CC6666','GLY':'#993333', 147 'HIS': '#00FF66','ILE': '#CC00CC','LEU': '#993333', 'LYS': '#660066', 148 'MET': '#CCCC99','PHE': '#CC99FF','PRO': '#663300','SER': '#0000CC', 149 'THR':'#6600CC','TRP': '#009999','TYR': '#FF99FF','VAL': '#CC0000' }; 150 151 this.aminoNames = ['ARG', 'HIS' , 'LYS' , 'ASP', 'GLU', 'SER' , 'THR', 'ASN', 'GLN', 'CYS', 152 'GLY', 'PRO', 'ALA' , 'VAL', 'LEU', 'ILE' , 'MET', 'PHE', 'TYR', 'TRP', ]; 153 154 this.three_to_one_LetterCode = {'ALA':'A', 'ARG':'R', 'ASN':'N', 'ASP':'D', 'CYS':'C', 155 'GLN':'Q', 'GLU':'E','GLY':'G','HIS':'H', 'ILE': 'I', 'LEU':'L', 'LYS':'K', 'MET': 'M', 156 'PHE':'F', 'PRO':'P', 'SER':'S', 'THR':'T', 'TRP':'W', 'TYR':'Y', 'VAL':'V'};

    345 } else if (recordName == 'SEQRES') { //get the sequence added by EM 346 if(line.substr(19,3) != " "){ 347 protein.sequence.push(line.substr(19,3)); 348 protein.chain.push(line.substr(11,1));

    118

    349 protein.chainsize.push(line.substr(14,3));} 350 if(line.substr(23,3) != " "){ 351 protein.sequence.push(line.substr(23,3)); 352 protein.chain.push(line.substr(11,1)); 353 protein.chainsize.push(line.substr(14,3)); 354 } 355 if(line.substr(27,3) != " "){ 356 protein.sequence.push(line.substr(27,3)); 357 protein.chain.push(line.substr(11,1)); 358 protein.chainsize.push(line.substr(14,3)); 359 } 360 if(line.substr(31,3) != " "){ 361 protein.sequence.push(line.substr(31,3)); 362 protein.chain.push(line.substr(11,1)); 363 protein.chainsize.push(line.substr(14,3)); 364 } 365 if(line.substr(35,3) != " "){ 366 protein.sequence.push(line.substr(35,3)); 367 protein.chain.push(line.substr(11,1)); 368 protein.chainsize.push(line.substr(14,3));} 369 if(line.substr(39,3) != " "){ 370 protein.sequence.push(line.substr(39,3)); 371 protein.chain.push(line.substr(11,1)); 372 protein.chainsize.push(line.substr(14,3)); 373 } 374 if(line.substr(43,3) != " "){ 375 protein.sequence.push(line.substr(43,3)); 376 protein.chain.push(line.substr(11,1)); 377 protein.chainsize.push(line.substr(14,3)); 378 } 379 if(line.substr(47,3) != " "){ 380 protein.sequence.push(line.substr(47,3)); 381 protein.chain.push(line.substr(11,1)); 382 protein.chainsize.push(line.substr(14,3)); 383 } 384 if(line.substr(51,3) != " "){ 385 protein.sequence.push(line.substr(51,3)); 386 protein.chain.push(line.substr(11,1)); 387 protein.chainsize.push(line.substr(14,3)); 388 } 389 if(line.substr(55,3) != " "){ 390 protein.sequence.push(line.substr(55,3)); 391 protein.chain.push(line.substr(11,1)); 392 protein.chainsize.push(line.substr(14,3)); 393 } 394 if(line.substr(59,3) != " "){ 395 protein.sequence.push(line.substr(59,3)); 396 protein.chain.push(line.substr(11,1)); 397 protein.chainsize.push(line.substr(14,3)); 398 } 399 if(line.substr(63,3) != " "){ 400 protein.sequence.push(line.substr(63,3)); 401 protein.chain.push(line.substr(11,1)); 402 protein.chainsize.push(line.substr(14,3)); 403 }

    119

    404 if(line.substr(67,3) != " "){ 405 protein.sequence.push(line.substr(67,3)); 406 protein.chain.push(line.substr(11,1)); 407 protein.chainsize.push(line.substr(14,3)); 408 } 409 }

    1830 /* Added by EM on 11/4/2013 1831 Colors each amino acid with a different color.*/ 1832 GLmol.prototype.colorByAminoacid = function(atomlist) { 1833 for( var i in atomlist) { 1834 var atom = this.atoms[atomlist[i]]; if (atom == undefined) continue; if (atom.hetflag) continue; 1835 atom.color = this.aminoColor[atom.resn]; 1836 } 1837 }; 1838 1839 /* Returns the element id_seqHigh element which contains the sequence with one letter codes*/ 1840 GLmol.prototype.displaySequenceHighlight = function(){ 1841 var element = $('#' + this.id + '_seqHigh'); 1842 var seqContent = ""; 1843 seqContent += this.getOLCSequence().join(""); 1844 1845 element.html(seqContent); 1846 return element; 1847 }; 1848 1849 /* 1850 * This function will return an array association where the chain will be mapped 1851 * with its respective chain. This will let us know how many chains are contained in the 1852 * protein sequence. 1853 */ 1854 GLmol.prototype.mapChainSize = function(){ 1855 var temp = {}; 1856 for(var i in this.protein.sequence){ 1857 1858 temp[this.protein.chain[i]] = this.protein.chainsize[i]; 1859 } 1860 return temp; 1861 }; 1862 1863 /* 1864 * This function iterates through the sequence and returns a 1865 * multidimensional array with the sequence resi numbers for 1866 * every chain in the sequence. 1867 */ 1868 GLmol.prototype.findResiSequenceNumbers = function(){ 1869 var seq_length = this.protein.sequence.length; 1870 var seqChain = this.mapChainSize(); 1871 var resi_numbers = []; 1872 var numbers = {}; 1873 for(var i in seqChain){ 1874 var current_chain = i; 1875 var current_chain_size = seqChain[i];

    120

    1876 1877 //get the new length and assign it to seq_length 1878 var new_length = seq_length - current_chain_size; 1879 var l = seq_length - new_length; 1880 for(var j = 0; j < l; ++j){ 1881 numbers[j+1] = current_chain; 1882 } 1883 resi_numbers.push(numbers); 1884 numbers = {}; 1885 } 1886 return resi_numbers; 1887 }; 1888 1889 /* Added by EM on 03/05/2014 1890 * This function finds the resi numbers of the selected text. Stores them 1891 * in an array and returns it. 1892 * */ 1893 GLmol.prototype.getResiFromSequence = function(element){ 1894 if(element.selectionStart != undefined){ //works on chrome and mozilla 1895 var startPos = element.selectionStart; 1896 var endPos = element.selectionEnd; 1897 var selText = element.value.substring(startPos, endPos); 1898 1899 var resiNumbers = {}; 1900 var resi_map = {}; 1901 1902 var resi_numbers = new Array(); 1903 resi_numbers.push(this.findResiSequenceNumbers()); 1904 1905 var k = 0; //k iterates through every amino acid in sequence 1906 for(var i in resi_numbers[0]){ 1907 for(var j in resi_numbers[0][i]){ 1908 var current_resi = j; 1909 var current_chain = resi_numbers[0][i][j]; 1910 1911 if(k == startPos && (selText.length == 1)){ 1912 resi_map[current_resi] = current_chain; 1913 } 1914 if(k >= startPos && k < endPos){ 1915 resi_map[current_resi] = current_chain; 1916 } 1917 ++k; 1918 } 1919 } 1920 } 1921 return resi_map; 1922 }; 1923 1924 /* Added by EM 1925 * This function iterates through the atoms and checks if the passed resiNum and chain_value are 1926 * equal to the atom chain and resi. If they are equal, assigns color value to the atom color. 1927 */ 1928 GLmol.prototype.getSerialByResi = function(seriales, resiNum, chain_value, color){ 1929 for(var i in this.atoms){ 121

    1930 if (this.atoms[i] == undefined) continue; 1931 if (this.atoms[i].hetflag) continue; 1932 if(this.atoms[i].chain == chain_value && this.atoms[i].resi == resiNum){ 1933 this.atoms[i].color = color; 1934 seriales.push(this.atoms[i].serial); 1935 } 1936 } 1937 }; 1938 1939 /* Added by EM 1940 * This function highlight the sequence represented as one letter codes. The function 1941 * returns an array containing the serial numbers of the selected amino acids for 1942 * drawing purposes. 1943 */ 1944 GLmol.prototype.highlightSequenceOLC = function(color){ 1945 var element = $('#' + this.id + '_seqHigh'); 1946 if(element.length) { 1947 var seriales = []; 1948 var resiNo = this.getResiFromSequence(element[0]); 1949 1950 for(var k in resiNo){ 1951 this.getSerialByResi(seriales, k, resiNo[k],color); 1952 } 1953 } 1954 return seriales; 1955 }; 1956 1957 /* Added by EM on 03/05/2014 1958 * Iterates through the protein sequence, converts each amino acid from three letter 1959 * code to one letter code. Returns an array of amino acids represented by one letter code. 1960 * */ 1961 GLmol.prototype.getOLCSequence = function(){ 1962 var all_resn = []; 1963 for(var i in this.protein.sequence){ 1964 var atom = this.protein.sequence[i]; 1965 1966 all_resn.push(this.three_to_one_LetterCode[atom]); 1967 } 1968 return all_resn; 1969 }; 1970 1971 /* EM 03/19/2014 1972 Puts sequence contents into text area id_seqHigh 1973 * */ 1974 GLmol.prototype.displaySequenceOLC = function(){ 1975 var element = $('#' + this.id + '_seqHigh'); 1976 var seqContent = ""; 1977 seqContent += this.getOLCSequence().join(""); 1978 element.html(seqContent); 1979 }; 1980 1981 /* 01/05/2014 - by Elizabeth Montes

    122

    1982 Checks to see if the checkbox is selected for an amino acid. If it is, it highlights the amino acid. 1983 Otherwise, the amino acid is not highlighted. */ 1984 GLmol.prototype.highlightAminoacids = function(all){ 1985 var idHeader = "#" + this.id + "_"; 1986 var name=""; 1987 for( var i in this.aminoNames ){ 1988 name = this.aminoNames[i]; 1989 if( $(idHeader + name).attr('checked') ) { 1990 var atomlist = all; 1991 for(var i in atomlist) { 1992 var atom = this.atoms[atomlist[i]]; 1993 if (atom == undefined) continue; 1994 if (atom.hetflag) continue; 1995 if($(idHeader + name).val() == atom.resn) { 1996 atom.color = this.aminoColor[atom.resn]; 1997 $(idHeader + name + "_bc").css("background-color", this.aminoColors[atom.resn]); 1998 } 1999 } 2000 } else{ $(idHeader + name + "_bc").css("background-color", "transparent"); } 2001 } 2002 }; 2003 2004 GLmol.prototype.defineRepCheckHighlight = function() { 2005 var all = this.getAllAtoms(); 2006 var hetatm = this.removeSolvents(this.getHetatms(all)); 2007 var asu = new THREE.Object3D(); 2008 this.colorByAtom(all, {}); 2009 this.colorByChain(all); 2010 2011 this.highlightAminoacids(all); 2012 if($("#" + this.id + "_sidechain").attr("checked")){ 2013 this.drawBondsAsLine(asu, this.getSidechains(all), this.lineWidth); 2014 } 2015 2016 var color = $("#" + this.id + "_hgcolor").val(); 2017 this.displaySequenceOLC(); 2018 if($("#" + this.id + "_highlight").attr("checked")) { 2019 all = [];hetatm= []; 2020 all = this.highlightSequenceOLC(color); 2021 } 2022 2023 this.drawAtomsAsSphere(asu, hetatm, this.sphereRadius); //hetatms 2024 this.drawCartoon(asu,all, false, this.thickness); 2025 this.modelGroup.add(asu); 2026 }; 2027 2028 /* Moved function from original viewer.html file */ 2029 GLmol.prototype.defineRepFromController = function(){ 2030 2031 var idHeader = "#" + this.id + '_'; 2032 var time = new Date(); 2033 var all = this.getAllAtoms(); 2034 if ($(idHeader + 'biomt').attr('checked') && this.protein.biomtChains != "") all = this.getChain(all, this.protein.biomtChains);

    123

    2035 var allHet = this.getHetatms(all); 2036 var hetatm = this.removeSolvents(allHet); 2037 2038 console.log("selection " + (+new Date() - time)); time = new Date(); 2039 2040 this.colorByAtom(all, {}); 2041 var colorMode = $(idHeader + 'color').val(); 2042 if (colorMode == 'ss') { 2043 this.colorByStructure(all, 0xcc00cc, 0x00cccc); 2044 } else if (colorMode == 'chain') { 2045 this.colorByChain(all); 2046 } else if (colorMode == 'chainbow') { 2047 this.colorChainbow(all); 2048 } else if (colorMode == 'b') { 2049 this.colorByBFactor(all); 2050 } else if (colorMode == 'polarity') { 2051 this.colorByPolarity(all, 0xcc0000, 0xcccccc); 2052 } else if (colorMode == 'aminoacid') { 2053 this.colorByAminoacid(all); 2054 } 2055 2056 console.log("color " + (+new Date() - time)); time = new Date(); 2057 2058 /* added by EM */ 2059 this.highlightAminoacids(all); 2060 2061 /* added by EM */ 2062 var color = parseInt($(idHeader + 'hgcolor').val()); 2063 this.displaySequenceOLC(); 2064 if($(idHeader + 'highlight').attr('checked')){ 2065 var temp =[]; 2066 temp = this.highlightSequenceOLC(color); 2067 all = []; allHet = []; hetatm= []; 2068 all = temp; 2069 } 2070 2071 var asu = new THREE.Object3D(); 2072 var mainchainMode = $(idHeader + 'mainchain').val(); 2073 var doNotSmoothen = ($(idHeader + 'doNotSmoothen').attr('checked') == 'checked'); 2074 2075 if ($(idHeader + 'showMainchain').attr('checked')) { 2076 if (mainchainMode == 'ribbon') { 2077 this.drawCartoon(asu, all, doNotSmoothen); 2078 this.drawCartoonNucleicAcid(asu, all); 2079 } else if (mainchainMode == 'thickRibbon') { 2080 this.drawCartoon(asu, all, doNotSmoothen, this.thickness); 2081 this.drawCartoonNucleicAcid(asu, all, null, this.thickness); 2082 } else if (mainchainMode == 'strand') { 2083 this.drawStrand(asu, all, null, null, null, null, null, doNotSmoothen); 2084 this.drawStrandNucleicAcid(asu, all); 2085 } else if (mainchainMode == 'chain') { 2086 this.drawMainchainCurve(asu, all, this.curveWidth, 'CA', 1); 2087 this.drawMainchainCurve(asu, all, this.curveWidth, 'O3\'', 1); 2088 } else if (mainchainMode == 'cylinderHelix') {

    124

    2089 this.drawHelixAsCylinder(asu, all, 1.6); 2090 this.drawCartoonNucleicAcid(asu, all); 2091 } else if (mainchainMode == 'tube') { 2092 this.drawMainchainTube(asu, all, 'CA'); 2093 this.drawMainchainTube(asu, all, 'O3\''); 2094 } else if (mainchainMode == 'bonds') { 2095 this.drawBondsAsLine(asu, all, this.lineWidth); 2096 } 2097 } 2098 2099 if ($(idHeader + 'line').attr('checked')) { 2100 this.drawBondsAsLine(this.modelGroup, this.getSidechains(all), this.lineWidth); 2101 } 2102 console.log("mainchain " + (+new Date() - time)); time = new Date(); 2103 2104 if ($(idHeader + 'showBases').attr('checked')) { 2105 var hetatmMode = $(idHeader + 'base').val(); 2106 if (hetatmMode == 'nuclStick') { 2107 this.drawNucleicAcidStick(this.modelGroup, all); 2108 } else if (hetatmMode == 'nuclLine') { 2109 this.drawNucleicAcidLine(this.modelGroup, all); 2110 } else if (hetatmMode == 'nuclPolygon') { 2111 this.drawNucleicAcidLadder(this.modelGroup, all); 2112 } 2113 } 2114 2115 var target = $(idHeader + 'symopHetatms').attr('checked') ? asu : this.modelGroup; 2116 if ($(idHeader + 'showNonBonded').attr('checked')) { 2117 var nonBonded = this.getNonbonded(allHet); 2118 var nbMode = $(idHeader + 'nb').val(); 2119 if (nbMode == 'nb_sphere') { 2120 this.drawAtomsAsIcosahedron(target, nonBonded, 0.3, true); 2121 } else if (nbMode == 'nb_cross') { 2122 this.drawAsCross(target, nonBonded, 0.3, true); 2123 } 2124 } 2125 2126 if ($(idHeader + 'showHetatms').attr('checked')) { 2127 var hetatmMode = $(idHeader + 'hetatm').val(); 2128 if (hetatmMode == 'stick') { 2129 this.drawBondsAsStick(target, hetatm, this.cylinderRadius, this.cylinderRadius, true); 2130 } else if (hetatmMode == 'sphere') { 2131 this.drawAtomsAsSphere(target, hetatm, this.sphereRadius); 2132 } else if (hetatmMode == 'line') { 2133 this.drawBondsAsLine(target, hetatm, this.curveWidth); 2134 } else if (hetatmMode == 'icosahedron') { 2135 this.drawAtomsAsIcosahedron(target, hetatm, this.sphereRadius); 2136 } else if (hetatmMode == 'ballAndStick') { 2137 this.drawBondsAsStick(target, hetatm, this.cylinderRadius / 2.0, this.cylinderRadius, true, false, 0.3); 2138 } else if (hetatmMode == 'ballAndStick2') { 2139 this.drawBondsAsStick(target, hetatm, this.cylinderRadius / 2.0, this.cylinderRadius, true, true, 0.3);

    125

    2140 } 2141 } 2142 console.log("hetatms " + (+new Date() - time)); time = new Date(); 2143 2144 var projectionMode = $(idHeader + 'projection').val(); 2145 if (projectionMode == 'perspective') this.camera = this.perspectiveCamera; 2146 else if (projectionMode == 'orthoscopic') this.camera = this.orthoscopicCamera; 2147 2148 this.setBackground(parseInt($(idHeader + 'bgcolor').val())); 2149 2150 if ($(idHeader + 'cell').attr('checked')) { 2151 this.drawUnitcell(this.modelGroup); 2152 } 2153 if ($(idHeader + 'biomt').attr('checked')) { 2154 this.drawSymmetryMates2(this.modelGroup, asu, this.protein.biomtMatrices); 2155 } 2156 if ($(idHeader + 'packing').attr('checked')) { 2157 this.drawSymmetryMatesWithTranslation2(this.modelGroup, asu, this.protein.symMat); 2158 } 2159 this.modelGroup.add(asu); 2160 }; 2161 2162 /* EM 03/09/2014 2163 * Shows the information on the About tab 2164 * */ 2165 GLmol.prototype.showAboutTabInfo = function(){ 2166 var strContent = ''; 2167 strContent += '

    About

    GLmol -- Molecular Viewer on WebGL/Javascript
    '; 2168 strContent += 'Version 0.47 (20120827)

    This program is written by biochem_fan and released under LGPL.'; 2169 strContent += 'Please visitmy project page for the details and source'; 2170 strContent += ' code distribution.

    Comments and Suggestions are welcome. Please mail to biochem_fan at '; 2171 strContent += ' users.sourceforge.jp or write in the'; 2172 strContent += ' forum.

    \

    How to use

    • Rotation: left button
    • Translation: middle button'; 2173 strContent += ' or Ctrl-key + left button
    • Zoom: mousewheel or right button(up/down) or Shift-key + left '; 2174 strContent += ' button(up/down)
    • Slab: left button + Ctrl-key. horizontal move adjusts near clipping plane,'; 2175 strContent += ' vertical move far clipping plane.

    You can also change mouse mode with radio buttons at'; 2176 strContent += ' right-bottom corner.

    '; 2177 $("#" + this.id + "_inInfoBox").html(strContent); 2178 }; 2179 2180 /* EM 03/09/2014 2181 * Shows the information on the Source tab 2182 * */ 2183 GLmol.prototype.showSourceTabInfo = function(){ 2184 var strContent = '';

    126

    2185 strContent += 'You can load PDB, SDF/MOL(MDL not SYBYL) or XYZ files
    -from local disk (don\'t worry. your file '; 2186 strContent += 'will not be uploaded),
    -from RCSB PDB server,PDBID: '; 2188 strContent += '
    -from PubChem server,'; 2190 strContent += 'Compound ID(CID):
    '; 2192 strContent += '-or from the textarea below.

    '; 2195 $('#' + this.id + '_srccontents').html(strContent); 2196 }; 2197 2198 /* EM 03/09/2014 2199 * Shows the information on the View tab 2200 * */ 2201 GLmol.prototype.showViewTabInfo = function(){ 2202 var strContent = ''; 2203 strContent += 'Color by
    '; 2211 strContent += ''; 2212 strContent += 'Select a highlight color and select sequence to highlight:'; 2218 strContent += '
    '; 2219 strContent += '

    '; 2220 strContent += 'Highligh Amino Acid:
    '; 2221 strContent += ' A '; 2222 strContent += ' R '; 2223 strContent += ' N ';

    127

    2224 strContent += ' D '; 2225 strContent += ' C '; 2226 strContent += ' Q '; 2227 strContent += ' E '; 2228 strContent += ' G '; 2229 strContent += ' H '; 2230 strContent += ' I
    '; 2231 strContent += ' L '; 2232 strContent += ' K '; 2233 strContent += ' M '; 2234 strContent += ' F '; 2235 strContent += ' P '; 2236 strContent += ' S '; 2237 strContent += ' T '; 2238 strContent += ' W '; 2239 strContent += ' Y '; 2240 strContent += ' V

    '; 2241 strContent += ''; 2242 strContent += ' Main chain as
    '; 2251 strContent += ''; 2252 strContent += ' Nucleic acid bases as
    '; 2257 strContent += 'Side chains as lines
    ';

    128

    2258 strContent += 'Don\'t smoothen beta-sheets in ribbons
    '; 2259 strContent += 'Non- bonded atoms (solvent/ions) as
    '; 2262 strContent += ''; 2263 strContent += ' Small molecules(HETATMs) as
    '; 2271 strContent += ' Multiple bond option is for SDF/MOL file ONLY.
    '; 2272 strContent += 'Unit cell
    '; 2273 strContent += 'Biological assembly (the last one defined)
    '; 2274 strContent += 'Crystal packing
    '; 2275 strContent += 'Show HETATMs in symmetry mates (slower)
    '; 2276 strContent += ' Background color: '; 2281 strContent += ' Projection:
    '; 2284 strContent += ''; 2285 strContent += ' '; 2286 $('#' + this.id + '_viewcontents').html(strContent); 2287 }; 2288 2289 /* EM 03/09/2014 2290 * Shows the information on the Rotate Zoom Slab Translate tab 2291 * 2292 * */ 2293 GLmol.prototype.showOptionTab = function(){ 2294 var strContents = ''; 2295 strContents += 'Rotate
    '; 2296 strContents += 'Translate
    ';

    129

    2297 strContents += 'Zoom
    '; 2298 strContents += 'Slab

    '; 2299 strContents += ''; 2301 $('#' + this.id + '_options').html(strContents); 2302 }; 2303 2304 /* EM 03/09/2014 2305 * Shows the information on the loading box when the molecule is loading 2306 * */ 2307 GLmol.prototype.showLoading = function(){ 2308 var strContents = ''; 2309 strContents += '

    Loading structure from server... It may take a while.

    '; 2310 strContents += '

    If you believe something went wrong, please make sure PDB ID is correct.
    Please also make'; 2311 strContents += ' sure that WebGL is enabled in your browser.

    '; 2317 $('#' + this.id + '_loading').html(strContents); 2318 }; 2319 2320 /* Moved from viewer.html to here 2321 This function is now called by object.addTab(idTab, height, index) instead of addTab(idTab, height, index) 2322 * */ 2323 GLmol.prototype.addTab = function(idTab, height, zIndex){ 2324 var tabId = "#" + this.id + idTab; //added this line 2325 $(tabId + ' .bottomTab').toggle( 2326 function() { 2327 $(tabId + ' .insideTab').show(); 2328 $(tabId). 2329 css('z-index', 100). 2330 animate({top: "110px", bottom: '100px', 'height': (window.innerWidth > 800) ? height : '300px'}); 2331 }, 2332 function() { 2333 $(tabId + ' .insideTab').hide(); 2334 $(tabId). 2335 css('z-index', zIndex). 2336 animate({top: '480px', bottom: '0px', 'height': '0px'}); 2337 } 2338 ); 2339 };

    130

    5. widgetFunctionality.js This appendix holds the contents of the file “widgetFunctionality.js.” The latter is a JavaScript file that contains several functions that support the widgets so they work properly.

    1 /* This file contains the functions needed for the widgets to work correctly. 2 * The widgets are: GLmol widgets, true/false questions, multipleChoiceQuestion 3 * Textarea 4 */ 5 6 function download(query, id) { 7 id.showOptionTab(); 8 var baseURL = ""; 9 if (query.substr(0, 4) == "pdb:") 10 { 11 query = query.substr(4).toUpperCase(); 12 if (!query.match(/^[1-9][A-Za-z0-9]{3}$/)) 13 { 14 alert("Wrong PDB ID"); return; 15 } 16 uri = "http://www.pdb.org/pdb/files/" + query + ".pdb"; 17 } 18 else if (query.substr(0, 4) == "cid:") 19 { 20 query = query.substr(4); 21 if (!query.match(/^[1-9]+$/)) { 22 alert("Wrong Compound ID"); return; } 23 uri = "http://www.pubchem.ncbi.nlm.nih.gov/rest/pug/compound/cid/" + 24 query + "/SDF?record_type=3d"; 25 } 26 27 id.showLoading(); 28 $("#loading").show(); 29 $.get(uri, function(ret) { 30 $('#' + id.id + '_src').val(ret); 31 $('#' + id.id + '_srctxt').val($('#' + id.id + '_src').val()); 32 id.loadMolecule(); 33 $("div.loadingMsg").hide(); 34 $("#loading").hide(); } 35 ); 36 } 37 38 function loadFile(id) { 39 var file = $("#" + id.id + "_file").get(0); 40 if (file) file = file.files; 41 if (!file || !window.FileReader || !file[0]) 42 { 43 alert("No file is selected. Or File API is not supported in your browser. Please try Firefox or Chrome."); 44 return; 45 } 46 $("#loading").show(); 47 var reader = new FileReader(); 48 reader.onload = function()

    131

    49 { 50 $("#" + id.id + "_src").val(reader.result); 51 id.loadMolecule(); 52 $("#loading").hide(); 53 }; 54 reader.readAsText(file[0]); 55 } 56 57 function saveImage(id) { 58 id.show(); 59 var imageURI = id.renderer.domElement.toDataURL("image/png"); 60 window.open(imageURI); 61 } 62 63 function addGLmolObject(id){ 64 id.showAboutTabInfo(); 65 id.showSourceTabInfo(); 66 id.showViewTabInfo(); 67 id.addTab("_srcbox", "300px", 1); 68 id.addTab("_viewbox", "300px", 2); 69 id.addTab("_infobox", "300px", 0); 70 id.defineRepresentation = id.defineRepFromController; 71 } 72 73 function isTrueFalse(name, count){ 74 var value = $("#correctValue"+count).val(); 75 var msgId = $("#answerid"+count).val(); 76 var msg1 = $("#msg1"+count).val(); 77 var msg2 = $("#msg2"+count).val(); 78 if(value == "True") { value = "true"; } if(value == "False") { value = "false"; } 79 if(value == name.value){ console.log("correct"); 80 $("#" + msgId).html(" Correct. " + msg1); 81 } 82 else{ 83 $("#" + msgId).html(" Incorrect. " + msg2); 84 } 85 } 86 87 function multipleChoice(name, count){ 88 var value = $("#cValue").val(); 89 if(name.id == value){ 90 if( name.id == "A" ) 91 { $("#displayMsg1"+count).html("" + $("#fcExplanation").val()); } 92 else if( name.id == "B" ) 93 { $("#displayMsg2"+count).html("" + $("#scExplanation").val());} 94 else if( name.id == "C" ) 95 { $("#displayMsg3"+count).html("" + $("#tcExplanation").val()); } 96 else if ( name.id == "D" ) 97 { $("#displayMsg4"+count).html("" + $("#fourExplanation").val());}

    132

    98 var names = document.getElementsByName(name.name); 99 for(var i = 0; i < names.length; ++i) 100 names[i].disabled=true; 101 } 102 else{ 103 if( name.id == "A" ) 104 { $("#displayMsg1"+count).html("" + $("#fcExplanation").val());} 105 else if( name.id == "B" ) 106 { $("#displayMsg2"+count).html("" + $("#scExplanation").val()); } 107 else if( name.id == "C" ) 108 { $("#displayMsg3"+count).html("" + $("#tcExplanation").val());} 109 else if( name.id == "D" ) 110 { $("#displayMsg4"+count).html("" + $("#fourExplanation").val()); } 111 } 112 }

    6. whipst.css This appendix demonstrates the code for the file “whipst.css.” The latter file defines how the web interface looks by applying CSS properties to several parts of the document, i.e. body, header, footer, etc.

    1 body{ 2 background-color:#e3f0d2; 3 color:#4b5d23; 4 font-size: 1.2em; 5 } 6 7 header{ 8 position: absolute; 9 padding-top:5px; 10 text-shadow: 5px 5px #e3f0d2; 11 color:#4b5d23; 12 left: 100px; 13 top: 10px; 14 width: 1570px; 15 height: 50px; 16 } 17 18 footer{ 19 position: absolute; 20 left: 920px; 21 top: 1100px; 22 text-align: right; 23 font-size:0.9em; 24 } 25 26 .boxes{ 27 background-color:#D8EEAA; 28 border:solid #BACD66 1px;

    133

    29 border-radius: 12px; 30 text-align: left; 31 font-size: 13px; 32 } 33 34 .boxes:hover{ 35 background-color: #e3f8d2; 36 } 37 38 #trueFalseQuestion { 39 position:absolute; 40 left:60px; 41 top:100px; 42 width: 70px; 43 height: 60px; 44 padding: 10px; 45 } 46 47 #multipleChoiceQuestion { 48 position:absolute; 49 top:190px; 50 left:60px; 51 width: 70px; 52 height: 60px; 53 padding: 10px; 54 } 55 56 #glmolwidget1_{ 57 position:absolute; 58 left:60px; 59 top:280px; 60 width: 70px; 61 height: 60px; 62 padding: 10px; 63 } 64 65 #glmolwidget2_{ 66 position:absolute; 67 left:60px; 68 top:370px; 69 width: 70px; 70 height: 60px; 71 padding: 10px; 72 } 73 74 #glmolwidget3_{ 75 position:absolute; 76 left:60px; 77 top:460px; 78 width: 70px; 79 height: 60px; 80 padding: 10px; 81 } 82 83 #paragraphText{

    134

    84 position:absolute; 85 left:60px; 86 top:550px; 87 width: 70px; 88 height: 60px; 89 padding: 10px; 90 } 91 92 #heading{ 93 position:absolute; 94 left:60px; 95 top:610px; 96 width: 70px; 97 height: 60px; 98 padding: 10px; 99 } 100 101 .pdbidInput{ 102 width: 40px; 103 } 104 105 .inputtext{ 106 width: 350px; 107 } 108 109 ul{ 110 list-style:none; 111 } 112 113 li .ui-draggable, .boxes{ 114 list-style:none; 115 width: 80px; 116 height: 70px; 117 padding: 0.5em; 118 } 119 120 121 .boxlist{ 122 position: absolute; 123 top: 100px; 124 left: 250px; 125 height: 790px; 126 width: 700px; 127 border-radius: 15px; 128 border: 2px solid #BACD66; 129 padding: 2px 0px; 130 background-color: #f1fbe8; 131 } 132 133 #title{ 134 position:relative; 135 left:30px; 136 } 137 .sortableList{ 138 top:30px;

    135

    139 width:650px; 140 height:745px; 141 border-radius: 12px; 142 overflow:scroll; 143 } 144 145 #trashContainer span{ 146 position:absolute; 147 left: 60px; 148 margin-top: 10px; 149 font-size: 1.0em; 150 } 151 152 #trashContainer{ 153 position:absolute; 154 top: 100px; 155 left: 1000px; 156 width: 80px; 157 height: 70px; 158 background-color: #e3f8d2; 159 border: #e3c8d2 dotted 1px ; 160 border-radius: 12px; 161 text-align: center; 162 padding: 10px; 163 } 164 #templateSelector{ 165 position: absolute; 166 top: 250px; 167 left: 1000px; 168 width: 80px; 169 height: 70px; 170 background-color: #e3f8d2; 171 border: #e3c8d2 dotted 1px ; 172 border-radius: 12px; 173 text-align: left; 174 padding: 0.5em; 175 } 176 177 #sortable-delete{ 178 margin-top: 0px; 179 margin-left: 10px; 180 border-radius: 12px; 181 background-image:url(https://lh5.googleusercontent.com/- tRFnx7ejDFg/U2fc20pO8vI/AAAAAAAAAuM/wsjyuzIE2ps/s60-no/trash_green_.png); 182 background-repeat:no-repeat; 183 widht:200px; 184 height:200px; 185 } 186 187 #sortable-delete li { 188 height: 0; 189 width: 0; 190 overflow: hidden; 191 text-align: center; 192 }

    136

    193 194 #trashContainer:hover{ 195 border: 1px solid #687e30; 196 background-image: -moz-linear-gradient(#a5cb5e, #cae387); 197 background-image: --gradient(linear, 0% 0%, 0% 100%, from(#cae387), to(#a5cb5e)); 198 background-image: -webkit-linear-gradient(#a5cb5e, #cae387); 199 background-image: -o-linear-gradient(#a5cb5e, #cae387); 200 background-color: #cae387; 201 opacity: 0.8; 202 } 203 204 #txtContainer{ 205 width:600px; 206 height: 100px; 207 border:1px solid black; 208 } 209 210 .smallBtn{ 211 width:30px; 212 height:30px 213 } 214 215 .placeholder { 216 width: 600px; 217 height: 100px; 218 list-style-type: none; 219 text-align: center; 220 font-style: italic; 221 border: 1px dashed #ddd !important; 222 background-color: #f1fbe8 !important; 223 color: #aaa !important; 224 } 225 226 #generateButton{ 227 left:1000px; 228 top: 800px; 229 } 230 231 #buttonMsg{ 232 position:absolute; 233 left:1000px; 234 top: 850px; 235 } 236 237 #resetButton{ 238 left: 1000px; 239 top: 750px; 240 } 241 242 .hidden{ 243 visibility: hidden; 244 display: none; 245 } 246 /*http://www.hongkiat.com/blog/css3-button-tutorials/ */

    137

    247 .button { 248 position:absolute; 249 display: block; 250 font-size: 14px; 251 text-decoration: none!important; 252 font-family: "Andale Mono", AndaleMono, monospace; 253 padding: 8px 12px; 254 border-radius: 3px; 255 -moz-border-radius: 3px; 256 box-shadow: inset 0px 0px 2px #fff; 257 -o-box-shadow: inset 0px 0px 2px #fff; 258 -webkit-box-shadow: inset 0px 0px 2px #fff; 259 -moz-box-shadow: inset 0px 0px 2px #fff; 260 } 261 262 .button:active { 263 box-shadow: inset 0px 0px 3px #999; 264 -o-box-shadow: inset 0px 0px 3px #999; 265 -webkit-box-shadow: inset 0px 0px 3px #999; 266 -moz-box-shadow: inset 0px 0px 3px #999; 267 } 268 269 /* Large Styles */ 270 .large {padding: 12px 24px;} 271 272 /* The styles for the green button */ 273 .green { 274 color: #5a742d; 275 border: 1px solid #95b959; 276 background-image: -moz-linear-gradient(#cae387, #a5cb5e); 277 background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#a5cb5e), to(#cae387)); 278 background-image: -webkit-linear-gradient(#cae387, #a5cb5e); 279 background-image: -o-linear-gradient(#cae387, #a5cb5e); 280 text-shadow: 1px 1px 1px #dff4bc; 281 background-color: #a5cb5e; 282 } 283 284 .green:hover { 285 border: 1px solid #687e30; 286 background-image: -moz-linear-gradient(#a5cb5e, #cae387); 287 background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, from(#cae387), to(#a5cb5e)); 288 background-image: -webkit-linear-gradient(#a5cb5e, #cae387); 289 background-image: -o-linear-gradient(#a5cb5e, #cae387); 290 background-color: #cae387; 291 } 292 293 .green:active { 294 border: 1px solid #506320; 295 } 296 297 .left { 298 border-top-right-radius: 0px; 299 -moz-border-top-right-radius: 0px; 300 border-bottom-right-radius: 0px; 138

    301 -moz-border-bottom-right-radius: 0px; 302 border-right: 0px; 303 } 304 305 .left:hover { 306 border-right: 0px; 307 } 308 309 .right { 310 border-top-left-radius: 0px; 311 -moz-border-top-left-radius: 0px; 312 border-bottom-left-radius: 0px; 313 -moz-border-bottom-left-radius: 0px; 314 } 315 316 ::-webkit-scrollbar { 317 height: 12px; 318 width: 12px; 319 -webkit-border-radius:15px; 320 background: #e3f8d2; 321 } 322 323 ::-webkit-scrollbar-thumb { 324 background: #e3f8d2; 325 -webkit-border-radius:15px; 326 -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75); 327 } 328 329 ::-webkit-scrollbar-corner { 330 -webkit-border-radius:15px; 331 background: #e3c9d2; 332 } 333 334 /* 335 For the GLmol object*/ 336 337 .glmolCanvas { 338 position: absolute; 339 background-color:#000000; 340 box-sizing:border-box; 341 -moz-box-sizing:border-box; /* Firefox */ 342 width: 680px; 343 height:500px; 344 margin-left: 230px; 345 } 346 347 .selectionObj{ 348 position:absolute; 349 border:1px groove #FFFFFF; 350 border-radius:10px; 351 padding:5px 10px; 352 background-color: transparent; 353 font-size:1em; 354 color:#FFF1E8; 355 top:30px;

    139

    356 opacity: 1.0; 357 } 358 359 .active_checkbox{ 360 display:inline; 361 } 362 363 .glmolsidechainbutton{ 364 position: absolute; 365 top: 425px; 366 width:100px; 367 height:27px; 368 } 369 .glmolbutton{ 370 position: absolute; 371 top: 465px; 372 width:90px; 373 height:27px; 374 } 375 .optionsTab{ 376 position: absolute; 377 color: white; 378 right: 10px; 379 bottom: 10px; 380 z-index: 99; 381 background-color: rgba(0, 0, 0, 0.65); 382 } 383 .pdbTitle{ 384 position:absolute; 385 color: white; 386 background-color: rgba(0, 0, 0, 0.65); 387 font-size:80%; 388 } 389 390 .loadingMsg{ 391 border: 2px solid white; 392 position: absolute; 393 color: white; 394 left: 10%; 395 top: 10%; 396 padding: 5px; 397 z-index:101; 398 } 399 400 iframe{ 401 margin-left: 0px; 402 width: 1150px; 403 height: 800px; 404 }

    140

    7. simple.css This appendix shows the contents for the file “simple.css.” The latter file defines a simple template that displays every widget in the order they are in the middle area from top to bottom.

    405 /* Programmer: Elizabeth Montes 406 * Start Date: 02/25/2014 407 * End Date: 408 */ 409 410 .hidden { 411 display: none; 412 } 413 414 body { 415 background:#F7FAF8; 416 width: 1000px; 417 } 418 419 button:hover { 420 background:#FFF1E8; 421 opacity: 0.5; 422 color:#000000; 423 font-weight:bold; 424 } 425 426 header{ 427 margin-left:120px; 428 } 429 430 p{ 431 margin-left:100px; 432 } 433 434 footer{ 435 position:absolute; 436 } 437 438 .info_container { 439 background-color:#F7FAF8; 440 text-align: left; 441 position: absolute; 442 width: 1398px; 443 height: 650px; 444 } 445 446 .glmolCanvas { 447 position: relative; 448 background-color:#000000; 449 box-sizing:border-box; 450 -moz-box-sizing:border-box; /* Firefox */ 451 width: 750px; 452 height:500px; 453 left:100px;

    141

    454 } 455 456 .selectionObj{ 457 position:absolute; 458 border:1px groove #FFFFFF; 459 border-radius:10px; 460 padding:5px 10px; 461 background-color: transparent; 462 font-size:1em; 463 color:#FFF1E8; 464 top:30px; 465 opacity: 1.0; 466 } 467 468 .glmoltextarea { 469 top:80px; 470 width:720px; 471 height:50px; 472 background-color: #FFF1E8; 473 font-size:1em; 474 color:#000000; 475 opacity: 0.8; 476 font-weight:bold; 477 } 478 479 .divhighlight{ 480 top:80px; 481 width:680px; 482 height:80px; 483 } 484 485 .glmoltxtview{ 486 width:480px; 487 height:50px; 488 } 489 490 .glmolSelButton { 491 top:130px; 492 left:550px; 493 width:170px; 494 height:30px; 495 } 496 497 .active_checkbox{ 498 display:inline; 499 } 500 501 .glmolsidechainbutton{ 502 position: absolute; 503 top: 440px; 504 width:90px; 505 height:18px; 506 } 507 508 .glmolbutton{

    142

    509 position: absolute; 510 top: 470px; 511 width:90px; 512 height:27px; 513 font-size: 0.8em; 514 } 515 516 .choosecolor{ 517 position:absolute; 518 top:0px; 519 border:1px groove #FFFFFF; 520 border-radius:8px; 521 background-color: transparent; 522 color:#FFFFFF; 523 } 524 525 table{ 526 border-width:2px; 527 width: 750px; 528 margin-left:100px; 529 } 530 531 td{ 532 width: 2500px; 533 } 534 535 .narrow{ 536 width: 50px; 537 } 538 539 td,th,tr{ 540 border-width:1px; 541 } 542 543 th{ 544 background-color: #EDE9F2; 545 } 546 547 table, th, td{ 548 border-color:#F768C0; 549 border-style: groove; 550 padding: 6px; 551 552 } 553 554 ::-webkit-scrollbar { 555 height: 12px; 556 width: 12px; 557 background: #EDE9F2; 558 } 559 560 ::-webkit-scrollbar-thumb { 561 background: #C3CDD6; 562 -webkit-border-radius:5px; 563 -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75);

    143

    564 } 565 566 ::-webkit-scrollbar-corner { 567 background: #C3CDD6; 568 } 569 570 input, select, button, textarea{ 571 border: 1px solid white; 572 background-color: black; 573 color: white; 574 } 575 576 .tabBox { 577 top: 480px; 578 position: absolute; 579 padding: 0px; 580 color: white; 581 height: 20px; 582 width: 200px; 583 left: 320px; 584 } 585 586 .bottomTab { 587 background-color: black; 588 border: 1px solid white; 589 color: white; 590 margin: 0px; 591 padding: 10px 10px 0px 10px; 592 -webkit-border-radius: 10px 10px 0px 0px; 593 -moz-border-radius: 10px 10px 0px 0px; 594 } 595 596 .insideTab { 597 border: 1px solid white; 598 width: 500px; 599 height: 370px; 600 background-color: rgba(0, 0, 0, 0.85); 601 margin:0px; 602 } 603 604 .tabBox p, .tabBox h1, .tabBox ul { 605 margin-left: 10px; 606 font-size: 90%; 607 } 608 609 .srcBox{ 610 left:10px; 611 z-index: 0; 612 } 613 614 .viewBox{ 615 left:110px; 616 z-index: 1; 617 } 618

    144

    619 .infoBox{ 620 left:230px; 621 z-index: 2; 622 } 623 624 .highlightBox{ 625 left: 310px; 626 z-index: 3; 627 } 628 629 .scroll{ 630 overflow: scroll; 631 } 632 633 .autoOverflow{ 634 overflow:auto; 635 } 636 637 .optionsTab{ 638 position: absolute; 639 color: white; 640 right: 10px; 641 bottom: 10px; 642 z-index: 99; 643 background-color: rgba(0, 0, 0, 0.65); 644 } 645 646 .pdbTitle{ 647 position:absolute; 648 color: white; 649 background-color: rgba(0, 0, 0, 0.65); 650 font-size:80%; 651 } 652 653 .loadingMsg{ 654 border: 2px solid white; 655 position: absolute; 656 color: white; 657 left: 10%; 658 top: 10%; 659 padding: 5px; 660 z-index:101; 661 }

    8. left.css This appendix contains the code for file “left.css” that defines the left template used by the generated tutorial. This file sends all GLmol widgets to the left side of the screen and the rest of the widgets to the right side in where they are ordered as they appear in the middle area in the web interface.

    1 /* Programmer: Elizabeth Montes 2 * Start Date: 02/25/2014 3 * End Date:

    145

    4 */ 5 6 #tabs { 7 width: 683px; 8 margin-left: 0px; 9 margin-right: auto; 10 margin-top: 10px; 11 background-color:#C3CDD6; 12 } 13 14 .hidden { 15 display: none; 16 } 17 18 body { 19 background:#F7FAF8; 20 } 21 22 button:hover { 23 background:#FFF1E8; 24 opacity: 0.5; 25 color:#000000; 26 font-weight:bold; 27 } 28 29 fieldset{ 30 position:absolute; 31 border: #F768C0 solid 1px; 32 width: 1366px; 33 height: 768px; 34 } 35 36 header{ 37 position:relative; 38 top:0px; 39 height: 50px; 40 text-align: center; 41 } 42 43 footer{ 44 position:relative; 45 top:710px; 46 height: 50px; 47 text-align: center; 48 } 49 50 #left{ 51 position:absolute; 52 top:70px; 53 left: 0px; 54 width: 683px; 55 border: solid #000000 none none none 1px; 56 } 57 58 #right{

    146

    59 position: absolute; 60 top: 70px; 61 left: 700px; 62 width: 683px; 63 height: 710px; 64 overflow: auto; 65 } 66 67 .info_container { 68 background-color:#F7FAF8; 69 text-align: left; 70 position: absolute; 71 width: 1398px; 72 height: 650px; 73 } 74 75 .glmolCanvas { 76 position: absolute; 77 left: 10px; 78 background-color:#000000; 79 box-sizing:border-box; 80 -moz-box-sizing:border-box; /* Firefox */ 81 width: 680px; 82 height:500px; 83 } 84 85 .selectionObj{ 86 position:absolute; 87 border:1px groove #FFFFFF; 88 border-radius:10px; 89 padding:5px 10px; 90 background-color: transparent; 91 font-size:1em; 92 color:#FFF1E8; 93 top:40px; 94 opacity: 1.0; 95 } 96 97 .glmoltextarea { 98 top:80px; 99 width:650px; 100 height:50px; 101 background-color: #FFF1E8; 102 font-size:1em; 103 color:#000000; 104 opacity: 0.8; 105 font-weight:bold; 106 } 107 108 .glmoltxtview{ 109 width:480px; 110 height:50px; 111 } 112 113 .glmolSelButton {

    147

    114 top:130px; 115 left:500px; 116 width:170px; 117 height:30px; 118 } 119 120 .glmolsidechainbutton{ 121 position: absolute; 122 top: 415px; 123 width:90px; 124 height:27px; 125 } 126 127 .glmolbutton{ 128 position: absolute; 129 top: 455px; 130 width:90px; 131 height:27px; 132 } 133 134 .divhighlight{ 135 top:80px; 136 width:680px; 137 height:80px; 138 } 139 140 .choosecolor{ 141 position:absolute; 142 top:0px; 143 border:1px groove #FFFFFF; 144 border-radius:8px; 145 background-color: transparent; 146 color:#FFFFFF; 147 } 148 149 .active_checkbox{ 150 display:inline; 151 } 152 153 table{ 154 border-width:2px; 155 width: 650px; 156 } 157 158 td{ 159 width: 200px; 160 } 161 162 .narrow{ 163 width: 50px; 164 } 165 166 td,th,tr{ 167 border-width:1px; 168 }

    148

    169 170 th{ 171 background-color: #EDE9F2; 172 } 173 174 table, th, td{ 175 border-color:#F768C0; 176 border-style: groove; 177 padding: 6px; 178 179 } 180 181 ::-webkit-scrollbar { 182 height: 12px; 183 width: 12px; 184 background: #EDE9F2; 185 } 186 187 ::-webkit-scrollbar-thumb { 188 background: #C3CDD6; 189 -webkit-border-radius:5px; 190 -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75); 191 } 192 193 ::-webkit-scrollbar-corner { 194 background: #C3CDD6; 195 } 196 197 input, select, button, textarea{ 198 border: 1px solid white; 199 background-color: black; 200 color: white; 201 } 202 203 .tabBox { 204 top: 480px; 205 position: absolute; 206 padding: 0px; 207 color: white; 208 height: 20px; 209 left: 320px; 210 } 211 212 .bottomTab { 213 background-color: black; 214 border: 1px solid white; 215 color: white; 216 margin: 0px; 217 padding: 10px 10px 0px 10px; 218 -webkit-border-radius: 10px 10px 0px 0px; 219 -moz-border-radius: 10px 10px 0px 0px; 220 } 221 222 .insideTab { 223 border: 1px solid white;

    149

    224 width: 500px; 225 height: 370px; 226 background-color: rgba(0, 0, 0, 0.85); 227 margin:0px; 228 } 229 230 .tabBox p, .tabBox h1, .tabBox ul { 231 margin-left: 10px; 232 font-size: 90%; 233 } 234 235 .srcBox{ 236 left:10px; 237 width: 200px; 238 z-index: 0; 239 } 240 241 .viewBox{ 242 left:110px; 243 width: 200px; 244 z-index: 1; 245 } 246 247 .infoBox{ 248 left:230px; 249 width: 150px; 250 z-index: 2; 251 } 252 253 .highlightBox{ 254 left: 310px; 255 z-index: 3; 256 } 257 258 .scroll{ 259 overflow: scroll; 260 } 261 262 .autoOverflow{ 263 overflow:auto; 264 } 265 266 .optionsTab{ 267 position: absolute; 268 color: white; 269 right: 10px; 270 bottom: 10px; 271 z-index: 99; 272 background-color: rgba(0, 0, 0, 0.65); 273 } 274 275 .pdbTitle{ 276 position:absolute; 277 color: white; 278 background-color: rgba(0, 0, 0, 0.65);

    150

    279 font-size:80%; 280 } 281 282 .loadingMsg{ 283 border: 2px solid white; 284 position: absolute; 285 color: white; 286 left: 10%; 287 top: 10%; 288 padding: 5px; 289 z-index:101; 290 } 291 292 #myTabs { 293 background: transparent; 294 border: none; 295 } 296 297 #myTabs .ui-widget-header { 298 background: transparent; 299 border: none; 300 border-bottom: 1px solid #c0c0c0; 301 -moz-border-radius: 0px; 302 -webkit-border-radius: 0px; 303 border-radius: 0px; 304 } 305 306 #myTabs .ui-tabs-nav .ui-state-default { 307 background: transparent; 308 border: none; 309 } 310 311 #myTabs .ui-tabs-nav .ui-state-active { 312 background: transparent; 313 border: none; 314 } 315 316 #myTabs .ui-tabs-nav .ui-state-default a { 317 color: #c0c0c0; 318 } 319 320 #myTabs .ui-tabs-nav .ui-state-active a { 321 color: #F768C0; 322 }

    9. right.css This appendix contains the code for file “right.css” that defines the right template used by the generated tutorial. This file sends all GLmol widgets to the right side of the screen and the rest of the widgets to the left side in where they are ordered as they appear in the middle area in the web interface.

    1 /* Programmer: Elizabeth Montes 2 * Start Date: 02/25/2014

    151

    3 * End Date: 4 */ 5 6 #tabs { 7 width: 687px; 8 margin-left: 0px; 9 margin-right: auto; 10 background-color:#C3CDD6; 11 } 12 13 .hidden { 14 display: none; 15 } 16 17 body { 18 background:#F7FAF8; 19 } 20 21 p{ 22 margin-left: 15px; 23 } 24 25 button:hover { 26 background:transparent; 27 } 28 29 fieldset{ 30 position:absolute; 31 border: #F768C0 solid 1px; 32 width: 1366px; 33 height: 768px; 34 } 35 36 header{ 37 position:relative; 38 top:0px; 39 height: 50px; 40 text-align: center; 41 } 42 43 footer{ 44 position:relative; 45 top:710px; 46 height: 50px; 47 text-align: center; 48 } 49 50 #right{ 51 position:absolute; 52 top:70px; 53 left: 0px; 54 width: 683px; 55 height: 710px; 56 border: solid #000000 none none none 1px; 57 overflow: auto;

    152

    58 } 59 60 #left{ 61 position: absolute; 62 top: 70px; 63 left: 680px; 64 width: 683px; 65 height: 710px; 66 } 67 68 .info_container { 69 background-color:#F7FAF8; 70 text-align: left; 71 position: absolute; 72 width: 1398px; 73 height: 650px; 74 } 75 76 .glmolCanvas { 77 position: absolute; 78 left: 10px; 79 background-color:#000000; 80 box-sizing:border-box; 81 -moz-box-sizing:border-box; /* Firefox */ 82 width: 680px; 83 height:500px; 84 } 85 86 .selectionObj{ 87 position:absolute; 88 border:1px groove #FFFFFF; 89 border-radius:10px; 90 padding:5px 10px; 91 background-color: transparent; 92 font-size:1em; 93 color:#FFF1E8; 94 top:40px; 95 opacity: 1.0; 96 } 97 98 .glmoltextarea { 99 top:80px; 100 width:650px; 101 height:50px; 102 background-color: #FFF1E8; 103 font-size:1em; 104 color:#000000; 105 opacity: 0.8; 106 font-weight:bold; 107 } 108 109 .glmoltxtview{ 110 width:480px; 111 height:50px; 112 }

    153

    113 114 .glmolSelButton { 115 top:130px; 116 left:500px; 117 width:170px; 118 height:30px; 119 } 120 121 .glmolsidechainbutton{ 122 position: absolute; 123 top: 415px; 124 width:90px; 125 height:27px; 126 } 127 128 .glmolbutton{ 129 position: absolute; 130 top: 455px; 131 width:90px; 132 height:27px; 133 } 134 135 .divhighlight{ 136 top:80px; 137 width:680px; 138 height:80px; 139 } 140 141 .choosecolor{ 142 position:absolute; 143 top:0px; 144 border:1px groove #FFFFFF; 145 border-radius:8px; 146 background-color: transparent; 147 color:#FFFFFF; 148 } 149 150 table{ 151 border-width:2px; 152 width: 650px; 153 } 154 155 td{ 156 width: 200px; 157 } 158 159 .narrow{ 160 width: 50px; 161 } 162 163 td,th,tr{ 164 border-width:1px; 165 } 166 167 th{

    154

    168 background-color: #EDE9F2; 169 } 170 171 table, th, td{ 172 border-color:#F768C0; 173 border-style: groove; 174 padding: 6px; 175 176 } 177 178 ::-webkit-scrollbar { 179 height: 12px; 180 width: 12px; 181 background: #EDE9F2; 182 } 183 184 ::-webkit-scrollbar-thumb { 185 background: #C3CDD6; 186 -webkit-border-radius:5px; 187 -webkit-box-shadow: 0px 1px 2px rgba(0, 0, 0, 0.75); 188 } 189 190 ::-webkit-scrollbar-corner { 191 background: #C3CDD6; 192 } 193 194 input, select, button, textarea{ 195 border: 1px solid white; 196 background-color: black; 197 color: white; 198 } 199 200 .tabBox { 201 top: 480px; 202 position: absolute; 203 padding: 0px; 204 color: white; 205 height: 20px; 206 width: 200px; 207 left: 320px; 208 } 209 210 .bottomTab { 211 background-color: black; 212 border: 1px solid white; 213 color: white; 214 margin: 0px; 215 padding: 10px 10px 0px 10px; 216 -webkit-border-radius: 10px 10px 0px 0px; 217 -moz-border-radius: 10px 10px 0px 0px; 218 } 219 220 .insideTab { 221 border: 1px solid white; 222 width: 500px;

    155

    223 height: 370px; 224 background-color: rgba(0, 0, 0, 0.85); 225 margin:0px; 226 } 227 228 .tabBox p, .tabBox h1, .tabBox ul { 229 margin-left: 10px; 230 font-size: 90%; 231 } 232 233 .srcBox{ 234 left:10px; 235 z-index: 0; 236 } 237 238 .viewBox{ 239 left:110px; 240 z-index: 1; 241 } 242 243 .infoBox{ 244 left:230px; 245 z-index: 2; 246 } 247 248 .highlightBox{ 249 left: 310px; 250 z-index: 3; 251 } 252 253 .scroll{ 254 overflow: scroll; 255 } 256 257 .autoOverflow{ 258 overflow:auto; 259 } 260 261 .optionsTab{ 262 position: absolute; 263 color: white; 264 right: 10px; 265 bottom: 10px; 266 z-index: 99; 267 background-color: rgba(0, 0, 0, 0.65); 268 } 269 270 .pdbTitle{ 271 position:absolute; 272 color: white; 273 background-color: rgba(0, 0, 0, 0.65); 274 font-size:80%; 275 } 276 277 .loadingMsg{

    156

    278 border: 2px solid white; 279 position: absolute; 280 color: white; 281 left: 10%; 282 top: 10%; 283 padding: 5px; 284 z-index:101; 285 } 286 287 .active_checkbox{ 288 display:inline; 289 } 290 291 #myTabs { 292 background: transparent; 293 border: none; 294 } 295 296 #myTabs .ui-widget-header { 297 background: transparent; 298 border: none; 299 border-bottom: 1px solid #c0c0c0; 300 -moz-border-radius: 0px; 301 -webkit-border-radius: 0px; 302 border-radius: 0px; 303 } 304 305 #myTabs .ui-tabs-nav .ui-state-default { 306 background: transparent; 307 border: none; 308 } 309 310 #myTabs .ui-tabs-nav .ui-state-active { 311 background: transparent ; 312 border: none; 313 } 314 315 #myTabs .ui-tabs-nav .ui-state-default a { 316 color: #c0c0c0; 317 } 318 319 #myTabs .ui-tabs-nav .ui-state-active a { 320 color: #F768C0; 321 }

    157