/lenasys/0.1

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/lenasys/0.1
1 by Henrik G.
First seed of Lenasys ... Needs to be Organized Further
1
DROP DATABASE dsystem;
2
CREATE DATABASE dsystem;
3
USE dsystem;
4
/* Student-tabell för att hålla koll på vilka som genomfört duggorna */
5
CREATE TABLE Student(
6
    ssn CHAR(11), /*YYMMDD-XXXX*/
7
    name VARCHAR(100),
8
    loginName VARCHAR(50), /*a02leifo */
9
    passw VARCHAR(50), /*MD5-hashat lösenord*/
10
    PRIMARY KEY(ssn)    
11
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
12
13
/*Tabell över kurser*/
14
CREATE TABLE Course(
15
    name VARCHAR(200),
16
    PRIMARY KEY(name)
17
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
18
19
CREATE TABLE StudentCourseRegistration(
20
    studentSsn CHAR(11), /*YYMMDD-XXXX*/
21
    courseName VARCHAR(200),
22
    courseOccasion VARCHAR(25),
23
    PRIMARY KEY(studentSsn, courseName, courseOccasion),
24
    FOREIGN KEY(studentSsn) REFERENCES Student(ssn),
25
    FOREIGN KEY(courseName) REFERENCES Course(name)
26
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
27
28
CREATE TABLE Quiz(
29
    nr INTEGER,
30
    courseName VARCHAR(200),
31
	opening TIMESTAMP,
32
	closing TIMESTAMP,
33
    qData TEXT,
34
    PRIMARY KEY(nr, courseName),
35
    FOREIGN KEY(courseName) REFERENCES Course(name)
36
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
37
38
CREATE TABLE QuizVariant(
39
    qVarNr INTEGER,
40
    quizNr INTEGER,
41
    quizCourseName VARCHAR(200),
42
    correctAnswer VARCHAR(255),
43
    quizObjectIDs TEXT,
44
    PRIMARY KEY(qVarNr, quizNr, quizCourseName),
45
    FOREIGN KEY(quizNr, quizCourseName) REFERENCES Quiz(nr, courseName)
46
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
47
48
CREATE TABLE QuizVariantObject(
49
    id VARCHAR(255),
50
    quizNr INTEGER,
51
    qVarNr INTEGER,
52
    quizCourseName VARCHAR(200),
53
    objectData TEXT,
54
    PRIMARY KEY(id, quizNr, qVarNr, quizCourseName),
55
    FOREIGN KEY(qVarNr, quizNr, quizCourseName) REFERENCES QuizVariant(qVarNr, quizNr, quizCourseName)
56
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
57
58
CREATE TABLE AssignedQuizzes(
59
    ssn CHAR(11), /*YYMMDD-XXXX*/
60
    quizNr INTEGER,
61
    qVarNr INTEGER,
62
    quizCourseName VARCHAR(200),
63
	courseOccasion VARCHAR(25) NOT NULL,
64
    answerHash VARCHAR(255), /*Hash of Student login name + answer */
65
    answer TEXT,
66
	grade VARCHAR(10),
67
	gradeComment TEXT,
68
	answeredDateTime TIMESTAMP,
69
    userAgent VARCHAR(1024),
70
    userIP VARCHAR(20), /*$_SERVER['REMOTE_ADDR']*/
71
    PRIMARY KEY(ssn, qVarNr, quizNr, quizCourseName),
72
    FOREIGN KEY(ssn) REFERENCES Student(ssn),
73
    FOREIGN KEY(qVarNr, quizNr, quizCourseName) REFERENCES QuizVariant(qVarNr, quizNr, quizCourseName)
74
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
75
76
77
CREATE TABLE QSystemUser(
78
    userName     VARCHAR(16) UNIQUE NOT NULL,
79
    passw          VARCHAR(41) NOT NULL,
80
    userType     VARCHAR(10) NOT NULL,
81
    PRIMARY KEY(userName)
82
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
83
84
/* Logging of failed user login attempts */
85
CREATE TABLE logFailedUserLogins(
86
    id INTEGER AUTO_INCREMENT,
87
    loginName VARCHAR(30),
88
    userAgent VARCHAR(1024), /*$_SERVER['HTTP_USER_AGENT']*/
89
    userIP VARCHAR(20), /*$_SERVER['REMOTE_ADDR']*/
90
    DateTime TIMESTAMP,
91
    PRIMARY KEY(id)
92
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
93
94
/* Logging of successful user logins */
95
CREATE TABLE logSuccessfulUserLogins(
96
    id INTEGER AUTO_INCREMENT,
97
    loginName VARCHAR(30),
98
    userAgent VARCHAR(1024), /*$_SERVER['HTTP_USER_AGENT']*/
99
    userIP VARCHAR(20), /*$_SERVER['REMOTE_ADDR']*/
100
    DateTime TIMESTAMP,
101
    PRIMARY KEY(id)
102
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
103
104
/* Logging of failed attempt to login to the backend */
105
CREATE TABLE logFailedUserLogins(
106
    id INTEGER AUTO_INCREMENT,
107
    userName VARCHAR(16),
108
    userType VARCHAR(10),
109
    userAgent VARCHAR(1024), /*$_SERVER['HTTP_USER_AGENT']*/
110
    userIP VARCHAR(20), /*$_SERVER['REMOTE_ADDR']*/
111
    DateTime TIMESTAMP,
112
    PRIMARY KEY(id)
113
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
114
115
/* Logging of successful logins to the backend */
116
CREATE TABLE logSuccessfulUserLogins(
117
    id INTEGER AUTO_INCREMENT,
118
    userName VARCHAR(16),
119
    userType VARCHAR(10),
120
    userAgent VARCHAR(1024), /*$_SERVER['HTTP_USER_AGENT']*/
121
    userIP VARCHAR(20), /*$_SERVER['REMOTE_ADDR']*/
122
    DateTime TIMESTAMP,
123
    PRIMARY KEY(id)
124
) ENGINE=INNODB CHARACTER SET utf8 COLLATE utf8_swedish_ci;
125
126
INSERT INTO Course(name) VALUES('DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)');
127
INSERT INTO QSystemUser(userName,passw,userType) VALUES('admin','123','admin');
128
INSERT INTO Quiz(nr, courseName, qData) VALUES(1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<div id="dugga"><h1>Dugga ett för en kurs</h1><p>Duggan ditten och duggan datten</p></div>');
129
INSERT INTO QuizVariant(quizNr, qVarNr, quizCourseName, correctAnswer, quizObjectIDs) VALUES(1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','1,2,3,4,5,6,7,8','TEST1 TEST2 TEST3 TEST4 TEST5 TEST6');
130
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST1',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<div id="TEST1"><p>Du ska göra bla bla...</p></div>');
131
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST2',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<div id="TEST2"><strong>1 2 3 4 5</strong></div>');
132
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST3',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<script lang="Javascript">alert("TEST3");</script>');
133
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST4',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<script lang="Javascript">alert("&lt;TEST4");</script>');
134
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST5',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','    <style type="text/css">         * {margin:0;padding:0;}      html {font-size:125%;}     body {         background-color: #cdcdcd;         font-size:50%;         font-family:Georgia, "Times New Roman", Times, serif;         color:#333;         }              #papper{         margin: 30px auto 0;         background-color:#FFF;         width:760px;         border: 2px solid #bdbdbd;         padding: 10px;     }     p {             font-size: 1.6em;         line-height: 140%;         margin: 0 60px 20px;         text-align:justify;     }      h1{         font-size:4.1em;         font-weight:bold;         color:#83201A;         letter-spacing:-0.1em;         word-spacing:0.3em;         text-align:center;         text-transform:uppercase;     }      h2{         font-size:2.5em;         color:#54110D;         text-align:center;         margin-bottom:10px;     }      img{         float:right;         border:solid 1px #83201a;         margin: 10px;     }      h3{         font-size:3.0em;         color: #999999;         float:left;         text-align:center;         width:60px;     }      p.ingress{         font-size:1.8em;         border-top:solid 1px #cdcdcd;         padding-top: 10px;     }      blockquote{         font-size:3.2em;         color:#83201a;         line-height:1.0em;         float:right;         border-left:solid 10px #b68e55;         padding-left: 10px;         margin-left: 10px;         margin-right:10px;         width: 193px;     }      p.ingress:first-letter {         font-size:6.5em;         color:#000;         float:left;         background-color:#b68e55;         border: solid 2px #83201a;         padding: 0.1em;         margin: 0 0.1em 0.1em 0;         line-height: 1.0em;     }      p.ingress:first-line {         font-variant:small-caps;     }      q{         color:#000;     }      #sidfot{         font-size:1.2em;         text-align:center;         border-top:solid 1px #cdcdcd;         padding-top:15px;     }      #avslut{         height:30px;     }     </style>     <div id="papper">          <h1>The Time Machine</h1>         <h2>by H. G. Wells [1898]</h2>         <h3>I</h3>         <img src="images/Timemachinebook.JPG" width="213" height="336" alt="The Time Machine by H. G. Wells" />                 <p class="ingress">The Time Traveller (for so it will be convenient to speak of him)                 was expounding a recondite matter to us. His grey eyes shone and                 twinkled, and his usually pale face was flushed and animated. The                 fire burned brightly, and the soft radiance of the incandescent                 lights in the lilies of silver caught the bubbles that flashed and                 passed in our glasses. Our chairs, being his patents, embraced and                 caressed us rather than submitted to be sat upon, and there was that                 luxurious after-dinner atmosphere when thought roams gracefully                 free of the trammels of precision. And he put it to us in this                 way—marking the points with a lean forefinger—as we sat and lazily                 admired his earnestness over this new paradox (as we thought it)         and his fecundity.</p>                 <blockquote>His grey eyes shone and twinkled, and his usually pale face was flushed and animated.</blockquote>                                     <p><q>You must follow me carefully. I shall have to controvert one or two                 ideas that are almost universally accepted. The geometry, for         instance, they taught you at school is founded on a misconception.</q></p>             <p><q>Is not that rather a large thing to expect us to begin upon?</q> said         Filby, an argumentative person with red hair.</p>         <p><q>I do not mean to ask you to accept anything without reasonable                 ground for it. You will soon admit as much as I need from you. You                 know of course that a mathematical line, a line of thickness <em>nil</em>,                 has no real existence. They taught you that? Neither has a         mathematical plane. These things are mere abstractions.</q></p>             <p><q>That is all right,</q> said the Psychologist.</p>             <p><q>Nor, having only length, breadth, and thickness, can a cube have a         real existence.</q></p>             <p><q>There I object,</q> said Filby. <q>Of course a solid body may exist. All         real things—</q></p>             <p><q>So most people think. But wait a moment. Can an <em>instantaneous</em>         cube exist?</q></p>             <p><q>Dont follow you,</q> said Filby.</p>             <p><q>Can a cube that does not last for any time at all, have a real         existence?</q></p>             <p>Filby became pensive. <q>Clearly,</q> the Time Traveller proceeded, <q>any                 real body must have extension in <em>four</em> directions: it must have                 Length, Breadth, Thickness, and--Duration. But through a natural                 infirmity of the flesh, which I will explain to you in a moment, we                 incline to overlook this fact. There are really four dimensions,                 three which we call the three planes of Space, and a fourth, Time.                 There is, however, a tendency to draw an unreal distinction between                 the former three dimensions and the latter, because it happens that                 our consciousness moves intermittently in one direction along the         latter from the beginning to the end of our lives.</q></p>             <p><q>That,</q> said a very young man, making spasmodic efforts to relight         his cigar over the lamp; <q>that &#8230; very clear indeed.</q></p>     <p><q>Now, it is very remarkable that this is so extensively overlooked,</q>                 continued the Time Traveller, with a slight accession of                 cheerfulness. <q>Really this is what is meant by the Fourth Dimension,                 though some people who talk about the Fourth Dimension do not know                 they mean it. It is only another way of looking at Time. <em>There is                 no difference between Time and any of the three dimensions of Space                 except that our consciousness moves along it</em>. But some foolish                 people have got hold of the wrong side of that idea. You have all         heard what they have to say about this Fourth Dimension?</q></p>                 <div id="sidfot">Texten är hämtad från <a href="http://www.gutenberg.org/wiki/Main_Page" title="Klicka här för att besöka Project Gutenberg" target="_blank">Project Gutenberg</a>. Bilden hämtad hos <a href="http://en.wikipedia.org/wiki/The_Time_Machine" title="Klicka här för att besöka Wikipedia" target="_blank">Wikipedia</a>         </div>         </div> <div id="avslut"></div>');
135
136
DELIMITER //
137
DROP PROCEDURE IF EXISTS CHECKLOGIN;
138
CREATE PROCEDURE CHECKLOGIN(userName VARCHAR(16), userPassword VARCHAR(41))
139
BEGIN
140
   SELECT userName,passw,userType FROM QSystemUser WHERE userName=userName AND passw=userPassword;
141
END;
142
//
143
DELIMITER ;
144
145
;
146
147
148
INSERT INTO QuizVariantObject(id, quizNr, qVarNr, quizCourseName, objectData) VALUES('TEST6',1,1,'DA133G Webbutveckling - datorgrafik G1N, 7,5hp (IKI)','<div><table><tr><td><canvas id="a" width="600" height="600" style="border:2px solid black;"></canvas></td><td valign="top"><div style="border:2px solid black;background-color:#fed;width:300;height:450;"><div id="infobox" style="padding:4px;">Change values in form to update curve and information box.<br><form>Function:<select id="function" name="function" ><option value="L 100 100 200 360">Line</option><option value="Q 200 300 140 260 400 200">Quadratic Curve</option><option value="C 160 220 440 120 220 440 360 500">Cubic Curve</option><option value="S 60 80 120 240 300 260">Circle Segment</option></select><button type="button" onclick="newbutton();">NEW</button><br>Operations:<br><select style="width:150px;" size="20" id="operations" name="operations"></select><br><button type="button" onclick="moveupbutton();">MOVE UP</button><button type="button" onclick="movedownbutton();">MOVE DOWN</button><button type="button" onclick="deletebutton();">DELETE</button><br></form></div></div></td></tr></table></div><script lang="Javascript">var mx=100,my=100,clickstate=0;function newbutton(){var funclist;var oplist;funclist=document.getElementById("function");oplist=document.getElementById("operations");oplist.innerHTML+="<option value=\'"+funclist.options[funclist.selectedIndex].value+"\'>"+funclist.options[funclist.selectedIndex].text+"</option>";                                         }                 function deletebutton()         {                 var elSel = document.getElementById("operations");               var i=0;               for (i=elSel.length-1;i>=0;i--) {                     if (elSel.options[i].selected) {                       elSel.remove(i);                     }               }         }                 function moveupbutton()         {                 var elSel = document.getElementById("operations");                 var ind=elSel.selectedIndex;                 var val;                 var tex;                  if(elSel.selectedIndex>0){                                                 val=elSel.options[ind].value;                         tex=elSel.options[ind].text;                          elSel.options[ind].value=elSel.options[ind-1].value;                         elSel.options[ind].text=elSel.options[ind-1].text;                                                 elSel.options[ind-1].value=val;                         tex=elSel.options[ind-1].text=tex;                                                     elSel.selectedIndex--;                                }         }          function movedownbutton()         {                 var elSel = document.getElementById("operations");                 var ind=elSel.selectedIndex;                 var val;                 var tex;                  if(elSel.selectedIndex<elSel.length-1){                                                 val=elSel.options[ind].value;                         tex=elSel.options[ind].text;                          elSel.options[ind].value=elSel.options[ind+1].value;                         elSel.options[ind].text=elSel.options[ind+1].text;                                                 elSel.options[ind+1].value=val;                         tex=elSel.options[ind+1].text=tex;                                                     elSel.selectedIndex++;                                }                         }          function ev_mouseup(ev)         {                 clickstate=0;                 cpsel=-1;                 cpno=0;         }                 function ev_mousedown(ev)         {                 clickstate=1;         }                 function ev_mousemove (ev)         {               var cx,cy=0;               if (ev.layerX||ev.layerX==0) { // Firefox                     cx=ev.layerX-acanvas.offsetLeft;                     cy=ev.layerY-acanvas.offsetTop;               } else if (ev.offsetX || ev.offsetX == 0) { // Operacx=ev.offsetX-acanvas.offsetLeft;cy=ev.offsetY-acanvas.offsetTop;}if(clickstate==1){mx=cx;my=cy;}gridx=Math.round((cx-(gridsize/2.0))/gridsize)*gridsize;gridy=Math.round((cy-(gridsize/2.0))/gridsize)*gridsize;                        }          // Fix scrolling on touch devices         var ScrollFix = function(elem) {             // Variables to track inputs             var startY, startTopScroll;                     elem = elem || document.querySelector(elem);                     // If there is no element, then do nothing              if(!elem)                 return;                     // Handle the start of interactions             elem.addEventListener("touchstart", function(event){                 startY = event.touches[0].pageY;                 startTopScroll = elem.scrollTop;                         if(startTopScroll <= 0)                     elem.scrollTop = 1;                         if(startTopScroll + elem.offsetHeight >= elem.scrollHeight)                     elem.scrollTop = elem.scrollHeight - elem.offsetHeight - 1;             }, false);         };          var acanvas=document.getElementById("a");         var context=acanvas.getContext("2d");                acanvas.addEventListener("mousemove", ev_mousemove, false);         acanvas.addEventListener("mouseup", ev_mouseup, false);         acanvas.addEventListener("mousedown", ev_mousedown, false);                 setTimeout("foo();",20);                 var gridsize=20;         var gridx,gridy=0;          function dashedline(sx,sy,ex,ey,dashlen,linewidth,col)         {             //                point("#f88",sx,sy); //                point("#f88",dx,dy);                         var dx=ex-sx;             var dy=ey-sy;                                         len=Math.sqrt((dx*dx)+(dy*dy));             notimes=Math.round(len/dashlen);                         dx=dx/notimes;             dy=dy/notimes;                         context.lineWidth = linewidth;             context.strokeStyle=col;              context.beginPath();              var xk,yk;             xk=sx;             yk=sy;             xh=dx/2.0;             yh=dy/2.0;             for(var i=0;i<notimes;i++){                      context.moveTo(xk,yk);                                    context.lineTo(xk+xh,yk+yh);                                     xk+=dx;                     yk+=dy;             }                                         context.stroke();                         }                                         function point(col,x,y)         {                 context.strokeStyle="#000";                 context.lineWidth = 1;                             context.fillStyle=col;                 context.fillRect(x-4,y-4,8,8);                        context.strokeRect(x-4,y-4,8,8);                                }                 function highlight(px,py)         {                 context.strokeStyle="#aaa";                 context.lineWidth = 1;                             context.strokeRect(px-8,py-8,16,16);                                                }                 // Arcto only works if both x1 and y2 are on circle border         function arcto(x0,y0,x1,y1,x2,y2)         {                  var r = Math.sqrt((x1-x0)*(x1-x0) + (y1-y0)*(y1-y0));                 var x = x0-r;                 var y = y0-r;                 var startAngle = (180/Math.PI*Math.atan2(y1-y0, x1-x0));                 var endAngle = (180/Math.PI*Math.atan2(y2-y0, x2-x0));                                 context.arc(x0, y0, r, 0, Math.PI*2.0, 1.0);          }          // Draws 90 degree arc         function arcdeg(x1,y1,x2,y2,x3,y3)         {                                         // First quadrant positive positive                                dashedline(x1,y1,x2,y2,8,1.0,"#999");                     dashedline(x3,y3,x2,y2,8,1.0,"#999");                                        point("#ff5",x1,y1);                     point("#f55",x2,y2);                     point("#f55",x3,y3);                                                                     k=(y3-y1)/(x3-x1);                                                                                yk=y1+((x2-x1)*k);                                         rx=x3-x1;                     ry=y3-y1;                      point("#f5f",x2,yk);                      context.strokeStyle = "#49f";                     context.lineWidth   = 1.0;                                        context.beginPath();                                        context.moveTo(x1,y1);                     for(i=0;i<48;i++){                             if(y3>=y1){                                     if(yk>=y2){                                             context.lineTo(x1+(Math.sin(((Math.PI/96.0)*-i)+(Math.PI*1.0))*rx),y3+(Math.cos(((Math.PI/96.0)*-i)+(Math.PI*1.0))*ry));                                     }else{                                             context.lineTo(x3+(Math.sin(((Math.PI/96.0)*i)+(Math.PI*1.5))*rx),y1+(Math.cos(((Math.PI/96.0)*i)+(Math.PI*1.5))*ry));                                     }                             }else{                                     if(yk<=y2){                                             context.lineTo(x1+(Math.sin(((Math.PI/96.0)*-i)+(Math.PI*1.0))*rx),y3+(Math.cos(((Math.PI/96.0)*-i)+(Math.PI*1.0))*ry));                                     }else{                                             context.lineTo(x3+(Math.sin(((Math.PI/96.0)*i)+(Math.PI*1.5))*rx),y1+(Math.cos(((Math.PI/96.0)*i)+(Math.PI*1.5))*ry));                                     }                                                        }                     }                     context.stroke();          }                 // Get point of operation         function getpoint(opno,cpno)         {                 // Get operations                 var elSel = document.getElementById("operations");                  // Bounds checking of operation, if outside bounds do nothing.                 if(oppos>0&&oppos<elSel.length){                                                                                     // Return both coordinates as an object!                       return {                         x : left,                         y : top                     };                                    }         }                 // Set point of operation         function setpoint(opno,cpno,xval,yval)         {                 // Get operations                 var elSel = document.getElementById("operations");                  // Bounds checking of operation, if outside bounds do nothing.                 if(opno>0&&opno<elSel.length){                                                 currop=elSel.options[opno].value;                         originalop=currop;                          // Start of operation loop                         var operation=currop.split(" ");                         opcode=operation[0];                                                 alert(opcode);                          // We want to update last control point                         if(cpno==-1){                                                         }                                                // Any later control point                         if(cpno>0){                                                     }                 }         }          var startx=80;         var starty=340;         var endx=400;         var endy=560;                 var cpno=0;                    // cpno is the number of the selected control point         var cpsel=-1;          function foo()         {                 context.clearRect(0,0,600,600);                                 // Draw grid lines                                context.strokeStyle = "#ddd";                 context.lineWidth   = 0.5;                 context.beginPath();                 for(i=0;i<600;i+=20){                         context.moveTo(i,0);                         context.lineTo(i,600);                         context.moveTo(0,i);                         context.lineTo(600,i);                 }                 context.stroke();                                            // Draw Crosshair                 context.beginPath();                 context.strokeStyle = "#444";                 context.lineWidth   = 1.0;                 context.moveTo(gridx-gridsize,gridy);                 context.lineTo(gridx+gridsize,gridy);                 context.moveTo(gridx,gridy-gridsize);                 context.lineTo(gridx,gridy+gridsize);                 context.stroke();                                                            // Mark start and end points                 point("#f52",startx,starty);                 point("#5f2",endx,endy);                  // This is our operations loop                  var originalop;                 var elSel = document.getElementById("operations");               var i=elSel.length-1;                             while(i>=0){                          currop=elSel.options[i].value;                          // Start of operation loop                         var operation=currop.split(" ");                         opcode=operation[0];                                 context.strokeStyle = "#49f";                         context.lineWidth   = 1.0;                                                 // Get coordinates depending on opcode                         if(opcode=="L"||opcode=="Q"||opcode=="C"||opcode=="S"){                                 p1x=parseInt(operation[1]);                                 p1y=parseInt(operation[2]);                         }                         if(opcode=="L"||opcode=="Q"||opcode=="C"||opcode=="S"){                                 p2x=parseInt(operation[3]);                                 p2y=parseInt(operation[4]);                         }                         if(opcode=="Q"||opcode=="C"||opcode=="S"){                                 p3x=parseInt(operation[5]);                                 p3y=parseInt(operation[6]);                         }                         if(opcode=="C"){                                 p4x=parseInt(operation[7]);                                 p4y=parseInt(operation[8]);                         }                                                 // Draw operation                                                 if(opcode=="L"){                                 context.beginPath();                                 context.moveTo(p1x,p1y);                                 context.lineTo(p2x,p2y);                                 context.stroke();                                            point("#f52",p1x,p1y);                                 point("#f52",p2x,p2y);                                 }else if(opcode=="Q"){                                 context.beginPath();                                 context.moveTo(p1x,p1y);                                 context.quadraticCurveTo(p2x,p2y,p3x,p3y);                                 context.stroke();                                            dashedline(p1x,p1y,p2x,p2y,8,1.0,"#aaa");                                 dashedline(p2x,p2y,p3x,p3y,8,1.0,"#aaa");                                                                                point("#f52",p1x,p1y);                                 point("#f52",p2x,p2y);                                 point("#f52",p3x,p3y);                         }else if(opcode=="C"){                                 context.beginPath();                                 context.moveTo(p1x,p1y);                                 context.bezierCurveTo(p2x,p2y,p3x,p3y,p4x,p4y);                                 context.stroke();                                            dashedline(p1x,p1y,p2x,p2y,8,1.0,"#aaa");                                 dashedline(p2x,p2y,p3x,p3y,8,1.0,"#aaa");                                                        dashedline(p3x,p3y,p4x,p4y,8,1.0,"#aaa");                                                                                point("#f52",p1x,p1y);                                 point("#f52",p2x,p2y);                                 point("#f52",p3x,p3y);                                 point("#f52",p4x,p4y);                         }else if(opcode=="S"){                                 arcdeg(p1x,p1y,p2x,p2y,p3x,p3y);                         }                                 // Highlight and detect click store selected operation and control point                         if(cpsel==-1){                                 if(gridx==p1x&&gridy==p1y){                                         // First point either is first point which is unmovable or also moves the last point of previous operation                                         point("#ff8",p1x,p1y);                                         highlight(p1x,p1y);                                         cpno=1;                                         if(clickstate==1) cpsel=i;                                 }                                 if(gridx==p2x&&gridy==p2y){                                         // Second point is control point in all but line                                         point("#ff8",p2x,p2y);                                                                                highlight(p2x,p2y);                                         cpno=2;                                         if(clickstate==1) cpsel=i;                                 }                                 if(opcode=="Q"||opcode=="C"||opcode=="S"){                                         if(gridx==p3x&&gridy==p3y){                                                 // Second point is control point in all but line                                                 point("#ff8",p3x,p3y);                                                                                        highlight(p3x,p3y);                                                 cpno=3;                                                 if(clickstate==1) cpsel=i;                                         }                                 }                                 if(opcode=="C"){                                         if(gridx==p4x&&gridy==p4y){                                                 // Second point is control point in all but line                                                 point("#ff8",p4x,p4y);                                                                                        highlight(p4x,p4y);                                                 cpno=4;                                                 if(clickstate==1) cpsel=i;                                         }                                 }                         }                                                         // We have selected a control point and we want to move it                         if(cpsel>=0&&i==cpsel&&cpno>0&&clickstate==1){                                  var operation=currop.split(" ");                                 if(cpno==1){                                                                                                    operation[1]=gridx;                                         operation[2]=gridy;                                 }else if(cpno==2){                                         operation[3]=gridx;                                         operation[4]=gridy;                                                        }else if(cpno==3){                                         operation[5]=gridx;                                         operation[6]=gridy;                                                        }else if(cpno==4){                                         operation[7]=gridx;                                         operation[8]=gridy;                                                        }                                 currop=operation.join(" ");                                    elSel.options[i].value=currop;                                 setpoint(i-1,1,gridx,gridy);                                  context.strokeStyle = "#ddd";                                 context.fillStyle="#000";                                 context.font = "bold 16px Arial";                                 context.fillText(currop+"::"+cpsel+" "+cpno+"::"+opcode+" "+p1x+" "+p1y+" "+p2x+" "+p2y+" "+p1x+" "+p1y+" "+gridx+" "+gridy, 4, 576);                          }   //                        elSel.options[i].value=currop;                          i--;                                       }                                 /*                 context.fillStyle="#000";                 context.font = "bold 16px Arial"; */ //                context.fillText(currop+"::"+cpsel+" "+cpno+"::"+opcode+" "+p1x+" "+p1y+" "+p2x+" "+p2y+" "+gridx+" "+gridy, 4, 576); //                context.fillText(currop+"::"+cpsel+" "+cpno+"::"+opcode+" "+p1x+" "+p1y+" "+p2x+" "+p2y+" "+gridx+" "+gridy, 4, 576); //                context.fillText(currop+"::"+cpsel+" "+cpno+"::"+opcode+" "+p1x+" "+p1y+" "+p2x+" "+p2y+" "+gridx+" "+gridy, 4, 576);                  setTimeout("foo();",100);                       }                               </script> ');  
149