jsxgraph 1.4.4 → 1.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -842,7 +842,7 @@ define('base/constants',['jxg'], function (JXG) {
842
842
 
843
843
  var major = 1,
844
844
  minor = 4,
845
- patch = 4,
845
+ patch = 5,
846
846
  add = '', //'dev'
847
847
  version = major + '.' + minor + '.' + patch + (add ? '-' + add : ''),
848
848
  constants;
@@ -3198,14 +3198,15 @@ define('utils/env',['jxg', 'utils/type'], function (JXG, Type) {
3198
3198
  * @param {String} inner_id id of the DOM element which is scaled and shifted
3199
3199
  * @param {Number} scale Scaling factor
3200
3200
  * @param {Number} vshift Vertical shift (in pixel)
3201
+ * @param {Object} doc document object or shadow root
3201
3202
  *
3202
3203
  * @private
3203
3204
  * @see JXG.Board#toFullscreen
3204
3205
  * @see JXG.Board#fullscreenListener
3205
3206
  *
3206
3207
  */
3207
- scaleJSXGraphDiv: function (wrap_id, inner_id, scale, vshift) {
3208
- var len = document.styleSheets.length, style,
3208
+ scaleJSXGraphDiv: function (wrap_id, inner_id, scale, vshift, doc) {
3209
+ var len = doc.styleSheets.length, style,
3209
3210
 
3210
3211
  pseudo_keys = [':fullscreen', ':-webkit-full-screen', ':-moz-full-screen', ':-ms-fullscreen'],
3211
3212
  len_pseudo = pseudo_keys.length, i,
@@ -3223,22 +3224,21 @@ define('utils/env',['jxg', 'utils/type'], function (JXG, Type) {
3223
3224
  // WebKit hack :(
3224
3225
  style.appendChild(document.createTextNode(''));
3225
3226
  // Add the <style> element to the page
3226
- document.body.appendChild(style);
3227
- len = document.styleSheets.length;
3227
+ doc.appendChild(style);
3228
+ len = doc.styleSheets.length;
3228
3229
  }
3229
3230
 
3230
3231
  // Remove a previously installed CSS rule.
3231
- if (document.styleSheets[len - 1].cssRules.length > 0 &&
3232
- regex.test(document.styleSheets[len - 1].cssRules[0].cssText) &&
3233
- document.styleSheets[len - 1].deleteRule) {
3234
-
3235
- document.styleSheets[len - 1].deleteRule(0);
3232
+ if (doc.styleSheets[len - 1].cssRules.length > 0 &&
3233
+ regex.test(doc.styleSheets[len - 1].cssRules[0].cssText) &&
3234
+ doc.styleSheets[len - 1].deleteRule) {
3235
+ doc.styleSheets[len - 1].deleteRule(0);
3236
3236
  }
3237
3237
 
3238
3238
  // Install a CSS rule to center the JSXGraph div at the first position of the list.
3239
3239
  for (i = 0; i < len_pseudo; i++) {
3240
3240
  try {
3241
- document.styleSheets[len - 1].insertRule('#' + wrap_id + pseudo_keys[i] + ' #' + inner_id + rule_inner, 0);
3241
+ doc.styleSheets[len - 1].insertRule('#' + wrap_id + pseudo_keys[i] + ' #' + inner_id + rule_inner, 0);
3242
3242
  break;
3243
3243
  } catch (err) {
3244
3244
  // console.log('JXG.scaleJSXGraphDiv: Could not add CSS rule "' + pseudo_keys[i] + '".');
@@ -11758,43 +11758,43 @@ define('math/numerics',['jxg', 'utils/type', 'utils/env', 'math/math'], function
11758
11758
  */
11759
11759
  /*
11760
11760
  * jcobyla
11761
- *
11761
+ *
11762
11762
  * The MIT License
11763
11763
  *
11764
11764
  * Copyright (c) 2012 Anders Gustafsson, Cureos AB.
11765
11765
  *
11766
11766
  * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files
11767
- * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
11768
- * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
11767
+ * (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge,
11768
+ * publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
11769
11769
  * subject to the following conditions:
11770
11770
  *
11771
11771
  * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
11772
11772
  *
11773
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11774
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
11775
- * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
11773
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
11774
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
11775
+ * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
11776
11776
  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
11777
- *
11777
+ *
11778
11778
  * Remarks:
11779
- *
11779
+ *
11780
11780
  * The original Fortran 77 version of this code was by Michael Powell (M.J.D.Powell @ damtp.cam.ac.uk)
11781
11781
  * The Fortran 90 version was by Alan Miller (Alan.Miller @ vic.cmis.csiro.au). Latest revision - 30 October 1998
11782
11782
  */
11783
11783
 
11784
11784
  /**
11785
11785
  * Constrained Optimization BY Linear Approximation in Java.
11786
- *
11786
+ *
11787
11787
  * COBYLA2 is an implementation of Powell's nonlinear derivative free constrained optimization that uses
11788
11788
  * a linear approximation approach. The algorithm is a sequential trust region algorithm that employs linear
11789
11789
  * approximations to the objective and constraint functions, where the approximations are formed by linear
11790
11790
  * interpolation at n + 1 points in the space of the variables and tries to maintain a regular shaped simplex
11791
11791
  * over iterations.
11792
- *
11792
+ *
11793
11793
  * It solves nonsmooth NLP with a moderate number of variables (about 100). Inequality constraints only.
11794
- *
11794
+ *
11795
11795
  * The initial point X is taken as one vertex of the initial simplex with zero being another, so, X should
11796
11796
  * not be entered as the zero vector.
11797
- *
11797
+ *
11798
11798
  * @author Anders Gustafsson, Cureos AB. Translation to Javascript by Reinhard Oldenburg, Goethe-University
11799
11799
  */
11800
11800
 
@@ -11807,7 +11807,7 @@ define('math/numerics',['jxg', 'utils/type', 'utils/env', 'math/math'], function
11807
11807
  utils/type
11808
11808
  */
11809
11809
 
11810
- define('math/nlp',['jxg'], function (JXG) {
11810
+ define('math/nlp',['jxg', 'utils/type'], function (JXG, Type) {
11811
11811
 
11812
11812
  "use strict";
11813
11813
 
@@ -11815,20 +11815,29 @@ define('math/nlp',['jxg'], function (JXG) {
11815
11815
  * The JXG.Math.Nlp namespace holds numerical algorithms for non-linear optimization.
11816
11816
  * @name JXG.Math.Nlp
11817
11817
  * @namespace
11818
- *
11818
+ *
11819
11819
  */
11820
- JXG.Math.Nlp = {
11820
+ JXG.Math.Nlp = {
11821
11821
 
11822
- arr: function(n) {
11823
- var a = new Array(n),
11824
- i;
11825
- for (i = 0; i <n ; i++) {
11826
- a[i] = 0.0;
11827
- }
11828
- return a;
11822
+ arr: function (n) {
11823
+ // Is 0 initialized
11824
+ return new Float64Array(n);
11825
+
11826
+ // var a = new Array(n),
11827
+ // i;
11828
+
11829
+ // if (Type.exists(a.fill)) {
11830
+ // a.fill(0.0, 0, n);
11831
+ // } else {
11832
+ // for (i = 0; i < n; i++) {
11833
+ // a[i] = 0.0;
11834
+ // }
11835
+ // }
11836
+
11837
+ // return a;
11829
11838
  },
11830
11839
 
11831
- arr2: function(n, m) {
11840
+ arr2: function (n, m) {
11832
11841
  var i = 0,
11833
11842
  a = new Array(n);
11834
11843
 
@@ -11839,7 +11848,7 @@ define('math/nlp',['jxg'], function (JXG) {
11839
11848
  return a;
11840
11849
  },
11841
11850
 
11842
- arraycopy: function(x, a, iox, b, n) {
11851
+ arraycopy: function (x, a, iox, b, n) {
11843
11852
  var i = 0;
11844
11853
  while (i < n) {
11845
11854
  iox[i + b] = x[i + a];
@@ -11869,7 +11878,7 @@ define('math/nlp',['jxg'], function (JXG) {
11869
11878
  * @param maxfun Maximum number of function evaluations before terminating.
11870
11879
  * @returns {Number} Exit status of the COBYLA2 optimization.
11871
11880
  */
11872
- FindMinimum: function(calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun) {
11881
+ FindMinimum: function (calcfc, n, m, x, rhobeg, rhoend, iprint, maxfun) {
11873
11882
  // CobylaExitStatus FindMinimum(final Calcfc calcfc, int n, int m, double[] x, double rhobeg, double rhoend, int iprint, int maxfun)
11874
11883
  // This subroutine minimizes an objective function F(X) subject to M
11875
11884
  // inequality constraints on X, where X is a vector of variables that has
@@ -11933,16 +11942,16 @@ define('math/nlp',['jxg'], function (JXG) {
11933
11942
 
11934
11943
  // Internal representation of the objective and constraints calculation method,
11935
11944
  // accounting for that X and CON arrays in the cobylb method are base-1 arrays.
11936
- fcalcfc = function(n, m, thisx, con) { // int n, int m, double[] x, double[] con
11937
- var ix = that.arr(n),
11938
- ocon, f;
11939
-
11940
- that.arraycopy(thisx, 1, ix, 0, n);
11941
- ocon = that.arr(m);
11942
- f = calcfc(n, m, ix, ocon);
11943
- that.arraycopy(ocon, 0, con, 1, m);
11944
- return f;
11945
- };
11945
+ fcalcfc = function (n, m, thisx, con) { // int n, int m, double[] x, double[] con
11946
+ var ix = that.arr(n),
11947
+ ocon, f;
11948
+
11949
+ that.arraycopy(thisx, 1, ix, 0, n);
11950
+ ocon = that.arr(m);
11951
+ f = calcfc(n, m, ix, ocon);
11952
+ that.arraycopy(ocon, 0, con, 1, m);
11953
+ return f;
11954
+ };
11946
11955
 
11947
11956
  status = this.cobylb(fcalcfc, n, m, mpp, iox, rhobeg, rhoend, iprint, maxfun);
11948
11957
  this.arraycopy(iox, 1, x, 0, n);
@@ -11954,18 +11963,18 @@ define('math/nlp',['jxg'], function (JXG) {
11954
11963
  // double rhobeg, double rhoend, int iprint, int maxfun)
11955
11964
  /**
11956
11965
  * JavaScript implementation of the non-linear optimization method COBYLA.
11957
- * @param {Function} calcfc
11958
- * @param {Number} n
11959
- * @param {Number} m
11960
- * @param {Number} mpp
11961
- * @param {Number} x
11962
- * @param {Number} rhobeg
11963
- * @param {Number} rhoend
11964
- * @param {Number} iprint
11965
- * @param {Number} maxfun
11966
+ * @param {Function} calcfc
11967
+ * @param {Number} n
11968
+ * @param {Number} m
11969
+ * @param {Number} mpp
11970
+ * @param {Number} x
11971
+ * @param {Number} rhobeg
11972
+ * @param {Number} rhoend
11973
+ * @param {Number} iprint
11974
+ * @param {Number} maxfun
11966
11975
  * @returns {Number} Exit status of the COBYLA2 optimization
11967
11976
  */
11968
- cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun) {
11977
+ cobylb: function (calcfc, n, m, mpp, x, rhobeg, rhoend, iprint, maxfun) {
11969
11978
  // calcf ist funktion die aufgerufen wird wie calcfc(n, m, ix, ocon)
11970
11979
  // N.B. Arguments CON, SIM, SIMI, DATMAT, A, VSIG, VETA, SIGBAR, DX, W & IACT
11971
11980
  // have been removed.
@@ -12141,8 +12150,7 @@ define('math/nlp',['jxg'], function (JXG) {
12141
12150
  sim[i][np] += temp;
12142
12151
 
12143
12152
  tempa = 0.0;
12144
- for (k = 1; k <= n; ++k)
12145
- {
12153
+ for (k = 1; k <= n; ++k) {
12146
12154
  sim[i][k] -= temp;
12147
12155
  tempa -= simi[k][i];
12148
12156
  }
@@ -12153,13 +12161,17 @@ define('math/nlp',['jxg'], function (JXG) {
12153
12161
  // Make an error return if SIGI is a poor approximation to the inverse of
12154
12162
  // the leading N by N submatrix of SIG.
12155
12163
  error = 0.0;
12156
- for (i = 1; i <= n; ++i) {
12157
- for (j = 1; j <= n; ++j) {
12158
- temp = this.DOT_PRODUCT(
12159
- this.PART(this.ROW(simi, i), 1, n),
12160
- this.PART(this.COL(sim, j), 1, n)
12161
- ) - (i === j ? 1.0 : 0.0);
12162
- error = Math.max(error, Math.abs(temp));
12164
+ if (false) {
12165
+ for (i = 1; i <= n; ++i) {
12166
+ for (j = 1; j <= n; ++j) {
12167
+ temp = this.DOT_PRODUCT_ROW_COL(simi, i, sim, j, 1, n) - (i === j ? 1.0 : 0.0);
12168
+ // temp = this.DOT_PRODUCT(
12169
+ // this.PART(this.ROW(simi, i), 1, n),
12170
+ // this.PART(this.COL(sim, j), 1, n)
12171
+ // ) - (i === j ? 1.0 : 0.0);
12172
+
12173
+ error = Math.max(error, Math.abs(temp));
12174
+ }
12163
12175
  }
12164
12176
  }
12165
12177
  if (error > 0.1) {
@@ -12178,8 +12190,9 @@ define('math/nlp',['jxg'], function (JXG) {
12178
12190
  }
12179
12191
 
12180
12192
  for (i = 1; i <= n; ++i) {
12181
- a[i][k] = (k === mp ? -1.0 : 1.0) * this.DOT_PRODUCT(
12182
- this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));
12193
+ a[i][k] = (k === mp ? -1.0 : 1.0) *
12194
+ this.DOT_PRODUCT_ROW_COL(w, -1, simi, i, 1, n);
12195
+ // this.DOT_PRODUCT(this.PART(w, 1, n), this.PART(this.COL(simi, i), 1, n));
12183
12196
  }
12184
12197
  }
12185
12198
 
@@ -12191,11 +12204,9 @@ define('math/nlp',['jxg'], function (JXG) {
12191
12204
 
12192
12205
  for (j = 1; j <= n; ++j) {
12193
12206
  wsig = 0.0;
12194
- for (k = 1; k <= n; ++k) {
12195
- wsig += simi[j][k] * simi[j][k];
12196
- }
12197
12207
  weta = 0.0;
12198
12208
  for (k = 1; k <= n; ++k) {
12209
+ wsig += simi[j][k] * simi[j][k];
12199
12210
  weta += sim[k][j] * sim[k][j];
12200
12211
  }
12201
12212
  vsig[j] = 1.0 / Math.sqrt(wsig);
@@ -12232,10 +12243,8 @@ define('math/nlp',['jxg'], function (JXG) {
12232
12243
  cvmaxm = 0.0;
12233
12244
  total = 0.0;
12234
12245
  for (k = 1; k <= mp; ++k) {
12235
- total = this.DOT_PRODUCT(
12236
- this.PART(this.COL(a, k), 1, n),
12237
- this.PART(dx, 1, n)
12238
- );
12246
+ // total = this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
12247
+ total = this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
12239
12248
  if (k < mp) {
12240
12249
  temp = datmat[k][np];
12241
12250
  cvmaxp = Math.max(cvmaxp, -total - temp);
@@ -12257,10 +12266,8 @@ define('math/nlp',['jxg'], function (JXG) {
12257
12266
 
12258
12267
  for (j = 1; j <= n; ++j) {
12259
12268
  if (j !== jdrop) {
12260
- temp = this.DOT_PRODUCT(
12261
- this.PART(this.ROW(simi, j), 1, n),
12262
- this.PART(dx, 1, n)
12263
- );
12269
+ // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
12270
+ temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
12264
12271
  for (k = 1; k <= n; ++k) {
12265
12272
  simi[j][k] -= temp * simi[jdrop][k];
12266
12273
  }
@@ -12290,7 +12297,8 @@ define('math/nlp',['jxg'], function (JXG) {
12290
12297
  resnew = 0.0;
12291
12298
  con[mp] = 0.0;
12292
12299
  for (k = 1; k <= mp; ++k) {
12293
- total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
12300
+ //total = con[k] - this.DOT_PRODUCT(this.PART(this.COL(a, k), 1, n), this.PART(dx, 1, n));
12301
+ total = con[k] - this.DOT_PRODUCT_ROW_COL(dx, -1, a, k, 1, n);
12294
12302
  if (k < mp) { resnew = Math.max(resnew, total); }
12295
12303
  }
12296
12304
 
@@ -12338,7 +12346,8 @@ define('math/nlp',['jxg'], function (JXG) {
12338
12346
  ratio = trured <= 0.0 ? 1.0 : 0.0;
12339
12347
  jdrop = 0;
12340
12348
  for (j = 1; j <= n; ++j) {
12341
- temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
12349
+ // temp = Math.abs(this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n)));
12350
+ temp = Math.abs(this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n));
12342
12351
  if (temp > ratio) {
12343
12352
  jdrop = j;
12344
12353
  ratio = temp;
@@ -12378,7 +12387,8 @@ define('math/nlp',['jxg'], function (JXG) {
12378
12387
  for (k = 1; k <= n; ++k) { simi[jdrop][k] /= temp; }
12379
12388
  for (j = 1; j <= n; ++j) {
12380
12389
  if (j !== jdrop) {
12381
- temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
12390
+ // temp = this.DOT_PRODUCT(this.PART(this.ROW(simi, j), 1, n), this.PART(dx, 1, n));
12391
+ temp = this.DOT_PRODUCT_ROW_COL(simi, j, dx, -1, 1, n);
12382
12392
  for (k = 1; k <= n; ++k) {
12383
12393
  simi[j][k] -= temp * simi[jdrop][k];
12384
12394
  }
@@ -12431,7 +12441,7 @@ define('math/nlp',['jxg'], function (JXG) {
12431
12441
  }
12432
12442
  }
12433
12443
  if (iprint >= 2) {
12434
- console.log("Reduction in RHO to "+rho+" and PARMU = "+parmu);
12444
+ console.log("Reduction in RHO to " + rho + " and PARMU = " + parmu);
12435
12445
  }
12436
12446
  if (iprint === 2) {
12437
12447
  this.PrintIterationResult(nfvals, datmat[mp][np], datmat[mpp][np], this.COL(sim, np), n, iprint);
@@ -12467,7 +12477,7 @@ define('math/nlp',['jxg'], function (JXG) {
12467
12477
  return status;
12468
12478
  },
12469
12479
 
12470
- trstlp: function(n, m, a, b, rho, dx) { //(int n, int m, double[][] a, double[] b, double rho, double[] dx)
12480
+ trstlp: function (n, m, a, b, rho, dx) { //(int n, int m, double[][] a, double[] b, double rho, double[] dx)
12471
12481
  // N.B. Arguments Z, ZDOTA, VMULTC, SDIRN, DXNEW, VMULTD & IACT have been removed.
12472
12482
 
12473
12483
  // This subroutine calculates an N-component vector DX by applying the
@@ -12581,9 +12591,8 @@ define('math/nlp',['jxg'], function (JXG) {
12581
12591
 
12582
12592
  L_70:
12583
12593
  do {
12584
- optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(
12585
- this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n)
12586
- );
12594
+ // optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT(this.PART(dx, 1, n), this.PART(this.COL(a, mcon), 1, n));
12595
+ optnew = (mcon === m) ? resmax : -this.DOT_PRODUCT_ROW_COL(dx, -1, a, mcon, 1, n);
12587
12596
 
12588
12597
  if (icount === 0 || optnew < optold) {
12589
12598
  optold = optnew;
@@ -12614,9 +12623,9 @@ define('math/nlp',['jxg'], function (JXG) {
12614
12623
  kp = k + 1;
12615
12624
  kk = iact[kp];
12616
12625
  sp = this.DOT_PRODUCT(
12617
- this.PART(this.COL(z, k), 1, n),
12618
- this.PART(this.COL(a, kk), 1, n)
12619
- );
12626
+ this.PART(this.COL(z, k), 1, n),
12627
+ this.PART(this.COL(a, kk), 1, n)
12628
+ );
12620
12629
  temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
12621
12630
  alpha = zdota[kp] / temp;
12622
12631
  beta = sp / temp;
@@ -12644,9 +12653,8 @@ define('math/nlp',['jxg'], function (JXG) {
12644
12653
  temp = 1.0 / zdota[nact];
12645
12654
  for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
12646
12655
  } else {
12647
- temp = this.DOT_PRODUCT(
12648
- this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n)
12649
- );
12656
+ // temp = this.DOT_PRODUCT(this.PART(sdirn, 1, n), this.PART(this.COL(z, nact + 1), 1, n));
12657
+ temp = this.DOT_PRODUCT_ROW_COL(sdirn, -1, z, nact + 1, 1, n);
12650
12658
  for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact + 1]; }
12651
12659
  }
12652
12660
  } else {
@@ -12655,34 +12663,34 @@ define('math/nlp',['jxg'], function (JXG) {
12655
12663
  tot = 0.0;
12656
12664
 
12657
12665
  // {
12658
- k = n;
12659
- while (k > nact) {
12660
- sp = 0.0;
12661
- spabs = 0.0;
12666
+ k = n;
12667
+ while (k > nact) {
12668
+ sp = 0.0;
12669
+ spabs = 0.0;
12670
+ for (i = 1; i <= n; ++i) {
12671
+ temp = z[i][k] * dxnew[i];
12672
+ sp += temp;
12673
+ spabs += Math.abs(temp);
12674
+ }
12675
+ acca = spabs + 0.1 * Math.abs(sp);
12676
+ accb = spabs + 0.2 * Math.abs(sp);
12677
+ if (spabs >= acca || acca >= accb) { sp = 0.0; }
12678
+ if (tot === 0.0) {
12679
+ tot = sp;
12680
+ } else {
12681
+ kp = k + 1;
12682
+ temp = Math.sqrt(sp * sp + tot * tot);
12683
+ alpha = sp / temp;
12684
+ beta = tot / temp;
12685
+ tot = temp;
12662
12686
  for (i = 1; i <= n; ++i) {
12663
- temp = z[i][k] * dxnew[i];
12664
- sp += temp;
12665
- spabs += Math.abs(temp);
12666
- }
12667
- acca = spabs + 0.1 * Math.abs(sp);
12668
- accb = spabs + 0.2 * Math.abs(sp);
12669
- if (spabs >= acca || acca >= accb) { sp = 0.0; }
12670
- if (tot === 0.0) {
12671
- tot = sp;
12672
- } else {
12673
- kp = k + 1;
12674
- temp = Math.sqrt(sp * sp + tot * tot);
12675
- alpha = sp / temp;
12676
- beta = tot / temp;
12677
- tot = temp;
12678
- for (i = 1; i <= n; ++i) {
12679
- temp = alpha * z[i][k] + beta * z[i][kp];
12680
- z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
12681
- z[i][k] = temp;
12682
- }
12687
+ temp = alpha * z[i][k] + beta * z[i][kp];
12688
+ z[i][kp] = alpha * z[i][kp] - beta * z[i][k];
12689
+ z[i][k] = temp;
12683
12690
  }
12684
- --k;
12685
12691
  }
12692
+ --k;
12693
+ }
12686
12694
  // }
12687
12695
 
12688
12696
  if (tot === 0.0) {
@@ -12695,34 +12703,34 @@ define('math/nlp',['jxg'], function (JXG) {
12695
12703
 
12696
12704
  ratio = -1.0;
12697
12705
  //{
12698
- k = nact;
12699
- do {
12700
- zdotv = 0.0;
12701
- zdvabs = 0.0;
12706
+ k = nact;
12707
+ do {
12708
+ zdotv = 0.0;
12709
+ zdvabs = 0.0;
12702
12710
 
12703
- for (i = 1; i <= n; ++i) {
12704
- temp = z[i][k] * dxnew[i];
12705
- zdotv += temp;
12706
- zdvabs += Math.abs(temp);
12711
+ for (i = 1; i <= n; ++i) {
12712
+ temp = z[i][k] * dxnew[i];
12713
+ zdotv += temp;
12714
+ zdvabs += Math.abs(temp);
12715
+ }
12716
+ acca = zdvabs + 0.1 * Math.abs(zdotv);
12717
+ accb = zdvabs + 0.2 * Math.abs(zdotv);
12718
+ if (zdvabs < acca && acca < accb) {
12719
+ temp = zdotv / zdota[k];
12720
+ if (temp > 0.0 && iact[k] <= m) {
12721
+ tempa = vmultc[k] / temp;
12722
+ if (ratio < 0.0 || tempa < ratio) { ratio = tempa; }
12707
12723
  }
12708
- acca = zdvabs + 0.1 * Math.abs(zdotv);
12709
- accb = zdvabs + 0.2 * Math.abs(zdotv);
12710
- if (zdvabs < acca && acca < accb) {
12711
- temp = zdotv / zdota[k];
12712
- if (temp > 0.0 && iact[k] <= m) {
12713
- tempa = vmultc[k] / temp;
12714
- if (ratio < 0.0 || tempa < ratio) { ratio = tempa; }
12715
- }
12716
-
12717
- if (k >= 2) {
12718
- kw = iact[k];
12719
- for (i = 1; i <= n; ++i) { dxnew[i] -= temp * a[i][kw]; }
12720
- }
12721
- vmultd[k] = temp;
12722
- } else {
12723
- vmultd[k] = 0.0;
12724
+
12725
+ if (k >= 2) {
12726
+ kw = iact[k];
12727
+ for (i = 1; i <= n; ++i) { dxnew[i] -= temp * a[i][kw]; }
12724
12728
  }
12725
- } while (--k > 0);
12729
+ vmultd[k] = temp;
12730
+ } else {
12731
+ vmultd[k] = 0.0;
12732
+ }
12733
+ } while (--k > 0);
12726
12734
  //}
12727
12735
  if (ratio < 0.0) { break L_60; }
12728
12736
 
@@ -12741,9 +12749,9 @@ define('math/nlp',['jxg'], function (JXG) {
12741
12749
  kp = k + 1;
12742
12750
  kw = iact[kp];
12743
12751
  sp = this.DOT_PRODUCT(
12744
- this.PART(this.COL(z, k), 1, n),
12745
- this.PART(this.COL(a, kw), 1, n)
12746
- );
12752
+ this.PART(this.COL(z, k), 1, n),
12753
+ this.PART(this.COL(a, kw), 1, n)
12754
+ );
12747
12755
  temp = Math.sqrt(sp * sp + zdota[kp] * zdota[kp]);
12748
12756
  alpha = zdota[kp] / temp;
12749
12757
  beta = sp / temp;
@@ -12762,9 +12770,9 @@ define('math/nlp',['jxg'], function (JXG) {
12762
12770
  vmultc[k] = vsave;
12763
12771
  }
12764
12772
  temp = this.DOT_PRODUCT(
12765
- this.PART(this.COL(z, nact), 1, n),
12766
- this.PART(this.COL(a, kk), 1, n)
12767
- );
12773
+ this.PART(this.COL(z, nact), 1, n),
12774
+ this.PART(this.COL(a, kk), 1, n)
12775
+ );
12768
12776
  if (temp === 0.0) { break L_60; }
12769
12777
  zdota[nact] = temp;
12770
12778
  vmultc[icon] = 0.0;
@@ -12787,9 +12795,9 @@ define('math/nlp',['jxg'], function (JXG) {
12787
12795
  if (mcon > m && kk !== mcon) {
12788
12796
  k = nact - 1;
12789
12797
  sp = this.DOT_PRODUCT(
12790
- this.PART(this.COL(z, k), 1, n),
12791
- this.PART(this.COL(a, kk), 1, n)
12792
- );
12798
+ this.PART(this.COL(z, k), 1, n),
12799
+ this.PART(this.COL(a, kk), 1, n)
12800
+ );
12793
12801
  temp = Math.sqrt(sp * sp + zdota[nact] * zdota[nact]);
12794
12802
  alpha = zdota[nact] / temp;
12795
12803
  beta = sp / temp;
@@ -12815,10 +12823,8 @@ define('math/nlp',['jxg'], function (JXG) {
12815
12823
  for (k = 1; k <= n; ++k) { sdirn[k] = temp * z[k][nact]; }
12816
12824
  } else {
12817
12825
  kk = iact[nact];
12818
- temp = (this.DOT_PRODUCT(
12819
- this.PART(sdirn, 1, n),
12820
- this.PART(this.COL(a, kk), 1, n)
12821
- ) - 1.0) / zdota[nact];
12826
+ // temp = (this.DOT_PRODUCT(this.PART(sdirn, 1, n),this.PART(this.COL(a, kk), 1, n)) - 1.0) / zdota[nact];
12827
+ temp = (this.DOT_PRODUCT_ROW_COL(sdirn, -1, a, kk, 1, n) - 1.0) / zdota[nact];
12822
12828
  for (k = 1; k <= n; ++k) { sdirn[k] -= temp * z[k][nact]; }
12823
12829
  }
12824
12830
  }
@@ -12858,9 +12864,8 @@ define('math/nlp',['jxg'], function (JXG) {
12858
12864
  resmax = 0.0;
12859
12865
  for (k = 1; k <= nact; ++k) {
12860
12866
  kk = iact[k];
12861
- temp = b[kk] - this.DOT_PRODUCT(
12862
- this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n)
12863
- );
12867
+ // temp = b[kk] - this.DOT_PRODUCT(this.PART(this.COL(a, kk), 1, n), this.PART(dxnew, 1, n));
12868
+ temp = b[kk] - this.DOT_PRODUCT_ROW_COL(dxnew, -1, a, kk, 1, n);
12864
12869
  resmax = Math.max(resmax, temp);
12865
12870
  }
12866
12871
  }
@@ -12870,25 +12875,25 @@ define('math/nlp',['jxg'], function (JXG) {
12870
12875
  // can be attributed to computer rounding errors. First calculate the new
12871
12876
  // Lagrange multipliers.
12872
12877
  //{
12873
- k = nact;
12874
- do {
12875
- zdotw = 0.0;
12876
- zdwabs = 0.0;
12877
- for (i = 1; i <= n; ++i) {
12878
- temp = z[i][k] * dxnew[i];
12879
- zdotw += temp;
12880
- zdwabs += Math.abs(temp);
12881
- }
12882
- acca = zdwabs + 0.1 * Math.abs(zdotw);
12883
- accb = zdwabs + 0.2 * Math.abs(zdotw);
12884
- if (zdwabs >= acca || acca >= accb) { zdotw = 0.0; }
12885
- vmultd[k] = zdotw / zdota[k];
12886
- if (k >= 2) {
12887
- kk = iact[k];
12888
- for (i = 1; i <= n; ++i) { dxnew[i] -= vmultd[k] * a[i][kk]; }
12889
- }
12890
- } while (k-- >= 2);
12891
- if (mcon > m) { vmultd[nact] = Math.max(0.0, vmultd[nact]); }
12878
+ k = nact;
12879
+ do {
12880
+ zdotw = 0.0;
12881
+ zdwabs = 0.0;
12882
+ for (i = 1; i <= n; ++i) {
12883
+ temp = z[i][k] * dxnew[i];
12884
+ zdotw += temp;
12885
+ zdwabs += Math.abs(temp);
12886
+ }
12887
+ acca = zdwabs + 0.1 * Math.abs(zdotw);
12888
+ accb = zdwabs + 0.2 * Math.abs(zdotw);
12889
+ if (zdwabs >= acca || acca >= accb) { zdotw = 0.0; }
12890
+ vmultd[k] = zdotw / zdota[k];
12891
+ if (k >= 2) {
12892
+ kk = iact[k];
12893
+ for (i = 1; i <= n; ++i) { dxnew[i] -= vmultd[k] * a[i][kk]; }
12894
+ }
12895
+ } while (k-- >= 2);
12896
+ if (mcon > m) { vmultd[nact] = Math.max(0.0, vmultd[nact]); }
12892
12897
  //}
12893
12898
 
12894
12899
  // Complete VMULTC by finding the new constraint residuals.
@@ -12953,12 +12958,12 @@ define('math/nlp',['jxg'], function (JXG) {
12953
12958
  return false;
12954
12959
  },
12955
12960
 
12956
- PrintIterationResult: function(nfvals, f, resmax, x, n, iprint) {
12957
- if (iprint > 1) { console.log("NFVALS = "+nfvals+" F = "+f+" MAXCV = "+resmax); }
12961
+ PrintIterationResult: function (nfvals, f, resmax, x, n, iprint) {
12962
+ if (iprint > 1) { console.log("NFVALS = " + nfvals + " F = " + f + " MAXCV = " + resmax); }
12958
12963
  if (iprint > 1) { console.log("X = " + this.PART(x, 1, n)); }
12959
12964
  },
12960
12965
 
12961
- ROW: function(src, rowidx) {
12966
+ ROW: function (src, rowidx) {
12962
12967
  return src[rowidx].slice();
12963
12968
  // var col,
12964
12969
  // cols = src[0].length,
@@ -12970,17 +12975,18 @@ define('math/nlp',['jxg'], function (JXG) {
12970
12975
  // return dest;
12971
12976
  },
12972
12977
 
12973
- COL: function(src, colidx) {
12978
+ COL: function (src, colidx) {
12974
12979
  var row,
12975
12980
  rows = src.length,
12976
- dest = this.arr(rows);
12981
+ dest = []; // this.arr(rows);
12982
+
12977
12983
  for (row = 0; row < rows; ++row) {
12978
12984
  dest[row] = src[row][colidx];
12979
12985
  }
12980
12986
  return dest;
12981
12987
  },
12982
12988
 
12983
- PART: function(src, from, to) {
12989
+ PART: function (src, from, to) {
12984
12990
  return src.slice(from, to + 1);
12985
12991
  // var srcidx,
12986
12992
  // dest = this.arr(to - from + 1),
@@ -12991,7 +12997,7 @@ define('math/nlp',['jxg'], function (JXG) {
12991
12997
  // return dest;
12992
12998
  },
12993
12999
 
12994
- FORMAT: function(x) {
13000
+ FORMAT: function (x) {
12995
13001
  return x.join(',');
12996
13002
  // var i, fmt = "";
12997
13003
  // for (i = 0; i < x.length; ++i) {
@@ -13000,12 +13006,38 @@ define('math/nlp',['jxg'], function (JXG) {
13000
13006
  // return fmt;
13001
13007
  },
13002
13008
 
13003
- DOT_PRODUCT: function(lhs, rhs) {
13009
+ DOT_PRODUCT: function (lhs, rhs) {
13004
13010
  var i, sum = 0.0,
13005
13011
  len = lhs.length;
13006
13012
  for (i = 0; i < len; ++i) {
13007
13013
  sum += lhs[i] * rhs[i];
13008
13014
  }
13015
+ return sum;
13016
+ },
13017
+
13018
+ DOT_PRODUCT_ROW_COL: function (lhs, row, rhs, col, start, end) {
13019
+ var i, sum = 0.0;
13020
+
13021
+ if (row === -1) {
13022
+ // lhs is vector
13023
+ for (i = start; i <= end; ++i) {
13024
+ sum += lhs[i] * rhs[i][col];
13025
+ }
13026
+ } else {
13027
+ // lhs is row of matrix
13028
+ if (col === -1) {
13029
+ // rhs is vector
13030
+ for (i = start; i <= end; ++i) {
13031
+ sum += lhs[row][i] * rhs[i];
13032
+ }
13033
+ } else {
13034
+ // rhs is column of matrix
13035
+ for (i = start; i <= end; ++i) {
13036
+ sum += lhs[row][i] * rhs[i][col];
13037
+ }
13038
+ }
13039
+ }
13040
+
13009
13041
  return sum;
13010
13042
  }
13011
13043
 
@@ -26658,14 +26690,33 @@ define('options',[
26658
26690
  * <p>
26659
26691
  * In case the element is a polygon or line and it has the attribute "scalable:false",
26660
26692
  * moving the element with two fingers results in a rotation or translation.
26693
+ * <p>
26694
+ * If an element is set to be neither scalable nor rotatable, it can only be translated.
26661
26695
  *
26662
26696
  * @type Boolean
26663
26697
  * @default true
26664
26698
  * @name JXG.GeometryElement#scalable
26665
26699
  * @see JXG.Ticks#fixed
26700
+ * @see JXG.GeometryElement#rotatable
26666
26701
  */
26667
26702
  scalable: true,
26668
26703
 
26704
+ /**
26705
+ * Determines whether two-finger manipulation may rotate this object.
26706
+ * If set to false, the object can only be scaled and translated.
26707
+ * <p>
26708
+ * In case the element is a polygon or line and it has the attribute "rotatable:false",
26709
+ * moving the element with two fingers results in a rotation or translation.
26710
+ * <p>
26711
+ * If an element is set to be neither scalable nor rotatable, it can only be translated.
26712
+ *
26713
+ * @type Boolean
26714
+ * @default true
26715
+ * @name JXG.GeometryElement#rotatable
26716
+ * @see JXG.GeometryElement#scalable
26717
+ */
26718
+ rotatable: true,
26719
+
26669
26720
  /**
26670
26721
  * If the element is dragged it will be moved on mousedown or touchstart to the
26671
26722
  * top of its layer. Works only for SVG renderer and for simple elements
@@ -26737,6 +26788,7 @@ define('options',[
26737
26788
 
26738
26789
  /**
26739
26790
  * Controls if an element can get the focus with the tab key.
26791
+ * tabindex corresponds to the HTML attribute of the same name.
26740
26792
  * See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">descriptiona at MDN</a>.
26741
26793
  * The additional value null completely disables focus of an element.
26742
26794
  * The value will be ignored if keyboard control of the board is not enabled or
@@ -26766,6 +26818,8 @@ define('options',[
26766
26818
  /**
26767
26819
  * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
26768
26820
  * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
26821
+ * The tird parameter is a null, number or a string. In the latter two cases, this value is taken.
26822
+ * Returns a string.
26769
26823
  *
26770
26824
  * @type function
26771
26825
  * @name Ticks#generateLabelText
@@ -26776,7 +26830,7 @@ define('options',[
26776
26830
  * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
26777
26831
  * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
26778
26832
  *
26779
- * @deprecated Use {@link JGX.Options@generateLabelValue}
26833
+ * @deprecated Use {@link JGX.Options@generateLabelText}
26780
26834
  * @type function
26781
26835
  * @name Ticks#generateLabelValue
26782
26836
  */
@@ -28752,7 +28806,6 @@ define('options',[
28752
28806
  */
28753
28807
  lastArrow: false,
28754
28808
 
28755
-
28756
28809
  /**
28757
28810
  * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
28758
28811
  * ends exactly at the border, if negative there is a margin to the inside, if positive the line
@@ -28929,7 +28982,6 @@ define('options',[
28929
28982
  */
28930
28983
  lineCap: 'butt'
28931
28984
 
28932
-
28933
28985
  /**#@-*/
28934
28986
  },
28935
28987
 
@@ -30870,8 +30922,10 @@ define('options',[
30870
30922
  display: 'html',
30871
30923
 
30872
30924
  /**
30873
- * Anchor element {@link Point}, {@link Text} or {@link Image} of the text. If it exists, the coordinates of the text are relative
30874
- * to this anchor element.
30925
+ * Anchor element {@link Point}, {@link Text} or {@link Image} of the text.
30926
+ * If it exists, the coordinates of the text are relative
30927
+ * to this anchor element. In this case, only numbers are possible coordinates,
30928
+ * functions are not supported.
30875
30929
  *
30876
30930
  * @name anchor
30877
30931
  * @memberOf Text.prototype
@@ -38685,6 +38739,7 @@ define('base/text',[
38685
38739
 
38686
38740
  this.orgText = text;
38687
38741
  if (Type.isFunction(text)) {
38742
+ // <value> tags will not be evaluated.
38688
38743
  this.updateText = function () {
38689
38744
  resolvedText = text().toString();
38690
38745
  if (ev_p && !ev_um && !ev_uk) {
@@ -38705,14 +38760,20 @@ define('base/text',[
38705
38760
  // Convert via ASCIIMathML
38706
38761
  this.content = "'`" + text + "`'";
38707
38762
  } else if (ev_um || ev_uk) {
38708
- this.content = "'" + text + "'";
38763
+ if (ev_p) {
38764
+ this.content = this.generateTerm(text, true, true, true); // Replace value-tags
38765
+ this.content = this.content.replace(/\\/g, "\\\\");
38766
+ } else {
38767
+ this.content = "'" + text + "'";
38768
+ }
38709
38769
  } else {
38710
38770
  // Converts GEONExT syntax into JavaScript string
38711
38771
  // Short math is allowed
38712
38772
  // Avoid geonext2JS calls
38713
- this.content = this.generateTerm(text, true, true);
38773
+ this.content = this.generateTerm(text, true, true, false);
38714
38774
  }
38715
38775
  }
38776
+ // Convert JessieCode to JS function
38716
38777
  updateText = this.board.jc.snippet(this.content, true, '', false);
38717
38778
  this.updateText = function () {
38718
38779
  this.plaintext = updateText();
@@ -39068,30 +39129,43 @@ define('base/text',[
39068
39129
  /**
39069
39130
  * Converts the GEONExT syntax of the <value> terms into JavaScript.
39070
39131
  * Also, all Objects whose name appears in the term are searched and
39071
- * the text is added as child to these objects.
39132
+ * the text is added as child to these objects.
39133
+ * This method is called if the attribute parse==true is set.
39072
39134
  *
39073
39135
  * @param{String} contentStr String to be parsed
39074
39136
  * @param{Boolean} [expand] Optional flag if shortened math syntax is allowed (e.g. 3x instead of 3*x).
39075
39137
  * @param{Boolean} [avoidGeonext2JS] Optional flag if geonext2JS should be called. For backwards compatibility
39076
39138
  * this has to be set explicitely to true.
39139
+ * @param{Boolean} [outputTeX] Optional flag which has to be true if the resulting term will be sent to MathJax or KaTeX.
39140
+ * If true, "_" and "^" are NOT replaced by HTML tags sub and sup. Default: false, i.e. the replacement is done.
39141
+ * This flag allows the combination of &lt;value&gt; tag containing calculations with TeX output.
39142
+ *
39077
39143
  * @private
39078
39144
  * @see JXG.GeonextParser.geonext2JS
39079
39145
  */
39080
- generateTerm: function (contentStr, expand, avoidGeonext2JS) {
39146
+ generateTerm: function (contentStr, expand, avoidGeonext2JS, outputTeX) {
39081
39147
  var res, term, i, j,
39082
39148
  plaintext = '""';
39083
39149
 
39084
- // revert possible jc replacement
39150
+ outputTeX = outputTeX || false;
39151
+
39152
+ // Revert possible jc replacement
39085
39153
  contentStr = contentStr || '';
39086
39154
  contentStr = contentStr.replace(/\r/g, '');
39087
39155
  contentStr = contentStr.replace(/\n/g, '');
39088
39156
  contentStr = contentStr.replace(/"/g, '\'');
39089
39157
  contentStr = contentStr.replace(/'/g, "\\'");
39090
39158
 
39091
- contentStr = contentStr.replace(/&amp;arc;/g, '&ang;');
39092
- contentStr = contentStr.replace(/<arc\s*\/>/g, '&ang;');
39093
- contentStr = contentStr.replace(/&lt;arc\s*\/&gt;/g, '&ang;');
39094
- contentStr = contentStr.replace(/&lt;sqrt\s*\/&gt;/g, '&radic;');
39159
+ if (!outputTeX) {
39160
+ // Old GEONExT syntax, not (yet) supported as TeX output.
39161
+ // Otherwise, the else clause should be used.
39162
+ // That means, i.e. the <arc> tag and <sqrt> tag are not
39163
+ // converted into TeX syntax.
39164
+ contentStr = contentStr.replace(/&amp;arc;/g, '&ang;');
39165
+ contentStr = contentStr.replace(/<arc\s*\/>/g, '&ang;');
39166
+ contentStr = contentStr.replace(/&lt;arc\s*\/&gt;/g, '&ang;');
39167
+ contentStr = contentStr.replace(/&lt;sqrt\s*\/&gt;/g, '&radic;');
39168
+ }
39095
39169
 
39096
39170
  contentStr = contentStr.replace(/&lt;value&gt;/g, '<value>');
39097
39171
  contentStr = contentStr.replace(/&lt;\/value&gt;/g, '</value>');
@@ -39101,7 +39175,12 @@ define('base/text',[
39101
39175
  j = contentStr.indexOf('</value>');
39102
39176
  if (i >= 0) {
39103
39177
  while (i >= 0) {
39104
- plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr.slice(0, i))) + '"';
39178
+ if (!outputTeX) {
39179
+ plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr.slice(0, i))) + '"';
39180
+ // plaintext += ' + "' + this.replaceSub(contentStr.slice(0, i)) + '"';
39181
+ } else {
39182
+ plaintext += ' + "' + contentStr.slice(0, i) + '"';
39183
+ }
39105
39184
  term = contentStr.slice(i + 7, j);
39106
39185
  term = term.replace(/\s+/g, ''); // Remove all whitespace
39107
39186
  if (expand === true) {
@@ -39134,10 +39213,14 @@ define('base/text',[
39134
39213
  }
39135
39214
  }
39136
39215
 
39137
- plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr)) + '"';
39138
- plaintext = this.convertGeonextAndSketchometry2CSS(plaintext);
39216
+ if (!outputTeX) {
39217
+ plaintext += ' + "' + this.replaceSub(this.replaceSup(contentStr)) + '"';
39218
+ plaintext = this.convertGeonextAndSketchometry2CSS(plaintext);
39219
+ } else {
39220
+ plaintext += ' + "' + contentStr + '"';
39221
+ }
39139
39222
 
39140
- // This should replace &amp;pi; by &pi;
39223
+ // This should replace e.g. &amp;pi; by &pi;
39141
39224
  plaintext = plaintext.replace(/&amp;/g, '&');
39142
39225
  plaintext = plaintext.replace(/"/g, "'");
39143
39226
 
@@ -41294,7 +41377,7 @@ define('parser/jessiecode',[
41294
41377
  case 'node_str':
41295
41378
  //ret = node.value.replace(/\\'/, "'").replace(/\\"/, '"').replace(/\\\\/, '\\');
41296
41379
  /*jslint regexp:true*/
41297
- ret = node.value.replace(/\\(.)/, '$1');
41380
+ ret = node.value.replace(/\\(.)/g, '$1'); // Remove backslash, important in JessieCode tags
41298
41381
  /*jslint regexp:false*/
41299
41382
  break;
41300
41383
  }
@@ -44740,7 +44823,8 @@ define('base/board',[
44740
44823
  */
44741
44824
  twoFingerTouchObject: function (tar, drag, id) {
44742
44825
  var np, op, nd, od,
44743
- d, alpha,
44826
+ d,
44827
+ alpha = 0,
44744
44828
  S, t1, t3, t4, t5,
44745
44829
  ar, i, len,
44746
44830
  fixEl, moveEl, fix;
@@ -44774,7 +44858,9 @@ define('base/board',[
44774
44858
  return;
44775
44859
  }
44776
44860
 
44777
- alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
44861
+ if (Type.evaluate(drag.visProp.rotatable)) {
44862
+ alpha = Geometry.rad(op.slice(1), fix.slice(1), np.slice(1));
44863
+ }
44778
44864
 
44779
44865
  t1 = this.create('transform', [alpha, [fix[1], fix[2]]], {type: 'rotate'});
44780
44866
  t1.update();
@@ -45945,7 +46031,8 @@ define('base/board',[
45945
46031
  * @returns {Boolean}
45946
46032
  */
45947
46033
  pointerUpListener: function (evt) {
45948
- var i, j, found, touchTargets;
46034
+ var i, j, found, touchTargets,
46035
+ updateNeeded = false;
45949
46036
 
45950
46037
  this.triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
45951
46038
  this.displayInfobox(false);
@@ -45983,8 +46070,14 @@ define('base/board',[
45983
46070
  }
45984
46071
  if (!found) {
45985
46072
  this.downObjects[i].triggerEventHandlers(['touchend', 'up', 'pointerup', 'MSPointerUp'], [evt]);
45986
- // this.downObjects[i].snapToGrid();
45987
- // this.downObjects[i].snapToPoints();
46073
+ if (!Type.exists(this.downObjects[i].coords)) {
46074
+ // snapTo methods have to be called e.g. for line elements here.
46075
+ // For coordsElements there might be a conflict with
46076
+ // attractors, see commit from 2022.04.08, 11:12:18.
46077
+ this.downObjects[i].snapToGrid();
46078
+ this.downObjects[i].snapToPoints();
46079
+ updateNeeded = true;
46080
+ }
45988
46081
  this.downObjects.splice(i, 1);
45989
46082
  }
45990
46083
  }
@@ -46005,7 +46098,9 @@ define('base/board',[
46005
46098
  // this.mode = this.BOARD_MODE_NONE;
46006
46099
 
46007
46100
  // this.originMoveEnd();
46008
- // this.update();
46101
+ if (updateNeeded) {
46102
+ this.update();
46103
+ }
46009
46104
 
46010
46105
  // After one finger leaves the screen the gesture is stopped.
46011
46106
  this._pointerClearTouches();
@@ -46340,7 +46435,8 @@ define('base/board',[
46340
46435
  eps = this.options.precision.touch,
46341
46436
  tmpTouches = [], found, foundNumber,
46342
46437
  evtTouches = evt && evt[JXG.touchProperty],
46343
- touchTargets;
46438
+ touchTargets,
46439
+ updateNeeded = false;
46344
46440
 
46345
46441
  this.triggerEventHandlers(['touchend', 'up'], [evt]);
46346
46442
  this.displayInfobox(false);
@@ -46441,8 +46537,14 @@ define('base/board',[
46441
46537
  }
46442
46538
  if (!found) {
46443
46539
  this.downObjects[i].triggerEventHandlers(['touchup', 'up'], [evt]);
46444
- // this.downObjects[i].snapToGrid();
46445
- // this.downObjects[i].snapToPoints();
46540
+ if (!Type.exists(this.downObjects[i].coords)) {
46541
+ // snapTo methods have to be called e.g. for line elements here.
46542
+ // For coordsElements there might be a conflict with
46543
+ // attractors, see commit from 2022.04.08, 11:12:18.
46544
+ this.downObjects[i].snapToGrid();
46545
+ this.downObjects[i].snapToPoints();
46546
+ updateNeeded = true;
46547
+ }
46446
46548
  this.downObjects.splice(i, 1);
46447
46549
  }
46448
46550
  }
@@ -46458,7 +46560,9 @@ define('base/board',[
46458
46560
  this.updateQuality = this.BOARD_QUALITY_HIGH;
46459
46561
 
46460
46562
  this.originMoveEnd();
46461
- this.update();
46563
+ if (updateNeeded) {
46564
+ this.update();
46565
+ }
46462
46566
  }
46463
46567
 
46464
46568
  return true;
@@ -46605,11 +46709,16 @@ define('base/board',[
46605
46709
  // redraw with high precision
46606
46710
  this.updateQuality = this.BOARD_QUALITY_HIGH;
46607
46711
 
46608
- // if (this.mouse && this.mouse.obj) {
46609
- // // The parameter is needed for lines with snapToGrid enabled
46610
- // this.mouse.obj.snapToGrid(this.mouse.targets[0]);
46611
- // this.mouse.obj.snapToPoints();
46612
- // }
46712
+ if (this.mouse && this.mouse.obj) {
46713
+ if (!Type.exists(this.mouse.obj.coords)) {
46714
+ // snapTo methods have to be called e.g. for line elements here.
46715
+ // For coordsElements there might be a conflict with
46716
+ // attractors, see commit from 2022.04.08, 11:12:18.
46717
+ // The parameter is needed for lines with snapToGrid enabled
46718
+ this.mouse.obj.snapToGrid(this.mouse.targets[0]);
46719
+ this.mouse.obj.snapToPoints();
46720
+ }
46721
+ }
46613
46722
 
46614
46723
  this.originMoveEnd();
46615
46724
  this.dehighlightAll();
@@ -46665,11 +46774,18 @@ define('base/board',[
46665
46774
  },
46666
46775
 
46667
46776
  /**
46668
- * Allow moving of JSXGraph elements with arrow keys
46669
- * and zooming of the construction with + / -.
46777
+ * Allow moving of JSXGraph elements with arrow keys.
46778
+ * The selection of the element is done with the tab key. For this,
46779
+ * the attribute "tabindex" of the element has to be set to some number (default=0).
46780
+ * tabindex corresponds to the HTML attribute of the same name.
46781
+ * <p>
46670
46782
  * Panning of the construction is done with arrow keys
46671
- * if the pan key (shift or ctrl) is pressed.
46672
- * The selection of the element is done with the tab key.
46783
+ * if the pan key (shift or ctrl - depending on the board attributes) is pressed.
46784
+ * <p>
46785
+ * Zooming is triggered with the keys +, o, -, if
46786
+ * the pan key (shift or ctrl - depending on the board attributes) is pressed.
46787
+ * <p>
46788
+ * Keyboard control (move, pan, and zoom) is disabled if an HTML element of type input or textarea has received focus.
46673
46789
  *
46674
46790
  * @param {Event} evt The browser's event object
46675
46791
  *
@@ -46680,7 +46796,7 @@ define('base/board',[
46680
46796
  */
46681
46797
  keyDownListener: function (evt) {
46682
46798
  var id_node = evt.target.id,
46683
- id, el, res,
46799
+ id, el, res, doc,
46684
46800
  sX = 0,
46685
46801
  sY = 0,
46686
46802
  // dx, dy are provided in screen units and
@@ -46695,6 +46811,15 @@ define('base/board',[
46695
46811
  return false;
46696
46812
  }
46697
46813
 
46814
+ // An element of type input or textarea has foxus, get out of here.
46815
+ doc = this.containerObj.shadowRoot || document;
46816
+ if (doc.activeElement) {
46817
+ el = doc.activeElement;
46818
+ if (el.tagName === 'INPUT' || el.tagName === 'textarea') {
46819
+ return false;
46820
+ }
46821
+ }
46822
+
46698
46823
  // Get the JSXGraph id from the id of the SVG node.
46699
46824
  id = id_node.replace(this.containerObj.id + '_', '');
46700
46825
  el = this.select(id);
@@ -46703,12 +46828,15 @@ define('base/board',[
46703
46828
  actPos = el.coords.usrCoords.slice(1);
46704
46829
  }
46705
46830
 
46706
- if (Type.evaluate(this.attr.keyboard.panshift) || Type.evaluate(this.attr.keyboard.panctrl)) {
46707
- doZoom = true;
46708
- }
46709
-
46710
46831
  if ((Type.evaluate(this.attr.keyboard.panshift) && evt.shiftKey) ||
46711
46832
  (Type.evaluate(this.attr.keyboard.panctrl) && evt.ctrlKey)) {
46833
+ // Pan key has been pressed
46834
+
46835
+ if (Type.evaluate(this.attr.zoom.enabled) === true) {
46836
+ doZoom = true;
46837
+ }
46838
+
46839
+ // Arrow keys
46712
46840
  if (evt.keyCode === 38) { // up
46713
46841
  this.clickUpArrow();
46714
46842
  } else if (evt.keyCode === 40) { // down
@@ -46717,10 +46845,20 @@ define('base/board',[
46717
46845
  this.clickLeftArrow();
46718
46846
  } else if (evt.keyCode === 39) { // right
46719
46847
  this.clickRightArrow();
46848
+
46849
+ // Zoom keys
46850
+ } else if (doZoom && evt.keyCode === 171) { // +
46851
+ this.zoomIn();
46852
+ } else if (doZoom && evt.keyCode === 173) { // -
46853
+ this.zoomOut();
46854
+ } else if (doZoom && evt.keyCode === 79) { // o
46855
+ this.zoom100();
46856
+
46720
46857
  } else {
46721
46858
  done = false;
46722
46859
  }
46723
46860
  } else {
46861
+
46724
46862
  // Adapt dx, dy to snapToGrid and attractToGrid
46725
46863
  // snapToGrid has priority.
46726
46864
  if (Type.exists(el.visProp)) {
@@ -46763,14 +46901,6 @@ define('base/board',[
46763
46901
  dir = [-dx, 0];
46764
46902
  } else if (evt.keyCode === 39) { // right
46765
46903
  dir = [dx, 0];
46766
- // } else if (evt.keyCode === 9) { // tab
46767
-
46768
- } else if (doZoom && evt.key === '+') { // +
46769
- this.zoomIn();
46770
- } else if (doZoom && evt.key === '-') { // -
46771
- this.zoomOut();
46772
- } else if (doZoom && evt.key === 'o') { // o
46773
- this.zoom100();
46774
46904
  } else {
46775
46905
  done = false;
46776
46906
  }
@@ -46803,12 +46933,13 @@ define('base/board',[
46803
46933
  if (done && Type.exists(evt.preventDefault)) {
46804
46934
  evt.preventDefault();
46805
46935
  }
46806
- return true;
46936
+ return done;
46807
46937
  },
46808
46938
 
46809
46939
  /**
46810
46940
  * Event listener for SVG elements getting focus.
46811
46941
  * This is needed for highlighting when using keyboard control.
46942
+ * Only elements having the attribute "tabindex" can receive focus.
46812
46943
  *
46813
46944
  * @see JXG.Board#keyFocusOutListener
46814
46945
  * @see JXG.Board#keyDownListener
@@ -46838,6 +46969,7 @@ define('base/board',[
46838
46969
  /**
46839
46970
  * Event listener for SVG elements losing focus.
46840
46971
  * This is needed for dehighlighting when using keyboard control.
46972
+ * Only elements having the attribute "tabindex" can receive focus.
46841
46973
  *
46842
46974
  * @see JXG.Board#keyFocusInListener
46843
46975
  * @see JXG.Board#keyDownListener
@@ -46888,8 +47020,8 @@ define('base/board',[
46888
47020
  }
46889
47021
 
46890
47022
  // If div is invisible - do nothing
46891
- if (w <= 0 || h <= 0 || Type.isNaN(w) || Type.isNaN(h)) {
46892
- return;
47023
+ if (w <= 0 || h <= 0 || isNaN(w) || isNaN(h)) {
47024
+ return;
46893
47025
  }
46894
47026
 
46895
47027
  // If bounding box is not yet initialized, do it now.
@@ -48903,31 +49035,43 @@ define('base/board',[
48903
49035
  */
48904
49036
  updateCSSTransforms: function () {
48905
49037
  var obj = this.containerObj,
48906
- o = obj,
48907
- o2 = obj;
49038
+ o = obj;
49039
+ // o2 = obj;
48908
49040
 
48909
49041
  this.cssTransMat = Env.getCSSTransformMatrix(o);
48910
49042
 
49043
+ // Newer variant of walking up the tree.
49044
+ // We walk up all parent nodes and collect possible CSS transforms.
49045
+ // Works also for ShadowDOM
49046
+ o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
49047
+ while (o) {
49048
+ this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
49049
+ o = o.parentNode === o.getRootNode() ? o.parentNode.host : o.parentNode;
49050
+ }
49051
+ this.cssTransMat = Mat.inverse(this.cssTransMat);
49052
+
48911
49053
  /*
48912
49054
  * In Mozilla and Webkit: offsetParent seems to jump at least to the next iframe,
48913
49055
  * if not to the body. In IE and if we are in an position:absolute environment
48914
49056
  * offsetParent walks up the DOM hierarchy.
48915
49057
  * In order to walk up the DOM hierarchy also in Mozilla and Webkit
48916
49058
  * we need the parentNode steps.
49059
+ *
49060
+ * Seems to be outdated
48917
49061
  */
48918
- o = o.offsetParent;
48919
- while (o) {
48920
- this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
48921
-
48922
- o2 = o2.parentNode;
48923
- while (o2 !== o) {
48924
- this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
48925
- o2 = o2.parentNode || o2.host;
48926
- }
49062
+ // o = o.offsetParent;
49063
+ // while (o) {
49064
+ // this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
49065
+
49066
+ // o2 = o2.parentNode;
49067
+ // while (o2 !== o) {
49068
+ // this.cssTransMat = Mat.matMatMult(Env.getCSSTransformMatrix(o), this.cssTransMat);
49069
+ // o2 = o2.parentNode;
49070
+ // }
48927
49071
 
48928
- o = o.offsetParent;
48929
- }
48930
- this.cssTransMat = Mat.inverse(this.cssTransMat);
49072
+ // o = o.offsetParent;
49073
+ // }
49074
+ // this.cssTransMat = Mat.inverse(this.cssTransMat);
48931
49075
 
48932
49076
  return this;
48933
49077
  },
@@ -49488,16 +49632,17 @@ define('base/board',[
49488
49632
  *
49489
49633
  */
49490
49634
  toFullscreen: function (id) {
49491
- var wrap_id, wrap_node, inner_node;
49635
+ var wrap_id, wrap_node, inner_node,
49636
+ doc = this.document;
49492
49637
 
49493
49638
  id = id || this.container;
49494
49639
  this._fullscreen_inner_id = id;
49495
- inner_node = this.document.getElementById(id);
49640
+ inner_node = doc.getElementById(id);
49496
49641
  wrap_id = 'fullscreenwrap_' + id;
49497
49642
 
49498
49643
  // Wrap a div around the JSXGraph div.
49499
- if (this.document.getElementById(wrap_id)) {
49500
- wrap_node = this.document.getElementById(wrap_id);
49644
+ if (doc.getElementById(wrap_id)) {
49645
+ wrap_node = doc.getElementById(wrap_id);
49501
49646
  } else {
49502
49647
  wrap_node = document.createElement('div');
49503
49648
  wrap_node.classList.add('JXG_wrap_private');
@@ -49516,8 +49661,14 @@ define('base/board',[
49516
49661
  wrap_node.mozRequestFullScreen ||
49517
49662
  wrap_node.msRequestFullscreen;
49518
49663
 
49519
- if (wrap_node.requestFullscreen) {
49520
- wrap_node.requestFullscreen();
49664
+ if (doc.fullscreenElement === null) {
49665
+ // Start fullscreen mode
49666
+ if (wrap_node.requestFullscreen) {
49667
+ wrap_node.requestFullscreen();
49668
+ }
49669
+ } else {
49670
+ // Leave fullscreen mode (e.g. when clicking on the icon)
49671
+ document.exitFullscreen();
49521
49672
  }
49522
49673
 
49523
49674
  return this;
@@ -49531,23 +49682,24 @@ define('base/board',[
49531
49682
  * @param {Object} evt fullscreen event object (unused)
49532
49683
  */
49533
49684
  fullscreenListener: function (evt) {
49534
- var res, inner_id, inner_node;
49685
+ var res, inner_id, inner_node,
49686
+ doc = this.document;
49535
49687
 
49536
49688
  inner_id = this._fullscreen_inner_id;
49537
49689
  if (!Type.exists(inner_id)) {
49538
49690
  return;
49539
49691
  }
49540
49692
 
49541
- this.document.fullscreenElement = this.document.fullscreenElement ||
49542
- this.document.webkitFullscreenElement ||
49543
- this.document.mozFullscreenElement ||
49544
- this.document.msFullscreenElement;
49693
+ doc.fullscreenElement = doc.fullscreenElement ||
49694
+ doc.webkitFullscreenElement ||
49695
+ doc.mozFullscreenElement ||
49696
+ doc.msFullscreenElement;
49545
49697
 
49546
- inner_node = this.document.getElementById(inner_id);
49698
+ inner_node = doc.getElementById(inner_id);
49547
49699
  // If full screen mode is started we have to remove CSS margin around the JSXGraph div.
49548
49700
  // Otherwise, the positioning of the fullscreen div will be false.
49549
49701
  // When leaving the fullscreen mode, the margin is put back in.
49550
- if (this.document.fullscreenElement) {
49702
+ if (doc.fullscreenElement) {
49551
49703
  // Just entered fullscreen mode
49552
49704
 
49553
49705
  // Get the data computed in board.toFullscreen()
@@ -49559,7 +49711,7 @@ define('base/board',[
49559
49711
  // Further, the CSS margin has to be removed when in fullscreen mode,
49560
49712
  // and must be restored later.
49561
49713
  inner_node._cssFullscreenStore = {
49562
- id: this.document.fullscreenElement.id,
49714
+ id: doc.fullscreenElement.id,
49563
49715
  isFullscreen: true,
49564
49716
  margin: inner_node.style.margin,
49565
49717
  width: inner_node.style.width,
@@ -49573,18 +49725,18 @@ define('base/board',[
49573
49725
  // Do the shifting and scaling via CSS pseudo rules
49574
49726
  // We do this after fullscreen mode has been established to get the correct size
49575
49727
  // of the JSXGraph div.
49576
- Env.scaleJSXGraphDiv(document.fullscreenElement.id, inner_id, res.scale, res.vshift);
49728
+ Env.scaleJSXGraphDiv(doc.fullscreenElement.id, inner_id, res.scale, res.vshift, doc);
49577
49729
 
49578
49730
  // Clear this.document.fullscreenElement, because Safari doesn't to it and
49579
49731
  // when leaving full screen mode it is still set.
49580
- this.document.fullscreenElement = null;
49732
+ doc.fullscreenElement = null;
49581
49733
 
49582
49734
  } else if (Type.exists(inner_node._cssFullscreenStore)) {
49583
49735
  // Just left the fullscreen mode
49584
49736
 
49585
49737
  // Remove the CSS rules added in Env.scaleJSXGraphDiv
49586
49738
  try {
49587
- this.document.styleSheets[this.document.styleSheets.length - 1].deleteRule(0);
49739
+ doc.styleSheets[doc.styleSheets.length - 1].deleteRule(0);
49588
49740
  } catch (err) {
49589
49741
  console.log('JSXGraph: Could not remove CSS rules for full screen mode');
49590
49742
  }
@@ -55517,7 +55669,8 @@ define('jsxgraph',[
55517
55669
  }
55518
55670
  };
55519
55671
 
55520
- // JessieScript/JessieCode startup: Search for script tags of type text/jessiescript and interprete them.
55672
+ // JessieScript/JessieCode startup:
55673
+ // Search for script tags of type text/jessiescript and interprete them.
55521
55674
  if (Env.isBrowser && typeof window === 'object' && typeof document === 'object') {
55522
55675
  Env.addEvent(window, 'load', function () {
55523
55676
  var type, i, j, div,
@@ -76286,7 +76439,7 @@ define('base/ticks',[
76286
76439
 
76287
76440
  // if value is Number
76288
76441
  if (Type.isNumber(value)) {
76289
- labelText = (Math.round(value * 1.e13) / 1.e13).toString();
76442
+ labelText = (Math.round(value * 1.e11) / 1.e11).toString();
76290
76443
  if (labelText.length > Type.evaluate(this.visProp.maxlabellength) ||
76291
76444
  labelText.indexOf('e') !== -1) {
76292
76445
 
@@ -80979,7 +81132,7 @@ define('3d/view3d',['jxg', 'options', 'base/constants', 'utils/type', 'math/math
80979
81132
  w = size[0];
80980
81133
  h = size[1];
80981
81134
 
80982
- /**
81135
+ /*
80983
81136
  * Frame around the view object
80984
81137
  */
80985
81138
  if (false) {
@@ -81988,6 +82141,44 @@ define('3d/point3d',['jxg', 'base/constants', 'math/math', 'math/geometry', 'uti
81988
82141
  return this;
81989
82142
  };
81990
82143
 
82144
+ el.normalizeCoords3D = function () {
82145
+ if (Math.abs(el.D3.coords[0]) > Mat.eps) {
82146
+ el.D3.coords[1] /= el.D3.coords[0];
82147
+ el.D3.coords[2] /= el.D3.coords[0];
82148
+ el.D3.coords[3] /= el.D3.coords[0];
82149
+ el.D3.coords[0] = 1.0;
82150
+ }
82151
+ return this;
82152
+ };
82153
+
82154
+ el.setPosition3D = function (coords, noevent) {
82155
+ var c = el.D3.coords,
82156
+ oc = el.D3.coords.slice(); // Copy of original values
82157
+
82158
+ if (coords.length === 3) { // Euclidean coordinates
82159
+ c[0] = 1.0;
82160
+ c[1] = coords[0];
82161
+ c[2] = coords[1];
82162
+ c[3] = coords[2];
82163
+ } else { // Homogeneous coordinates (normalized)
82164
+ c[0] = coords[0];
82165
+ c[1] = coords[1];
82166
+ c[2] = coords[2];
82167
+ el.normalizeCoords3D();
82168
+ }
82169
+
82170
+ // console.log(el.emitter, !noevent, oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3]);
82171
+ // Not yet working
82172
+ if (el.emitter && !noevent &&
82173
+ (oc[0] !== c[0] || oc[1] !== c[1] || oc[2] !== c[2] || oc[3] !== c[3])) {
82174
+ this.triggerEventHandlers(['update3D'], [oc]);
82175
+ }
82176
+ return this;
82177
+ };
82178
+
82179
+ // Not yet working
82180
+ el.__evt__update3D = function (oc) { };
82181
+
81991
82182
  return el;
81992
82183
  };
81993
82184
  JXG.registerElement('point3d', ThreeD.createPoint);