/*!
JSP to JSXG version 1.8.112
This file is the core of The JavaSketchpad-to-JSXGraph converter.
The JavaSketchpad-to-JSXGraph converter is property of the authors
and the University of Eastern Finland, Department of Physics and Mathematics,
and it is therefore eligble to the general conditions of e-materials of the
Ministry of Education in Finland and EU.
The JavaSketchpad-to-JSXGraph converter is free to use tool under UEF licence,
in the hope it will be useful, but WITHOUT ANY WARRANTY.
"This application project was started during working proccess of my
Master's Thesis. Purpose was mainly to use it in converting
previously made JSP sketches in new form. For myself this tool
has also been in use for several times just to simplify the creation
of a JSXGraph image, since the JSP syntax for me is easier to write."
2018 Henri Tanskanen
*/
//macros update
let jsp_macros = "";
/** JAVASKETCHPAD TO JSXGRAPH CONVERTER : MAIN FUNCTION
* This is the main function, that creates converted JSXGraph code from code-input and other input elements.
* This function connects all the parts that are needed when constructing JSXG element from JSP element.
* Input variables are:
* code_input that is jsp code we want to convert (String)
* size_input (optional) has table size information as width and height for example [400,400] (Array)
* elementname_input (optional) has the element name information (String)
* isFullPageConvert (optional) has the info if we are using fullpage convertor (boolean)
* @param {String} code_input - original Java Sketchpad code
* @param {Array<Int>} size_input - tablesize
* @param {String} elementname_input - element name
* @param {Boolean} isFullPageConvert - if is full page conver
* @return {String} codestring - fully converted code to JSXGraph
*/
function jspToJsx(code_input, size_input, elementname_input, isFullPageConvert) {
let //locusPoints=30,
//animticks = 50,
locus_counter = 0,
startingtime = 0,
endingtime = 0,
executiontime = 0,
evas = [],
codestring = "",
boardname = "",
elid = "",
tmpstring = "",
errors = "<span style='text-decoration:underline'>Errors:</span><br>",
warnings = "<span style='text-decoration:underline'>Warnings:</span><br>",
sketch = "",
boardstyle = "",
boarddiv = "",
board_update_events = "",
buttonstyle="<sty"+"le>.jxgbox button {padding:",
sketchrows = [],
sketchrows_comment =[],
elr =[],
el =[],
calc = [],
imgHeight,
imgWidth,
right_side_titles_and_buttons = [];
let i,j,k,m,tmp;
try {
clearAll(['jsxgimage','jsxgcode','JSketchPadCode','testing', 'errormessages'], ['err_comms', 'err_info', 'err_submit_btn', 'ERRORS']);
// reading sketchcode and setting
// coordinate system (if in code command UnitPoint, else 100px)
sketch = (code_input !== 'codearea') ? code_input : getUserVal(code_input);//.replace(/(\r\n|\n|\r|" ")/gm,"");
sketch = sketch.replace(/(\t)/gm, " ");
//sketch = sketch.trim();
//BREAK IF CODE WONT PASS DUMMYTEST
if (!codeDummyTest(sketch)) {
alert('There is some problems in your JSP-code. Convertion was stopped. Check your code!');
return false;
//
}
//check codestyle (and switch from JSP-$ if needed)
if(!checkJSPStyle(sketch)) sketch = varJSPtoNumJSP(sketch);
const ui_ids = {
code: sketch,
width: 'boardwidthinput',
height: 'boardheightinput',
scale: 'scale',
zoom: 'zoom',
boardName: 'jsxgboardname',
elementId: 'jsxgelementid',
scriptSource: 'source',
addMathjax: 'addmathjax',
mathjaxSource: 'mathjax_source',
addStylesheet: 'addstylesheet',
styleSource: 'stylesource',
printJsp: 'originalcode',
JSXrenderer: 'jsxrenderer_sel',
pointSize: 'jsxpointsize',
measurementAccuracy: 'measurementaccuracy',
addGridLayers: 'addgridlayer',
addClearTrace: 'cleartracebutton',
clearTraceStyle: 'cleartracestyle',
latexPoints: 'latex',
latexTexts: 'latex_fixedtext',
addBorder: 'jsxgimageborders',
addUTF: 'addutf8',
forceWhiteBack: 'forcewhiteback',
useHightlight: 'usehighlight',
showGrid: 'showgrid',
drawAxis: 'drawaxis',
useAttributeVisible: 'hide_element',
locusSetting: 'curve_locus',
showObjectCoordinates: 'jsxshowinfo',
buttonStyling: 'usebuttonstyle',
buttonPadding: 'buttonpaddingsel',
buttonMarginTop: 'buttonmargintopsel',
buttonBackground: 'buttonbackgroundcolorsel',
buttonVerticalAdj: 'buttonverticaladjsel',
labelAlign: 'jsxlabelalignment',
vectorTranslationVerticalCorrection: 'vectortranslation_correction'
};
// Reading sketch settings from user interface
// params are index.php ids for the selectors
let UI_SETTINGS = new JSPtoJSXUISettings(ui_ids);
if (elementname_input && isFullPageConvert) {
UI_SETTINGS.boardName = UI_SETTINGS.elementID = elementname_input;
}
//input codearea to err_jspcode for submitting errors
if (document.getElementById('err_jspcode')) document.getElementById('err_jspcode').value = sketch;
if (document.getElementById('jsxgboardname')) document.getElementById('jsxgboardname').value = boardname = UI_SETTINGS.boardName;
if (document.getElementById('jsxgelementid')) document.getElementById('jsxgelementid').value = elid = UI_SETTINGS.elementId;
if (document.getElementById('boardwidthinput')) document.getElementById('boardwidthinput').value = UI_SETTINGS.width;
if (document.getElementById('boardheightinput')) document.getElementById('boardheightinput').value = UI_SETTINGS.height;
sketchrows = separateCommands(sketch); // getting the rows from the JSP code
for (i in sketchrows) { //creating each jsp-jsx object
if (sketchrows[i]) {
elr[i] = sketchpadrowToJsxgElement(sketchrows[i], UI_SETTINGS.appletsize, UI_SETTINGS.coord_div, UI_SETTINGS.scale, UI_SETTINGS.scale, UI_SETTINGS.has_origin_unit, boardname); // each row into JSXG object
}
}
// getting animation type option
//animtype = document.getElementById('animationsel').value;
//if (animtype != "animtype1") animticks = eval(animtype.slice(10, 12));
//buttonstyle
if (UI_SETTINGS.buttonStyling) {
buttonstyle = "#"+boardname+
" button {padding:" + UI_SETTINGS.buttonPadding +
"margin-top:"+ UI_SETTINGS.buttonMarginTop +
"background-color:"+ UI_SETTINGS.buttonBackground +
"}\n";
} else buttonstyle = "";
boardstyle = "<sty"+"le>#"+boardname + " {\n" +
"\tborder-style:solid;\n"+
"\tborder-width:"+UI_SETTINGS.addBorder+"px;\n"+
"\twidth:"+UI_SETTINGS.appletsize[0]+"px;\n"+
"\theight: "+UI_SETTINGS.appletsize[1]+"px;\n"+
"\toverflow: hidden;\n"+
"\tposition: relative;\n"+
"\tbackground-color:#"+UI_SETTINGS.bgColour+";"+
"}\n"+
"\t"+buttonstyle+
//UI_SETTINGS.labelsizeStyleAddon+
"</s"+"tyle>\n";
boarddiv = "<div class='jxgbox' id='"+boardname+"' > </div>";
// initializing board element for the html page (this program)
document.getElementById("jsxgimage").innerHTML = /*buttonstyle.replace('#'+boardname, '.jxgbox')+*/boardstyle+boarddiv;
// writing var board iniatilizing and variable definitions into codestring, evaluating them
// and replacing boardname for generated code
codestring = "var "+boardname+
"_b = JXG.JSXGraph.initBoard('"+boardname+"', {\n"+
UI_SETTINGS.JSXrenderer +
"\tboundingbox:["+UI_SETTINGS.boardsize+"],\n"+
"\toriginX:"+UI_SETTINGS.originXY.X+", originY:"+UI_SETTINGS.originXY.Y+",\n"+
"\tzoomX:"+UI_SETTINGS.zoom+", zoomY:"+UI_SETTINGS.zoom+",\n"+
"\tkeepaspectratio:false,\n"+
"\taxis:"+UI_SETTINGS.drawAxis+",\n"+
"\tshowCopyright: false,\n"+
"\tshowNavigation: false,\n"+
"\tgrid: "+UI_SETTINGS.showGrid+",\n";
if (document.getElementById('cleartracebutton').value == 'show' || (document.getElementById('cleartracebutton').value == 'auto' && sketch.indexOf('traced')>0))
codestring = codestring + "\tshowClearTraces:true\n";
codestring = codestring +
"} );\n"+
// defining variables that will be written in converter code
"var "+
elid+"_el=[],\n"+
elid+"_tel=[],\n"+
elid+"_transf=[],\n"+
elid+"_transf2=[],\n"+
elid+"_animOn=false,\n"+
elid+"_anims=[],\n"+
elid+"_unit;\n\n";
if (codestring.indexOf('showClearTraces:true')>0) codestring+="document.getElementById('"+boardname+"_navigationbar').firstChild.innerHTML = '"+UI_SETTINGS.clearTraceStyle+"';\n";
if (UI_SETTINGS.addGridLayers > 0) {
for (i=0; i<UI_SETTINGS.addGridLayers; i++) {
codestring += boardname + "_b.create('grid', []);\n";
}
}
eval(codestring); // eavaluating board and varaibles for the sample sketch in the right column of converter page
if (!isFullPageConvert)
codestring += "\n";
codestring = codestring.replace("JSXBoard",boardname); // replacing boardname with user defined name
if (contains(UI_SETTINGS.printJsp, 'Yes') && !isFullPageConvert) {
if (contains(UI_SETTINGS.printJsp,'Yes with tags'))
document.getElementById("JSketchPadCode").innerHTML = getOrigString(elr, UI_SETTINGS.width, UI_SETTINGS.height, true);
else
document.getElementById("JSketchPadCode").innerHTML = getOrigString(elr, UI_SETTINGS.width, UI_SETTINGS.height, false);
}
for (i in elr) {
if (elr[i]) {
el[elr[i].Row] = elr[i];
sketchrows_comment[elr[i].Row] = elr[i];
}
}
//MathJax in code
var add_mathjax = "";
if (document.getElementById('addmathjax').checked == true)
add_mathjax = "<"+"scr"+"ipt src='" + document.getElementById('mathjax_source').value + "'>"+"<"+"/"+"scr"+"ipt>\n";
else add_mathjax = "";
// Beginning of the codestring for the user
codestring += "<><script src ='" + UI_SETTINGS.scriptSource +"'> <"+"/scr"+"ipt"+"> \n"+
//UI_SETTINGS.stylesheetSource +
UI_SETTINGS.addUTF +
add_mathjax +
boardstyle +
boarddiv +"\n<"+
"script"+">//![CDATA[\n"+
"(function(){\n"+
codestring;
//this is to calculate time that convertion takes
startingtime = new Date().getTime();
console.log('all ok start to convert');
for (i in el) {
if (el[i]) {
if (el[i].Att.Stop)
break;
else if (el[i].Row ) {
var obj_c = elid+"_el["+el[i].Row+"] = "+boardname+"_b.create";
// POINTS * * * * /
if (el[i].JsxType == 'point') {
evas[el[i].Row] = obj_c+"('point', ["+el[i].Pos+"],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'unitpoint'){
evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+"+1+";}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y();}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+" );";
}
else if (el[i].JsxType == 'midpoint'){
evas[el[i].Row] = obj_c+"('midpoint', ["+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'intersection') {
evas[el[i].Row] = obj_c+"('intersection', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"], "+el[i].Att.Info+"],"+setAttributes({element:el[i],extraAttribute:'alwaysIntersect:false',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'glider') {
tmpstring = gliderPoint(eval(elid+"_el["+el[i].Pos[0]+"]"),el[i].Pos[1],eval(elid+"_el["+el[el[i].Pos[0]].Pos[0]+"]"))[0]+","+gliderPoint(eval(elid+"_el["+el[i].Pos[0]+"]"),el[i].Pos[1],eval(elid+"_el["+el[el[i].Pos[0]].Pos[0]+"]"))[1];
evas[el[i].Row] = obj_c+"('glider', ["+tmpstring+","+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'plotxy') {
// PlotXY(objRef1, objRef2, objRef3);
// Defines the point on the coordinate system objRef2 specified horizontally by the value of measurement objRef3 and vertically by the value of objRef1.
// That is, PlotXY() plots the point (objRef3, objRef1) on objRef2.
//
evas[el[i].Row] = obj_c+"('point', [function() {return "+elid+"_el["+el[el[i].Pos[1]].Pos[0]+"].X() + "+calc[el[i].Pos[2]]+";}, function() {return "+elid+"_el["+el[el[i].Pos[1]].Pos[0]+"].Y() + "+calc[el[i].Pos[0]]+";}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
// * * * * /POINTS /
// CIRCLES * * * * * /
else if (el[i].JsxType == 'circle') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+"); ";
}
else if (el[i].JsxType == 'circle by radius') {
evas[el[i].Row] = obj_c+"('circle', ["+elid+"_el["+el[i].Pos[0]+"], function(){return "+elid+"_el["+el[i].Pos[1]+"].L();}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+"); ";
}
// * * * * * * /CIRCLES /
// STAIGHT LINES * * * * /
else if (el[i].JsxType == 'line' || el[i].JsxType == 'perpendicular' || el[i].JsxType == 'parallel') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'segment') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'ray') {
evas[el[i].Row] = obj_c+"('line', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'axisx') {
evas[el[i].Row] = obj_c+"('axis', [["+elid+"_el["+el[i].Pos[0]+"][0].X(),"+elid+"_el["+el[i].Pos[0]+"][0].Y()], ["+elid+"_el["+el[i].Pos[0]+"][0].X()+1, "+elid+"_el["+el[i].Pos[0]+"][0].Y()]],"+setAttributes({element:el[i]})+"); " +elid+"_el["+el[i].Row+"].removeAllTicks();";
}
else if (el[i].JsxType == 'axisy') {
evas[el[i].Row] = obj_c+"('axis', [["+elid+"_el["+el[i].Pos[0]+"][0].X(),"+elid+"_el["+el[i].Pos[0]+"][0].Y()], ["+elid+"_el["+el[i].Pos[0]+"][0].X(), "+elid+"_el["+el[i].Pos[0]+"][0].Y()+1]],"+setAttributes({element:el[i]})+"); "+elid+"_el["+el[i].Row+"].removeAllTicks();";
}
// * * * * /STRAIGHT LINES /
// INTERIORS * * * * * /
else if (el[i].JsxType == 'polygon') {
for (j=0; j<el[i].Pos.length; j++) {
if (j != el[i].Pos.length-1) tmpstring = tmpstring + elid+"_el["+el[i].Pos[j]+"],"; else tmpstring = tmpstring + elid+"_el["+el[i].Pos[j]+"],"; }
evas[el[i].Row] = obj_c+"('polygon', ["+tmpstring+"],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'circle interior') {
if ((el[el[i].Pos[0]].JsxType == 'circle' || el[el[i].Pos[0]].JsxType == 'circle by radius') && el[i].Opts.indexOf('visible:false')<0) {
evas[el[i].Row] = elid+"_el["+el[i].Pos[0]+"].setAttribute({color:'"+el[i].Att.Color+"'});"; }
else evas[el[i].Row] = "";
}
// * * * * /INTERIORS /
// TRANSFORMATIONS * * * * /
else if (el[i].JsxType == 'reflection') {
evas[el[i].Row] = obj_c+"('"+el[i].JsxType+"', ["+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'dilation') {
evas[el[i].Row] = obj_c+"('point', [function(){return "+el[i].Pos[2]+"*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+el[i].Pos[2]+"*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'dilation/segmentratio') {
evas[el[i].Row] = obj_c+"('point', [function(){return ("+elid+"_el["+el[i].Pos[2]+"].L()/"+elid+"_el["+el[i].Pos[3]+"].L())*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return ("+elid+"_el["+el[i].Pos[2]+"].L()/"+elid+"_el["+el[i].Pos[3]+"].L())*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'dilation/3ptratio') {
// Dilation/3PtRatio (objRef1, objRef2, objRef3, objRef4, objRef5);
// Defines the image of any objRef1 dilated with respect to center point objRef2 by the signed ratio implied by the distances between points objRef3, 4, and 5.
// If these three points are A, B, and C, respectively, the three-point ratio implied by them is |AC|/|AB|.
evas[el[i].Row] = obj_c+"('point', [function(){return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[4]+"]))) * ("+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[4]+"]) / "+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[3]+"])) * ("+elid+"_el["+el[i].Pos[0]+"].X() - "+elid+"_el["+el[i].Pos[1]+"].X()) + "+elid+"_el["+el[i].Pos[1]+"].X()},function() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[4]+"]))) * ("+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[4]+"]) / "+elid+"_el["+el[i].Pos[2]+"].Dist("+elid+"_el["+el[i].Pos[3]+"])) * ("+elid+"_el["+el[i].Pos[0]+"].Y() - "+elid+"_el["+el[i].Pos[1]+"].Y()) + "+elid+"_el["+el[i].Pos[1]+"].Y()}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
//Dilation/MarkedRatio (objRef1, objRef2, objRef3)
//Defines the image of any objRef1 dilated with respect to center point objRef2 by the scaling factor determined by measurement objRef3.
else if (el[i].JsxType == 'dilation/markedratio') {
evas[el[i].Row] = obj_c+"('point', [function(){var ratio = "+calc[el[i].Pos[2]]+";return ratio*("+elid+"_el["+el[i].Pos[0]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X())+"+elid+"_el["+el[i].Pos[1]+"].X();},function(){var ratio = "+calc[el[i].Pos[2]]+";return ratio*("+elid+"_el["+el[i].Pos[0]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y())+"+elid+"_el["+el[i].Pos[1]+"].Y();}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
else if (el[i].JsxType == 'rotation') {
//5.5.6 Rotation (objRef1, objRef2, num);
//Defines the image of any objRef1 rotated around center point objRef2 by the radian angle specified by num.
//eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+","+elid+"_el[el[i].Pos[1]]], {type:'rotate'})");
//codestring = codestring +
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+","+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});";
evas[el[i].Row] = evas[el[i].Row] + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]], {name:'"+el[i].Att.Name+"', color:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute, size:"+el[i].Att.Size+", showInfoBox:"+el[i].Att.Infobox+", label:"+el[i].Att.LabelAlign+"} );";
}
else if (el[i].JsxType == 'rotation/measuredangle') {
//5.5.6 Rotation (objRef1, objRef2, objRef3);
// Defines the image of any objRef1 rotated around center point objRef2 by the radian angle expressed by measurement objRef3.
if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='circle') {
//el[i].CType = "circles";
//evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + obj_c+"('point',["+elid+"_el["+el[i].Pos[0]+"].center, "+elid+"_transf["+el[i].Row+"]],"+setAttributes(el[i], "fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute",UI_SETTINGS.useAttributeVisible)+"); "+boardname+"_b.create('circle', ["+elid+"_el["+el[i].Row+"], function(){return "+elid+"_el["+el[i].Pos[0]+"].radius;}],"+setAttributes(el[el[i].Pos[0]],'',UI_SETTINGS.useAttributeVisible,elid)+");";
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + elid+"_el["+el[i].Row+"] = " + boardname + "_b.create('point',["+elid+"_el["+el[i].Pos[0]+"].center, "+elid+"_transf["+el[i].Row+"]],"+setAttributes({element:el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute",visibility:UI_SETTINGS.useAttributeVisible})+"); "+elid+"_tel["+el[i].Row +"] = " + boardname + "_b.create('circle', ["+elid+"_el["+el[i].Row+"], function(){return "+elid+"_el["+el[i].Pos[0]+"].radius;}],"+setAttributes({element:el[/*el[i].Pos[0]*/el[i].Row],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid,elementType:'circles'})+");";
}
else {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[+el[i].Pos[2]]+"},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes({element:el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
}
if(el[i].Opts.indexOf('traced')>=0 && el[i].Opts.indexOf('visible:false')<0) {
//evas[el[i].Row] = evas[el[i].Row] + "\n\n"+ boardname+"_b.on('update', function(){if("+calc[+el[i].Pos[2]]+">=0 || "+calc[+el[i].Pos[2]]+"<0) "+elid+"_el["+el[i].Row+1 +"].setAttribute('trace:true'); });"
board_update_events = board_update_events + "if("+calc[+el[i].Pos[2]]+">=0 || "+calc[+el[i].Pos[2]]+"<0) "+elid+"_tel["+el[i].Row +"].setAttribute('trace:true');";
}
}
else if (el[i].JsxType == 'rotation/markedangle') {
/* Rotation/MarkedAngle (objRef1, objRef2, objRef3, objRef4, objRef5);
* Defines the image of any objRef1 rotated around center point objRef2 by the directed angle implied by the three points objRef3-objRef4-objRef5.
* JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"])
*/
if (el[el[i].Pos[0]].CType == 'points'){
evas[el[i].Row] = elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function() {return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"]);},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});\n" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes({element:el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
el[i].ParentType = 'points';
} else if (el[el[i].Pos[0]].CType == 'straightlines') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function() {return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[2]+"], "+elid+"_el["+el[i].Pos[3]+"], "+elid+"_el["+el[i].Pos[4]+"]);},"+elid+"_el["+el[i].Pos[1]+"]], {type:'rotate'});";
evas[el[i].Row] = evas[el[i].Row] + "\n" + obj_c +
"('" + eval(elid+"_el["+el[i].Pos[0]+"]").getType() + "', ["+
"["+elid+"_el["+el[i].Pos[0]+"].point1, "+elid+"_transf["+el[i].Row+"]], "+
"["+elid+"_el["+el[i].Pos[0]+"].point2, "+elid+"_transf["+el[i].Row+"]]],"+setAttributes({element: el[el[i].Pos[0]], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:el[i] })+");";
el[i].ParentType = 'straightlines';
}
else {
alert('Rotation/MarkedAngle works only for points and straight lines for now... Convertion stopped on line ' + el[i].Row + "," + el[i].Type + "(" + el[i].Pos + ")[" + el[i].Opts.slice(1) + "];");
return null;
}
}
else if (el[i].JsxType == 'translation') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+UI_SETTINGS.scale*el[i].Pos[1]/UI_SETTINGS.coord_div+","+ UI_SETTINGS.scale*el[i].Pos[2]/UI_SETTINGS.coord_div+"], {type:'translate'});" + obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+elid+"_transf["+el[i].Row+"]],"+setAttributes({element: el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
}
else if (el[i].JsxType == 'translation/fixedangle/markeddistance') {
/* Translation/FixedAngle/MarkedDistance (objRef1, objRef2, num);
* Defines the image of any objRef1 translated by the distance expressed by measurement objRef2 in the direction expressed by num radians.
* [ https://www.math.uni-bielefeld.de/~lisken/jsp/qref.html ]
*/
if (el[el[i].Pos[0]].CType == 'points' || el[el[i].Pos[0]].CType == 'transformations' || jsp_macros.indexOf(el[el[i].Pos[0]].Type)>=0) {
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]],"+setAttributes({element: el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
}
else if (el[el[i].Pos[0]].CType == 'straightlines') {
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point1], {type:'rotate'})");
eval(elid+"_transf2[el[i].Row +1 ] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point2], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point1], {type:'rotate'});";
codestring = codestring + elid+"_transf2["+el[i].Row + 1+"] = "+boardname+"_b.create('transform', ["+el[i].Pos[2]+", "+elid+"_el["+el[i].Pos[0]+"].point2], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('line', [["+elid+"_el["+el[i].Pos[0]+"].point1, ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]], ["+elid+"_el["+el[i].Pos[0]+"].point2, ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"+1]]]],"+setAttributes({element:el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
}
else {
alert( el[i].Type + " not working for " + el[el[i].Pos[0]].CType + ", \nline " + el[i].Row + " in JSP code. \nConverting was stopped!");
return 'null';
}
}
else if (el[i].JsxType == 'translation/markedangle/markeddistance') {
/* Translation/MarkedAngle/MarkedDistance (objRef1, objRef2, objRef3);
* Defines the image of any objRef1 translated by the distance expressed by distance measurement objRef3 in the direction expressed by angle measurement objRef2.
* [ https://www.math.uni-bielefeld.de/~lisken/jsp/qref.html ]
*/
eval(elid+"_transf[el[i].Row] = "+boardname+"_b.create('transform', [function(){return Math.abs("+elid+"_el["+el[i].Pos[0]+"].X()-("+calc[el[i].Pos[2]]+"/UI_SETTINGS.coord_div))+"+elid+"_el["+el[i].Pos[0]+"].X();}, 0], {type:'translate'})");
eval(elid+"_transf2[el[i].Row] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'})");
codestring = codestring + elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return Math.abs("+elid+"_el["+el[i].Pos[0]+"].X()-("+calc[el[i].Pos[2]]+"/UI_SETTINGS.coord_div))+"+elid+"_el["+el[i].Pos[0]+"].X();}, 0], {type:'translate'});";
codestring = codestring + elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('transform', [function(){return "+calc[el[i].Pos[1]]+";}, "+elid+"_el["+el[i].Pos[0]+"]], {type:'rotate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], ["+elid+"_transf["+el[i].Row+"],"+elid+"_transf2["+el[i].Row+"]]],"+setAttributes({element: el[i], extraAttribute:"fixed:"+elid+"_el["+el[i].Pos[0]+"].getAttribute", visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+");";
}
else if (el[i].JsxType == 'vectortranslation') {
// VectorTranslation (objRef1, objRef2, objRef3);
// Defines the image of any objRef1 translated by the vector implied by two points objRef2 -> objRef3.
// objRef2 is the foot of the vector, and objRef3 is its tail.
if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='point' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='glider' || el[el[i].Pos[0]].JsxType=='intersection' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='reflection' || eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='midpoint') {
//evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+(Math.sign("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X()))*Math.abs("+elid+"_el["+el[i].Pos[1]+"].X()-"+elid+"_el["+el[i].Pos[2]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y()+(Math.sign("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y()))*Math.abs("+elid+"_el["+el[i].Pos[1]+"].Y()-"+elid+"_el["+el[i].Pos[2]+"].Y());}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
//evas[el[i].Row] = obj_c+"('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
eval (elid + "_transf[" + el[i].Row + "] = " + boardname + "_b.create('transform', [function(){return "+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y();}], {type:'translate'});");
codestring = codestring + elid + "_transf[" + el[i].Row + "] = " + boardname + "_b.create('transform', [function(){return "+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X();},function(){return "+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y();}], {type:'translate'});";
evas[el[i].Row] = obj_c+"('point', ["+elid+"_el["+el[i].Pos[0]+"], "+ elid+"_transf["+el[i].Row+"]],"+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
}
// FOR SEGMENT
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='segment') {
if (el[el[i].Pos[0]].Att.ArrowF == true) el[i].Att.ArrowF=true; else el[i].Att.ArrowF=false;
if (el[el[i].Pos[0]].Att.ArrowL == true) el[i].Att.ArrowL=true; else el[i].Att.ArrowL=false;
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf2["+el[i].Row+"].hideElement(); "+obj_c+"('segment', ["+elid+"_transf["+el[i].Row+"], "+elid+"_transf2["+el[i].Row+"]], "+setAttributes({element: el[i], extraAttribute:'strokeWidth:'+el[i].Att.Strokewidth, visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+" );";
}
// FOR LINE
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()")=='line') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point1.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+elid+"_transf2["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].point2.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf2["+el[i].Row+"].hideElement(); "+obj_c+"('line', ["+elid+"_transf["+el[i].Row+"], "+elid+"_transf2["+el[i].Row+"]], "+setAttributes({element:el[i], extraAttribute:'strokeWidth:'+el[i].Att.Strokewidth, visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+" );";
}
// FOR CIRCLES
else if (eval(elid+"_el["+el[i].Pos[0]+"].getType()") =='circle') {
evas[el[i].Row] = elid+"_transf["+el[i].Row+"] = "+boardname+"_b.create('point', [function(){return "+elid+"_el["+el[i].Pos[0]+"].center.X()+("+elid+"_el["+el[i].Pos[2]+"].X()-"+elid+"_el["+el[i].Pos[1]+"].X());}, function(){return "+elid+"_el["+el[i].Pos[0]+"].center.Y()+("+elid+"_el["+el[i].Pos[2]+"].Y()-"+elid+"_el["+el[i].Pos[1]+"].Y());}] );"+elid+"_transf["+el[i].Row+"].hideElement(); "+obj_c+"('circle', ["+elid+"_transf["+el[i].Row+"], function() {return "+elid+"_el["+el[i].Pos[0]+"].Radius();}], "+setAttributes({element: el[i], extraAttribute:'strokeWidth:'+el[i].Att.Strokewidth, visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+" );";
}
}
// * * * * * * /TRANSFORMATIONS /
// * * * * * * IMAGES /
else if (el[i].JsxType == 'image') {
// Image (num1, num2, string);
// Defines a rectangular picture image positioned in the plane at the (X, Y) location specified by (num1, num2).
// string specifies the URL of the image relative to the URL of the web page which contains this
//
imgWidth="";
imgHeight="";
document.getElementById('hiddenimg').src = el[i].Pos[2];
imgWidth = document.getElementById('hiddenimg').width;
imgHeight = document.getElementById('hiddenimg').height;
[imgWidth, imgHeight] = [imgWidth/UI_SETTINGS.coord_div, imgHeight/UI_SETTINGS.coord_div];
evas[el[i].Row] = obj_c+"('image', ['"+el[i].Pos[2]+"',["+el[i].Pos[0]+","+el[i].Pos[1]+"], ["+imgWidth+","+imgHeight+"]], {visible:"+el[i].Att.Visible+"} );";
}
else if (el[i].JsxType == 'imageonpoint') {
// Image (num1, num2, string);
// Defines a rectangular picture image positioned in the plane at the (X, Y) location specified by (num1, num2).
// string specifies the URL of the image relative to the URL of the web page which contains this
//
imgWidth="";
imgHeight="";
document.getElementById('hiddenimg').src = el[i].Pos[1];
imgWidth = document.getElementById('hiddenimg').width;
imgHeight = document.getElementById('hiddenimg').height;
[imgWidth, imgHeight] = [imgWidth/UI_SETTINGS.coord_div, imgHeight/UI_SETTINGS.coord_div];
evas[el[i].Row] = obj_c+"('image', ['"+el[i].Pos[1]+"',[function(){return "+elid+"_el["+el[i].Pos[0]+"].X();},function(){return "+elid+"_el["+el[i].Pos[0]+"].Y();}], ["+imgWidth+","+imgHeight+"]], {visible:"+el[i].Att.Visible+"} );";
}
// * * * * * * /IMAGES /
// MEASUREMENTS * * * * * /
else if (el[i].JsxType == 'length') {
// Length(obj1, numX, numY, string);
// Constructs a measurement of the length of segment obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].L();} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3] +'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'angle') {
// Angle(obj1, obj2, obj3, numX, numY, string);
// Constructs a measurement of the angle implied by the three points obj1, obj2, and obj3, with obj2 being the vertex of the angle.
// The angle will be reported as either a directed or an undirected angle, depending on the setting of the global DirectedAngles parameter.
//evas[el[i].Row] = "function "+elid+el[i].Row+"() {if (JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]) < 3.141593) return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]); else return 6.28318530718 - JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]);}";
if (UI_SETTINGS.directed_angles == 1)
evas[el[i].Row] = "function "+elid+el[i].Row+"() {if (JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]) < 3.141593) return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]); else return -1* (6.28318530718 - JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]));}";
else if (UI_SETTINGS.directed_angles == 0)
evas[el[i].Row] = "function "+elid+el[i].Row+"() {if (JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]) < 3.141593) return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]); else return (6.28318530718 - JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]));}";
//evas[el[i].Row] = "function "+elid+el[i].Row+"() { return JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[2]+"]);}";
else errors = errors + "DirectedAngles parameter is invalid!\n";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[3]+','+el[i].Pos[4]+',function(){return "'+el[i].Pos[5] +'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'circumference') {
// Circumference(obj1, numX, numY, string);
// Constructs a measurement of the circumference of circle or circle interior obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Radius()*Math.PI*2} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'radius') {
// Radius(obj1, numX, numY, string);
// Constructs a measurement of the radius of circle or circle interior obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Radius()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'area') {
// Area (obj1, numX, numY, string);
// Constructs a measurement of the area of the circle, circle interior, or polygon interior obj1. Note that the area is reported in square distance units.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].Area()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'slope') {
// Slope (obj1, numX, numY, string);
// Constructs a measurement of the slope of straight object obj1.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].getSlope()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[1]+','+el[i].Pos[2]+',function(){return "'+el[i].Pos[3]+'" + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'calculate') {
// Calculate(numX, numY, prefixStr, exprStr) (objRef1, ..., objRefN);
// Constructs a measurement of the value of a calculated expression. numX, numY, and prefixStr are the standard left and top coordinates and prefix string of every measurement object; exprStr contains a representation of the expression to calculate, and objRef1 through objRefN are object identifiers of any other measurement objects the value of which act as components of the expression.
///
// The exprStr expression is expressed in reverse Polish notation (RPN), in which arithmetic operators follow their operands. RPN eliminates the need for parentheses, because the order of evaluation is strictly left-to-right. Thus "(1+2)/3" can be phrased in RPN as "1 2 + 3 /".
//
// Valid tokens within exprStr include:
//
// numeric constants. Any real number can be expressed, with an optional preliminary negative sign (for negative numbers) and an optional single decimal point (for expressing non-integer values). A numeric constant may include a terminal space to delimit it in circumstances where two numeric constants are adjacent.
// +, -, /, *. These operators perform their standard arithmetic operation: addition, subtraction, division, and multiplication.
// ^: This operator performs exponentiation.
// %: This operator performs unary negation.
// @xxxx: This operator applies a predefined function. xxxx is a four-character sequence indicating the function, and may be one of the following: sin_ (sine), cos_ (cosine), tan_ (tangent), abs_ (absolute value), sqrt (square root), ln__ (natural log), rond (rounding), trnc (truncation toward zero), sgn_ (signnum), asin (arcsine), acos (arccosine), atan (arctangent), or log_ (base-10 logarithm).
// x where x is in {A-Z}. This operand substitutes the value of another measurement in the sketch: A corresponds to measurement objRef1, B corresponds to measurement objRef2, etc. It is an error to pass an operator that does not have a corresponding objRef; i. e. to refer to C when you only supply two objRefs in the construction (implicitly, A and B).
// #xy where x is in {A-Z} and y is in {1-9}. This operand substitutes the value of component y of a vector-based measurement x. x refers to an objRef according to the same rules above (i. e. A is objRef1, B is objRef2, etc.). Parent objRefx must be a vector-based measurement: in DR3 of JavaSketchpad, the only vector-based measurement is the Coordinate pair. y indicates the component of the vector to isolate. In DR3, the only legal values for y are 1 and 2: 1 indicates the x-component of a coordinate pair, 2 indicates the y-component of that pair.
// Examples:
//
// Calculate(10, 10, 'Sum is ','AB+C+') (5, 6, 7);
//
// Calculates the sum of measurement objects #5, 6, and 7 in the sketch, and positions their sum at (10, 10) on the coordinate plane.
//
// Calculate(20, 20, 'Distance is ','#A1#B1-2^#A2#B2-2^+@sqrt') (8, 9);
//
// Calculates the Euclidean distance (sqrt[dX^2+dY^2]) between the two coordinate pair measurements referenced as objects #8 and 9 in the sketch.
//
// Note that a space character may be used inside exprStr to delimit individual tokens. This allows you to express one plus three as '1 3+' where '13+' would be interpreted as thirteen plus (whatever preceded it).
//
// Note also that the objRef list must not be empty, even if no tokens in the expression refer to object references (i. e. even if the expression's value is constant). This is a limitation of DR3, and will be fixed in the next release.
tmp = [];
for (k=0; k<el[i].Pos[4].length; k++)
tmp[k] = el[i].Pos[4][k];
calc[el[i].Row] = calculateFunction(el[i].Pos[3],tmp,calc,el[i].Row);
evas[el[i].Row] = (obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "'+el[i].Pos[2] + ' " + Math.round(('+calc[el[i].Row]+')*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+' + "'+el[i].Att.Suffix+'";}],{color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'});');
//if (!el[i].Att.Visible)
//evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
else if (el[i].JsxType == 'distance') {
/// Distance(obj1, obj2, numX, numY, string);
// Constructs a measurement of the distance between obj1 and obj2.
// obj2 must be a point, obj1 may be either a point or a straight object,
// in which case the distance is reported as the minimum (perpendicular) distance between point obj2 and the extended line containing obj1.
if (el[el[i].Pos[0]].CType == 'points')
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[1]+"].Dist("+elid+"_el["+el[i].Pos[0]+"] ) * "+UI_SETTINGS.unit_in_pixels+"} ";
else if (el[el[i].Pos[0]].CType == 'straightlines' || el[el[i].Pos[0]].ParentType == 'straightlines') {
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return Math.abs(("+elid+"_el["+el[i].Pos[1]+"].X()*("+elid+"_el["+el[i].Pos[0]+"].point2.Y()-"+elid+"_el["+el[i].Pos[0]+"].point1.Y())) - ("+elid+"_el["+el[i].Pos[1]+"].Y()*("+elid+"_el["+el[i].Pos[0]+"].point2.X()-"+elid+"_el["+el[i].Pos[0]+"].point1.X())) + "+elid+"_el["+el[i].Pos[0]+"].point2.X()*"+elid+"_el["+el[i].Pos[0]+"].point1.Y() - "+elid+"_el["+el[i].Pos[0]+"].point2.Y()*"+elid+"_el["+el[i].Pos[0]+"].point1.X() ) / Math.sqrt(Math.pow(("+elid+"_el["+el[i].Pos[0]+"].point2.Y()-"+elid+"_el["+el[i].Pos[0]+"].point1.Y()),2) + Math.pow(("+elid+"_el["+el[i].Pos[0]+"].point2.X()-"+elid+"_el["+el[i].Pos[0]+"].point1.X()),2)) * "+UI_SETTINGS.unit_in_pixels+";} ";
}else
errors = errors + "distance measurement from point to "+ el[el[i].Pos[0]].CType + " is not working (Line "+el[i].Row+")!<br>";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[2]+','+el[i].Pos[3]+',function(){return "'+el[i].Pos[4] + ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'ratio/segments') {
// Ratio/Segments (obj1, obj2, numX, numY, string);
// Constructs a measurement of the ratio of the length of segment obj1 to the length of segment obj2. That is, this construction measures |obj|/|obj2|.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return "+elid+"_el["+el[i].Pos[0]+"].L() / "+elid+"_el["+el[i].Pos[1]+"].L()} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[2]+','+el[i].Pos[3]+',function(){return "'+el[i].Pos[4] + ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+';}], {color:"'+el[i].Att.Color+'", fixed:'+el[i].Att.Fixed+'} );';
}
else if (el[i].JsxType == 'ratio/points') {
/// Ratio/Points (obj1, obj2, obj3, numX, numY, string);
// Constructs a measurement of the three-point ratio implied by points obj1, obj2, and obj3.
// If these points are A, B, and C, respectively, then the three-point ratio is |AC|/|AB|.
evas[el[i].Row] = "function "+elid+el[i].Row+"() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+elid+"_el["+el[i].Pos[1]+"], "+elid+"_el["+el[i].Pos[0]+"], "+elid+"_el["+el[i].Pos[2]+"])))*"+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[2]+"]) / "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"])} ";
calc[el[i].Row] = elid+el[i].Row+"()";
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("text", ['+el[i].Pos[3]+','+el[i].Pos[4]+',function(){return "'+el[i].Pos[5]+ ' " + Math.round('+calc[el[i].Row]+'*'+UI_SETTINGS.measurementAccuracy+')/'+UI_SETTINGS.measurementAccuracy+' + "'+el[i].Att.Suffix+'";}],'+setAttributes({element:el[i], extraAttribute:'', visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
}
// * * * * * /MEASUREMENTS /
// BUTTONS /
else if (el[i].JsxType == 'text') {
if (document.getElementById('latex_fixedtext').checked == true)
evas[el[i].Row] = obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "\\\\"+"( '+el[i].Pos[2]+' \\\\"+")";}],'+setAttributes({element:el[i], extraAttribute:'', visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
else
evas[el[i].Row] = obj_c+'("text", ['+el[i].Pos[0]+','+el[i].Pos[1]+',function(){return "'+el[i].Pos[2]+'";}],'+setAttributes({element:el[i],extraAttribute:'', visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
}
else if (el[i].JsxType == 'movebutton') {
for (j = 0; j < el[i].Anim.length; j+=2)
tmpstring = tmpstring +elid+"_el["+el[i].Anim[j+1]+"].moveTo(["+elid+"_el["+el[i].Anim[j]+"].X(), "+elid+"_el["+el[i].Anim[j]+"].Y()],"+el[i].Pos[2]+");";
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[3]+' ", function() {'+tmpstring+'} ],'+setAttributes({element:el[i],extraAttribute:'', visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'showbutton') {
for (j = 0; j < el[i].Anim.length; j++) {
if (el[el[i].Anim[j]]) {
if (el[el[i].Anim[j]].CType == 'buttons' || el[el[i].Anim[j]].CType == 'measurements')
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].showElement();";
else if (el[el[i].Anim[j]].JsxType == 'originandunit')
tmpstring = tmpstring + boardname +"_b.addGrid();";
else if (el[el[i].Anim[j]].JsxType == 'locus') {
if (el[el[el[i].Anim[j]].Pos[1]].JsxType == 'point' && UI_SETTINGS.locusSetting) {tmpstring = tmpstring + elid+el[el[i].Anim[j]].Row+"visible=true;"+elid+"Locus"+el[el[i].Anim[j]].Row+"("+elid+"_el["+el[el[i].Anim[j]].Pos[2]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[0]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[1]+"]);";}
else tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:true});";
}
else
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:true});";
//if (el[i].Pos[2].indexOf("Jäljitä") >= 0 || el[i].Pos[2].indexOf("Trace") >= 0)
if (el[el[i].Anim[j]].Opts.indexOf('traced')>=0){
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({trace:true});";
}
}
else errors = errors + "- Error in JSP-code on line {"+el[i].Row+"}. ShowButton is trying to show element that does not excist!<br>";
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {'+tmpstring+'} ],'+setAttributes({element:el[i], visibility: UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'hidebutton') {
for (j = 0; j < el[i].Anim.length; j++) {
if (el[el[i].Anim[j]]) {
if (el[el[i].Anim[j]].CType == 'buttons' || el[el[i].Anim[j]].CType == 'measurements')
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].hideElement();";
else if (el[el[i].Anim[j]].JsxType == 'originandunit')
tmpstring = tmpstring + boardname +"_b.removeGrids();";
else if (el[el[i].Anim[j]].JsxType == 'locus') {
if (el[el[el[i].Anim[j]].Pos[1]].JsxType == 'point' && UI_SETTINGS.locusSetting) {tmpstring = tmpstring + elid+el[el[i].Anim[j]].Row+"visible=false;"+elid+"Locus"+el[el[i].Anim[j]].Row+"("+elid+"_el["+el[el[i].Anim[j]].Pos[2]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[0]+"],"+elid+"_el["+el[el[i].Anim[j]].Pos[1]+"]);";}
else tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:false});";
}
else
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].hideElement();";
//tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({visible:false});";
//if (el[i].Pos[2].indexOf("Lopeta") >= 0 || el[i].Pos[2].indexOf("Stop") >= 0) {
if (el[el[i].Anim[j]].Opts.indexOf('traced')>=0) {
tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].setAttribute({trace:false});";
//tmpstring = tmpstring + elid+"_el["+el[i].Anim[j]+"].clearTrace();";
}
}
else errors = errors + "- Error in JSP-code on line {"+el[i].Row+"}. HideButton is trying to hide element that does not excist!<br>";
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {'+tmpstring+'} ],'+setAttributes({element:el[i], visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
el[i].Anim = tmpstring;
}
else if (el[i].JsxType == 'animatebutton') { //ANIMBUTTON
//AnimateButton (xpos, ypos, label) (point/path pairs) (speeds) (once-only flags) (direction flags);
let UTIC = 100,
varType = el[el[i].Anim[0][0]].JsxType,
varS = elid+"_el["+el[i].Anim[0][0]+"]",
pathType = el[el[i].Anim[0][1]].JsxType,
pathS = elid+"_el["+el[i].Anim[0][1]+"]",
animSpeed = el[i].Anim[1][0],
//animTics = (2*UI_SETTINGS.boardsize[2])/UTIC,
repeatAnimation = el[i].Anim[2][0],
direction = el[i].Anim[3][0],
dirS = "",
animS = elid+"_anims["+el[i].Anim[0][0]+"]",
pathOrigL = "",
//limisS = "",
repeatS = "",
runsRule = "",
rAnS = "",
segmRelS = "",
initVarType = "",
animStartP = "",
animStartS = "",
clearRunS = "",
//clearRunSRule = "",
funcAni = "";
if(pathType === 'line') { //y=kx+b // k = getSlope() // b = getRise()
pathOrigL = "function origL_"+elid+"_"+el[i].Row+"(){return ("+animSpeed+"/100);}";
runsRule = "runs_" +elid+ "_" +el[i].Row+ "++;\n";
if (direction === 1) //from left to right
dirS = "if ( nPos[0]>="+UI_SETTINGS.boardsize[0]+"&&nPos[0]<="+UI_SETTINGS.boardsize[2]+" && nPos[1]>="+UI_SETTINGS.boardsize[3]+" && nPos[1] <= "+UI_SETTINGS.boardsize[1]+")nPos=["+varS+".X()+"+UI_SETTINGS.boardsize[2]*2+"/100,"+pathS+".getSlope()*("+varS+".X()+"+UI_SETTINGS.boardsize[2]*2+"/100)+"+pathS+".getRise()]; else nPos=["+UI_SETTINGS.boardsize[0]+","+pathS+".getSlope()*"+UI_SETTINGS.boardsize[0]+"+"+pathS+".getRise()];";
else //from right to left
dirS = "if ( nPos[0]>="+UI_SETTINGS.boardsize[0]+"&&nPos[0]<="+UI_SETTINGS.boardsize[2]+" && nPos[1]>="+UI_SETTINGS.boardsize[3]+" && nPos[1] <= "+UI_SETTINGS.boardsize[1]+")nPos=["+varS+".X()-"+UI_SETTINGS.boardsize[2]*2+"/100,"+pathS+".getSlope()*("+varS+".X()-"+UI_SETTINGS.boardsize[2]*2+"/100)+"+pathS+".getRise()]; else nPos=["+UI_SETTINGS.boardsize[2]+","+pathS+".getSlope()*"+UI_SETTINGS.boardsize[2]+"+"+pathS+".getRise()];";
}
else if (pathType === 'circle') {
pathOrigL = "let origpl_"+elid+"_"+el[i].Row+"="+pathS+".Radius();function origL_"+elid+"_"+el[i].Row+"(){return ("+animSpeed+"/100)*"+pathS+".Radius()/origpl_"+elid+"_"+el[i].Row+";}";
runsRule = direction === 1 ? "+0.06283185307" : "-0.06283185307";
}
if (pathType === 'segment') {
if (varType === 'glider')
clearRunS = /*varS+".free(); "+*/varS+".visit([0,0],1); "+/*varS+".makeGlider("+pathS+");*/" clearTimeout(rng_"+elid+"_"+el[i].Row+"); ";
else {
initVarType = varS +".makeGlider("+pathS+");";
clearRunS = varS+".free(); "+varS+".visit([0,0],1); "+/*varS+".makeGlider("+pathS+");*/" clearTimeout(rng_"+elid+"_"+el[i].Row+"); ";
}
}
else
clearRunS = "clearTimeout(rng_"+elid+"_"+el[i].Row+");";
// init repeating
if (repeatAnimation > 0) {
if (pathType === 'segment') {
repeatS = "";
}
else if (pathType === 'line')
repeatS = "if (runs_"+elid+"_"+el[i].Row+ "/100 > "+repeatAnimation+"+0.01) {animOn_"+elid+"_"+el[i].Row+"=false; clearTimeout(rng_"+elid+"_"+el[i].Row+"); runs_"+elid+"_"+el[i].Row+ "=0;}";
else if (pathType === 'circle')
repeatS = "&&repeatOnce<100";
else
repeatS = "";
}
if (pathType === 'segment') {
if (repeatAnimation === 0) { //repeat
if (direction === 0) { // direction from p1 -> p2
rAnS = ""+
"function rSAn1_"+elid+"_"+el[i].Row+"(sPoi) {"+
"let sAnIv2_"+elid+"_"+el[i].Row+" = "+varS+".Dist("+pathS+".point2)/"+pathS+".L()*"+animSpeed+";"+
"if(sPoi[0]=="+pathS+".point2.X()&&sPoi[1]=="+pathS+".point2.Y()){rSAn2_"+elid+"_"+el[i].Row+"();}"+
varS+".moveAlong([sPoi,["+pathS+".point2.X(),"+pathS+".point2.Y()]],sAnIv2_"+elid+"_"+el[i].Row+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"()}});"+
"}"+
"function rSAn2_"+elid+"_"+el[i].Row+"(sPoi) {"+
varS+".moveAlong([["+pathS+".point2.X(),"+pathS+".point2.Y()],["+pathS+".point1.X(),"+pathS+".point1.Y()]],"+animSpeed+",{callback:function(){rSAn3_"+elid+"_"+el[i].Row+"()}});"+
"}"+
"function rSAn3_"+elid+"_"+el[i].Row+"(sPoi) {"+
varS+".moveAlong([["+pathS+".point1.X(),"+pathS+".point1.Y()],["+pathS+".point2.X(),"+pathS+".point2.Y()]],"+animSpeed+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"()}});"+
"}";
}
else { //direction p2 -> p1
rAnS = ""+
"function rSAn1_"+elid+"_"+el[i].Row+"(sPoi) {"+
"let sAnIv1_"+elid+"_"+el[i].Row+"="+varS+".Dist("+pathS+".point1)/"+pathS+".L()*"+animSpeed+";"+
"if(sPoi[0]=="+pathS+".point1.X()&&sPoi[1]=="+pathS+".point1.Y()){rSAn2_"+elid+"_"+el[i].Row+"();}"+
varS+".moveAlong([sPoi,["+pathS+".point1.X(),"+pathS+".point1.Y()]],sAnIv1_"+elid+"_"+el[i].Row+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"()}});"+
"}"+
"function rSAn2_"+elid+"_"+el[i].Row+"(sPoi) {"+
varS+".moveAlong([["+pathS+".point1.X(),"+pathS+".point1.Y()],["+pathS+".point2.X(),"+pathS+".point2.Y()]],"+animSpeed+",{callback:function(){rSAn3_"+elid+"_"+el[i].Row+"()}});"+
"}"+
"function rSAn3_"+elid+"_"+el[i].Row+"(sPoi) {"+
varS+".moveAlong([["+pathS+".point2.X(),"+pathS+".point2.Y()],["+pathS+".point1.X(),"+pathS+".point1.Y()]],"+animSpeed+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"()}});"+
"}";
}
}
else { // run animation once
if (direction === 0) { //direction p1 -> p2
rAnS = ""+
"function rSAn1_"+elid+"_"+el[i].Row+"(sPoi) { "+
"let sAnIv1_"+elid+"_"+el[i].Row+"="+varS+".Dist("+pathS+".point1)/"+pathS+".L()*"+animSpeed+";"+
"let sAnIv2_"+elid+"_"+el[i].Row+"="+varS+".Dist("+pathS+".point2)/"+pathS+".L()*"+animSpeed+";"+
"if (sPoi[0]=="+pathS+".point2.X()&&sPoi[1]=="+pathS+".point2.Y()) {rSAn2_"+elid+"_"+el[i].Row+"(sPoi, sAnIv1_"+elid+"_"+el[i].Row+");}"+
varS+".moveAlong([sPoi,["+pathS+".point2.X(),"+pathS+".point2.Y()]],sAnIv2_"+elid+"_"+el[i].Row+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"(sPoi,sAnIv1_"+elid+"_"+el[i].Row+")}});"+
"}"+
"function rSAn2_"+elid+"_"+el[i].Row+"(sPoi,speed){"+
varS+".moveAlong([["+pathS+".point2.X(),"+pathS+".point2.Y()], ["+pathS+".point1.X(),"+pathS+".point1.Y()]],"+animSpeed+",{callback:function(){rSAn3_"+elid+"_"+el[i].Row+"(sPoi,speed);}});"+
"}"+
"function rSAn3_"+elid+"_"+el[i].Row+"(sPoi,speed){"+
varS+".moveAlong([["+pathS+".point1.X(),"+pathS+".point1.Y()], sPoi],speed,{callback:function(){toggleAnim_"+elid+"_"+el[i].Row+"();}});"+
"}";
}
else { // direction p2 -> p1
rAnS = ""+
"function rSAn1_"+elid+"_"+el[i].Row+"(sPoi) { "+
"let sAnIv1_"+elid+"_"+el[i].Row+"="+varS+".Dist("+pathS+".point1)/"+pathS+".L()*"+animSpeed+";"+
"let sAnIv2_"+elid+"_"+el[i].Row+"="+varS+".Dist("+pathS+".point2)/"+pathS+".L()*"+animSpeed+";"+
"if(sPoi[0]=="+pathS+".point1.X()&&sPoi[1]=="+pathS+".point1.Y()){rSAn2_"+elid+"_"+el[i].Row+"(sPoi, sAnIv2_"+elid+"_"+el[i].Row+");}"+
varS+".moveAlong([sPoi,["+pathS+".point1.X(), "+pathS+".point1.Y()]],sAnIv1_"+elid+"_"+el[i].Row+",{callback:function(){rSAn2_"+elid+"_"+el[i].Row+"(sPoi,sAnIv2_"+elid+"_"+el[i].Row+")}});"+
"}"+
"function rSAn2_"+elid+"_"+el[i].Row+"(sPoi,speed){"+
varS+".moveAlong([["+pathS+".point1.X(),"+pathS+".point1.Y()], ["+pathS+".point2.X(),"+pathS+".point2.Y()]],"+animSpeed+",{callback:function(){rSAn3_"+elid+"_"+el[i].Row+"(sPoi,speed);}});"+
"}"+
"function rSAn3_"+elid+"_"+el[i].Row+"(sPoi,speed){"+
varS+".moveAlong([["+pathS+".point2.X(),"+pathS+".point2.Y()], sPoi],speed,{callback:function(){toggleAnim_"+elid+"_"+el[i].Row+"();}});"+
"}";
}
}
rAnS += pathS+".on('up',function(){if ("+animS+") {toggleAnim_"+elid+"_"+el[i].Row+"(); toggleAnim_"+elid+"_"+el[i].Row+"()}});"+
pathS+".point1.on('up',function(){if ("+animS+") {toggleAnim_"+elid+"_"+el[i].Row+"(); toggleAnim_"+elid+"_"+el[i].Row+"()}});"+
pathS+".point2.on('up',function(){if ("+animS+") {toggleAnim_"+elid+"_"+el[i].Row+"(); toggleAnim_"+elid+"_"+el[i].Row+"()}});";
}
else if (pathType === 'circle') {
rAnS = "function rAn_"+elid+"_"+el[i].Row+"(nPos, repeatOnce){"+
"dynInterval_"+elid+"_"+el[i].Row+"=origL_"+elid+"_"+el[i].Row +"();" +
varS + ".moveTo(["+pathS+".center.X()+"+pathS+".radius*Math.cos(nPos),"+pathS+".center.Y()+"+pathS+".radius*Math.sin(nPos)]);" +
"if("+ animS + repeatS+")rng_"+elid+"_"+el[i].Row+"=setTimeout(function(){rAn_"+elid+"_"+el[i].Row+"(nPos"+runsRule+",repeatOnce+1)},dynInterval_"+elid+"_"+el[i].Row+");"+
"else toggleAnim_"+elid+"_"+el[i].Row+"();"+
"}";
}
else {
rAnS = "function rAn_"+elid+"_"+el[i].Row+"(nPos){"+
runsRule +
"dynInterval_"+elid+"_"+el[i].Row+"=origL_"+elid+"_"+el[i].Row +"();" +
"" + varS + ".moveTo(nPos);" +
dirS +
repeatS +
"if("+animS+")rng_"+elid+"_"+el[i].Row+"=setTimeout(function(){rAn_"+elid+"_"+el[i].Row+"(nPos)},dynInterval_"+elid+"_"+el[i].Row+");"+
"}";
}
if (pathType === 'circle')
animStartP = "let sPoi = Math.atan2("+varS+".Y() - "+pathS+".center.Y(), "+varS+".X() - "+pathS+".center.X());";
else
animStartP = "let sPoi=["+varS+".X(),"+varS+".Y()];";
if (pathType === 'segment')
animStartS = "if("+animS+")rSAn1_"+elid+"_"+el[i].Row+"(sPoi);";
else if (pathType === 'circle')
animStartS = "if("+animS+")rAn_"+elid+"_"+el[i].Row+"(sPoi, 0);";
else
animStartS = "if("+animS+")rAn_"+elid+"_"+el[i].Row+"(sPoi);";
// create function for animation object /
funcAni = ""+
animS+"=false;"+
"let rng_"+elid+"_"+el[i].Row+","+
"dynInterval_"+elid+"_"+el[i].Row+","+
"runs_"+elid+"_"+el[i].Row+" = 0,"+
"relStartPos"+elid+"_"+el[i].Row+";"+
pathOrigL +
"function toggleAnim_"+elid+"_"+el[i].Row+"(){"+
"runs_"+elid+"_"+el[i].Row+"=0;"+
initVarType +
animStartP +
segmRelS +
"if(!"+animS+")"+animS+"=true;else{"+animS+"=false;};"+
animStartS +
"else {"+
clearRunS +
"}}"+
rAnS+
obj_c+"('button', ["+el[i].Pos[0]+","+el[i].Pos[1]+", '"+el[i].Pos[2]+"', function(){toggleAnim_"+elid+"_"+el[i].Row+"()}],{});";
// PARANNA TÄTÄ !!!!
tmpstring = "toggleAnim_"+elid+"_"+el[i].Row+"();";
el[i].Anim = tmpstring;
evas[el[i].Row] = funcAni;
}
/*
else if (el[i].JsxType == 'animatebutton') { //ANIMBUTTON
// AnimateButton
// (xpos, ypos, label) (point/path pairs)
// (speeds) (once-only flags) (direction flags);
evas[el[i].Row] ="";
for (j=0; j<el[i].Anim[0].length; j+=2) {
tmpstring = tmpstring +
"if (!anim"+el[i].Row+j+") {\n"+
"\tanim"+el[i].Row+j+"=true; \n"+
"\t"+elid+"_animOn=true; \n"+
"animateOn"+el[i].Row+j+"();\n"+
"} else {\n"+
"\tanim"+el[i].Row+j+" = false; \n"+
"\t"+elid+"_animOn=false; \n"+
"\tanimateOff"+el[i].Row+j+"();\n"+
"}";
//Create anim path (corners of the board, or segment start and end point)
if (el[i].Anim[3][j] == 1) {//If counter clockwise (on circle) or start-end-start-point on segment
// VANHA TOIMIVA: evas[el[i].Row] = evas[el[i].Row] + "var "+elid+"_path"+el[i].Row+j+"=[];if("+elid+"_el["+el[i].Anim[0][j+1]+"].getType()=='segment'){"+elid+"_path"+el[i].Row+j+"=["+elid+"_el["+el[i].Anim[0][j+1]+"].point1,"+elid+"_el["+el[i].Anim[0][j+1]+"].point2,"+elid+"_el["+el[i].Anim[0][j+1]+"].point1];}else{"+elid+"_path"+el[i].Row+j+"=[["+boardsize[2]+","+boardsize[1]+"],["+boardsize[0]+","+boardsize[1]+"],["+boardsize[0]+","+boardsize[3]+"],["+boardsize[2]+","+boardsize[3]+"],["+boardsize[2]+","+boardsize[1]+"]];}";
evas[el[i].Row] = evas[el[i].Row] +
"function "+elid+"_path"+el[i].Row+j+"(a,b,c) {\n"+
"\tif(a.getType()=='segment'){\n"+
"\t\treturn [[b.X(), b.Y()], [a.point1.X(), a.point1.Y()], [b.X(), b.Y()]];\n"+
"\t}else{\n"+
"return [["+UI_SETTINGS.boardsize[2]+",0], [0,"+UI_SETTINGS.boardsize[1]+"], ["+UI_SETTINGS.boardsize[0]+", 0], [0, "+UI_SETTINGS.boardsize[3]+"], ["+UI_SETTINGS.boardsize[2]+", 0]];"+
"\t}\n"+
"}";
}
else //if clockwise (on circle) or only on-way movement on segment
evas[el[i].Row] = evas[el[i].Row] +
"function "+elid+"_path"+el[i].Row+j+"(a,b,c) {\n"+
"\tif(a.getType()=='segment'){\n"+
"\t\treturn [[a.point1.X(), a.point1.Y()], [a.point2.X(), a.point2.Y()]];\n"+
"\t}else{\n"+
"return [["+UI_SETTINGS.boardsize[2]+",0], [0,"+UI_SETTINGS.boardsize[3]+"], ["+UI_SETTINGS.boardsize[0]+", 0], [0, "+UI_SETTINGS.boardsize[1]+"], ["+UI_SETTINGS.boardsize[2]+", 0]];"+
"\t}\n"+
"}";
// create variable anim[Row nr][j] and functions needed (animOn, animOff)
if (el[i].Anim[2][j] == 0) { // if run repeatedly
if (eval(elid+"_el["+el[i].Anim[0][j+1]+"]").getType() == 'segment')
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
else
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
}
else { // if run only once
if (eval(elid+"_el["+el[i].Anim[0][j+1]+"]").getType() == 'segment')
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\tanim"+el[i].Row+j+" = false; \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\tvar path_"+el[i].Row+"="+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"], "+elid+"_el["+el[i].Anim[0][j]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong(path_"+el[i].Row+", "+el[i].Anim[1][j]+");\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+
"\t\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
else
evas[el[i].Row] = evas[el[i].Row] +
"var anim"+el[i].Row+j+" = false; \n"+
"var antype"+el[i].Row+j+"="+elid+"_el["+el[i].Anim[0][j]+"].getType(); \n"+
"function animateOn"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[i].Anim[0][j+1]+"]); \n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].moveAlong("+elid+"_path"+el[i].Row+j+"("+elid+"_el["+el[i].Anim[0][j+1]+"]), "+el[i].Anim[1][j]+", {callback: animateOn"+el[i].Row+j+"});\n"+
"}; \n"+
"function animateOff"+el[i].Row+j+"() {\n"+
"\t"+elid+"_el["+el[i].Anim[0][j]+"].visit([0,0], 1); \n"+
"\tif (antype"+el[i].Row+j+" == 'point')"+elid+"_el["+el[i].Anim[0][j]+"].free(); \n"+
"\tif (antype"+el[i].Row+j+" == 'glider')"+elid+"_el["+el[i].Anim[0][j]+"].makeGlider("+elid+"_el["+el[el[i].Anim[0][j]].Pos[0]+"]); \n"+
"}; ";
}
}
if (animtype.indexOf("animtype1")>=0) evas[el[i].Row] = evas[el[i].Row] + 'function click'+el[i].Row+'() {'+tmpstring+'} '+obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+'", function() { click'+el[i].Row+'();}], {fixed:true} );';
// if user selected 'animtype2' the this
else {
evas[el[i].Row] = evas[el[i].Row] + obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function() {if ('+elid+'_animOn){'+elid+'_el['+el[i].Anim[0][0]+'].stopAnimation(); '+elid+'_animOn=false;} else{'+elid+'_el['+el[i].Anim[0][0]+'].startAnimation(1,'+animticks+'); '+elid+'_animOn=true;}}], {fixed:true, showInfoBox:'+el[i].Att.Infobox+'});';
if (eval(elid+"_el["+el[i].Anim[0][0]+"]").getType()!="glider")
errors = errors + "Error on line ["+el[i].Row+"]: You can't use animation2 for other objects than 'Point on object'. <br>Some animation may not work properly.<br><br>";
}
el[i].Anim = tmpstring;
} //ANIMBUTTON*/
else if (el[i].JsxType == 'simultaneousbutton') {
for (j = 0; j < el[i].Anim.length; j++) {
tmpstring = " "+tmpstring + el[el[i].Anim[j]].Anim;
}
evas[el[i].Row] = obj_c+'("button", ['+el[i].Pos[0]+','+el[i].Pos[1]+', "'+el[i].Pos[2]+' ", function(){'+tmpstring+'} ],'+setAttributes({element:el[i], visibility:UI_SETTINGS.useAttributeVisible, elementId:elid})+');';
el[i].Anim = tmpstring;
}
// * * * * * * /BUTTONS
// COORDINATE SYSTEM * * * * /
else if(el[i].JsxType == 'originandunit') {
evas[el[i].Row] = elid+"_el["+el[i].Row+"] = ["+elid+"_el["+el[i].Pos[0]+"],function(){return "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"]);}];";
evas[el[i].Row] += elid+"_unit = ["+elid+"_el["+el[i].Pos[0]+"],function(){return "+elid+"_el["+el[i].Pos[0]+"].Dist("+elid+"_el["+el[i].Pos[1]+"]);}];";
//evas[el[i].Row] += boardname+'_b.moveOrigin('+UI_SETTINGS.scale * getOrigin(sketch).slice(0,getOrigin(sketch).indexOf(','))+','+UI_SETTINGS.scale * getOrigin(sketch).slice(getOrigin(sketch).indexOf(',')+1,getOrigin(sketch).length)+');';
evas[el[i].Row] += boardname+"_b.moveOrigin("+el[el[i].Pos[0]].oPos+");";
// evas[el[i].Row] += "var " + elid+"_grid = " + boardname+"_b.create('grid', []);";
//evas[el[i].Row] += boardname+"_b.update();";
//evas[el[i].Row] += elid+"_el["+el[i].Pos[1]+"].on('drag', function(){"+boardname+"_b.setAttribute({unitx : 90});});" + boardname+"_b.fullUpdate();";
}
else if(el[i].JsxType == 'coordinates') {
/*Coordinates(obj1, obj2, numX, numY, string);
Constructs a measurement of the ordered pair of coordinates representing point obj1's location with respect to the coordinate system obj2.
https://www.math.uni-bielefeld.de/~lisken/cgi-bin/jsp_qref?5.7.11+5.9*+5.7
*/
calc[el[i].Row] = ["function(){return "+elid+"_el["+el[i].Pos[0]+"].X();}", "function(){return "+elid+"_el["+el[i].Pos[0]+"].Y();}"];
evas[el[i].Row] = obj_c+"('text', ["+el[i].Pos[2]+","+el[i].Pos[3]+",function(){return '"+el[i].Pos[4]+" ('+ Math.round("+elid+"_el["+el[i].Pos[0]+"].X()*"+UI_SETTINGS.measurementAccuracy+")/"+UI_SETTINGS.measurementAccuracy+" +','+ Math.round("+elid+"_el["+el[i].Pos[0]+"].Y()*"+UI_SETTINGS.measurementAccuracy+")/"+UI_SETTINGS.measurementAccuracy+" +')';}], {name:'"+el[i].Att.Name+"',color:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", anchorX:'"+el[i].Att.AnchorX+"', fixed:"+el[i].Att.Fixed+", showInfoBox:"+el[i].Att.Infobox+", anchorX:'left'} );";
}
// * * * * * /COORDINATE SYSTEM /
// LOCUS * * * * * * /
else if (el[i].JsxType == 'locus') {
if (el[i].Pos[3]>100) el[i].Pos[3] = 100;
// First let's check if Locus is replaced
// el.locusToReplace = row of the locus
// el.replaceLocus = replace function as string "function(x){something...}"
if(el[i].JSPComment.indexOf('calcLocus')>=0) {
let newLocus = calc[el[i].replaceLocus[0]];
while (newLocus.indexOf(elid+el[i].replaceLocus[1]+'()')>0) {
newLocus = newLocus.replace(elid+el[i].replaceLocus[1]+'()', el[i].replaceLocus[2]);
}
//console.log(calc[el[i].replaceLocus[0]]);
newLocus = obj_c + "('functiongraph', [function("+el[i].replaceLocus[2]+") {return " /*+ elid + "_unit() * "*/ + newLocus/*+"+"+elid+"_unit[0].Y()*/+";}";
if (typeof el[i].replaceLocus[3] === 'object' && typeof el[i].replaceLocus[3][0] === 'number' && typeof el[i].replaceLocus[3][1] === 'number')
newLocus += ", "+el[i].replaceLocus[3] + "], "+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
else if (typeof el[i].replaceLocus[3] === 'number')
newLocus += ", function(){return "+elid+"_el["+el[i].replaceLocus[3]+"].point1.X();}, function(){return "+elid+"_el["+el[i].replaceLocus[3]+"].point2.X();} ], "+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
else
newLocus += "], "+setAttributes({element:el[i],extraAttribute:'',visibility:UI_SETTINGS.useAttributeVisible,elementId:elid})+");";
if (el[i].replaceLocus[4] === 'r') {
console.log(el[i].JSPComment);
}
console.log('Locus '+el[i].Original_line+' replaced to: '+newLocus);
evas[el[i].Row] = newLocus;
}
else if(el[i].JSPComment.indexOf('locus')>=0) {
try {
let lrtmp1 = '';
let lrtmp2 = '';
let reps = [];
reps = (replaceJspVariablesFromString(el[i].replaceLocus));
/*while (el[i].replaceLocus.indexOf('@')>0) {
lrtmp1 = el[i].replaceLocus.slice(el[i].replaceLocus.indexOf('@'), el[i].replaceLocus.indexOf('@', el[i].replaceLocus.indexOf('@')+1)+1);
if (calc[eval(lrtmp1.slice(1,lrtmp1.length-1))])
lrtmp2 = calc[eval(lrtmp1.slice(1,lrtmp1.length-1))];
else lrtmp2 = elid + "_el[" + lrtmp1.slice(1,lrtmp1.length-1) +"]";
el[i].replaceLocus = el[i].replaceLocus.replace(lrtmp1, lrtmp2);
} */
for (j=0; j<reps.length; j++) {
while (el[i].replaceLocus.indexOf('{'+reps[j]+'}')>=0){
lrtmp1 = '{'+reps[j]+'}';
if (calc[eval(reps[j])])
lrtmp2 = calc[eval(reps[j])];
else lrtmp2 = elid + "_el[" + reps[j] + "]";
el[i].replaceLocus = el[i].replaceLocus.replace(lrtmp1, lrtmp2);
}
}
if (el[i].replaceLocus.indexOf('functiongraph')<0) {
el[i].replaceLocus = "'functiongraph', [" + el[i].replaceLocus + "]";
}
el[i].replaceLocus += ', ' + setAttributes({element:el[i], visibility:UI_SETTINGS.useAttributeVisible, elementId:elid});
evas[el[i].Row] = obj_c+"( "+el[i].replaceLocus+ ");";
} catch(err) {alert(err.message + err);}
} else {
// JSP description: Locus(obj1, obj2, obj3, num);
//Constructs the locus of obj1 as point obj2 moves along the path determined by obj3.
//JavaSketchpad devotes num samples to the representation of the locus--higher values of
//num correspond to more accurate approximations of the locus, but take more time and computer memory to process.
let usertick = 1/30; //set user ticks here
if (el[i].Pos[3] <= 20) usertick = 1/eval(el[i].Pos[3]);
else usertick = 1/((eval(el[i].Pos[3]) / 21) + 20);
// If locus is created by path of a glider, locus will be created normally as a tracecurve construction in JSXGraph
if (eval(elid+"_el["+el[i].Pos[1]+"]").getType() == 'glider')
evas[el[i].Row] = obj_c+"('tracecurve', ["+elid+"_el["+el[i].Pos[1]+"],"+elid+"_el["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+el[i].Pos[3]+", highlight:false} );";
else if (eval(elid+"_el["+el[i].Pos[1]+"]").getType() == 'point') {
locus_counter = locus_counter +1;
let lrobj = [];
let end_gh_r = eval(el[i].Pos[0]);
k = eval(el[i].Pos[1]);
let need_to_duplicate = [];
//let tmp_listnr = 0;
let tmp_duplicate = "";
let tmp_duplicates = [];
let tmp_tmp = "";
let numPoints = eval(el[i].Pos[3]);
if (numPoints<50) numPoints = 50;
else if (numPoints>100) numPoints = 100;
if (el[el[i].Pos[2]].JsxType == 'circle') {
if (!UI_SETTINGS.locusSetting) {
lrobj.push(eval(el[i].Pos[1])); //starting row to check + duplicate
need_to_duplicate.push(eval(el[i].Pos[1]));
while(k < end_gh_r) {
k = k+1;
for (j=0; j<need_to_duplicate.length; j++) {
if (evas[el[k].Row].indexOf(elid+"_el["+need_to_duplicate[j]+"]")>=0 && need_to_duplicate.indexOf(k)<0) {
need_to_duplicate.push(k);
}
}
} // here is the list for lines needed to duplicate : alert(need_to_duplicate);
if (el[need_to_duplicate[0]].JsxType == 'point')
tmp_duplicates.push( "var " + elid + "_dup"+locus_counter+" = [];\n"+
elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"] = " + boardname + "_b.create('glider', ["+elid+"_el["+el[i].Pos[2]+"]], );\n"+ elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"].hideElement();");
else {alert("Something went wrong in Locus operation!"); return null;}
for (j = 1; j<need_to_duplicate.length; j++) {
tmp_duplicate = evas[need_to_duplicate[j]];
for (m=0; m<need_to_duplicate.length; m++) {
while(tmp_duplicate.indexOf(elid+"_el["+need_to_duplicate[m]+"]")>=0)
tmp_duplicate = tmp_duplicate.replace(elid+"_el["+need_to_duplicate[m]+"]", elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"]");
while(tmp_duplicate.indexOf(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();")>=0)
tmp_duplicate = tmp_duplicate.replace(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();", "\n");
if (tmp_duplicate.indexOf('],{')>0) {
tmp_tmp = tmp_duplicate.slice(tmp_duplicate.indexOf('],{')+2, tmp_duplicate.lastIndexOf('}')+1);
tmp_duplicate = tmp_duplicate.replace(tmp_tmp, " {} ");
}
}
tmp_duplicates.push(tmp_duplicate + elid + "_dup"+locus_counter+"["+need_to_duplicate[j]+"].hideElement()");
}
evas[el[i].Row] = "";
for (j=0; j<tmp_duplicates.length; j++) {
evas[el[i].Row] = evas[el[i].Row] + tmp_duplicates[j] + "\n";
}
evas[el[i].Row] = evas[el[i].Row] + obj_c + "('tracecurve', ["+elid+"_dup"+locus_counter+"["+el[i].Pos[1]+"],"+elid+"_dup"+locus_counter+"["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+numPoints+", highlight:false} );";
}
// If locus is created by path that is circle or segment, and a point other than glider mover along that path, locus will be created by this algorithm
// Algorithm creates locus like explained next:
// - make the point to be a gliderpoint on wanted path
// - move point along that path distance of a tick (user can define, default is 30 ticks)
// - while point is moving along path, collect the coordinatedata of the point we want to draw the locus
// - clear all old segments if there are any, and create segments between all the coordinatepoint from the data
// - make point not to be gliderpoint anymore, and return it to its startingpoint
// - make events for the nessessary objects to launch this function
else {
// vanhja "toimiva"
//evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){var objstart=[obj3.X(),obj3.Y()];var locuspath=[];var tick=0;obj3.makeGlider(obj1);while(tick<=1.02){obj3.setGliderPosition(tick); locuspath.push([obj2.X(),obj2.Y()]); tick=tick+"+usertick+";} for(i=0; i<locuspath.length; i++){"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][i]); if(i==0)"+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i],locuspath[locuspath.length-1]],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); else "+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i-1],locuspath[i]],{strokeWidth:1,fixed:true, visible:"+elid+el[i].Row+"visible}); } if(!"+elid+"_animOn){obj3.free(); obj3.setPosition(JXG.COORDS_BY_USER, objstart); "+boardname+"_b.update();} return locuspath; }";
evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; \n"+
"function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){\n\t"+
"var objstart=[obj3.X(),obj3.Y()],\n\t"+
"\tlocuspathx=[], locuspathy=[],\n\t"+
"\ttick=0;\n\t"+
"obj3.makeGlider(obj1);\n\t"+
"while(tick<=1.00){\n\t\t"+
"obj3.setGliderPosition(tick); \n\t\t"+
"locuspathx.push(obj2.X()); \n\t\t"+
"locuspathy.push(obj2.Y()); \n\t\t"+
"tick=tick+"+usertick+";} \n\t"+
boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][0]); \n\t"+
elid+"_el["+el[i].Row+"][0]="+boardname+"_b.create('curve',[locuspathx, locuspathy],{doAdvancedPlot:false,numberPointsLow:10,numberPointsHigh:10, strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); \n\t"+
"if(!"+elid+"_animOn){\n\t\t"+
"obj3.free(); \n\t\t"+
"obj3.setPosition(JXG.COORDS_BY_USER, objstart); \n\t\t"+
boardname+"_b.update();\n\t} \n"+
"}";
//alert(evas[el[i].Row]);
evas[el[i].Row] = evas[el[i].Row] + elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n";
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[i].Pos[2]+"].on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});\n"+
elid+"_el["+el[i].Pos[2]+"].center.on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});";
if (el[el[i].Pos[2]].JsxType == 'circle') {
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[el[el[i].Pos[2]].Pos[1]].Row+"].on('up', function() {\n"+
"\t"+ elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n});";
}
}
}
else if (el[el[i].Pos[2]].JsxType == 'segment') {
if (!UI_SETTINGS.locusSetting) {
lrobj.push(eval(el[i].Pos[1])); //starting row to check + duplicate
//alert(lrobj[0] +","+ end_gh_r);
need_to_duplicate.push(eval(el[i].Pos[1]));
while(k < end_gh_r) {
k = k+1;
for (j=0; j<need_to_duplicate.length; j++) {
if (evas[el[k].Row].indexOf(elid+"_el["+need_to_duplicate[j]+"]")>=0 && need_to_duplicate.indexOf(k)<0) {
need_to_duplicate.push(k);
}
}
} // here is the list for lines needed to duplicate : alert(need_to_duplicate);
if (el[need_to_duplicate[0]].JsxType == 'point')
tmp_duplicates.push( "var " + elid + "_dup"+locus_counter+" = [];\n"+
elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"] = " + boardname + "_b.create('glider', ["+elid+"_el["+el[i].Pos[2]+"]], );\n"+ elid + "_dup"+locus_counter+"["+need_to_duplicate[0]+"].hideElement();");
else {alert("Something went wrong in Locus operation!"); return null;}
for (j = 1; j<need_to_duplicate.length; j++) {
tmp_duplicate = evas[need_to_duplicate[j]];
for (m=0; m<need_to_duplicate.length; m++) {
while(tmp_duplicate.indexOf(elid+"_el["+need_to_duplicate[m]+"]")>=0)
tmp_duplicate = tmp_duplicate.replace(elid+"_el["+need_to_duplicate[m]+"]", elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"]");
while(tmp_duplicate.indexOf(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();")>=0)
tmp_duplicate = tmp_duplicate.replace(elid + "_dup"+locus_counter+"["+need_to_duplicate[m]+"].hideElement();", "\n");
if (tmp_duplicate.indexOf('],{')>0) {
tmp_tmp = tmp_duplicate.slice(tmp_duplicate.indexOf('],{')+2, tmp_duplicate.lastIndexOf('}')+1);
tmp_duplicate = tmp_duplicate.replace(tmp_tmp, " {} ");
}
}
tmp_duplicates.push(tmp_duplicate + elid + "_dup"+locus_counter+"["+need_to_duplicate[j]+"].hideElement()");
}
evas[el[i].Row] = "";
for (j=0; j<tmp_duplicates.length; j++) {
evas[el[i].Row] = evas[el[i].Row] + tmp_duplicates[j] + "\n";
}
evas[el[i].Row] = evas[el[i].Row] + obj_c + "('tracecurve', ["+elid+"_dup"+locus_counter+"["+el[i].Pos[1]+"],"+elid+"_dup"+locus_counter+"["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+", numberPoints:"+numPoints+", highlight:false} );";
}
else {
//vanha "toimiva"
//evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){var objstart=[obj3.X(),obj3.Y()];var locuspath=[];var tick=0;obj3.makeGlider(obj1);while(tick<=1.02){obj3.setGliderPosition(tick); locuspath.push([obj2.X(),obj2.Y()]); tick=tick+"+usertick+";} for(i=0; i<locuspath.length; i++){"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][i]); if(i==0)"+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i],locuspath[i]],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); else "+elid+"_el["+el[i].Row+"][i]="+boardname+"_b.create('segment',[locuspath[i-1],locuspath[i]],{strokeWidth:1,fixed:true, visible:"+elid+el[i].Row+"visible}); } if(!"+elid+"_animOn){obj3.free(); obj3.setPosition(JXG.COORDS_BY_USER, objstart); "+boardname+"_b.update();} return locuspath; }";
evas[el[i].Row] = "var "+elid+el[i].Row+"visible="+el[i].Att.Visible+";"+ elid+"_el["+el[i].Row+"]=[]; \n"+
"function "+elid+"Locus"+el[i].Row+"(obj1,obj2,obj3){\n"+
"\tvar objstart=[obj3.X(),obj3.Y()],\n\t"+
"\tlocuspathx=[], locuspathy=[],\n"+
"\ttick=0;\n"+
"\tobj3.makeGlider(obj1);\n"+
"\tobj3.setGliderPosition(0);\n"+
"\tlocuspathx.push(obj2.X());locuspathy.push(obj2.Y());\n"+
"\tobj3.setGliderPosition(1);\n"+
"\tlocuspathx.push(obj2.X());locuspathy.push(obj2.Y());\n"+
"\t"+boardname+"_b.removeObject("+elid+"_el["+el[i].Row+"][0]); \n"+
"\t"+elid+"_el["+el[i].Row+"][0]="+boardname+"_b.create('curve',[locuspathx,locuspathy],{strokeWidth:1,fixed:true,visible:"+elid+el[i].Row+"visible}); \n"+
"\tif(!"+elid+"_animOn){\n"+
"\t\tobj3.free(); \n"+
"\t\tobj3.setPosition(JXG.COORDS_BY_USER, objstart); \n"+
"\t\t"+boardname+"_b.update();\n"+
"} \n"+
"}";
evas[el[i].Row] = evas[el[i].Row] + elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);";
evas[el[i].Row] = evas[el[i].Row] +
elid+"_el["+el[i].Pos[2]+"].on('up', function() {\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});\n"+
elid+"_el["+el[i].Pos[2]+"].point1.on('up', function() {\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});\n"+
elid+"_el["+el[i].Pos[2]+"].point2.on('up', function(){\n"+
"\t"+elid+"Locus"+el[i].Row+"("+elid+"_el["+el[i].Pos[2]+"],"+elid+"_el["+el[i].Pos[0]+"],"+elid+"_el["+el[i].Pos[1]+"]);\n"+
"});";
}
}
else errors = errors + "Traced point [line:"+el[i].Pos[1]+"] is not a type 'Point on object' [type is "+el[el[i].Pos[1]].Type+"].<br> 'Locus' can be constructed for a 'Point'-element only if path [line:"+el[i].Pos[2]+"] in 'Circle' or 'Segment'.<br>Locus [line:"+el[i].Row+"] was not constructed!<br><br>";
}
else
//evas[el[i].Row] = obj_c+"('locus', ["+elid+"_el["+el[i].Pos[0]+"]], {name:'"+el[i].Att.Name+"', strokeColor:'"+el[i].Att.Color+"', visible:"+el[i].Att.Visible+"} );";
errors = errors + "Error on line ["+el[i].Row+"]: Traced point on line ["+el[i].Pos[1]+"] is not a type 'Point on object'.<br> This locus may not work properly. <br><br>";
}
}
// * * * * * /LOCUS /
// ********* / MACROS /
else if (jsp_macros.indexOf(el[i].Type) >= 0) {
tmp = "";
for (k in el[i].Pos) {
if (el[i].Pos[k]) tmp = tmp + elid + "_el[" + el[i].Pos[k] + "],";
}
tmp = tmp.slice(0,tmp.lastIndexOf(','));
//tmp = tmp + '"' + setAttributes(el[i], '') + '"';
evas[el[i].Row] = elid+"_el["+el[i].Row+"] = " + el[i].Type + "(" + tmp + ");\n" + elid+"_el["+ el[i].Row +"].setAttribute("+setAttributes({element:el[i]})+");";
//alert(evas[el[i].Row]);
}
else {
errors += "Operator '"+el[i].Type+"' is unknown or is not supported yet.<br> Converting stopped on line ["+el[i].Row+"]. <br><br>";
//errors = errors + el[i].Original_line + "\n\n";
//errors = errors + "\n" + document.getElementById(code_input).value.slice(document.getElementById(code_input).value.lastIndexOf(';', el[i].att), document.getElementById(code_input).value.indexOf(';'), el[i].att ) + " might also be bad $JSP name for element.";
break;
}
if (el[i].Macro.length > 0) {
if (1 === 1) {
warnings += "<span style='color:#cc5500'>There are macros used in JSP code. Macros are not currently working. Macro lines<br><span style='color:#000; font-family:courier; font-size:0.9em;'>"+el[i].Macro+"</span><br>were bypassed.</span><br>";
}
else {
tmp = "";
//console.log('toimii tähän saakka');
for (j = 1; j<el[i].Macro.length; j++) {
//console.log(el[i].Macro[j].Row);
if (j<el[i].Macro.length-1) {
el[i].Macro[j] = "\tvar " + el[i].Macro[0].slice(0,3) + "_" + el[i].Macro[j].Row + " = " + boardname + "_b.create" + getMacroFunction(el[i].Macro[j]) + "\n";
tmp = tmp + el[i].Macro[j];
}
else el[i].Macro[j] = "\treturn " + document.getElementById('jsxgboardname').value + "_b.create" + getMacroFunction(el[i].Macro[j]) + "\n";
}
el[i].Macro[0] = "function " + el[i].Macro[0] + " { \n";
el[i].Macro[el[i].Macro.length-1] = el[i].Macro[el[i].Macro.length-1] + "}\n";
tmp = el[i].Macro[0] + tmp + el[i].Macro[el[i].Macro.length-1];
evas[el[i].Row] = tmp + evas[el[i].Row];
}
}
//Hide buttons and measurements if they are 'hidden' in options field
if (!el[i].Att.Visible && (el[i].CType == 'measurements' || el[i].CType == 'buttons') ) {evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";}
//update 12.3.2018: visibility setting
if (UI_SETTINGS.useAttributeVisible == true && el[i].JSPComment.indexOf('attVisible')<0 /*&& el[i].Opts.indexOf('traced')<0*/ && !(el[i].CType == 'measurements' || el[i].CType == 'buttons' || jsp_macros.indexOf(el[i].Type)<0) || el[i].JsxType == 'macros') {
if (evas[el[i].Row].indexOf('visible:false,')>=0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf(',', evas[el[i].Row].indexOf('visible'))+1), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
else if (evas[el[i].Row].indexOf('visible:false}')>=0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf('}', evas[el[i].Row].indexOf('visible'))), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();"; }
} //end update
if (UI_SETTINGS.useAttributeVisible == true && el[i].JSPComment.indexOf('attVisible')<0 && (el[i].Type == 'VectorTranslation' || el[i].Type == 'Point on object') && evas[el[i].Row].indexOf('visible:false,')>0) {
evas[el[i].Row] = evas[el[i].Row].replace(evas[el[i].Row].slice(evas[el[i].Row].indexOf('visible'), evas[el[i].Row].indexOf(',', evas[el[i].Row].indexOf('visible'))+1), '');
evas[el[i].Row] = evas[el[i].Row] + elid+"_el["+el[i].Row+"].hideElement();";
}
} //end of else
//18.9. ,-attribute, labelsize
if (contains(el[i].JSPComment,'smallLabel'))
evas[el[i].Row]+= elid+"_el["+el[i].Row+"].label.setAttribute({fontSize:10});";
if (contains(el[i].JSPComment,'bigLabel'))
evas[el[i].Row]+= elid+"_el["+el[i].Row+"].label.setAttribute({fontSize:15});";
//CONVERT ROW
eval(evas[el[i].Row]);
tmpstring = "";
if (document.getElementById('originalcode').value == 'Comment' && !isFullPageConvert)
codestring = codestring + "\n /* " +getOrigString(el[i], 0, 0, false, 'SketchrowOnly')+ " */\n";
if (el[i].comment.length>0 || el[i].JSPComment.length>0 || el[i].LastComment.length>0 ) {
try {
//add normal comment if there is one
if (el[i].comment.length>1)
codestring = codestring + el[i].comment + "\n" ;
//add new jsx code string
codestring = codestring + evas[el[i].Row] + "\n";
//add dot command if there is one
if (el[i].JSPComment.length>1)
codestring = codestring + "/* " + el[i].JSPComment.slice(0, this.length-1) + " */\n";
//finally add last comment if there is one at the end of the code
if (el[i].LastComment.length > 1)
codestring = codestring + el[i].LastComment + "\n";
} catch(e) {alert(el[i].comment);}
}
else
codestring = codestring + evas[el[i].Row] + "\n" ;
if (!isFullPageConvert){
codestring = codestring+"\n";
}
}
} //end of for
if (board_update_events.length > 0) {
board_update_events = boardname+"_b.on('update', function(){" + board_update_events + "});\n\n";
codestring = codestring + board_update_events;
eval(board_update_events);
}
if (sketch == 'null') errors = errors + document.getElementById('errormessages_prog').innerHTML;
//Check for errors
if (errors.length>0 && document.getElementById(code_input) && document.getElementById(code_input).value.length>0) document.getElementById('ERRORS').style.display="block";
} //end of try
catch(err){
document.getElementById('ERRORS').style.display="inline-block";
errors = errors + "<br>ERROR OCCURRED DURING COMPILATION!<br>Error name: "+err.name+"<br>Error message: "+err.message+"<br>Error stack: "+err.stack+"<br><br>Operation on line "+ lineCount(sketch, el[evas.length-1].Orig.slice(0, el[evas.length-1].Orig.lastIndexOf(')')+1)) +el[evas.length-1].Orig+" caused this problem.";
//document.getElementById('errormessages_dev').innerHTML = "<form action='posterror.php' method='POST' name='Error occurred in JSPtoJSXG'><br>"+"<textarea rows='3' cols='30' name='errormes' style='display:none;'>"+errors+"<"+"/"+"textarea><br>"+"<textarea rows='3' cols='30' name='jspcode' style='display:none;'>"+document.getElementById(code_input).value+"<"+"/"+"textarea><br>"+"<textarea rows='3' cols='40' name='comms'>"+"your own comments here..."+"<"+"/"+"textarea><br>"+"<input type='submit' value='Send errormessage' /"+"></"+"form>";
document.getElementById('err_mes').value = errors;
document.getElementById('err_comms').value = "write comments (optional)";
//document.getElementById('err_jspcode').value = document.getElementById(code_input);
document.getElementById('err_comms').style.display = "block";
document.getElementById('err_info').style.display = "block";
document.getElementById('err_submit_btn').style.display = "block";
}
// stop the clock
endingtime = new Date().getTime();
//calculate time used in convertion
executiontime = (endingtime - startingtime) / 1000;
codestring = codestring + "})();//]]>\n<"+"/"+"script"+">"; // end of the converted codetext
var add_mathjax_button = "";
/*if (document.getElementById('latex').checked == true || document.getElementById('latex_fixedtext').checked == true)
//MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
add_mathjax_button = '<input onclick="runMathJax()" value="Run MathJax Hub" type="button" class="browseButton">';
*/
/*if (isFullPageConvert) {
document.getElementById('jsxgimage').innerHTML = "";
if (errors.length > 30 || sketch == 'null') document.getElementById('errormessages').innerHTML = "<font color='red'><b>Convertion done in "+executiontime+" seconds, but some errors occurred.<br><br></b></font>"+errors;
else document.getElementById('errormessages').innerHTML = "<font color='green'><b>Convertion done in "+executiontime+" seconds, no errors occurred.</b></font>";
return codestring;
}
else {*/
//codestring = "<div><div style='display:inline-block; letter-spacing:1.5px;'>"+add_mathjax_button+"<div style='display:inline-block;margin-right:20px;'><font size='4'><b>JSXGraph code:</b></font></div></div> <div style='display:inline-block; '> <input onclick='downloadJSX()' value='Save JSX/HTML' type='button' class='browseButton'></div> <div style='display:inline-block; '> <input onclick='editJSXcode(1)' value='Open this in JSX code-editor' type='button' class='browseButton' /></div> <div style='display:inline-block; '> <input onclick='copyToClipboard()' value='Copy JSX code to clipboard' type='button' class='browseButton'></div></div><div style='display:block; margin-top:2px;'><textarea id ='jsxcode' cols='' rows='' value="+codestring+" </textarea></div>";
codestring = add_mathjax_button+"<textarea id ='jsxcode' cols='' rows='' value="+codestring+" </textarea>";
right_side_titles_and_buttons = document.getElementsByClassName('right_side_hidden_element');
document.getElementById("jsxgcode").innerHTML = codestring;
if (errors.length > 60 || warnings.length > 60 || sketch == 'null'){
document.getElementById('errormessages').innerHTML = "<span style='color=#ff2b00; font-weight:bold;'>Convertion done in "+executiontime+" seconds, but some warnings/errors occurred.</span><br>";
if (errors.length > 60) document.getElementById('errormessages').innerHTML += errors;
if (warnings.length > 60) document.getElementById('errormessages').innerHTML += warnings;
}
else document.getElementById('errormessages').innerHTML = "<span style='color:#0b6623; font-weight:bold;'>Convertion done in "+executiontime+" seconds, no errors.</span>";
try {
if (!isFullPageConvert) {
for(i=0; i<right_side_titles_and_buttons.length; i++)
right_side_titles_and_buttons[i].style.display = "block";
document.getElementById('jsxcode').style.width = "100%";
document.getElementById('jsxcode').style.height = window.screen.availHeight/2.5 +"px";
document.getElementById('JSketchPadCode').style.width = "100%";
document.getElementById('JSketchPadCode').style.height = window.screen.availHeight/2.5 +"px";
}
} catch(e) {alert(e.message);}
codestring = codestring.slice(codestring.indexOf('cript src =')-2, codestring.lastIndexOf('</script')+9);
//run mathjax hub automatically
if (document.getElementById('latex').checked || document.getElementById('latex_fixedtext').checked || codestring.indexOf('\\\\')>=0) {
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
console.log('Converting took ' + executiontime);
if (errors != '<u>Errors:</u><br><br>') console.log('Convertion done. Errors:\n\t'+errors.slice(errors.indexOf('<br>')+8)); else console.log('Convertion ready, no errors.');
return codestring;
}
(function($){
$.fn.linenumbers = function(in_opts, prt){
// Settings and Defaults
let opt = $.extend({
col_width: '25px',
start: 1,
digits: 4
},in_opts);
//let is_long = false;
let i, lencheck;
return this.each(function(){
// Get some numbers sorted out for the CSS changes
var new_textarea_width = '0px';
$(this).css({'width':'inherit'});
new_textarea_width = (parseInt($(this).css('width'))-parseInt(opt.col_width))+'px';
// Create the div and the new textarea and style it
$(this).before('<div id="linenumbersdiv" style="width:'+$(this).css('width')+';"><textarea style="width:'+new_textarea_width+';height:100%;float:left;margin-right:'+'-'+new_textarea_width+';margin-left:0px;margin-top:0px;margin-bottom:0px;font-family:monospace;white-space:pre;overflow:hidden;font-size:13px;" disabled="disabled"></textarea>');
$(this).after('<div style="clear:both;"></div></div>');
// Edit the existing textarea's styles
$(this).css({'font-family':'monospace','width':new_textarea_width,'float':'right'/*, 'line-height':$(this).css('line-height'), 'font-size':$(this).css('font-size')*/});
// Define a simple variable for the line-numbers box
var lnbox = $(this).parent().find('textarea[disabled="disabled"]');
// Bind some actions to all sorts of events that may change it's contents
$(this).bind('blur focus change keyup keydown',function(){
// Break apart and regex the lines, everything to spaces sans linebreaks
var lines = "\n"+$(this).val();
lines = lines.match(/[^\n]*\n[^\n]*/gi);
//add one (empty) line
lines.push('');
// declare output var
var line_number_output='';
// declare spacers and max_spacers vars, and set defaults
var max_spacers = ''; var spacers = '';
for(i=0;i<opt.digits;i++){
max_spacers += ' ';
}
// Loop through and process each line
$.each(lines,function(k,v){
// Add a line if not blank
if(k!=0){
line_number_output += "\n";
}
// Determine the appropriate number of leading spaces
lencheck = k+opt.start+'!';
spacers = max_spacers.substr(lencheck.length-1);
// Add the line, trimmed and with out line number, to the output variable
line_number_output += spacers+(k+opt.start)+'.'+v.replace(/\n/gi,'').replace(/./gi,' ').substr(opt.digits+1);
});
//for (var i=0; i<lines.length; i++) {
// if (lines[i].length>10) is_long = true;
//}
//if (is_long)
//line_number_output += '\n' + (lines.length+1) + '.';
// Give the text area out modified content.
$(lnbox).val(line_number_output);
// Change scroll position as they type, makes sure they stay in sync
$(lnbox).scrollTop($(this).scrollTop());
});
// Lock scrolling together, for mouse-wheel scrolling
$(this).scroll(function(){
$(lnbox).scrollTop($(this).scrollTop());
});
// Fire it off once to get things started
$(this).trigger('change');
});
};
})(jQuery);
class JSPtoJSXUISettings {
constructor(props) {
/*
code,
width,
height,
scale,
zoom,
boardName,
elementId,
scriptSource,
addMathjax,
mathjaxSource,
addStylesheet,
stylesheetSource,
printJsp,
JSXrenderer,
pointSize,
measurementAccuracy,
addGridLayers,
addClearTrace,
clearTraceStyle,
latexPoints,
latexTexts,
addBorder,
addUTF,
forceWhiteBack,
useHightlight,
showGrid,
drawAxis,
useAttributeVisible,
locusSetting,
showObjectCoordinates,
buttonStyling,
buttonPadding,
buttonMarginTop,
buttonBackground,
buttonVerticalAdj,
labelAlign,
vectorTranslationVerticalCorrection
*/
console.log('UI SETTINGS:');
this.code = this.getSketchCode(props.code);
console.log('CODE SET OK!');
this.scale = this.getUserVal(props.scale) ? eval(this.getUserVal(props.scale)) : 1;
console.log('scale set ok: '+this.scale);
this.width = this.readWidthHeight(this.code, props.width, props.height, this.scale).Width ? this.readWidthHeight(this.code, props.width, props.height, this.scale).Width : 500;
this.height = this.readWidthHeight(this.code, props.width, props.height, this.scale).Height ? this.readWidthHeight(this.code, props.width, props.height, this.scale).Height: 500;
console.log('width and height set to:\n\t'+this.width +'\n\t'+this.height);
this.zoom = this.getUserVal(props.zoom) ? this.getUserVal(props.zoom) : 1;
console.log('zoom set ok: '+this.zoom);
this.boardName = this.getBoardName(props.boardName, props.elementId).boardname;
this.elementId = this.getBoardName(props.boardName, props.elementId).elid;
console.log('boardname and elid set ok:\n\t' +this.boardName + '\n\t' + this.elementId);
this.scriptSource = this.getUserVal(props.scriptSource) ? this.getUserVal(props.scriptSource) : "//cdnjs.cloudflare.com/ajax/libs/jsxgraph/0.99.7/jsxgraphcore.js";
this.addMathjax = this.getUserVal(props.addMathjax);
this.mathjaxSource = this.getUserVal(props.mathjaxSource);
this.addStylesheet = this.getUserVal(props.addStylesheet);
this.stylesheetSource = "";
//FIX THIS!!
//if (this.addStylesheet ) {console.log("4.5" + this.getUserVal(props.styleSource)); this.stylesheetSource = "<link rel='stylesheet' type='text/css' href='" + this.getUserVal(props.styleSource) +"' />\n"; }
//console.log(this.stylesheetSource);
//console.log('5 sources set ok:\n\tJSXGraph source: \t' +this.scriptSource + '\n\tUse mathjax source: \t' + this.addMathjax + ' ' + this.mathjaxSource + '\n\tUse stylesheet source: \t' + addStylesheet + ' ' + this.stylesheetSource);
this.printJsp = this.getUserVal(props.printJsp);
console.log('printJsp set ok');
this.JSXrenderer = (this.getUserVal(props.JSXrenderer) != 'default') ? "\trenderer:'"+ this.getUserVal(props.JSXrenderer) +"',\n " : "";
console.log('JSXrenderer set ok');
this.pointSize = this.getUserVal(props.pointSize);
console.log('point size set ok');
this.measurementAccuracy = this.getUserVal(props.measurementAccuracy);
console.log('mesaccu set ok');
this.addGridLayers = eval(this.getUserVal(props.addGridLayers).slice(this.getUserVal(props.addGridLayers).length-1));
console.log('gridlayer set ok');
this.addClearTrace = this.getUserVal(props.addClearTrace);
console.log('addcleartrace set ok');
this.clearTraceStyle = this.getUserVal(props.clearTraceStyle);
console.log('cleartrace style set ok');
console.log('selection menus set ok:\n\tprintJSP:\t' + this.printJsp + '\n\tJSXrenderer:\t'+this.JSXrenderer+'\n\tpointSize:\t'+this.pointSize+'\n\tmeasAccu:\t'+this.measurementAccuracy+'\n\tanimation:\t'+this.animation+'\n\tgridLayers:\t'+this.addGridLayers+'\n\tadd cleartrace:\t'+this.addClearTrace+'\n\tcleartstyle:\t'+this.clearTraceStyle);
this.latexPoints = this.getUserVal(props.latexPoints);
this.latexTexts = this.getUserVal(props.latexTexts);
this.addBorder = this.getBorderWidth(this.getUserVal(props.addBorder));
this.addUTF = this.getUserVal(props.addUTF) ? "<!-- HTML5 --><meta charset='utf-8'> \n<!-- HTML 4.x --><meta http-equiv='content-type' content='text/html; charset=utf-8'>\n" : "";
this.forceWhiteBack = this.getUserVal(props.forceWhiteBack);
this.useHightlight = this.getUserVal(props.useHightlight);
this.showGrid = this.getUserVal(props.showGrid);
this.drawAxis = this.getUserVal(props.drawAxis);
this.useAttributeVisible = this.getUserVal(props.useAttributeVisible) ? false : true;
this.locusSetting = this.getUserVal(props.locusSetting);
this.showObjectCoordinates = this.getUserVal(props.showObjectCoordinates);
console.log('radio selections set ok');
this.buttonStyling = this.getUserVal(props.buttonStyling);
this.buttonPadding = this.getUserVal(props.buttonPadding);
this.buttonMarginTop = this.getUserVal(props.buttonMarginTop);
this.buttonBackground = this.getUserVal(props.buttonBackground);
this.buttonVerticalAdj = this.getUserVal(props.buttonVerticalAdj);
console.log('button stylings set ok');
this.labelAlign = this.getUserVal(props.labelAlign);
console.log('label alignment set ok');
this.vectorTranslationVerticalCorrection = this.getUserVal(props.vectorTranslationVerticalCorrection);
console.log('vector translation vertical correction set ok');
this.arrowHeadSize = "5";
}
// getter for appletsize
get appletsize() {
return [this.scale * this.width, this.scale * this.height];
}
// coordinate system setting
// getter for unit_in_pixels
get unit_in_pixels() {
if (contains(this.code,"UnitPoint")) {
return eval(this.code.slice(this.code.indexOf(",", this.code.indexOf("UnitPoint"))+1, this.code.indexOf(")", this.code.indexOf("UnitPoint")))) * this.scale;
//eval(getValueFromString(this.code, 'UnitPoint'))
}
else return 1;
}
get coord_div() {
return eval(this.unit_in_pixels);
}
//getter for has_origin_unit (string) (if there is Origin&Unit object in jsp code)
get has_origin_unit() {
if (contains(this.code,"Origin&Unit") || contains(this.code,"OriginAndUnit")) {
//if (!contains(this.code,"$")) {
return getOrigin(this.code);
//}
//return "";
}
return "";
}
// getter for boardsize
get boardsize() {
return [Math.round(((this.appletsize[0]/this.coord_div/2)*-1)*100)/100, Math.round((this.appletsize[1]/this.coord_div/2)*100)/100, Math.round((this.appletsize[0]/this.coord_div/2)*100)/100, Math.round(((this.appletsize[1]/this.coord_div/2)*-1)*100)/100];
}
//getter for origin info
get originXY() {
return {X: Math.round(100*(this.scale*this.appletsize[0]/this.coord_div/2))/100, Y: Math.round(100*(this.scale*this.appletsize[1]/this.coord_div/2))/100};
}
// getter for unitxy // setting unitx and unity // for hiding buttons outside the borders of the image //
get unitxy() {
return {X : this.scale*this.appletsize[0]/this.coord_div, Y : this.scale*this.appletsize[1]/this.coord_div};
}
// angles
get directed_angles() {
if (contains(this.code,'DirectedAngles')) {
try {
return eval(getValueFromString(this.code, 'DirectedAngles', '='));
} catch(err) {alert("Convertor error, <br> JSP Param 'DirectedAngles' caused this error. <br>"+ err.message);
console.log("Convertor error, <br> JSP Param 'DirectedAngles' caused this error. <br>"+ err.message);
}
}
else return 1;
}
//board colour attributes
get bgColour() {
let back_red, back_blue, back_green;
if (this.forceWhiteBack) return "FFFFFF";
if (contains(this.code,'BackRed')) {try{back_red = eval(getValueFromString(this.code, 'BackRed', '=')); }catch(e){alert(e.message);}}
if (contains(this.code,'BackGreen')) {try {back_green = eval(getValueFromString(this.code, 'BackGreen', '=')); }catch(e){alert(e.message);}}
if (contains(this.code,'BackBlue')) {try {back_blue = eval(getValueFromString(this.code, 'BackBlue', '=')); }catch(e){alert(e.message);}}
if (back_red && back_green && back_blue) return rgbToHex(back_red, back_green, back_blue);
else return "FFFFFF";
}
//codestring add-ons
//big/small labels
get labelsizeStyleAddon() {
let labels = '';
if (contains(this.code, 'smallLabel'))
labels += '\t.'+this.boardName+'_smalllabels {font:10px; }\n';
else if (contains(this.code, 'bigLabel'))
labels += '\t.'+this.boardName+'_biglabels {font:20px; }\n';
return labels;
}
getSketchCode(code) {
if (code != 'codearea') {
return code;
}
else return this.getUserVal(code);
}
//method that reads boardname and element id
getBoardName(boardName, elementId) {
//let boardName="", elementId="";
if ((contains(this.code,'JSX board name') && contains(this.code,'JSX element id')) || contains(this.code,'JSX boardname') && contains(this.code,'JSX element id')) {
if (contains(this.code,'JSX board name')) boardName = getValueFromString(this.code, 'JSX board name');
else boardName = getValueFromString(this.code, 'JSX boardname');
elementId = getValueFromString(this.code, 'JSX element id');
return {boardname: boardName, elid: elementId};
}
else {
boardName = getUserVal(boardName);
elementId = getUserVal(elementId);
if (boardName == '' && elementId == '') return {boardname : 'JXGboard', elid : 'id'};
if (boardName == '' ) return {boardname : 'JXGboard', elid : elementId};
if (elementId == '' ) return {boardname : boardName, elid : 'id'};
return {boardname : boardName, elid : elementId};
}
}
//if (boardname.indexOf(' ')>=0 || elid.indexOf(' ')>=0)
//alert("Spaces not allowed in JSXGraph board name or element id!");
// method that reads value from ui
getUserVal(id, type) {
var element = document.getElementById(id);
if (!element) return undefined;
if (!type && element.type == 'checkbox')
type = 'radio';
if (type == 'radio')
return element.checked;
else {
if (element.value.length < 1) {
console.error('Empty ' + id + ' value!');
//alert('Empty ' + id + ' value!');
return undefined;
}
return element.value;
}
}
// method to read width and height values (from jsp code or ui values)
readWidthHeight(sketch, width, height, scale) {
if (contains(sketch.toUpperCase(),"WIDTH") && contains(sketch.toUpperCase(),"HEIGHT")) {
return {Width: getBoardSizeFromCode(sketch)[0], Height: getBoardSizeFromCode(sketch)[1]};
}
else {
return {Width: getUserVal(width), Height: getUserVal(height)};
}
}
getBorderWidth(x) {
if (x) return "1";
else return "0";
}
}
/*
* Method to check if in long string file in given index has a specific word, checking char by char
* This is for dotcommands checking, max dotcommand length is 10 chars!
* str = long string file
* ind = given index to start checking from
* wrd = word to look for
* len = max dotcommand length by user (optional, default 10 char)
*/
function hasDotcommandInIndx(str, ind, wrd, len) {
let str_shrink = '';
let max_len = ind + 10;
if (len) max_len = ind + len;
//create shorter string
for (let i = ind; i<max_len; i++) {
str_shrink += str.charAt(ind);
}
//check
if (str_shrink.indexOf(wrd)>=0) return true;
return false;
}
/*
*
* returns all variables that need to be replaced
*
*/
function replaceJspVariablesFromString(str) {
let output = [];
let tmp = "";
let max_len = 3;
for (let i=0; i<str.length; i++) {
if (str.charAt(i) == '{') {
i++;
tmp = (str.slice(i, bracketClosure(str, '{', i)-1));
if (tmp.length<=max_len && Number.isInteger(eval(tmp))) output.push(str.slice(i, bracketClosure(str, '{', i)-1));
}
}
return output;
}
/*
* Return line count for some string to occur in given texarea (id value)
*
*
*/
function lineCount(code, txt, id) {
let str = (code === 'codearea') ? document.getElementById(id).value : code;
if (str.indexOf(txt)<0) return -1;
return (str.slice(0, str.indexOf(txt)).match(/\n/g)||[]).length + 1;
//return (str.slice(0, str.indexOf(txt)).match(/[^\n]*\n[^\n]*/gi)).length +1;
}
/**
* Simple string cleaning function (trim and replace all ' with "), return changed s (String).
* @method cleanString
* @param {String} s - string
* @return {String} s - "cleaned" string
*/
function cleanString(s) {
s = s.trim();
//s = s.replace(/"/g, "\'');
return s;
}
/**
* Help function to change colour from RBG to Hex
* source: http://www.javascripter.net/faq/rgbtohex.htm
* @method rgbToHex
* @param {String} R -
* @param {String} G -
* @param {String} B -
* @return {String} toHex(R)+toHex(G)+toHex(B) - calculated Hex-colour
*/
function rgbToHex(R,G,B) {return toHex(R)+toHex(G)+toHex(B);}
/**
* Help function to change colour from RBG to Hex
* source: http://www.javascripter.net/faq/rgbtohex.htm
* @method toHex
* @param {String} n - value to be changed
* @return {String} changed Hex-value
*/
function toHex(n) {
n = parseInt(n,10);
if (isNaN(n)) return "00";
n = Math.max(0,Math.min(n,255));
return "0123456789ABCDEF".charAt((n-n%16)/16) + "0123456789ABCDEF".charAt(n%16);
} /* /source */
/**
* Check if input (string) is jspcode with $variables
* @method checkJSPStyle
* @param {String} c - JSP code
* @return {Boolean}
*/
function checkJSPStyle(c) {
if (c.indexOf('$')>=0) //if there is $-char in code return false
return false;
return true;
}
/*
* Check if char is alphabet
* @method isAlpabet
* @param {Char} c - char
* @return {boolean} true if c is an alphabet else false
*/
function isAlphabet(c) {
const alphabets = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
if (alphabets.indexOf(c)>=0) return true;
return false;
}
function contains(a, obj) {
if (a.indexOf(obj) > -1) return true;
return false;
}
/**
* returns index of bracket closure from a string
s = given string
b = bracket style (start bracket)
t = index (number or indexOf(string))
*/
function bracketClosure(s, b, t) {
let counter = 0;
let bracket_style = '}';
let i;
if (b == '(') bracket_style = ')';
else if (b == '[') bracket_style = ']';
if (Number.isInteger(t)) {
i=t;
while (counter > -1) {
if (s.charAt(i) == b) {counter = counter+1; i++;}
else if (s.charAt(i) == bracket_style) {counter= counter-1; i++;}
else i++;
if (i==s.length-1) return i;
}
}
else if (!Number.isInteger(t)) {
i = s.indexOf(b,s.indexOf(t))+1;
if (i<0) return s.length-1;
while (counter > -1) {
if (s[i] == b) {counter=counter+1; i++;}
else if (s[i] == bracket_style) {counter=counter-1; i++;}
else i++;
if (i==s.length-1) return i;
}
}
else {alert('error'); return null;}
return i;
}
/* s: string
* c: starting string
* m: start from m (string) after c
* i: index to start from
*/
function getValueFromString(s, c, m, i) {
const goodChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_";
let value = "";
let ind = 0;
if (i) ind = i;
else if (m) ind = s.indexOf(m, s.indexOf(c));
else ind = s.indexOf(c) + c.length;
while(s.charAt(ind) == ' ' || goodChars.indexOf(s.charAt(ind))<0) ind = ind+1;
while(goodChars.indexOf(s.charAt(ind))>=0) {
value = value + s[ind];
ind=ind+1;
}
return value;
}
function changeTextApostrophes(text) {
let t = text;
let count = 0;
let i1, i2;
let strp = [];
let tmp;
let result = "";
if (t.indexOf("'")<0)
return t;
else {
strp.push(t.slice(0, t.indexOf("'")));
let i = t.indexOf("'");
/*for (let i=t.indexOf("'"); i<t.length; i++)*/ while (i < t.length) {
if (t.charAt(i) == "'") {
i1 = i;
while (t.charAt(i) == "'" && i < t.length) {
count = count + 1;
i = i + 1;
}
i2 = i;
tmp = t.slice(i1, i2);
//alert(tmp);
count = count / 2;
//alert(t[i+1]);
for (let j=0; j<count; j++)
tmp = tmp.replace("''", "\'");
//i = i2;
count = 0;
strp.push(tmp);
}
else {
i1= i;
while (t.charAt(i) != "'" && i < t.length)
i = i + 1;
i2 = i;
tmp = t.slice(i1,i2);
//alert(tmp);
strp.push(tmp);
//i = i2;
}
}
for (let i = 0; i<strp.length; i++)
result = result + strp[i];
return result;
}
}
function uniq_fast(a) {
let seen = {};
let out = [];
let len = a.length;
let j = 0;
for(let i = 0; i < len; i++) {
let item = a[i];
if(seen[item] !== 1) {
seen[item] = 1;
out[j++] = item;
}
}
return out;
}
/**
* Divides one string file (original Java Sketchpad code) into array of separate rows and returns rows (Array).
* @method separateCommands
* @param {String} a - Java Sketchpad code -string
* @return {Array<String>} rows - separated rows from Java Sketchpad code as an array
**/
function separateCommands(a, is_macro) {
let rows = [],
indx = 0,
i = 0,
comment="",
tmp = "",
tmp2 = "",
macro = "",
wo_nr = [],
add = 0,
bug_stopper = 0;
const numbers = "1234567890",
br_numb = "1}2}3}4}5}6}7}8}9}0}",
sr_numb = "{1{2{3{4{5{6{7{8{9";
while (a.indexOf('<!--')>0 && a.indexOf('-->')>0) {
a=a.slice(0, a.indexOf('<!--'))+a.slice(a.indexOf('-->')+3);
}
//let's put the index for i
if (a.indexOf('£(') < a.indexOf('{'))
i = a.indexOf('£(');
else i = a.indexOf('{');
if (is_macro) {
rows.push(a.slice(0, a.indexOf(')')+1));
a = a.slice(a.indexOf(')')+1);
i = indx = 0;
while ( i < a.length) {
if (a.charAt(i) == ';') {
rows.push(a.slice(indx, i+1));
i++;
indx = i;
}
else i++;
}
}
while(i<a.length ) {
if (a[i] == '{' && numbers.indexOf(a[i+1])>=0) {
indx = a.indexOf(';', i);
if (comment.length > 0) {
rows.push(comment + a.slice(i, indx+1));
//console.log(rows[rows.length-1]);
comment = "";
} else {
rows.push(a.slice(i, indx+1));
}
i = indx;
}
else if (a.charAt(i) == '£' && a.charAt(i+1) == '(') {
macro = "MACRO:" + a.slice(i+2, a.indexOf('£)',i)) + ":MACRO ";
i = a.indexOf('£)',i)+1;
rows.push(macro);
}
else if (hasDotcommandInIndx(a,i,'{,LabelAl',9) || hasDotcommandInIndx(a,i,'{,label',7) || hasDotcommandInIndx(a,i,'{,text',6) || hasDotcommandInIndx(a,i,'{,dash',6) || hasDotcommandInIndx(a,i,'{,latex',7)) {
rows.push(a.slice(i+2, bracketClosure(a, '{', i+3)));
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('//')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('//')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else if (rows[rows.length-2].indexOf('/*comment')>=0){
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment:" + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1)-1;
}
else if (hasDotcommandInIndx(a, i, '{,segmAnim', 10) || hasDotcommandInIndx(a, i, '{,calcLocus', 11) || hasDotcommandInIndx(a, i, '{,locus', 7) || hasDotcommandInIndx(a, i, '{,jxg', 5) || hasDotcommandInIndx(a, i, '{,setAtt', 8) || hasDotcommandInIndx(a,i,'{,smallLabel', 12) || hasDotcommandInIndx(a,i,'{,bigLabel', 10)) {
indx = i+2;
tmp2 = a.slice(i+1, bracketClosure(a, '{', i+1)-1);
rows.push(tmp2);
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment: " + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1);
}
else if (a[i] == '{' && a[i+1] == ',') { // useroption (e.g. arrowL or psize()) as commends in JSP code after command line
rows.push(a.slice(i+2, bracketClosure(a, '{', i+3)-1));
if (rows[rows.length-2].indexOf('//comment')>=0) {
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else if (rows[rows.length-2].indexOf('/*comment')>=0){
tmp = rows[rows.length-2].slice(rows[rows.length-2].lastIndexOf('*/')+2, rows[rows.length-2].lastIndexOf(';')+1);
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf('*/')+2) + "//comment:" + rows.pop() + "//" + tmp;
}
else
rows[rows.length-2] = rows[rows.length-2].slice(0, rows[rows.length-2].lastIndexOf(']')) + "//comment:" + rows.pop() + "//];";
i = bracketClosure(a, '{', i+1)-1;
}
else if (a[i] == '{' && numbers.indexOf(a[i+1])<0) {
comment = comment + '/*comment:' + a.slice(i+1, bracketClosure(a, '{', i+1)-1) + '*/' ;
i = bracketClosure(a, '{', i+1)-1;
}
i++;
bug_stopper = bug_stopper +1;
} //end of while
//add last comment possibly
if (comment.length > 0) {
//comment = comment.replace('comment', 'lastcomment');
rows[rows.length-1] = rows[rows.length-1] + comment.slice(0, comment.indexOf('/*')+2) + 'lastComment' + comment.slice(comment.indexOf('comment')+7) ;
//alert(rows[rows.length-1]);
comment = "";
}
for (let i=0; i<rows.length; i++) {
if (rows[i].indexOf('MACRO:')>=0) {
rows[i] = rows[i] + rows[i+1];
rows.splice(i+1, 1);
}
}
//console.log(rows);
return rows;
}
/**
* Divides one big string file (original Java Sketchpad code) into array of separate rows and returns rows info as an Object.
* @method createJspCodeObject
* @param {String} a - Java Sketchpad code -string
* @return {Object} jspObj - separated rows from Java Sketchpad code as an object
**/
function createJspCodeObject(a, is_macro) {
let jspObj = {}; //object to store data
let init="", //Jsp initialising info (top of the code)
row="", //Jsp coderows
macro="";
let i=0, ind1=0, ind2=0;
let alength = a.length;
let numbers = "1234567890";
}
//var jsp = /*points*/ "Point|FixedPoint|Midpoint|Point on object|Intersect|Intersect1|Intersect2|PlotXY|UnitPoint|DriverPoint|"+
// /*straight lines*/ "Segment|Ray|Line|Perpendicular|Parallel|AxisX|AxisY|Polygon|Circle interior|Circle|Circle by radius|"+
// /*transformations*/ "Reflection|Dilation|Dilation/SegmentRatio|Dilation/3PtRatio|Dilation/MarkedRatio|Rotation|Rotation/MarkedAngle|"+
// "Translation|VectorTranslation|Translation/FixedAngle/MarkedDistance|PolarTranslation|"+
// "Translation/MarkedAngle/FixedDistance|Translation/MarkedAngle/MarkedDistance|"+
// /*image*/ "Image|"+
// /*measurements*/ "Length|Angle|Perimeter|Circumference|Radius|Area|Slope|Distance|Ratio/Segments|Ratio/Points|Calculate|Parameter|"+
// /*text & buttons*/ "FixedText|ShowButton|HideButton|MoveButton|AnimateButton|"+
// /*coord system */ "Coordinates|Origin&Unit|UnitCircle|"+
// /*locus*/ "Locus|";
function getMacroFunction(e,attributes) {
if (!attributes)
attributes = setAttributes(e, '');
if (e.Type == 'Point' || e.Type == 'FixedPoint') {
return "('point', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Midpoint') {
return "('midpoint', ["+e.Pos[0]+"], "+attributes+");";
}
else if (e.Type == 'Point on object') {
try { return "('glider', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");"; }
catch(e) { console.error('Error: Point on object can\'t be used in macro. '); return null; }
}
else if (e.Type == 'Segment') {
return "('segment', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Line' || e.Type == 'Perpendicular' || e.Type == 'Parallel') {
return "('line', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Polygon') {
console.error('Error: Polygon can\'t be used in macro. Contact admin.'); return null;
}
else if (e.Type == 'Ray') {
return "('line', ["+e.Pos[0]+","+e.Pos[1]+"], "+attributes+");";
}
else if (e.Type == 'Intersect' || e.Type == 'Intersect2' || e.Type == 'Intersect1') {
return "('intersection', ["+e.Pos+", "+e.Att.Info+"], "+attributes+");";
}
else if (e.Type == 'Dilation/3PtRatio') {
return "('point', [function(){return Math.sign(Math.cos(JXG.Math.Geometry.rad("+e.Pos[3]+", "+e.Pos[2]+", "+e.Pos[4]+"))) * ("+e.Pos[2]+".Dist("+e.Pos[4]+") / "+e.Pos[2]+".Dist("+e.Pos[3]+")) * ("+e.Pos[0]+".X() - "+e.Pos[1]+".X()) + "+e.Pos[1]+".X()},function() {return Math.sign(Math.cos(JXG.Math.Geometry.rad("+e.Pos[3]+", "+e.Pos[2]+", "+e.Pos[4]+"))) * ("+e.Pos[2]+".Dist("+e.Pos[4]+") / "+e.Pos[2]+".Dist("+e.Pos[3]+")) * ("+e.Pos[0]+".Y() - "+e.Pos[1]+".Y()) + "+e.Pos[1]+".Y()}], "+attributes+");";
}
else {
console.error('Macro failed! ');
return null;
}
}
function getMacroPosValues(e){
let values = [], ind1 = 0;
for (let i = 0; i<e.length; i++) {
if (e[i] == ',') {
values.push(e.slice(ind1, i));
ind1 = i+1;
}
}
values.push(e.slice(ind1));
return values;
}
/**
* Slices one row of JavaSketchpad code to javascript object that has following informtion:
* - Row (row number in sketchpad code),
* - Type (Type of sketchpad element as sketchpad constructor),
* - JsxType (type as javascript understands element [in this algorithm]),
* - Pos (includes info about position [x- and y-coordinates], possible name [buttons, texts, measurements] or/and objects [rows] that are referred to),
* - Opts (sliced string from '[' to ']' in sketchpad code),
* - Att (specific info included in Opts [sketchpad code sliced from '[' to ']'] as a jsxgraph attributes. This info includes following attributes:
* Name, Color, Fixed, Visible, WithLabel, StrokeWidth, Straightlast, Straightfirst, AnchorX, Trace, Size, Infobox, LabelAlign
* - Anim (has the info needed to create buttons [list of the objects (rows) referred to when creating a button],
* @method sketchpadrowToJsxgElement
* @param {String} a - One row of Java Sketchpad code
* @return {Object} el - Object that has information separated from original Java Sketchpad element
**/
function sketchpadrowToJsxgElement(a, appletsize,coord_div,scalex,scaley,has_origin_unit,boardname) {
let el,
row,
type='',
jsxtype='',
ref='',
ctype='',
orig=a,
pos,
opts,
hlight,
att,
visib=true,
anim=[],
tmpanim,
labalig="",
psize,
sinfo,
comment="",
jspcomment="",
labelalign,
arrowf=false,
arrowl=false,
snaptogrid="false",
//jxg_command = "",
//set_attr = "",
suf="",
macro ="",
//input_macro = "",
macro_add = 1,
fixed=false,
tmp="",
orig_line="";
let usercomments = ['arrowL','arrowF','psize','snapToGrid','text','latex','LabelAlign','labelAlign','showInfoBox','label','locus','calcLocus','setAttribute#','jxg#','attVisible','highlight','dash', 'smallLabel','bigLabel','segmAnim'],
extraattributes = "",
loc_to_rep=0,
rep_loc ="",
first_jspcomment = -2,
last_comment = "";
//if last row is a comment
a = a.trim();
if (a.indexOf('];')<0) a = a.slice(0,a.length-1) + "[];";
if (a.indexOf("font(")>0) {
a = a.replace(a.slice(a.indexOf("font("), a.indexOf(")", a.indexOf("font("))+1), a.slice(a.indexOf("font(")+6, a.indexOf(")", a.indexOf("font("))-1));
}
//macros 2.5.2018
if (a.indexOf('MACRO:')>=0 && a.indexOf(':MACRO')>=0) {
try {
macro = a.slice(a.indexOf('MACRO:') + 6, a.indexOf(':MACRO'));
a = a.slice(a.indexOf(':MACRO')+7);
macro = separateCommands(macro, true);
console.log("Macro found: " + macro);
macro[0] = macro[0].trim();
macro[0] = macro[0].slice(0, macro[0].length-1) + ",att)";
} catch(e) {alert('Creating macro-list failed');}
try {
jsp_macros = jsp_macros + macro[0].slice(0, macro[0].indexOf('(')).trim();
} catch(e) {alert('Error while adding macro name value to all_macros string');}
/* disabling, not working correctly
for (var i in macro) {
if (i>0) {
macro[i] = "{" + i + "} " + macro[i];
macro_add += 1;
}
macro[i] = macro[i].replace(/£1/gi, '#1');
macro[i] = macro[i].replace(/£/gi, '');
if (i>0) {
macro[i] = sketchpadrowToJsxgElement(macro[i]);
if (macro[i].Pos.indexOf('#1')>=0) {
tmp = macro[0].slice(0,3) + '_' + (macro[i].Row-1);
macro[i].Pos = macro[i].Pos.replace(/#1/gi, tmp);
}
changeTypeToJSX(macro[i]);
macro[i].Pos = getMacroPosValues(macro[i].Pos);
changeAttributesToJSX(macro[i]);
changeOptionsToJSX(macro[i]);
}
console.log(macro[i]);
} */
}
if (a.indexOf('/*comment:')>=0 ) {
if (a.indexOf('lastComment')>=0) {
comment = a.slice(a.indexOf('/*'), a.lastIndexOf('*/', a.indexOf('lastComment'))+2);
}
else
comment = a.slice(a.indexOf('/*'), a.lastIndexOf('*/')+2);
}
if (a.indexOf('//comment:')>=0 ) {
jspcomment = a.slice(a.indexOf('//comment'), a.lastIndexOf('//')+2);
}
if (a.indexOf('lastComment')>=0) {
last_comment = a.slice(a.indexOf('/*', a.indexOf('{')), a.lastIndexOf('*')+1) + "/";
while(last_comment.indexOf('comment:')>=0)
last_comment = last_comment.replace('comment:', '');
a = a.slice(a.indexOf('{'), a.indexOf('/*', a.indexOf('{')));
}
if (jspcomment.length>0) {
a = a.replace(jspcomment, '');
jspcomment = "{" + jspcomment + "}";
while (jspcomment.indexOf('//comment:')>=0)
jspcomment = jspcomment.replace('//comment:', ',');
while(jspcomment.indexOf('//')>=0)
jspcomment = jspcomment.replace('//', '}\n{');
while(jspcomment.indexOf('{}')>=0)
jspcomment = jspcomment.replace('{}', '');
while(jspcomment.indexOf('}}')>=0)
jspcomment = jspcomment.replace('}}', '}');
if (jspcomment.indexOf('lastComment')>=0)
jspcomment = jspcomment.slice(0, bracketClosure(jspcomment, '{'));
}
if (comment.length>0) {
while (comment.indexOf('comment:')>=0) {
comment = comment.replace('comment:', '');
}
while (comment.indexOf('*//*')>=0) {
comment = comment.replace('*//*', '}\n{');
}
comment = comment.replace('*/', '*/\n');
if (last_comment.length<1)
a = a.slice(a.lastIndexOf('*/')+2, a.length-1);
}
if (last_comment.length>0) {
while (last_comment.indexOf('lastComment:')>=0) {
last_comment = last_comment.replace('lastComment:', '');
}
while (last_comment.indexOf('*//*')>=0) {
last_comment = last_comment.replace('*//*', '}\n{');
}
last_comment = last_comment.replace('*/', '*/\n');
}
try {row = eval(a.slice(a.indexOf("{")+1, a.indexOf("}"))); } catch(e) {alert(e.message);}
type = a.slice(a.indexOf("}")+1, a.indexOf("(")).trim();
if (a.indexOf(")[")>=0 && a.indexOf(")['")<0 && a.indexOf(") ['") && a.indexOf(")[ '") && a.indexOf(") [ '"))
pos = a.slice(a.indexOf("(")+1, a.indexOf(")[")).trim();
else pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")", a.lastIndexOf("[")-1)).trim();
ref = pos;
opts = a.slice(a.indexOf("["), a.indexOf("]")+1).trim();
if (type=="Calculate" || type=="Ratio/Points") {
if (a.indexOf("layer(")>=0)
a = a.replace(a.slice(a.indexOf("layer("), a.indexOf(")", a.indexOf("layer("))+1), "");
if (a.indexOf("color(")>=0) {
tmp = a.slice(a.indexOf("color("), a.indexOf(")", a.indexOf("color("))+1);
a = a.replace(tmp, "colorvaluehere"); //change 'color(...)' to 'colorvaluehere'
}
if (a.indexOf("suffix")>0)
pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")", a.indexOf("suffix")-1)+1).trim();
else pos = a.slice(a.indexOf("(")+1, a.lastIndexOf(")")+1).trim();
if (a.indexOf("colorvaluehere")>=0)
a = a.replace("colorvaluehere",tmp); //change 'colorvaluehere' back to 'color(...)'
}
else if (type=="MoveButton" || type=="ShowButton" || type=="HideButton" || type=="SimultaneousButton") {
//anim = eval("["+a.slice(a.indexOf('(', a.indexOf('(') + 1)+1, a.indexOf(')', a.indexOf(')') + 1))+"]");
if (opts.indexOf("color(")==-1 && opts.indexOf("layer(")==-1)
anim = eval("["+a.slice(a.lastIndexOf('(')+1, a.lastIndexOf(')'))+"]");
else anim = eval("["+a.slice(a.lastIndexOf('(', a.lastIndexOf('['))+1, a.lastIndexOf(')', a.lastIndexOf('[')))+"]");
}
else if (type=="AnimateButton") {
if (a.lastIndexOf('[')>0)
tmpanim = a.slice(a.indexOf(")", a.lastIndexOf("'"))+1,a.lastIndexOf(")", a.lastIndexOf('['))) + "]";
else
tmpanim = a.slice(a.indexOf(")", a.lastIndexOf("'"))+1,a.lastIndexOf(")")) + "]";
tmpanim = tmpanim.replace(/\(/g, "[");
tmpanim = tmpanim.replace(/\)/g, "]");
anim[0] = eval(tmpanim.slice(tmpanim.indexOf("["),tmpanim.indexOf("]")+1));
anim[1] = eval(tmpanim.slice(tmpanim.indexOf("][")+1,tmpanim.indexOf("]",tmpanim.indexOf("][")+1)+1));
anim[2] = eval(tmpanim.slice(tmpanim.indexOf("[",tmpanim.indexOf("][")+2), tmpanim.lastIndexOf("][")+1));
anim[3] = eval(tmpanim.slice(tmpanim.lastIndexOf("][")+1,tmpanim.lastIndexOf("]")+1));
for (var i=0; i<anim[0].length; i+=2) { //change to ms and other options, make extras zero
anim[1][i] = anim[1][i]*1000; anim[1].splice(i+1,0,0);
anim[2].splice(i+1,0,0);
anim[3].splice(i+1,0,0);
}
}
//if JSP object type is measurement set fixed true and ctype = 'measurements'
if (type == 'Coordinates' || type == 'Length' || type == 'Angle' || type == 'Perimeter' ||
type == 'Circumference' || type == 'Radius' || type == 'Area' || type == 'Slope' ||
type == 'Distance' || type == 'Ratio/Segments' || type == 'Ratio/Points' || type == 'Calculate' || type == 'Parameter') {
fixed = true;
ctype = 'measurements';
}
if (type == 'ShowButton' || type == 'HideButton' || type == 'SimultaneousButton' || type == 'AnimateButton' || type == 'MoveButton') {
fixed = true;
ctype = 'buttons';
}
if (type == 'Point' || type == 'Point on object' || type == 'UnitPoint')
ctype = 'points';
// check extra-attributes here
// POINT SIZE
psize = eval(document.getElementById('jsxpointsize').value);
if (a.indexOf("psize(")>0) {
psize = eval(a.slice(a.indexOf("psize(")+6, a.indexOf(")", a.indexOf("psize(")+6)));
}
if (jspcomment.indexOf("psize")>0) {
//psize = eval(jspcomment.slice(jspcomment.indexOf("psize(")+6, jspcomment.indexOf(")", jspcomment.indexOf("psize(")+6)));
psize = eval(jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('psize'))+1, bracketClosure(jspcomment, '(', 'psize')-1));
}
// SHOW INFOBOX
if (document.getElementById('jsxshowinfo').checked == true) sinfo = true;
else sinfo = false;
if (a.indexOf("showInfoBox")>0 || jspcomment.indexOf('showInfoBox') > 0)
sinfo = true;
// LABEL ALIGNMENT
labelalign = createLabelAlign(document.getElementById('jsxlabelalignment').value, 0);
if (a.indexOf("LabelAlign(")>0) {
labalig = a.slice(a.indexOf("LabelAlign(")+11, a.indexOf(")", a.indexOf("LabelAlign(")));
labelalign = createLabelAlign(labalig,0);
}
if (jspcomment.indexOf("LabelAlign")>0) {
//alert(jspcomment);
labalig = jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('LabelAlign'))+1, bracketClosure(jspcomment, '(', 'LabelAlign')-1);
labelalign = createLabelAlign(labalig,0);
}
if (jspcomment.indexOf("labelAlign")>0) {
//alert(jspcomment);
labalig = jspcomment.slice(jspcomment.indexOf("(", jspcomment.indexOf('labelAlign'))+1, bracketClosure(jspcomment, '(', 'labelAlign')-1);
labelalign = createLabelAlign(labalig,0);
}
if (type == "VectorTranslation")
labelalign = createLabelAlign(document.getElementById('jsxlabelalignment').value, eval(document.getElementById('vectortranslation_correction').value));
if (labalig.length>0) {
labelalign = "{offset:["+labalig+"]}"; }
// ARROWS
if (a.indexOf("arrowF") > 0 || jspcomment.indexOf('arrowF')>0)
arrowf = true;
if (a.indexOf("arrowL")>0 || jspcomment.indexOf('arrowL')> 0)
arrowl = true;
//locusToFunction comment
if (jspcomment.indexOf('locus') >= 0) {
loc_to_rep = row;
rep_loc = jspcomment.slice(jspcomment.indexOf('(')+1, jspcomment.lastIndexOf(')'));
}
// locus from calculate
if (jspcomment.indexOf('calcLocus') >= 0) {
rep_loc = eval('['+jspcomment.slice(jspcomment.indexOf('(')+1, jspcomment.lastIndexOf(')'))+']');
}
//update 4.4.2018 highlight
if (jspcomment.indexOf('highlight')>=0 || document.getElementById('usehighlight').checked == true)
hlight = true;
else hlight = false;
// SNAP TO
if (a.indexOf("snapToGrid")>0 || jspcomment.indexOf('snapToGrid')> 0)
snaptogrid = true;
// isvisible?
if (a.indexOf('hidden')>0) visib= false; else visib = true;
att= { Name:'',
Color:'black',
Fixed:fixed,
Visible:visib,
Withlabel:true,
Strokewidth:1,
Straightlast:true,
Straightfirst:true,
AnchorX:'middle',
Info:0,
Trace:false,
Size:psize,
Infobox:sinfo,
LabelAlign:labelalign,
Stop:false,
ArrowF:arrowf,
ArrowL:arrowl,
SnapToGrid:snaptogrid,
Highlight:hlight,
Suffix:suf
};
el= { Row:row,
Type:type,
JsxType:jsxtype,
CType:ctype,
ParentType:'none',
oPos:pos,
Pos:pos,
Opts:opts,
Att:att,
Anim:anim,
Macro: macro,
comment,
JSPComment:jspcomment,
LastComment:last_comment,
Ref:ref,
isReferred:true,
Orig: orig,
Original_line: a,
locusToReplace:loc_to_rep,
replaceLocus:rep_loc,
bname:boardname
};
el = changeTypeToJSX(el);
el = changePosInfoToJSX(el,appletsize,coord_div,scalex,scaley,has_origin_unit);
el = changeAttributesToJSX(el);
el = changeOptionsToJSX(el);
return el;
}
/**
* Check if param p is valid JSP constructor or not. Return true in case p is JSP constructor, else false
* @method checkJSPitem
* @param {String} p - string value JSP constructor
* @return {boolen} true if p is JSP type constructor, else false
*/
function checkJSPitem(p) {
var jsp = /*points*/ "|Point|FixedPoint|Midpoint|Point on object|Intersect|Intersect1|Intersect2|PlotXY|UnitPoint|DriverPoint|"+
/*straight lines*/ "|Segment|Ray|Line|Perpendicular|Parallel|AxisX|AxisY|Polygon|Circle interior|Circle|Circle by radius|"+
/*transformations*/ "|Reflection|Dilation|Dilation/SegmentRatio|Dilation/3PtRatio|Dilation/MarkedRatio|Rotation|Rotation/MarkedAngle|"+
"|Translation|VectorTranslation|Translation/FixedAngle/MarkedDistance|PolarTranslation|"+
"|Translation/MarkedAngle/FixedDistance|Translation/MarkedAngle/MarkedDistance|"+
/*image*/ "|Image|"+
/*measurements*/ "|Length|Angle|Perimeter|Circumference|Radius|Area|Slope|Distance|Ratio/Segments|Ratio/Points|Calculate|Parameter|"+
/*text & buttons*/ "|FixedText|ShowButton|HideButton|MoveButton|AnimateButton|SimultaneousButton|"+
/*coord system */ "|Coordinates|Origin&Unit|UnitCircle|"+
/*locus*/ "|Locus|";
if (jsp.indexOf(p)<0) return false;
else return true;
}
/**
* To check code for simple errors which are length, brackets etc.
* @method codeDummyTest
* @param {String} code -
* @return {Boolean} valid - true if code passes dummy-test, else false
*/
function codeDummyTest(code) {
var valid = true;
if (code.length == 0) return true;
if (code.indexOf('(')<0 || code.indexOf(')')<0) valid = false;
else if (code.indexOf('[')<0 || code.indexOf(']')<0) valid = false;
else if (code.indexOf(';')<0) valid = false;
else if (code.length>0 && code.length<10) valid = false;
else if (code.indexOf(' {0} ')>-1) valid = false;
return valid;
}
/**
* Calculates and returns path for the animation
* @method getCircleAnimationPath
* @param {Strign} object - object in convertor
* @param {String} type - type of an object
* @param {Int} direction - direction of the animation, possible values are 0 or 1, if not given direction will be 1
* @return {String} path - retuns path as a string that has the array in it
*/
function getAnimationPath(object, type, direction) {
let c = object;
let path = [];
let next_tick = 0;
let ticksaddon = 0.1;
if (type == 'circle') {
while (next_tick <= 1) {
path.push("["+c+".X("+next_tick+"), "+c+".Y("+next_tick+")]");
next_tick = Math.round((next_tick + ticksaddon)*10)/10;
}
if (direction == 1) path = path.reverse();
//path.pop();
}
else {
if (direction == 0) {
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
}
else {
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
path.push("["+c+".point2.X(),"+c+".point2.Y()]");
path.push("["+c+".point1.X(),"+c+".point1.Y()]");
}
}
return "["+path+"]";
}
/**
* This function creates label offset for the elements in jsxgboard
* @method createLabelAlign
* @param {String} l - value given in UI, direction for moving label
* @param {String} a - value is how much to move the label
* @return {String} - attribute to change label position in JSXGraph image
*/
function createLabelAlign(l, v) {
if (l == "ct") {return "{offset:[0," + (10+v) + "]}";}
else if (l == "rt") {return "{offset:[10," + (10+v) + "]}";}
else if (l == "rm") {return "{offset:[10," + (0+v) + "]}";}
else if (l == "rb") {return "{offset:[10," + (-10+v) + "]}";}
else if (l == "cb") {return "{offset:[0," + (-10+v) + "]}";}
else if (l == "lb") {return "{offset:[-10," + (-10+v) + "]}";}
else if (l == "lm") {return "{offset:[-10," + (0+v) + "]}";}
else if (l == "lt") {return "{offset:[-10," + (10+v) + "]}";}
else try {
//alert("{offset:["+l+"]}");
return "{offset:["+l+"]}";
} catch(e){console.error('error in label align function'); alert(e.message);}
}
/*
* reads and return board dimensions from code
* @param {String} codetxt - JSP code
* @return {Object[array]} - width and height values as string in list [width(String), height(String)]
*
*/
function getBoardSizeFromCode(codetxt) {
const goodChar="0123456789";
const goodWidth=["WIDTH", "Width", "width"];
const goodHeight=["HEIGHT", "Height", "height"];
let i, indx1=0, indx2=0, w="", h="";
for (i=0; i<goodWidth.length; i++) {
if (codetxt.indexOf(goodWidth[i])>=0) {
indx1 = codetxt.indexOf(goodWidth[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
w = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (w.lenght<1) alert("Load error. File has no width value.");
for (i=0; i<goodHeight.length; i++) {
if (codetxt.indexOf(goodHeight[i])>=0) {
indx1 = codetxt.indexOf(goodHeight[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
h = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (h.lenght<1) alert("Load error. File has no height value.");
return [w,h];
}
/*
* THIS WILL BE REMOVED AND REPLACED WITH BETTER SOLUTION IN FUTURE
* generates original code from converted object
* @param {Object[array]} e - converted code in list
* @param {} w -
* @param {} h -
* @param {Boolean} withtags -
* @param {Object} options -
* @return {String} - generated JSP code as string
*/
function getOrigString(e, w, h, withtags, options) {
let s="", i;
let com = "", jspcom = "", lastcom = "";
const end = "\n{ This JavaSketchpad code was generated by JSP to JSXG convertor }\n{ see http://cs.uef.fi/matematiikka/ABACUS/JavasketcpadToJSXgraph/ }\n";
if (options == 'SketchrowOnly') {
if (e.JSPComment.length == 0 && e.comment.length > 0) s = s + "{" + e.comment.slice(2,this.length-3) + "}" ;
s = s + "{"+e.Row+"} " + e.Type + "(";
s = s+e.Pos + ")";
s = s + e.Opts + ";\n";
s = s.replace('))[', ')[');
if (e.comment.length > 0 && e.JSPComment.length > 0) s = s + e.JSPComment + "";
return s;
}
else {
for (i in e) {
if (e[i]) {
if (e[i].comment.length > 1)
com = '\n{' + e[i].comment.slice(2, this.length-3) + '}\n';
if (e[i].JSPComment.length > 1)
jspcom = e[i].JSPComment + '';
if (e[i].LastComment.length > 1)
lastcom = '{' + e[i].LastComment.slice(2, this.length-3) + '}';
//if (e[i].JSPComment.length == 0 && e[i].comment.length > 0) { s = s + "{" + e[i].comment.slice(2,e[i].comment.length-3) + "}\n" ; }
s= s+com;
s = s + "\n{"+e[i].Row+"} " + e[i].Type + "(";
s = s+e[i].Pos + ")";
s = s + e[i].Opts + ";\n";
s = s.replace('))[', ')[');
//if (e[i].JSPComment.length > 0) s = s + e[i].JSPComment + "\n";
s = s+jspcom;
s = s+lastcom;
com = '';
jspcom = '';
lastcom = '';
}
}
if (withtags){
return '<font size="4" style="letter-spacing:1.5px;"><b>JavaSketchpad code:</b></font><input onclick="copyJSPToClipboard()"" value="Copy JSP code to clipboard" type="button" class="browseButton"> <br><textarea id="jspgeneratedcode" cols="120" rows="50"><APPLET \nCODEBASE="jsp" ARCHIVE="jsp4.jar" CODE="GSP.class" WIDTH='+w+' HEIGHT='+h+' ALIGN=Left>\n<PARAM NAME=Offscreen VALUE=1><PARAM NAME=Frame VALUE=1>\n<PARAM NAME=MeasureInDegrees VALUE=1><PARAM NAME=DirectedAngles VALUE=0>\n<PARAM NAME=BackRed VALUE=250><PARAM NAME=BackGreen VALUE=250><PARAM NAME=BackBlue VALUE=250>\n<PARAM NAME=Construction VALUE="\n'+s+end+'">\n</APPLET></textarea>';
}
else
return '<font size="4" style="letter-spacing:1.5px;"><b>JavaSketchpad code:</b></font><input onclick="copyJSPToClipboard()"" value="Copy JSP code to clipboard" type="button" class="browseButton"> <br><textarea id="jspgeneratedcode" cols="120" rows="50">' + s + end +'</textarea>';
}
}
/*
* get JSP command from line
* @param {String} s - codeline
* @param {Integer} i - index of string
* @param {String} c - string to look from s to get index
* @param {String} m - string to look after c
* @return {String} value - JSP command as string
*/
function getJSPCmndFromString(s, i, c, m) {
const goodChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-_/";
let value = "";
let ind = 0;
if (i>=0) ind = i;
else if (m) ind = s.indexOf(m, s.indexOf(c));
else ind = s.indexOf(c) + c.length;
while(s.charAt(ind) == ' ' || goodChars.indexOf(s.charAt(ind))<0) ind = ind+1;
while(goodChars.indexOf(s.charAt(ind))>=0) {
value = value + s[ind];
ind=ind+1;
}
return value;
}
/**
* Function to change coordinates so that the (0,0) is the origo.
* @method changeToCoord
* @param {Int} x - x coordinate in Java Sketchpad form
* @param {Int} y - y coordinate in Java Sketchpad form
* @param {Array<Int>} appletsize - appletsize
* @param {Int} coord_div - coordinates dividor if coordinates has been set in Java Sketchpad code using Origin&Unit and Unitpoint commands
* @param {Double} scalex - factor that is used in scaling the image horizontally
* @param {Double} scaley - factor that is used in scaling the image vertically (this is not actually used, since the scalex and scaley are defines as the same value in main function)
* @param {String} hasorigin - coordinates of origin if it has been changes in original Java Sketchapd code
* @return {Array} - created coordinates (Array)
*/
function changeToCoord(x,y,appletsize, coord_div, scalex, scaley, hasorign) {
let origin, moved_origin;
origin = [appletsize[0]/coord_div/2, appletsize[1]/coord_div/2];
if (hasorign.length > 0) {
moved_origin = eval('['+hasorign+']');
//moved_origin = hasorign;
moved_origin[0] = moved_origin[0]*scalex; moved_origin[1] = moved_origin[1]*scaley; //alert(moved_origin);
x = (-1*(origin[0]-((scalex*x)/coord_div))-((moved_origin[0]-(appletsize[0]/2))/coord_div));
y = (origin[1]-((scaley*y)/coord_div)+((moved_origin[1]-(appletsize[1]/2))/coord_div));
}
else {
x = (-1*(origin[0]-((scalex*x)/coord_div)));
y = (origin[1]-((scaley*y)/coord_div));
}
return [Math.round(x*100)/100, Math.round(y*100)/100];
}
/**
* Checks if there is Origin&Unit constructor in code, and return originelements rownr (String).
* @method getOrigin
* @param {String} a - original Java Sketchpad code
* @return {String} org - information that is in the Origin&Unit line between the brackets '(' and ')'
*/
function getOrigin(a) {
let rw="", org;
if (a.indexOf('Origin&Unit')>=0)
rw = a.slice(a.indexOf('(', a.indexOf('Origin&Unit'))+1, a.indexOf(',', a.indexOf('Origin&Unit')));
else if (a.indexOf('OriginAndUnit')>=0)
rw = a.slice(a.indexOf('(', a.indexOf('OriginAndUnit'))+1, a.indexOf(',', a.indexOf('OriginAndUnit')));
rw = '{'+rw+'}';
org = a.slice(a.indexOf('(',a.indexOf(rw))+1, a.indexOf(')',a.indexOf(rw)));
return org;
}
/**
* Changes all input code $name variablenames to {rownumber} representation and returns changed code (string)
* @method varJSPtoNumJSP
* @param {String} c - JSP code in $-form
* @return {String} c - JAva Sketchpad code in {row no}-form
*/
function varJSPtoNumJSP(c) {
let dList = [], dStr="", dVar="", indx, indx1, indx2, j, comments=[], tmp="", tmp2="", tmp3="", tmp4="", bcmem, add=0 , bug_stopper = 0;
//check for comments and "extra" lines
while (c.indexOf('${')>=0 && bug_stopper <= 5000) {
//removing $jsp comments - update on 04.04.2018
c = c.slice(0, c.indexOf('${')) + c.slice(c.indexOf('$}')+2);
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 1. Error in converting $JSP comments!"); return "null";}
} //tmp = "";
if (bug_stopper != 0) {bug_stopper = 0;}
//check for macros and rename all $-chars
while (c.indexOf('$(')>=0 && bug_stopper <= 5000) {
tmp = tmp2 = c.slice(c.indexOf('$('), c.indexOf('$)')+2);
//while (tmp2.indexOf('$')>=0)
//tmp2 = tmp2.replace('$', '#');
tmp2 = tmp2.replace(/\$/gi, '£');
c = c.replace(tmp, tmp2);
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 1. Error in converting $JSP comments!"); return "null";}
}
tmp = tmp2 = "";
if (bug_stopper != 0) {bug_stopper = 0;}
while (c.indexOf('#')>=0 && c.indexOf('#')<c.indexOf('$') && bug_stopper <= 5000) {
comments.push(c.slice(c.indexOf('#'), c.indexOf('$')));
tmp2 = comments.pop();
if ((tmp2.indexOf('WIDTH')>=0 || tmp2.indexOf('Width')>=0 || tmp2.indexOf('width')>=0) && (tmp2.indexOf('HEIGHT')>=0) || tmp2.indexOf('Height')>=0 || tmp2.indexOf('height')>=0)
tmp = tmp2;
c = c.replace(tmp2, "");
bug_stopper++;
if (bug_stopper >= 5000) {alert ("Error 2. Error in converting $JSP code!"); return "null";}
} c = tmp + c;
tmp = tmp2 = "";
if (bug_stopper != 0) {bug_stopper = 0;}
let k = 1;
j = c.indexOf('$');
for(let i=j; i<c.length; i++) {
if (c.charAt(i) == '$' && c.charAt(i+1)!='{' && c.charAt(i+1)!='}' && c.charAt(i+1)!='(' && c.charAt(i+1)!=')') {
indx1 = bcmem = i;
while (c.charAt(i)!=' ' && c.charAt(i)!=',' && c.charAt(i)!=')' && c.charAt(i)!='@' && c.charAt(i)!='(') i++;
indx2 = i;
dVar = c.slice(indx1,indx2);
if (checkJSPitem('|'+dVar.slice(1)+'|') && !checkJSPitem('|' + getValueFromString(c,'','',indx2) + '|')) {
document.getElementById('errormessages_prog').innerHTML = dVar + ' on line '+ lineCount('codearea', dVar) +' is not a valid variable name without object construction command!\n ';
$('#codearea').linenumbers({col_width:'37px', digits:'3'}, lineCount('codearea', dVar));
return 'null';
}
dVar = dVar + '|';
if (dStr.indexOf(dVar)==-1 && dVar != '$1|') {
dStr = dStr + dVar;
dList.push([dVar,k++]);
}
if (c.indexOf(';',i) >= 0 )
i = c.indexOf(';',i);
else {
document.getElementById('errormessages_prog').innerHTML = 'There is a semicolon (;) missing on line <font color="#F00">' + c.slice(indx1, indx1+60) + '</font>';
return 'null';
}
} //end of if
//if dot command 3.5.2018
else if (c.charAt(i) == '{' && c.charAt(i+1) == ',') {
i = bracketClosure(c, '{', i+1)-1;
}
/* update on 16.3.2018: User can input commands without variable name. Creates temporary variable name for each of these lines. */
else if (c.charAt(i) != ' ' && c.charAt(i) != '{' && c.charAt(i) != ';' && c.charAt(i) != '$' && c.charAt(i) != '<' && isAlphabet(c.charAt(i))) {
indx = i;
while (c.charAt(i) != ';' && c.charAt(i) != '}' && c.charAt(i) != '>') i++;
indx2=i+1;
if (c.charAt(i) == ';') {
tmp3 = (c.slice(indx,i));
//alert(tmp3);
try {
//if (checkJSPitem(tmp3.slice(0, tmp3.indexOf('(')).trim()) && tmp3.indexOf(';')<0) {
if (checkJSPitem(getJSPCmndFromString(tmp3, 0)) && tmp3.indexOf(';')<0) {
//if (c.slice(indx,indx2+1).indexOf('$') >= 0 && (c.slice(indx,indx2+1).indexOf('$') < c.slice(indx,indx2+1).indexOf(';'))) {
//document.getElementById('errormessages_prog').innerHTML = "Found error in code. <br>Look for the line:<br><br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! May be unknown command, error in syntax or missing ';'. <br><br>Convertion was stopped.";
//c= c.slice(0, indx); i=0;
//return "null";
//}
//alert(tmp3.slice(0, tmp3.indexOf('(')));
//if (c.indexOf(tmp3, indx2) < 0) {
tmp4 = '$var_wthout_name_'+add+' '+tmp3;
//c = c.replace(tmp3, tmp4);
c = c.slice(0,indx) + tmp4 + ";" + c.slice(indx2);
//alert(c);
add++;
i = bcmem-1;
//}
//else {
//document.getElementById('errormessages_prog').innerHTML = "Found error in code. <br>Look for the line:<br><br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! There is duplicate of this line in code.";
//c= c.slice(0, indx); i=0;
//return "null";
//}
bug_stopper++;
if (bug_stopper > 10000) {
alert("ERROR! \n(" + tmp3 +")\nThis caused problems! ");
return null;
}
//if (c[i] == ';') alert(c[i] + c[i+1] + c[i+2]);
}
else {
//alert("Found error in code. \nLook for the line:\n\n" + tmp3 + "\n\nand fix it! \n\nConvertion was done to the point where error occurred.");
//alert(tmp3);
document.getElementById('errormessages_prog').innerHTML = "Error 7. Found error in code. <br>Look for the line:<br><br>"+ getJSPCmndFromString(tmp3,0) + "<br>" + c.slice(indx,indx2+1) + "<br><br>and fix it! May be unknown command, error in syntax or missing ';'. <br><br>Convertion was stopped.";
//return "{1} FixedText(50,10,'ERROR IN CODE!')[];";
//alert(c.slice(0, bcmem));
//return c.slice(0, bcmem);
c= c.slice(0, indx); i=0;
return "null";
}
} catch(e) {document.getElementById('ERRORS').innerHTML = e.message;}
}
}
/*end of update */
//alert(c);
} //end of for loop
dList.sort(function(a,b) {
return b[0].length - a[0].length;
});
//alert(dList);
for(let i=0; i<dList.length; i++) {
dList[i][0] = dList[i][0].replace('|', '');
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 3. Error in $JSP convertion."; return "null";}
}
if (bug_stopper != 10000) {bug_stopper = 0;}
while (c.indexOf('$1')>=0) {
c = c.replace('$1', '#-1#');
}
while (c.indexOf('$2')>=0) {
c = c.replace('$2', '#-2#');
}
while (c.indexOf('$3')>=0) {
c = c.replace('$3', '#-3#');
}
while (c.indexOf('$4')>=0) {
c = c.replace('$4', '#-4#');
}
//update 7.9.2018 replace variables in ,locus{ }
let locus_indexses = [];
let locuses = [];
let old_locuses = [];
//let new_locuses = [];
let ex_in = 0;
while (c.indexOf(',locus', ex_in)>0) {
locus_indexses.push(c.indexOf(',locus',ex_in));
locuses.push(c.slice(c.indexOf(',locus',ex_in), bracketClosure(c, '{', c.indexOf(',locus',ex_in))));
ex_in = c.indexOf(',locus',ex_in)+6;
}
//update 7.9.2018
if (locuses.length>0) {
for (let j=0; j<locuses.length; j++) {
old_locuses[j] = locuses[j];
for(let k=0; k<dList.length; k++) {
while (locuses[j].indexOf(dList[k][0])>=0) locuses[j] = locuses[j].replace(dList[k][0], "{"+dList[k][1]+"}");
}
c = c.replace(old_locuses[j], locuses[j]);
}
}
for(let i=0; i<dList.length; i++) {
j=i+1;
c = c.replace(dList[i][0], "{"+dList[i][1]+"}");
while(c.indexOf(dList[i][0])>=0 && (c[c.indexOf(dList[i][0])+dList[i][0].length] == ' ' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ',' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ')' || c[c.indexOf(dList[i][0])+dList[i][0].length] == '@')) {
c = c.replace(dList[i][0], dList[i][1]);
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 4. Error in replacing $JSP variables to {rows}."; return "null";}
}
}
if (bug_stopper != 10000) {bug_stopper = 0;}
while (c.indexOf('$')>=0) {
for (let i=0; i<dList.length; i++) {
j=i+1;
while(c.indexOf(dList[i][0])>=0 && (c[c.indexOf(dList[i][0])+dList[i][0].length] == ' ' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ',' || c[c.indexOf(dList[i][0])+dList[i][0].length] == ')'))
c = c.replace(dList[i], j);
}
while (c.indexOf('${')>=0)
c = c.replace('${', '{');
while (c.indexOf('$}')>=0)
c = c.replace('$}', '}');
bug_stopper++;
if (bug_stopper>=10000) {document.getElementById('errormessages_prog').innerHTML = "Error 5. Error in replacing $JSP variables to {rows}.<br>Check that there is no undefined variables in your $JSP code and variables without name are not referred to.<br><br>Maybe this is the cause of error :<br> "+c.slice(c.indexOf('$'), c.indexOf(',',c.indexOf('$'))) +"<br><br> Check also that there are no missing semicolons (;) on command lines, possibly before command line :<br> " + c.slice(c.indexOf('$'), c.indexOf(',',c.indexOf('$'))) + "..."; return "null";}
}
//console.log(c);
return c;
}
function subAndSup(s) {
let r = s;
let tmp = "";
if (r.indexOf('SUB{'>=0) || r.indexOf('SUP{')>=0) {
while (r.indexOf('SUB{')>=0) {
tmp = r.slice(r.indexOf('SUB{'), bracketClosure(r, '{', 'SUB{')+1);
r = r.replace(tmp, '\\\\"+")<sub>\\\\"+"('+tmp.slice(tmp.indexOf("{")+1, tmp.lastIndexOf("}"))+'\\\\"+")</su'+'b>\\\\"+"(');
}
while (r.indexOf('SUP{')>=0) {
tmp = r.slice(r.indexOf('SUP{'), bracketClosure(r, '{', 'SUP{')+1);
r = r.replace(tmp, '\\\\"+")<sup>\\\\"+"('+tmp.slice(tmp.indexOf("{")+1, tmp.lastIndexOf("}"))+'\\\\"+")</su'+'p>\\\\"+"(');
}
r = r.replace("\\\\'+'( \\\\'+')", "");
r = r.replace("\\\\'+'(\\\\'+')", "");
return r;
}
return r;
}
function labelByUser(a) {
if (a.Opts.indexOf('label')>=0)
a.Att.Name = a.Opts.slice(a.Opts.indexOf("(", a.Opts.indexOf('label'))+2, a.Opts.lastIndexOf("'", bracketClosure(a.Opts, '(', 'label')));
if (a.JSPComment.indexOf('label(')>=0) {
a.Att.Name = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label('))+1, a.JSPComment.lastIndexOf("'"));
a.Att.Name = subAndSup(a.Att.Name);
}
a.Att.Name = changeTextApostrophes(a.Att.Name);
return a;
}
/**
* Function to create string that contains funtion as a string for 'Calculate' operation.
* E.g. input calculateFunction("A2+3*@sin_", [5]) will product a string "(Math.sin((3*(A+2))))", where A is replaced with value from row no 5 in Java Sketchpad code.
* Inputs are string (a), array of element indexes (b) and measurements (calculations) in that indexes in array b are referring to.
* Uses function mathCalc to create string.
* @method calculateFunction(string, array, array)
* @param {String} a - string that has the calculation, for example "A2+3*@sin_"
* @param {Array<Int>} b - array of elements in calculate command that are used as variables. For example if command is Calculate(0,315,'f(x,y) = ','A2^ B2^ -')(53,54)[magenta], b will be [53,54]
* @param {Array<String>} calc - has the calculations that jsptojsx convertor has created as strings.
* @return {String} ans - answer for the calculation
*/
function calculateFunction(a,b,calc, line) {
var i, j=0, tmpstr="", obj = [], terms = [], ans="", vbstr="", indx=0, v_indx=0;
var abc = "ABCDEFGHIJ", operators = "+-*/^%!", functions = "sin_ cos_ tan_ abs_ sqrt ln__ rond trnc sgn_ asin acos atan log_";
var alrt = false;
a = a.slice(a.lastIndexOf("'", a.lastIndexOf("'")-1)+1, a.lastIndexOf("'"));
//for checking purposes, insert @alrt at the end of the calcultion to alert the return function
if (a.indexOf('@alrt')>0) {
a = a.slice(0, a.indexOf('@alrt'));
alrt = true;
}
//Gettin values for variables here
while (a.indexOf("#")>=0){
indx = a.indexOf("#");
/*if (a[indx+1] == 'A') j=0;
else if (a[indx+1] == 'B') j=1;
else if (a[indx+1] == 'C') j=2;
else if (a[indx+1] == 'D') j=3;*/
if (a[indx+2] == '1') v_indx=0;
else v_indx = 1;
tmpstr = calc[b[getNumberOfCharForCalculate(a[indx+1])]][v_indx];
tmpstr = tmpstr.replace("function(){return ","");
tmpstr = tmpstr.replace(";}","");
while (tmpstr.indexOf("Dist")>=0 || tmpstr.indexOf("JXG.")>=0 || tmpstr.indexOf("Geometry")>=0) {
tmpstr = tmpstr.replace("Dist","dist"); //change Dist() because it has capital 'D'
tmpstr = tmpstr.replace("JXG.","jxg."); //change capital JXG
tmpstr = tmpstr.replace("Geometry","geometry"); //change capital Geometry
}
tmpstr = "|"+tmpstr+"|";
vbstr = a.slice(indx, indx+3);
while(a.indexOf(vbstr)>=0)
a = a.replace(vbstr, tmpstr);
vbstr="";
}
for (i=0; i<abc.length; i++) {
if (a.indexOf(abc[i])>=0 ) {
//tmpstr = calc[b[j]];
tmpstr = calc[b[getNumberOfCharForCalculate(abc[i])]];
tmpstr = tmpstr.replace("function(){return ","");
tmpstr = tmpstr.replace(";}","");
while (tmpstr.indexOf("Dist")>=0 || tmpstr.indexOf("JXG.")>=0 || tmpstr.indexOf("Geometry")>=0) {
tmpstr = tmpstr.replace("Dist","dist"); //change Dist() because it has capital 'D'
tmpstr = tmpstr.replace("JXG.","jxg."); //change capital JXG
tmpstr = tmpstr.replace("Geometry","geometry"); //change capital Geometry
}
tmpstr = "|"+tmpstr+"|";
while(a.indexOf(abc[i])>=0 )
a = a.replace(abc[i], " "+tmpstr+" ");
j++;
}
}
while (a.indexOf("dist")>=0 || a.indexOf("jxg.")>=0 || a.indexOf("geometry")>=0) {
a=a.replace("dist","Dist"); //change all lowletter 'dist' back to 'Dist'
a=a.replace("jxg.","JXG."); //change capital JXG
a=a.replace("geometry","Geometry"); //change capital Geometry
}
if (a.indexOf(',|')>=0 || a.indexOf('|,')>=0) { alert('Error in calculate command line '+ line +', check your commas and apostrophes.'); return null;}
for (i=0; i<a.length; i++){
if (a[i] == "@") {
i++;
terms.push(a[i++]+a[i++]+a[i++]+a[i]);
}
else if (a[i] == "|") {
terms.push(a.slice(i+1,a.indexOf("|",i+1)));
i = a.indexOf("|",i+1);
}
else if (operators.indexOf(a[i]) >= 0) {
terms.push(a[i]);
}
else if (a[i] != " ") {
var string =""; j=i;
while(a[j] != " " && a[j] != "@" && operators.indexOf(a[j]) == -1 && abc.indexOf(a[j]) == -1) {
string = string+a[j];
j++;
}
terms.push(string); i=j-1;
}
}
for (i=0; i<terms.length; i++) {
if (functions.indexOf(terms[i].toString()) >= 0) {
ans = mathCalc(terms[i], obj.pop());
obj.push(ans);
}
else if (operators.indexOf(terms[i].toString()) >=0) {
ans = mathCalc(terms[i], obj.pop(), obj.pop());
obj.push(ans);
}
else {
obj.push(terms[i]);
}
}
if (obj.length>0)
ans = obj.pop();
if (alrt) alert (ans);
console.log('result of calculate: '+ans);
return ans;
}
/**
* Creates one calculation with given operator and inputs. Second input is optional.
* E.g. mathCalc("+", "1", "5") returns string "(1+5)" and
* mathCalc("@sin_", "3.14") returns string "Math.sin(3.14)".
* @method mathCalc
* @param {String} f - mathematical operation
* @param {String} a - mathematical value or expression
* @param {String} b - mathematical value or expression
* @return {String} mathematical expression as a JavaScript string
*/
function mathCalc(f,a,b) {
if (f == "+") {return "("+b+"+"+a+")";}
else if (f == "-") {return "("+b+"-"+a+")";}
else if (f == "*") {return "("+b+"*"+a+")";}
else if (f == "/") {return "("+b+"/"+a+")";}
else if (f == "^") {return "Math.pow("+b+","+a+")";}
else if (f == "%") {return "(-1*"+a+")";}
else if (f == "!") {return "(-1*"+a+")";}
else if (f == "sin_") {return "Math.sin("+a+")";}
else if (f == "cos_") {return "Math.cos("+a+")";}
else if (f == "tan_") {return "Math.tan("+a+")";}
else if (f == "abs_") {return "Math.abs("+a+")";}
else if (f == "sqrt") {return "Math.sqrt("+a+")";}
else if (f == "ln__") {return "Math.log("+a+")";}
//else if (f == "rond") {if (Math.abs(Math.abs(a)-Math.abs(Math.floor(a))) < Math.abs(Math.abs(a)-Math.abs(Math.ceil(a)))) return Math.floor(a); else return Math.ceil(a);}
else if (f == "trnc") {return "Math.floor("+a+")";} // SGN_!
else if (f == "rond") {return "Math.round("+a+")";}
else if (f == "sgn_") {return "Math.sign("+a+")";}
else if (f == "asin") {return "Math.asin("+a+")";}
else if (f == "acos") {return "Math.acos("+a+")";}
else if (f == "atan") {return "Math.atan("+a+")";}
else if (f == "log_") {return "Math.log10("+a+")";}
}
/**
* Simple function to get number of char for the Calculate operation (get order of variable)
* @method getNumberOfCharForClaculation
* @param {String} a - alphabet from A to F
* @return {Int} integer from 0 to 5
*/
function getNumberOfCharForCalculate(a) {
if (a=='A') return 0;
else if (a=='B') return 1;
else if (a=='C') return 2;
else if (a=='D') return 3;
else if (a=='E') return 4;
else if (a=='F') return 5;
else if (a=='G') return 6;
else if (a=='H') return 7;
else if (a=='I') return 8;
else if (a=='J') return 9;
else return 0;
}
/**
* Changes property JsxType of an element given as object created in sketchpadrowToJsxgElement(string)
* [mostly just changes property to lowercase letters]
* Also change the CType (constructor type), possible types are:
* points, straightlines, circles, measurements, transformations, images, buttons, coordinatesystem, locus
* @method changeTypeToJSX
* @param {Object} a -
* @return {Object} a - return the object
*/
function changeTypeToJSX(a) {
try {
if (a.Type == "FixedPoint") {
a.JsxType = 'point';
a.Opts = a.Opts.replace("]",",fixed:true]");
a.CType = 'points';
}
else if (a.Type == "Point" || a.Type == "PlotXY" || a.Type == "UnitPoint") {
a.JsxType = a.Type.toLowerCase();
a.CType = 'points';
}
else if (a.Type == "Origin&Unit" || a.Type == "OriginAndUnit" || a.Type == "Origin&Unit") {
a.JsxType = 'originandunit';
a.CType = 'coorninatesystem';
a.ParentType = 'point';
}
else if (a.Type == "Point on object") {
a.JsxType = 'glider';
a.CType = 'points';
a.ParentType = 'line';
}
else if (a.Type == "MidPoint" || a.Type == "Midpoint") {
a.JsxType = a.Type.toLowerCase();
a.CType = 'points';
a.ParentType = 'line';
}
else if (a.Type=='Line' || a.Type == 'Segment' || a.Type == 'Ray' || a.Type == 'Parallel' || a.Type == 'Perpendicular' || a.Type == 'AxisX' || a.Type == 'AxisY') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'straightlines';
a.ParentType = 'point';
}
else if (a.Type == 'Circle' || a.Type == 'Circle by radius' ) {
a.JsxType = a.Type.toLowerCase();
a.CType = 'circles';
a.ParentType = 'point';
}
else if (a.Type == "FixedText") {
a.JsxType = 'text';
a.CType = 'buttons';
}
else if (a.Type == "Intersect1" || a.Type == "Intersect2" || a.Type == "Intersect") {
if (a.Type == "Intersect2") a.Att.Info = 0; else a.Att.Info = 1;
a.JsxType = 'intersection';
a.CType = 'points';
a.ParentType = 'line';
}
else if ( a.Type == 'Reflection' || a.Type == 'Dilation' || a.Type == 'Dilation/SegmentRatio' || a.Type == 'Dilation/3ptRatio' || a.Type == 'Dilation/3PtRatio' ||
a.Type == 'Dilation/MarkedRatio' || a.Type == 'Rotation' || a.Type == 'Rotation/MarkedAngle' || a.Type == 'Rotation/MeasuredAngle' ||
a.Type == 'Translation' || a.Type == 'VectorTranslation' || a.Type == 'Translation/MarkedAngle/MarkedDistance' ||
a.Type == 'Translation/Markedangle/Markeddistance' || a.Type == 'PolarTranslation' || a.Type == 'Translation/FixedAngle/MarkedDistance') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'transformations';
}
else if ( a.Type == 'Coordinates' || a.Type == 'Length' || a.Type == 'Angle' || a.Type == 'Perimeter' || a.Type == 'Circumference' ||
a.Type == 'Radius' || a.Type == 'Area' || a.Type == 'Slope' || a.Type == 'Distance' || a.Type == 'Ratio/Segments' ||
a.Type == 'Ratio/Points' || a.Type == 'Calculate' || a.Type == 'Parameter') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'measurements';
}
else if (a.Type == 'ShowButton' || a.Type == 'HideButton' || a.Type == 'SimultaneousButton' || a.Type == 'AnimateButton' || a.Type == 'MoveButton') {
a.JsxType = a.Type.toLowerCase();
a.CType = 'buttons';
}
else if (a.Type == 'Polygon' ) {
a.JsxType = 'polygon';
a.CType = 'interiors';
}
else if (a.Type == 'Circle interior' ) {
a.JsxType = a.Type.toLowerCase();
a.CType = 'interiors';
}
else if (a.Type == 'Locus') {
a.JsxType = a.Type.toLowerCase();
a.CType='curves';
}
else if (jsp_macros.indexOf(a.Type)>=0)
a.JsxType = 'macros';
else {
a.JsxType = a.Type.toLowerCase();
a.CType = 'unknown';
//alert(a.JsxType);
}
} catch(e) {alert( "Error (element-handles: function getElemRefs): " + e.message);}
return a;
}
/**
* Changes property Pos of an element given as object created in sketchpadrowToJsxgElement(string)
* Outcome depends of type of the element as follows:
* - Point will change Pos to array with point coordinates [x,y],
* - Unit coord will change Pos to array with reference to object and a coordinate [ref to obj, y],
* @method changePosInfoToJSX
* @param {Object} a -
* @param {Array} applets -
* @param {Int} coordd - coord divider, this is read from the original code in the main function JSPtoSJX
* @param {Double} scx - scale x factor, this is read in the main function
* @param {Double} scy - scale y factor, this is read in the main function
* @param {Int} hasoriginunit - origin&unit info read in the main function from the original code
* @return {Object} a - return the object with changed values
* ...
*/
function changePosInfoToJSX(a, applets, coordd, scx, scy, hasoriginunit) {
let x,y,o,t,values = [], laba, butvadj=0;
//button vertical adjustment:
if (document.getElementById('usebuttonstyle').checked == true) butvadj = document.getElementById('buttonverticaladjsel').value;
x = a.Pos.slice(0,a.Pos.indexOf(","));
y = a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.length);
if (a.Pos.indexOf('#-1#')>=0 || a.Pos.indexOf('#-2#')>=0 || a.Pos.indexOf('#-3#')>=0|| a.Pos.indexOf('#-4#')>=0) {
while (a.Pos.indexOf('#-1#')>=0)
a.Pos = a.Pos.replace('#-1#', a.Row-1);
while (a.Pos.indexOf('#-2#')>=0)
a.Pos = a.Pos.replace('#-2#', a.Row-2);
while (a.Pos.indexOf('#-3#')>=0)
a.Pos = a.Pos.replace('#-3#', a.Row-3);
while (a.Pos.indexOf('#-4#')>=0)
a.Pos = a.Pos.replace('#-4#', a.Row-4);
}
if (a.JsxType == 'point')
a.Pos = changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit);
else if (a.JsxType == 'unitpoint'){
a.Pos = [eval(x), changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1]];
}
else if (a.JsxType == 'originandunit') {
a.Pos = eval("["+a.Pos+"]");
}
else if (a.JsxType == 'text' || a.JsxType == 'image') {
y = a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1));
t = a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'"));
t = cleanString(t);
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
if (a.JSPComment.indexOf('latex')>=0) t = '\\\\"+"( ' + a.JSPComment.slice(a.JSPComment.indexOf('(', a.JSPComment.indexOf("latex"))+1, bracketClosure(a.JSPComment, "(", "latex")-1) + ' \\\\"+")';
t=subAndSup(t);
t=changeTextApostrophes(t);
if (a.JSPComment.indexOf('LabelAlign')>=0 || a.JSPComment.indexOf('labelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); x = eval(x)+eval(laba[0]); y = eval(y) + eval(laba[1]);}
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0],changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1],t];
}
else if (a.JsxType == 'movebutton') {
y = eval(a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1))) + eval(butvadj);
o = 1000 * eval(a.Pos.slice(a.Pos.indexOf(",", a.Pos.indexOf(",")+1)+1, a.Pos.indexOf(",'")));
t = a.Pos.slice(a.Pos.indexOf("'")+1, a.Pos.lastIndexOf("'"));
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
t=subAndSup(t);
t=changeTextApostrophes(t);
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0],changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1],o,t];
}
else if (a.JsxType == 'showbutton' || a.JsxType == 'hidebutton' || a.JsxType == 'simultaneousbutton' || a.JsxType == 'animatebutton') {
y = eval(a.Pos.slice(a.Pos.indexOf(",")+1,a.Pos.indexOf(",", a.Pos.indexOf(",")+1))) + eval(butvadj);
t = a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'"));
if (t.indexOf('F(')>=0) { t=t.replace(/F/g, 'F'); }
if (t.length==0) t="UNLABELED BUTTON";
if (a.JSPComment.indexOf('text')>=0) t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('label'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
t=subAndSup(t);
t=changeTextApostrophes(t);
a.Pos = [changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[0], changeToCoord(x,y,applets,coordd,scx,scy,hasoriginunit)[1], t];
}
else if (a.JsxType == 'ratio/points' || a.JsxType == 'angle') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[3] = changeToCoord(values[3],values[4],applets,coordd,scx,scy,hasoriginunit)[0];
values[4] = changeToCoord(values[3],values[4],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'distance' || a.JsxType == 'coordinates' || a.JsxType == 'ratio/segments') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[2] = changeToCoord(values[2],values[3],applets,coordd,scx,scy,hasoriginunit)[0];
values[3] = changeToCoord(values[2],values[3],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'length' || a.JsxType == 'circumference' || a.JsxType == 'radius' || a.JsxType == 'area' || a.JsxType == 'slope') {
values = eval("["+a.Pos.slice(0,a.Pos.lastIndexOf(",", a.Pos.indexOf("'")))+"]");
values[1] = changeToCoord(values[1],values[2],applets,coordd,scx,scy,hasoriginunit)[0];
values[2] = changeToCoord(values[1],values[2],applets,coordd,scx,scy,hasoriginunit)[1];
if (a.JSPComment.indexOf('text')>=0)
t = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) t = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else
t = (a.Pos.slice(a.Pos.indexOf("'")+1,a.Pos.lastIndexOf("'")));
t=subAndSup(t);
t=changeTextApostrophes(t);
values.push(t);
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[3] = eval(values[3]+laba[0]); values[4] = eval(values[4] + laba[1]);}
a.Pos = values;
}
else if (a.JsxType == 'calculate') {
values = eval("["+ a.Pos.slice(0,a.Pos.indexOf(",", a.Pos.indexOf(",")+1)) + "]");
values = changeToCoord(values[0],values[1],applets,coordd,scx,scy,hasoriginunit);
if (a.JSPComment.indexOf('text')>=0)
values[2] = a.JSPComment.slice(a.JSPComment.indexOf("'", a.JSPComment.indexOf('text'))+1, a.JSPComment.lastIndexOf("'", bracketClosure(a.JSPComment, '(', 'text')));
else if (a.JSPComment.indexOf('latex')>=0) values[2] = "\\\\'+'( " + a.JSPComment.slice(a.JSPComment.indexOf("(", a.JSPComment.indexOf('latex'))+1, bracketClosure(a.JSPComment, '(', 'latex')-1) + " \\\\'+')";
else {
values[2] = a.Pos.slice(a.Pos.indexOf("'")+1, a.Pos.lastIndexOf("'", a.Pos.lastIndexOf("'")-1));
values[2] = values[2].slice(0, values[2].lastIndexOf("'"));
values[2] = cleanString(values[2]);
}
values[2]=subAndSup(values[2]);
values[2]=changeTextApostrophes(values[2]);
values[3] = a.Pos;
values[4] = eval("["+a.Pos.slice(a.Pos.lastIndexOf("(")+1,a.Pos.lastIndexOf(")"))+"]");
if (a.JSPComment.indexOf('LabelAlign')>=0) {laba = eval(a.Att.LabelAlign.slice(a.Att.LabelAlign.indexOf('['), a.Att.LabelAlign.indexOf(']')+1)); values[0] = eval(values[0]+laba[0]); values[1] = eval(values[1] + laba[1]);}
a.Pos = values;
}
else {
a.Pos = eval("["+a.Pos+"]");
}
return a;
}
/*
* Inputs references to objects parents
* @param {Object} el - Converter element
* @return {Object} el - Converter element with refs set
*
*/
function getElemRefs(el) {
try {
if (el.Type == 'Point on object' || el.Type == 'UnitPoint' || el.Type == 'Dilation' || el.Type == 'Rotation' || el.Type == 'Translation/FixedAngle/MarkedDistance' || el.Type == 'Translation/MarkedAngle/FixedDistance' || el.Type == 'Locus') {
el.Ref = eval('[' + el.Pos.slice(0, this.lastIndexOf(',')) + ']');
}
else if (el.Type == 'Translation' || el.Type == 'PolarTranslation' ) {
el.Ref = eval('[' + el.Pos.slice(0, this.lastIndexOf(',', this.lastIndexOf(','))) + ']');
}
else if (el.CType == 'measurements') {
if (el.Type == 'Angle' || el.Type == 'Ratio/Points') //has 3 objRef (Angle, Ratio/Points)
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',', this.indexOf(',', this.indexOf(',')+1)+1)) + ']');
else if (el.Type == 'Distance' || el.Type == 'Ratio/Segments') //has 2 objRef (Distance, Ratio/Segments, )
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',', this.indexOf(',')+1)) + ']');
else if (el.Type == 'Calculate') //is calculate
el.Ref = eval('[' + el.Pos.slice(this.lastIndexOf('(')+1, this.length-1) + ']');
else //has 1 objRef (Length, Perimeter, Circumference, Radius, Area, Slope, Coordinates, Parameter)
el.Ref = eval('[' + el.Pos.slice(0, this.indexOf(',')) + ']');
}
else if (el.CType == 'buttons') {
el.Ref = eval('[' + el.Pos.slice(this.lastIndexOf('(')+1, this.length) + ']');
}
else if (el.Type == 'FixedText' || el.Type == 'FixedPoint' || el.Type == 'Point' || el.Type == 'Image')
el.Ref = -1;
else {
el.Ref = eval('[' + el.Pos + ']');
}
} catch(err) {alert("Error (element-handles: function getElemRefs): Line " + el.Row + ", " +err.message);}
return el;
}
/**
* Changes some values in original Java Sketchpad code into form that JSXGraph can understand.
* @method changeOptionsToJSX
* @param {Object} a - object a is created from original code and has the values that will be changed
* @return {Object} a - return object a with changed values
*/
function changeOptionsToJSX(a) {
//change brackets
a.Opts = a.Opts.replace("[", "{");
a.Opts = a.Opts.replace("]", "}");
a.Opts = a.Opts.replace(a.Opts.slice(a.Opts.indexOf("layer"), a.Opts.indexOf("layer")+9), "");
//change color
a.Opts = a.Opts.replace("black", "color:'black'");
a.Opts = a.Opts.replace("white", "color:'white'");
a.Opts = a.Opts.replace("red", "color:'red'");
a.Opts = a.Opts.replace("blue", "color:'blue'");
a.Opts = a.Opts.replace("green", "color:'green'");
a.Opts = a.Opts.replace("yellow", "color:'yellow'");
a.Opts = a.Opts.replace("magenta", "color:'magenta'");
a.Opts = a.Opts.replace("cyan", "color:'cyan'");
// change name
a.Opts = a.Opts.replace("label('", "name:'");
a.Opts = a.Opts.replace("label ('", "name:'");
a.Opts = a.Opts.replace("'),", "',");
a.Opts = a.Opts.replace("')", "'");
// text alignment
a.Opts = a.Opts.replace("justifyLeft", "anchorX:'left'");
a.Opts = a.Opts.replace("justifyCenter", "anchorX:'middle'");
a.Opts = a.Opts.replace("justifyRight", "anchorX:'right'");
//change other options
a.Opts = a.Opts.replace("hidden", "visible:false");
a.Opts = a.Opts.replace("thick", "strokeWidth=2");
a.Opts = a.Opts.replace("bold,", "");
a.Opts = a.Opts.replace("{plain,", "{");
a.Opts = a.Opts.replace("font(", "");
a.Opts = a.Opts.replace("'Helvetica',", "");
a.Opts = a.Opts.replace(",,", ",");
return a;
}
/**
* Changes some attributes from original Java Sketchpad code into form that JSXGraph can understand
* @method changeAttributesToJSX(string)
* @param {Object} a - object a is created from original code and has the values that will be changed
* @return {Object} a - return object a with changed values
*/
function changeAttributesToJSX(a) {
let tmpcolor = [], tmp="", ind=0;
// name attribute
if (a.Opts.indexOf("label")>=0 || (a.JSPComment.indexOf("label")>=0 && a.JSPComment.indexOf("label") != a.JSPComment.indexOf("labelAlign"))) {
a=labelByUser(a); //attributes-handler
}
if (document.getElementById('latex').checked == true && a.Att.Name.length > 0) {
tmp = a.Att.Name;
//alert(tmp);
a.Att.Name = '\\\\'+'"+"('+tmp+'\\\\'+'"+")';
a.Att.Name = a.Att.Name.replace('\\\\"+"( \\\\"+")', '');
a.Att.Name = a.Att.Name.replace('\\\\"+"(\\\\"+")', '');
//alert(a.Att.Name);
}
// colour attribute
if (a.Opts.indexOf("white")>=0)
a.Att.Color = 'grey';
else if (a.Opts.indexOf("black")>=0)
a.Att.Color = 'black';
else if (a.Opts.indexOf("red")>=0)
a.Att.Color = 'red';
else if (a.Opts.indexOf("blue")>=0)
a.Att.Color = 'blue';
else if (a.Opts.indexOf("green")>=0)
a.Att.Color = 'green';
else if (a.Opts.indexOf("yellow")>=0)
a.Att.Color = 'yellow';
else if (a.Opts.indexOf("magenta")>=0)
a.Att.Color = 'magenta';
else if (a.Opts.indexOf("cyan")>=0)
a.Att.Color = 'cyan';
else if (a.Opts.indexOf("color(")>=0) {
tmpcolor = eval("[" + a.Opts.slice(a.Opts.indexOf("color(")+6, a.Opts.indexOf(")", a.Opts.indexOf("color(")+6)) + "]");
a.Att.Color = "#"+ rgbToHex(tmpcolor[0],tmpcolor[1],tmpcolor[2]);
}
// visible attribute
if (a.Opts.indexOf("hidden")>=0)
a.Att.Visible = false;
if (a.Opts.indexOf("traced")>=0)
a.Att.Trace = true;
// thickness attribute
if (a.Opts.indexOf("thick3")>=0 || a.Opts.indexOf("thick")>=0)
a.Att.Strokewidth = 3;
if (a.Opts.indexOf("thick6")>=0)
a.Att.Strokewidth = 6;
if (a.Opts.indexOf("thick5")>=0)
a.Att.Strokewidth = 5;
if (a.Opts.indexOf("thick4")>=0)
a.Att.Strokewidth = 4;
if (a.Opts.indexOf("thick2")>=0)
a.Att.Strokewidth = 2;
if (a.Opts.indexOf("thick") <0 )
a.Att.Strokewidth = 1;
if (a.Opts.indexOf("fixed:true") >= 0)
a.Att.Fixed = true;
else if (a.Opts.indexOf("fixed:false") >= 0)
a.Att.Fixed = false;
// text alignment attribute
if (a.Opts.indexOf("justifyLeft") >= 0)
a.Att.AnchorX = 'left';
else if (a.Opts.indexOf("justifyCenter") >= 0)
a.Att.AnchorX = 'middle';
else if (a.Opts.indexOf("justifyRight") >= 0)
a.Att.AnchorX = 'right';
//suffix
if (a.Opts.indexOf("suffix") >= 0) {
a.Att.Suffix = a.Opts.slice(a.Opts.indexOf("'",a.Opts.indexOf("suffix"))+1, a.Opts.indexOf("'",a.Opts.indexOf("'",a.Opts.indexOf("suffix"))+1));
}
if (a.Opts.indexOf("_BREAK") >=0)
a.Att.Stop = true;
return a;
}
/**
* Get options as a full string {options}, that has all the options that are needed in construction of this object.
* The purpose of this function is to shorten the converted code.
* This is also to make changing of defaul options easier (for example point color).
* @method setAttributes
* @param {Object} e - Object that has option values
* @param {String} s - optional, extra option to add options string. This is for some special attributes. Function just adds s in the return string.
* @return {String} options - String that has only the options needed, for example {name:'A', color:'red'}. There will be no options that values are default in JSXgraph syntax
*/
//function setAttributes(e, s, own, n, type) {
function setAttributes(props) {
//straightLast:"+el[i].Att.Straightlast+", straightFirst:"+el[i].Att.Straightfirst+", lastArrow:"+el[i].Att.ArrowL+", firstArrow:"+el[i].Att.ArrowF+"} );";
let e=props.element,
s= props.extraAttribute ? props.extraAttribute : '',
vis= props.visibility ? props.visibility : '',
n=props.elementId,
type=props.elementType;
let options = "{";
let labelSettings = e.Att.LabelAlign.slice(1,e.Att.LabelAlign.length-1);
if (contains(e.JSPComment,'smallLabel'))
labelSettings += ',cssClass:"'+e.bname+'_smalllabels",highlightCssClass:"'+e.bname+'_smalllabels"';
if (contains(e.JSPComment,'bigLabel'))
labelSettings += ',cssClass:"'+e.bname+'_biglabels",highlightCssClass:"'+e.bname+'_biglabels"';
if (e.CType == 'points') {
options += 'name:"'+e.Att.Name+'",';
if (e.Att.Name.length > 0 ) options += "label:{"+labelSettings+"},";
if (e.Att.Color.length > 0) options += "color:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Fixed) options += "fixed:"+e.Att.Fixed+",";
if (e.Att.Size != 2) options += "size:"+e.Att.Size+",";
//if (e.Att.Trace == true) options += "trace:"+e.Att.Trace+", ";
if (!e.Att.Infobox) options += "showInfoBox:"+e.Att.Infobox+",";
if (e.Att.SnapToGrid == true) options += "snapToGrid:"+e.Att.SnapToGrid+",";
}
else if (e.CType == 'straightlines' || e.CType == 'curves') {
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
if (e.Att.Color.length > 0) options += "strokeColor:'"+e.Att.Color+"',";
if (e.JsxType == 'ray') options += "straightFirst:false,";
options += "strokeWidth:"+e.Att.Strokewidth+",";
if (e.Att.ArrowL == true) {if (e.JsxType === 'segment') options +="firstArrow:{type:1, size:7},"; else options += "lastArrow:{type:1, size:7},";}
//if (e.Att.ArrowL == true) {if (e.JsxType === 'segment') options +="firstArrow:true,"; else options += "lastArrow:true,";}
if (e.Att.ArrowF == true) {if (e.JsxType === 'segment') options +="lastArrow:{type:1, size:7},"; else options += "firstArrow:{type:1, size:7},";}
//if (e.Att.ArrowF == true) {if (e.JsxType === 'segment') options +="lastArrow:true,"; else options += "firstArrow:true,";}
if (e.JSPComment.indexOf('dash')>=0) options += "dash:" + (e.JSPComment.slice(e.JSPComment.indexOf('(')+1, e.JSPComment.lastIndexOf(')'))) + ",";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
}
else if (e.CType == 'circles' || type == 'circles') {
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
if (e.Att.Color.length > 0) options += "strokeColor:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Trace == true) options += "trace:"+e.Att.Trace+", ";
options += "strokeWidth:"+e.Att.Strokewidth+",";
if (e.JSPComment.indexOf('dash')>=0) options += "dash:" + (e.JSPComment.slice(e.JSPComment.indexOf('(')+1, e.JSPComment.lastIndexOf(')'))) + ",";
}
else if (e.CType == 'interiors') {
//{name:'"+el[i].Att.Name+"', fillColor:'"+el[i].Att.Color+"', withLines:false,visible:"+el[i].Att.Visible+", highlight:false, showInfoBox:"+el[i].Att.Infobox+", label:"+el[i].Att.LabelAlign+"}
options += "fillColor:'"+e.Att.Color+"',withLines:false,";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Name.length > 0) options += "label:'"+e.Att.Name+"',";
}
else if (e.CType == 'transformations') {
options += 'name:"'+e.Att.Name+'",';
if (e.Att.Name.length > 0 /*&& e.Att.LabelAlign != '{offset:[0,10]}'*/) options += "label:"+e.Att.LabelAlign+",";
if (e.Att.Color.length > 0 && e.Att.Color != 'red') options += "color:'"+e.Att.Color+"',";
if (!e.Att.Visible) options += "visible:"+e.Att.Visible+",";
if (e.Att.Size != 2) options += "size:"+e.Att.Size+",";
if (!e.Att.Infobox) options += "showInfoBox:"+e.Att.Infobox+",";
}
else if (e.CType == 'measurements') {
if (e.Att.Color.length > 0 && e.Att.Color != 'black') options += "color:'"+e.Att.Color+"',";
if (e.Att.Fixed) options += "fixed:true,";
}
else if (e.CType == 'buttons') {
options += "fixed:true,";
if (e.Att.Color.length > 0 && e.Att.Color != 'black') options += "color:'"+e.Att.Color+"',";
if (e.JsxType=='text') options += "anchorX:'"+e.Att.AnchorX+"',";
}
else {
options += "color:'"+e.Att.Color+"',";
}
//update 4.4.2018 highlight
if (!e.Att.Highlight)
options += "highlight:false,";
if (s.length>0) options += s;
if (options[options.length-1]==",")
return options.slice(0,options.length-1) + "}";
else
return options + "}";
}
/**
* Function that creates and returns (Array) position of the glider point.
* Param variables are string and number(a,b).
* @method gliderPoint
* @param {Object} a - JSXGraph Object
* @param {Double} b - this is to set the glider point
* @param {Object} c - Object circle
* @return {Array} - coordinates for moving glider to right position
*/
function gliderPoint(a,b,c) {
let d, dx, dy, x=0,y=0, p1x, p2x, p1y, p2y;
if (a.getType() == 'segment' || a.getType() == 'line' || a.getType() == 'axis') {
//alert(a.getType() +", ");
p1x = a.point1.X();
p2x = a.point2.X();
p1y = a.point1.Y();
p2y = a.point2.Y();
dx = p2x - p1x;
dy = p2y - p1y;
/*x = p1x + (dx * b);
y = p1y + (dy * b);
*/
x = p1x + (b*dx);
y = p1y + (b*dy);
return [x,y];
}
else if (a.getType() == 'parallel' || a.getType() == 'perpendicular') {
x = a.point1.X()+b;
y = a.point1.Y()+b;
return [x,y];
}
else if (a.getType() == 'circle') {
d = a.Radius();
x = c.X() + d*Math.cos(b);
y = c.Y() - d*Math.sin(b);
return [x,y];
}
}
function distanceToStraightline(l, p) {
var p1 = l.point1,
p2 = l.point2,
dist = Math.abs((p.X()*(p2.Y()-p1.Y())) - (p.Y()*(p2.X()-p1.X())) + p2.X()*p1.Y() - p2.Y()*p1.X() ) / Math.sqrt(Math.pow((p2.Y()-p1.Y()),2) + Math.pow((p2.X()-p1.X()),2));
return dist;
}
function trimJspCode(code_input) {
let code = "",
coderows = [],
row = [],
all_refs = [],
hidden_and_not_ref = [],
out = '',
tmp = '',
i;
//read JSP-code
code= document.getElementById(code_input).value.replace(/(\r\n|\n|\r|" ")/gm,"");
code = code.replace(/(\t)/gm, " ");
code = code.trim();
if (!codeDummyTest(code)) {
alert('There is some problems in your JSP-code. Check your code!');
return false;
//
}
coderows = separateCommands(code);
for (i=0; i<coderows.length; i++) {
row[i] = sketchpadrowToJsxgElement(coderows[i]);
row[i] = getElemRefs(row[i]);
}
try {
for (i=0; i<row.length; i++) {
all_refs = all_refs.concat(row[i].Ref);
}
} catch(e){alert(e.message);}
all_refs = uniq_fast(all_refs);
try {
for (i=0; i<row.length; i++) {
if (contains(all_refs, row[i].Row)) row[i].isReferred = true;
else row[i].isReferred = false;
if (!row[i].Att.Visible && !row[i].isReferred && row[i].Type != 'UnitPoint') {
hidden_and_not_ref.push(row[i].Row);
tmp = tmp + "\n" + row[i].Orig;
}
}
if (hidden_and_not_ref.length>0) {
tmp = 'These '+hidden_and_not_ref.length+' lines can be removed from the JSP-code:\n' +tmp + "\n\nDelete these lines?";
} else {tmp = "Nothing can be removed."; alert(tmp); return false;}
} catch(e) {alert(e.message);}
if (confirm(tmp)) {
var len = hidden_and_not_ref.length;
for(i=len-1; i>-1; i--)
row.splice(hidden_and_not_ref[i]-1, 1);
for (i=0; i<row.length; i++)
out = out + row[i].Orig +'\n';
document.getElementById(code_input).value = out;
alert('Deleted '+len+ ' lines.');
return true;
}
return false;
}
let code_to_mem;
window.onload = function() {
let rootElement = document.getElementById('JSPtoJSX-Convertor');
rootElement.appendChild(createHtml("JSPtoJSX-Convertor", "./json/HTMLGUI.json"));
rootElement.appendChild(createFooter());
//write update data in document
$.get('./php/updated.php', function(data) {
let updated = eval(data);
// index updated // document.getElementsByClassName('lastupdate-box')[0].textContent = updated[0];
// js updated // document.getElementsByClassName('lastupdate-box')[1].textContent = updated[1];
// app updated
document.getElementsByClassName('lastupdate-box')[1].textContent = updated[2];
});
}; //end of window.onload
/* copyToClipboard
*Helpfunction to copy JXGcode to clipboard.
*/
function copyToClipboard() {
document.getElementById('jsxcode').select();
document.execCommand('copy');
//alert("Copying done!");
}
function copyJSPToClipboard() {
document.getElementById('jspgeneratedcode').select();
document.execCommand('copy');
}
/* openNewWindow
Is used when link is wanted to open in new window.
*/
function openNewWindow(link) {
window.open(link, link, "toolbar=0,status=0,menubar=0,scrollbars=1");
}
function openNewConverterWindow(link) {
window.open(link, link, "fullscreen=yes, status=0");
}
function editJSXcode(link, code, img) {
if (link == 0) document.getElementById('hidden_jsx_editor_value').innerHTML = "";
else document.getElementById('hidden_jsx_editor_value').innerHTML = "1";
window.open('html/JSXeditor.html','html/JSXeditor.html', 'fullscreen=yes');
}
/**
* This function checks some things from string (the JSP code), inputs code into codearea and runs function jspToJsx
* @param {String} codetxt - code as string
* @return {Boolea} - false if codetxt not found, else true;
*/
function inputCodeAndValues(codetxt) {
clearAll(['jsxgimage','jsxgcode','JSketchPadCode','testing', 'errormessages'], ['err_comms', 'err_info', 'err_submit_btn', 'ERRORS']);
if(!codetxt) return false;
let sizew=400;
let sizeh=400;
let bname="JSXBoard";
let ename="id";
sizew = getWidthHeight(codetxt)[0];
sizeh = getWidthHeight(codetxt)[1];
//if (codetxt.indexOf("BNAME=")>=0 && codetxt.indexOf("#BNAME")>=0)
//bname = codetxt.slice(codetxt.indexOf("BNAME=")+6, codetxt.indexOf("#"));
//if (codetxt.indexOf("ENAME=")>=0 && codetxt.indexOf("#ENAME")>=0)
//ename = codetxt.slice(codetxt.indexOf("ENAME=")+6, codetxt.indexOf("#", codetxt.indexOf("#")+1));
//if (!checkJSPStyle(codetxt)) {
if (codetxt.indexOf("<JSP>")>=0 && codetxt.indexOf("</JSP>")>=0) {
codetxt = codetxt.slice(codetxt.indexOf("<JSP>"), codetxt.indexOf("</JSP>")+6);
}
else if (codetxt.indexOf("<APPLET>")>=0 && codetxt.indexOf("</APPLET>")>=0) {
codetxt = codetxt.slice(codetxt.indexOf("<APPLET>"), codetxt.indexOf("</APPLET>")+9);
}
if (codetxt.indexOf("<jsp>")>=0 && codetxt.indexOf("</jsp>")>=0) {
codetxt = codetxt.slice(codetxt.indexOf("<JSP>"), codetxt.indexOf("</JSP>")+6);
}
else if (codetxt.indexOf("<applet>")>=0 && codetxt.indexOf("</applet>")>=0) {
codetxt = codetxt.slice(codetxt.indexOf("<applet>"), codetxt.indexOf("</applet>")+9);
}
//else {
// if (codetxt.lastIndexOf(';')<codetxt.lastIndexOf('$}'))
// codetxt = codetxt.slice(codetxt.indexOf("$"), codetxt.lastIndexOf("$}")+2);
// else
// codetxt = codetxt.slice(codetxt.indexOf("$"), codetxt.lastIndexOf(";")+1);
//}
//}
//else codetxt = codetxt.slice(codetxt.indexOf("{"), codetxt.lastIndexOf(";")+1);
document.getElementById('codearea').value = codetxt;
document.getElementById('boardwidthinput').value = sizew;
document.getElementById('boardheightinput').value = sizeh;
document.getElementById('jsxgboardname').value = bname;
document.getElementById('jsxgelementid').value = ename;
clearAll(['jsxgimage','jsxgcode','JSketchPadCode','testing','errormessages'], ['err_comms', 'err_info', 'err_submit_btn', 'ERRORS']);
document.getElementById('ERRORS').style.display = "inline-block";
jspToJsx('codearea');
return true;
}
function convertPagetoJSX(codetxt) {
let imglisting=[], sizelisting=[], namelisting=[], convertedlisting=[], tmp="";
while (codetxt.indexOf('<APPLET')>=0) {
tmp = codetxt.slice(codetxt.indexOf('<APPLET'), codetxt.indexOf('</APPLET>')+9);
codetxt = codetxt.replace(tmp, "<REPAPPLET>");
imglisting.push(tmp);
}
for (let i=0; i<imglisting.length; i++) {
sizelisting.push(getWidthHeight(imglisting[i]));
}
for (let i=0; i<imglisting.length; i++) {
namelisting.push("img_"+i);
}
for (let i=0; i<imglisting.length; i++) {
imglisting[i] = imglisting[i].slice(imglisting[i].indexOf('{'), imglisting[i].lastIndexOf(';')+1);
}
for (let i=0; i<imglisting.length; i++) {
convertedlisting.push(jspToJsx(imglisting[i], sizelisting[i], namelisting[i], true));
}
for (let i=0; i<convertedlisting.length; i++) {
codetxt = codetxt.replace("<REPAPPLET>", convertedlisting[i]);
}
document.getElementById("codearea").value = codetxt;
document.getElementById("loading").style.display = "none";
document.getElementById("jsxgimage").innerHTML = "All "+convertedlisting.length+" images converted ok!<br><br><input onclick='downloadConvPage()' value='Save converted html' type='button' class='browseButton'>";
clearAll(['jsxgcode','JSketchPadCode','testing'], ['err_comms', 'err_info', 'err_submit_btn']);
//alert("All "+convertedlisting.length+" images converted ok!");
return null;
}
/* source: http://www.htmlgoodies.com/beyond/javascript/read-text-files-using-the-javascript-filereader.html#fbid=40sibQt8vco
*/
function readSingleFile(evt) {
//Retrieve the first (and only!) File from the FileList object
let f = evt.target.files[0];
if (f) {
let r = new FileReader();
r.onload = function(e) {
let contents = e.target.result;
inputCodeAndValues(contents);
};
r.readAsText(f);
}
else
alert("Failed to load file");
}
function readFullPageFile(evt) {
//Retrieve the first (and only!) File from the FileList object
let f = evt.target.files[0];
document.getElementById("loading").style.display = "block";
if (f) {
let r = new FileReader();
r.onload = function(e) {
let contents = e.target.result;
convertPagetoJSX(contents);
};
r.readAsText(f);
}
else
alert("Failed to load file");
}
//function downloadFile(){
function downloadJSX(){
let text=document.getElementById('jsxcode').value;
let filename = document.getElementById('jsxgboardname').value +".html";
let blob = new Blob([text], {type: "text/plain"});
let url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
}
//function downloadConvPage(){
function downloadConvPage(){
let text=document.getElementById('codearea').value;
let filename = "convertedpage.html";
let blob = new Blob([text], {type: "text/plain"});
let url = window.URL.createObjectURL(blob);
let a = document.createElement("a");
a.href = url;
a.download = filename;
a.click();
}
/* not in use anymore function selectChange(c) {
let sel = "";
try {
if (c == 'course') {
sel = document.getElementById('course_selection').value;
if (sel == 'JSPTestfiles') {
document.getElementById('JSPTestfiles').style.display = 'inline-block';
document.getElementById('MatematiikanJohdantoKurssi2018').style.display = 'none';
}
else if (sel == 'MatematiikanJohdantoKurssi2018') {
document.getElementById('JSPTestfiles').style.display = 'none';
document.getElementById('MatematiikanJohdantoKurssi2018').style.display = 'inline-block';
}
return true;
}
else if(c == 'JSPTestfiles') {
sel = document.getElementById('JSPTestfiles').value;
if (sel != '-1') inputCodeAndValues(getSelectedExample(sel));
}
else if (c == 'MatematiikanJohdantoKurssi2018') {
sel = document.getElementById('MatematiikanJohdantoKurssi2018').value;
if (sel != '-1') inputCodeAndValues(MatematiikanJohdantoKurssi2018(sel));
}
$('#codearea').linenumbers({col_width:'37px', digits:'3'});
return true;
} catch(e) {alert(e.message);}
}
*/
/**
* Open file fron path and convert it
* @param {String} folder - folder name
* @param {String} file - file name with extension
*/
function openSelectionFile(folder, file) {
if (file == '..') return null;
let sel = './jspfiles/'+folder+'/' + file;
let request = new XMLHttpRequest();
request.open('GET', sel);
request.responseType = 'text';
request.send();
request.onload = function() {
let file = request.responseText;
console.log('File '+sel+' was read!');
//check $JSP
if (file.indexOf('<JSP>')>=0) file = file.slice(file.indexOf('<JSP>'), file.indexOf('</JSP>'));
inputCodeAndValues(file);
};
}
/**
* Get width and height values from code (string)
* @param {String} codetxt - code
* @return {Object} [array] - array that has dimension values: [width, height]
*/
function getWidthHeight(codetxt) {
let goodChar="0123456789", goodWidth=["WIDTH", "width", "Width"], goodHeight=["HEIGHT", "height", "Height"], indx1=0, indx2=0, w="", h="";
for (let i=0; i<goodWidth.length; i++) {
if (codetxt.indexOf(goodWidth[i])>=0) {
indx1 = codetxt.indexOf(goodWidth[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
w = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (w.lenght<1) alert("Load error. File has no width value.");
for (let i=0; i<goodHeight.length; i++) {
if (codetxt.indexOf(goodHeight[i])>=0) {
indx1 = codetxt.indexOf(goodHeight[i]);
while (goodChar.indexOf(codetxt[indx1])==-1)
indx1++;
indx2 = indx1;
while (goodChar.indexOf(codetxt[indx2])>=0)
indx2++;
h = codetxt.slice(indx1, indx2);
indx1=0; indx2=0;
}
}
if (h.lenght<1) alert("Load error. File has no height value.");
return [w,h];
}
/* clearArea
*/
function clearArea() {
document.getElementById('codearea').value="";
document.getElementById('codearea').select();
}
function runMathJax() {
MathJax.Hub.Queue(["Typeset",MathJax.Hub]);
}
/*
* Hide/Open menuarea and enlarge/shrink codearea
*/
function enlargeCodearea(t) {
let menus = document.getElementById('menuarea');
let editor = document.getElementById('left-column-editor-area');
let codebox = document.getElementById('codearea');
let arrow_down = document.getElementById('menuarea_hiddener');
let arrow_up = document.getElementById('menuarea_opener');
let exp_height = window.screen.availHeight / 1.3;
if (t==1) {
menus.style.display = "none";
editor.style.height = exp_height+"px";
codebox.rows = "60";
arrow_down.style.display = "none";
arrow_up.style.display = "block";
}
else {
menus.style.display = "block";
editor.style.height = "500px";
codebox.rows = "32";
arrow_down.style.display = "block";
arrow_up.style.display = "none";
}
return true;
}
function switchDollarJSPtoJSP(codearea) {
let code = document.getElementById(codearea).value;
code_to_mem = code;
//alert(varJSPtoNumJSP(code));
document.getElementById(codearea).value = varJSPtoNumJSP(code);
}
function JspCodeAddRows() {
let code = document.getElementById('codearea').value;
code = code.replace(/; /g, ';');
code = code.replace(/;/g, ';\n');
document.getElementById('codearea').value = code;
}
function JspCodeDeleteRows() {
let code = document.getElementById('codearea').value;
code = code.replace(/\n\n/g, '\n');
//code = code.replace(/;/g, ';\n');
code = code.replace('{', '\n {');
code = code.replace('$', '\n $');
document.getElementById('codearea').value = code;
}
/*
* Get value from user selection
* @param {String} id - HTML id of element to check
* @param {String} type - type of HTML element as string
* @return {Boolean} - if type == 'radio' return true if radio/checkbox is checked
* @return {String} - value of selected element i.e. textarea
*/
function getUserVal(id, type) {
if (!type && document.getElementById(id).type == 'checkbox')
type = 'radio';
if (type === 'radio')
return document.getElementById(id).checked;
return document.getElementById(id).value;
}
/*
* clears jsxg images and other stuff from HTML document
* @param {Object} clearlist - list of element ids to set innerHTML = ""
* @param {Object} hidelist - list of element ids to set display:none
* @param {Object} hideclass - list if classnames that will set display none
*/
function clearAll(clearlist, hidelist, hideclass) {
let hide_all_class;
//clear innerHTML
for (let i=0; i<clearlist.length; i++) { document.getElementById(clearlist[i]).innerHTML = ""; }
//hide elements
for (let i=0; i<hidelist.length; i++) {document.getElementById(hidelist[i]).style.display = "none"; }
if (hideclass) {
hide_all_class = document.getElementsByClassName(hideclass);
for (let i=0; i<hide_all_class.length; i++)
hide_all_class[i].style.display = "none";
}
// Set a fake timeout to get the highest timeout id
let highestTimeoutId = setTimeout(";");
for (let i = 0 ; i < highestTimeoutId ; i++) {
clearTimeout(i);
}
}
function refreshFolders() {
let dropdown_courses_menu = document.getElementById('dropdown-course-selectors');
if (dropdown_courses_menu) dropdown_courses_menu.innerHTML = "";
//let main_course_selection = document.querySelector('#course_selection');
let main_course_selection = document.createElement('select');
main_course_selection.id = "course_selection";
//main_course_selection.style = "display: inline-block";
//main_course_selection.innerHTML = "";
$.get('./php/constructcoursesdata.php', function(data) {
//let coursesData = eval(data);
console.log('Courses data written in json/courses-data.json');
let requestExampleJson = new XMLHttpRequest();
requestExampleJson.open('GET', './json/courses-files.json');
requestExampleJson.responseType = 'json';
requestExampleJson.send();
requestExampleJson.onreadystatechange = function() {
//if(coursesData) {
if(this.status === 200 && this.readyState === 4) {
let jsonObj = requestExampleJson.response;
//let jsonObj = coursesData;
let newSelection;
for(let i in jsonObj) {
if (jsonObj[i]) {
let newCourseOption = document.createElement('option');
newCourseOption.value = Object.keys(jsonObj[i])[0];
newCourseOption.textContent = Object.keys(jsonObj[i])[0];
main_course_selection.appendChild(newCourseOption);
newSelection = document.createElement('select');
newSelection.id = (Object.keys(jsonObj[i])[0]);
newSelection.classList.add('courses-selection');
if (i==0) newSelection.classList.add('courses-selection-visible');
else newSelection.classList.add('courses-selection-hidden');
let newOption;
for (let key in jsonObj[i]) {
if (jsonObj[i][key]) {
for (let j=0; j<jsonObj[i][key].length; j++) {
if (jsonObj[i][key][j] !== '.') {
newOption = document.createElement('option');
newOption.value = jsonObj[i][key][j];
newOption.textContent = jsonObj[i][key][j];
newSelection.appendChild(newOption);
}
}
}
}
newSelection.addEventListener('change', function() {
console.log('open file ' + this.value);
openSelectionFile(this.id, this.value);
});
if(dropdown_courses_menu) dropdown_courses_menu.appendChild(newSelection);
}
}
main_course_selection.addEventListener('change', function() {
let set_id = "#"+this.value;
let hide_classes = ".courses-selection";
console.log('selected menu '+set_id);
$(hide_classes).removeClass('courses-selection-visible').addClass('courses-selection-hidden');
$(set_id).removeClass('courses-selection-hidden').addClass('courses-selection-visible');
});
if (dropdown_courses_menu) dropdown_courses_menu.appendChild(main_course_selection);
}
};
});
}
function printErrors(props) {
const errEl = document.getElementById('errormessages');
if (errEl.innerHTML.indexOf('but some warnings/errors occurred') < 0) errEl.innerHTML = "<span style='color=#ff2b00; font-weight:bold;'>Convertion done, but some warnings/errors occurred.</span><br>";
}
function createHtml(divid, source, jsonObj) {
//var topHtmlElement = document.getElementById(divid);
var topHtmlElement = document.createElement('div');
var requestJson = new XMLHttpRequest();
requestJson.open('GET', source, true);
requestJson.responseType = 'json';
requestJson.send();
requestJson.onreadystatechange = function() {
if (this.status === 200 && this.readyState === 4) {
var data = this.response.jsptojsxData;
for (var key in data) {
if (data[key]) {
var newParentElement = document.createElement('div');
newParentElement.id = key;
var currentData = data[key].array;
$.each( currentData, function() {
var newElem = document.createElement(this.tag);
if (this.id) newElem.id = this.id;
if (this.class)newElem.setAttribute('class',this.class);
if (this.text) newElem.textContent = this.text;
if (this.name) newElem.setAttribute('name', this.name);
if (this.href) newElem.setAttribute('href', this.href);
if (this.target) newElem.setAttribute('target', this.target);
if (this.inpvalue) newElem.setAttribute('value', this.inpvalue);
if (this.inptype) newElem.setAttribute('type', this.inptype);
if (this.checked) newElem.setAttribute('checked', this.checked);
if (this.onclick) newElem.setAttribute('onclick', this.onclick);
if (this.src) newElem.setAttribute('src', this.src);
if (this.alt) newElem.setAttribute('alt', this.alt);
if (this.title) newElem.setAttribute('title', this.title);
if (this.rows) newElem.setAttribute('rows', this.rows);
if (this.cols) newElem.setAttribute('cols', this.cols);
if (this.autofocus) newElem.setAttribute('autofocus', this.autofocus);
if (this.size) newElem.setAttribute('size', this.size);
if (this.disabled) newElem.setAttribute('disabled', this.disabled);
if (this.selected) newElem.setAttribute('selected', this.selected);
if (this.childs) {
$.each(this.childs.array, function() {
newElem.appendChild(getChild(this));
});
}
newParentElement.appendChild(newElem);
});
topHtmlElement.appendChild(newParentElement);
}
}
}
$(function() {
$('#codearea').linenumbers({col_width:'37px', digits:'3'});
});
refreshFolders();
};
return topHtmlElement;
}
function createFooter() {
var footer = document.createElement('div');
footer.id='footer';
var date = new Date();
var year = date.getFullYear();
footer.appendChild(document.createElement('hr'));
var name = document.createElement('div'); name.textContent = year + ' Henri Tanskanen, University of Eastern Finland';
var email = document.createElement('div'); email.textContent = 'htanska@uef.fi';
var hidimg = document.createElement('img'); hidimg.id = "hiddenimg"; hidimg.setAttribute('class', 'hidden'); hidimg.setAttribute('src', 'http://www.uef.fi/uef-theme/images/footerlogo.png');
var pageconv = document.createElement('div'); pageconv.id="pageconvert";
var hidden_jsx_editor_value = document.createElement('div'); hidden_jsx_editor_value.id="hidden_jsx_editor_value"; hidden_jsx_editor_value.setAttribute('class', 'hidden');
footer.appendChild(name);
footer.appendChild(email);
footer.appendChild(hidimg);
footer.appendChild(pageconv);
footer.appendChild(hidden_jsx_editor_value);
return footer;
}
function getChild(el, update) {
var newChild = document.createElement(el.tag);
if (el.id) newChild.id = el.id;
if (el.class)newChild.setAttribute('class',el.class);
if (el.text) newChild.textContent = el.text;
if (el.name) newChild.setAttribute('name', el.name);
if (el.href) newChild.setAttribute('href', el.href);
if (el.target) newChild.setAttribute('target', el.target);
if (el.inpvalue) newChild.setAttribute('value', el.inpvalue);
if (el.inptype) newChild.setAttribute('type', el.inptype);
if (el.checked) newChild.setAttribute('checked', el.checked);
if (el.onclick) newChild.setAttribute('onclick', el.onclick);
if (el.src) newChild.setAttribute('src', el.src);
if (el.alt) newChild.setAttribute('alt', el.alt);
if (el.title) newChild.setAttribute('title', el.title);
if (el.rows) newChild.setAttribute('rows', el.rows);
if (el.cols) newChild.setAttribute('cols', el.cols);
if (el.autofocus) newChild.setAttribute('autofocus', el.autofocus);
if (el.size) newChild.setAttribute('size', el.size);
if (el.disabled) newChild.setAttribute('disabled', el.disabled);
if (el.selected) newChild.setAttribute('selected', el.selected);
if (el.action) newChild.setAttribute('action', el.action);
if (el.method) newChild.setAttribute('method', el.method);
if (update) {
if (el.php && el.php === 'index') newChild.textContent = update[0];
if (el.php && el.php === 'core') newChild.textContent = update[1];
}
if (el.listener) newChild.addEventListener(el.listener, function(){ if ($(this).prop('checked') ==true) { $(el.listenerTarget).prop('disabled', false); $(el.listenerTarget+"_text").css('color','#ddd'); } else { $(el.listenerTarget).prop('disabled', true); $(el.listenerTarget+"_text").css('color','#888'); } });
if (el.childs) {
$.each(el.childs.array, function() {
newChild.appendChild(getChild(this));
});
}
return newChild;
}