1 /*
  2     Copyright 2008-2023
  3         Matthias Ehmann,
  4         Michael Gerhaeuser,
  5         Carsten Miller,
  6         Bianca Valentin,
  7         Alfred Wassermann,
  8         Peter Wilfahrt
  9 
 10     This file is part of JSXGraph.
 11 
 12     JSXGraph is free software dual licensed under the GNU LGPL or MIT License.
 13 
 14     You can redistribute it and/or modify it under the terms of the
 15 
 16       * GNU Lesser General Public License as published by
 17         the Free Software Foundation, either version 3 of the License, or
 18         (at your option) any later version
 19       OR
 20       * MIT License: https://github.com/jsxgraph/jsxgraph/blob/master/LICENSE.MIT
 21 
 22     JSXGraph is distributed in the hope that it will be useful,
 23     but WITHOUT ANY WARRANTY; without even the implied warranty of
 24     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 25     GNU Lesser General Public License for more details.
 26 
 27     You should have received a copy of the GNU Lesser General Public License and
 28     the MIT License along with JSXGraph. If not, see <https://www.gnu.org/licenses/>
 29     and <https://opensource.org/licenses/MIT/>.
 30  */
 31 
 32 /*global JXG:true, define: true*/
 33 /*jslint nomen: true, plusplus: true*/
 34 
 35 import JXG from "./jxg";
 36 import Const from "./base/constants";
 37 import Mat from "./math/math";
 38 import Color from "./utils/color";
 39 import Type from "./utils/type";
 40 
 41 /**
 42  * Options Namespace
 43  * @description These are the default options of the board and of all geometry elements.
 44  * @namespace
 45  * @name JXG.Options
 46  */
 47 JXG.Options = {
 48 
 49     jc: {
 50         enabled: true,
 51         compile: true
 52     },
 53 
 54     /*
 55      * Options that are used directly within the board class
 56      */
 57     board: {
 58         /**#@+
 59          * @visprop
 60          */
 61 
 62         //updateType: 'hierarchical', // 'all'
 63 
 64         /**
 65          * Time (in msec) between two animation steps. Used in
 66          * {@link JXG.CoordsElement#moveAlong}, {@link JXG.CoordsElement#moveTo} and
 67          * {@link JXG.CoordsElement#visit}.
 68          *
 69          * @name JXG.Board#animationDelay
 70          * @type Number
 71          * @default 35
 72          * @see JXG.CoordsElement#moveAlong
 73          * @see JXG.CoordsElement#moveTo
 74          * @see JXG.CoordsElement#visit
 75          */
 76         animationDelay: 35,
 77 
 78         /**
 79          * Show default axis.
 80          * If shown, the horizontal axis can be accessed via JXG.Board.defaultAxes.x, the
 81          * vertical axis can be accessed via JXG.Board.defaultAxes.y.
 82          * Both axes have a sub-element "defaultTicks".
 83          *
 84          * Value can be Boolean or an object containing axis attributes.
 85          *
 86          * @name JXG.Board#axis
 87          * @type Boolean
 88          * @default false
 89          */
 90         axis: false,
 91 
 92         /**
 93          * Bounding box of the visible area in user coordinates.
 94          * It is an array consisting of four values:
 95          * [x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>]
 96          *
 97          * The canvas will be spanned from the upper left corner (<sub>1</sub>, y<sub>1</sub>)
 98          * to the lower right corner (x<sub>2</sub>, y<sub>2</sub>).
 99          *
100          * @name JXG.Board#boundingBox
101          * @type Array
102          * @see JXG.Board#maxBoundingBox
103          * @see JXG.Board#keepAspectRatio
104          *
105          * @default [-5, 5, 5, -5]
106          * @example
107          * var board = JXG.JSXGraph.initBoard('jxgbox', {
108          *         boundingbox: [-5, 5, 5, -5],
109          *         axis: true
110          *     });
111          */
112         boundingBox: [-5, 5, 5, -5],
113 
114         /**
115          * Enable browser scrolling on touch interfaces if the user double taps into an empty region
116          * of the board.
117          *
118          * <ul>
119          * <li> Implemented for pointer touch devices - not with mouse, pen or old iOS touch.
120          * <li> It only works if browserPan:true
121          * <li> One finger action by the settings "pan.enabled:true" and "pan.needTwoFingers:false" has priority
122          * </ul>
123          *
124          * @name JXG.Board#browserPan
125          * @see JXG.Board#pan
126          * @type Boolean
127          * @default false
128          *
129          * @example
130          * const board = JXG.JSXGraph.initBoard('jxgbox', {
131          *     boundingbox: [-5, 5, 5, -5], axis: true,
132          *     pan: {
133          *         enabled: true,
134          *         needTwoFingers: true,
135          *     },
136          *     browserPan: true,
137          *     zoom: {
138          *         enabled: false
139          *     }
140          * });
141          *
142          * var p1 = board.create('point', [1, -1]);
143          * var p2 = board.create('point', [2.5, -2]);
144          * var li1 = board.create('line', [p1, p2]);
145          *
146          * </pre><div id="JXGcd50c814-be81-4280-9458-d73e50cece8d" class="jxgbox" style="width: 300px; height: 300px;"></div>
147          * <script type="text/javascript">
148          *     (function() {
149          *         var board = JXG.JSXGraph.initBoard('JXGcd50c814-be81-4280-9458-d73e50cece8d',
150          *             {showcopyright: false, shownavigation: false,
151          *              axis: true,
152          *              pan: {
153          *                enabled: true,
154          *                needTwoFingers: true,
155          *             },
156          *             browserPan: true,
157          *             zoom: {
158          *               enabled: false
159          *             }
160          *          });
161          *
162          *     var p1 = board.create('point', [1, -1]);
163          *     var p2 = board.create('point', [2.5, -2]);
164          *     var li1 = board.create('line', [p1, p2]);
165          *
166          *     })();
167          *
168          * </script><pre>
169          *
170          *
171          */
172         browserPan: false,
173 
174         /**
175          * Attributes for the default axes in case of the attribute
176          * axis:true in {@link JXG.JSXGraph#initBoard}.
177          *
178          * @name JXG.Board#defaultAxes
179          * @type Object
180          * @default <tt>{x: {name:'x'}, y: {name: 'y'}}</tt>
181          *
182          * @example
183          * const board = JXG.JSXGraph.initBoard('id', {
184          *     boundingbox: [-5, 5, 5, -5], axis:true,
185          *     defaultAxes: {
186          *         x: {
187          *           name: 'Distance (mi)',
188          *           withLabel: true,
189          *           label: {
190          *             position: 'rt',
191          *             offset: [-5, 15],
192          *             anchorX: 'right'
193          *           }
194          *         },
195          *         y: {
196          *           withLabel: true,
197          *           name: 'Y',
198          *           label: {
199          *             position: 'rt',
200          *             offset: [-20, -5],
201          *             anchorY: 'top'
202          *           }
203          *         }
204          *     }
205          * });
206          *
207          * </pre><div id="JXGc3af5eb8-7401-4476-80b5-379ecbd068c6" class="jxgbox" style="width: 300px; height: 300px;"></div>
208          * <script type="text/javascript">
209          *     (function() {
210          *     var board = JXG.JSXGraph.initBoard('JXGc3af5eb8-7401-4476-80b5-379ecbd068c6', {
211          *         showcopyright: false, shownavigation: false,
212          *         boundingbox: [-5, 5, 5, -5], axis:true,
213          *         defaultAxes: {
214          *             x: {
215          *               name: 'Distance (mi)',
216          *               withLabel: true,
217          *               label: {
218          *                 position: 'rt',
219          *                 offset: [-5, 15],
220          *                 anchorX: 'right'
221          *               }
222          *             },
223          *             y: {
224          *               withLabel: true,
225          *               name: 'Y',
226          *               label: {
227          *                 position: 'rt',
228          *                 offset: [-20, -5],
229          *                 anchorY: 'top'
230          *               }
231          *             }
232          *         }
233          *     });
234          *
235          *     })();
236          *
237          * </script><pre>
238          *
239          * @example
240          *  // Display ticks labels as fractions
241          *  var board = JXG.JSXGraph.initBoard('jxgbox', {
242          *      boundingbox: [-1.2, 2.3, 1.2, -2.3],
243          *      axis: true,
244          *      defaultAxes: {
245          *          x: {
246          *              ticks: {
247          *                  label: {
248          *                      useMathJax: true,
249          *                      display: 'html',
250          *                      toFraction: true
251          *                  }
252          *              }
253          *          },
254          *          y: {
255          *              ticks: {
256          *                  label: {
257          *                      useMathJax: true,
258          *                      display: 'html',
259          *                      toFraction: true
260          *                  }
261          *              }
262          *          }
263          *      }
264          *  });
265          *
266          * </pre><div id="JXG484d2f00-c853-4acb-a8bd-46a9e232d13b" class="jxgbox" style="width: 300px; height: 300px;"></div>
267          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
268          * <script type="text/javascript">
269          *     (function() {
270          *         var board = JXG.JSXGraph.initBoard('JXG484d2f00-c853-4acb-a8bd-46a9e232d13b',
271          *             {boundingbox: [-1.2, 2.3, 1.2, -2.3],
272          *              axis: true, showcopyright: false, shownavigation: true,
273          *                 defaultAxes: {
274          *                     x: {
275          *                         ticks: {
276          *                             label: {
277          *                                 useMathJax: true,
278          *                                 display: 'html',
279          *                                 toFraction: true
280          *                             }
281          *                         }
282          *                     },
283          *                     y: {
284          *                         ticks: {
285          *                             label: {
286          *                                 useMathJax: true,
287          *                                 display: 'html',
288          *                                 toFraction: true
289          *                             }
290          *                         }
291          *                     }
292          *                 }
293          *             });
294          *     })();
295          *
296          * </script><pre>
297          *
298          */
299         defaultAxes: {
300             x: {
301                 name: 'x',
302                 fixed: true,
303                 ticks: {
304                     label: {
305                         visible: 'inherit',
306                         anchorX: 'middle',
307                         anchorY: 'top',
308                         fontSize: 12,
309                         offset: [0, -3]
310                     },
311                     tickEndings: [0, 1],
312                     majorTickEndings: [1, 1],
313                     drawZero: false,
314                     needsRegularUpdate: false,
315                     visible: 'inherit'
316                 }
317             },
318             y: {
319                 name: 'y',
320                 fixed: true,
321                 ticks: {
322                     label: {
323                         visible: 'inherit',
324                         anchorX: 'right',
325                         anchorY: 'middle',
326                         fontSize: 12,
327                         offset: [-6, 0]
328                     },
329                     tickEndings: [1, 0],
330                     majorTickEndings: [1, 1],
331                     drawZero: false,
332                     needsRegularUpdate: false,
333                     visible: 'inherit'
334                 }
335             }
336         },
337 
338         /**
339          * Description string for the board.
340          * Primarily used in an invisible text element which is adressed by
341          * the attribute 'aria-describedby' from the JSXGraph container.
342          * JSXGraph creates a new div-element with id "{containerid}_ARIAdescription"
343          * containing this string.
344          *
345          * @name JXG.Board#description
346          * @see JXG.Board#title
347          * @type String
348          * @default ''
349          *
350          */
351         description: '',
352 
353         /**
354          * Supply the document object. Defaults to window.document
355          *
356          * @name JXG.Board#document
357          * @type Object
358          * @description DOM object
359          * @default false (meaning window.document)
360          */
361         document: false,
362 
363         /**
364          * Control the possibilities for dragging objects.
365          *
366          * Possible sub-attributes with default values are:
367          * <pre>
368          * drag: {
369          *   enabled: true   // Allow dragging
370          * }
371          * </pre>
372          *
373          * @name JXG.Board#drag
374          * @type Object
375          * @default <tt>{enabled: true}</tt>
376          */
377         drag: {
378             enabled: true
379         },
380 
381         /**
382          * Attribute(s) to control the fullscreen icon. The attribute "showFullscreen"
383          * controls if the icon is shown.
384          * The following attribute(s) can be set:
385          * <ul>
386          *  <li> symbol (String): Unicode symbol which is shown in the navigation bar.  Default: svg code for '\u26f6', other
387          * possibilities are the unicode symbols '\u26f6' and '\u25a1'. However, '\u26f6' is not supported by MacOS and iOS.
388          *  <li> scale (number between 0 and 1): Relative size of the larger side of the JSXGraph board in the fullscreen window. 1.0 gives full width or height.
389          * Default value is 0.85.
390          *  <li> id (String): Id of the HTML element which is brought to full screen or null if the JSXgraph div is taken.
391          * It may be an outer div element, e.g. if the old aspect ratio trick is used. Default: null, i.e. use the JSXGraph div.
392          * </ul>
393          *
394          * @example
395          * var board = JXG.JSXGraph.initBoard('35bec5a2-fd4d-11e8-ab14-901b0e1b8723',
396          *             {boundingbox: [-8, 8, 8,-8], axis: true,
397          *             showcopyright: false,
398          *             showFullscreen: true,
399          *             fullscreen: {
400          *                  symbol: '\u22c7',
401          *                  scale: 0.95
402          *              }
403          *             });
404          * var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});
405          *
406          * </pre><div id="JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723" class="jxgbox" style="width: 300px; height: 300px;"></div>
407          * <script type="text/javascript">
408          *     (function() {
409          *         var board = JXG.JSXGraph.initBoard('JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723',
410          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false,
411          *              showFullscreen: true,
412          *              fullscreen: {
413          *                  symbol: '\u22c7',
414          *                  scale: 0.95
415          *                  }
416          *             });
417          *     var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});
418          *     })();
419          *
420          * </script><pre>
421          *
422          * @name JXG.Board#fullscreen
423          * @default svg code
424          * @see JXG.Board#showFullscreen
425          * @see JXG.AbstractRenderer#drawNavigationBar
426          * @type Object
427          */
428         fullscreen: {
429             symbol: '<svg height="1em" width="1em" version="1.1" viewBox="10 10 18 18"><path fill="#666" d="m 10,16 2,0 0,-4 4,0 0,-2 L 10,10 l 0,6 0,0 z"></path><path fill="#666" d="m 20,10 0,2 4,0 0,4 2,0 L 26,10 l -6,0 0,0 z"></path><path fill="#666" d="m 24,24 -4,0 0,2 L 26,26 l 0,-6 -2,0 0,4 0,0 z"></path><path fill="#666" d="M 12,20 10,20 10,26 l 6,0 0,-2 -4,0 0,-4 0,0 z"></path></svg>',
430             // symbol: '\u26f6', // '\u26f6' (not supported by MacOS),
431             scale: 0.85,
432             id: null
433         },
434 
435         /**
436          * If set true and
437          * hasPoint() is true for both an element and it's label,
438          * the element (and not the label) is taken as drag element.
439          * <p>
440          * If set false and hasPoint() is true for both an element and it's label,
441          * the label is taken (if it is on a higher layer than the element)
442          * <p>
443          * Meanwhile, this feature might be irrelevant.
444          * @name JXG.Board#ignoreLabels
445          * @type Booelan
446          * @default true
447          */
448         ignoreLabels: true,
449 
450         /**
451          * Support for internationalization of number formatting. This affects
452          * <ul>
453          *  <li> axis labels
454          *  <li> infobox
455          *  <li> texts consisting of numbers only
456          *  <li> smartlabel elements
457          *  <li> slider labels
458          *  <li> tapemeasure elements
459          *  <li> integral element labels
460          * </ul>
461          * See <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat</a>
462          * for an overview on the possibilities and the options.
463          * <p>
464          * User generated texts consisting of texts AND numbers have to be internationalized by the user, see
465          * {@link Text#intl}.
466          * Language locale and options can be individually controlled for each element by its intl attribute.
467          * If no locale is set, the default language of the browser is used.
468          *
469          * @name JXG.Board#intl
470          * @type Object
471          * @default <tt>{enabled: false}</tt>
472          * @see Integral#label
473          * @see Slider#intl
474          * @see Text#intl
475          * @see Ticks#intl
476          * @see JXG.Board.infobox
477          *
478          * @example
479          * // Set the board-wide locale and use individual
480          * // options for a text.
481          * const board = JXG.JSXGraph.initBoard(BOARDID, {
482          *     axis: true,
483          *     intl: {
484          *         enabled: true,
485          *         locale: 'de-DE'
486          *     },
487          *     boundingbox:[-0.5, 0.5, 0.5, -0.5]
488          * });
489          *
490          * var t = board.create('text', [0.05, 0.2, -Math.PI*100], {
491          *         digits: 2,
492          *         intl: {
493          *                 enabled: true,
494          *                 options: {
495          *                     style: 'unit',
496          *                     unit: 'celsius'
497          *                 }
498          *             }
499          *     });
500          *
501          * </pre><div id="JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9" class="jxgbox" style="width: 300px; height: 300px;"></div>
502          * <script type="text/javascript">
503          *     (function() {
504          *     var board = JXG.JSXGraph.initBoard('JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9', {
505          *         axis: true, showcopyright: false, shownavigation: false,
506          *         intl: {
507          *             enabled: true,
508          *             locale: 'de-DE'
509          *         },
510          *     boundingbox:[-0.5, 0.5, 0.5, -0.5]
511          *     });
512          *     var t = board.create('text', [0.05, 0.2, -Math.PI*100], {
513          *         digits: 2,
514          *         intl: {
515          *                 enabled: true,
516          *                 options: {
517          *                     style: 'unit',
518          *                     unit: 'celsius'
519          *                 }
520          *             }
521          *     });
522          *
523          *     })();
524          *
525          * </script><pre>
526          *
527          * @example
528          * // Here, locale is disabled in general, but enabled for the horizontal
529          * // axis and the infobox.
530          * const board = JXG.JSXGraph.initBoard(BOARDID, {
531          *     boundingbox: [-0.5, 0.5, 0.5, -0.5],
532          *     intl: {
533          *         enabled: false,
534          *         locale: 'de-DE'
535          *     },
536          *     keepaspectratio: true,
537          *     axis: true,
538          *     defaultAxes: {
539          *         x: {
540          *             ticks: {
541          *                 intl: {
542          *                         enabled: true,
543          *                         options: {
544          *                             style: 'unit',
545          *                             unit: 'kilometer-per-hour',
546          *                             unitDisplay: 'narrow'
547          *                         }
548          *                 }
549          *             }
550          *         },
551          *         y: {
552          *             ticks: {
553          *             }
554          *         }
555          *     },
556          *     infobox: {
557          *         fontSize: 12,
558          *         intl: {
559          *             enabled: true,
560          *             options: {
561          *                 minimumFractionDigits: 4,
562          *                 maximumFractionDigits: 5
563          *             }
564          *         }
565          *     }
566          * });
567          *
568          * var p = board.create('point', [0.1, 0.1], {});
569          *
570          * </pre><div id="JXG07d5d95c-9324-4fc4-aad3-098e433f195f" class="jxgbox" style="width: 600px; height: 300px;"></div>
571          * <script type="text/javascript">
572          *     (function() {
573          *     var board = JXG.JSXGraph.initBoard('JXG07d5d95c-9324-4fc4-aad3-098e433f195f', {
574          *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,
575          *         intl: {
576          *             enabled: false,
577          *             locale: 'de-DE'
578          *         },
579          *         keepaspectratio: true,
580          *         axis: true,
581          *         defaultAxes: {
582          *             x: {
583          *                 ticks: {
584          *                     intl: {
585          *                             enabled: true,
586          *                             options: {
587          *                                 style: 'unit',
588          *                                 unit: 'kilometer-per-hour',
589          *                                 unitDisplay: 'narrow'
590          *                             }
591          *                     }
592          *                 }
593          *             },
594          *             y: {
595          *                 ticks: {
596          *                 }
597          *             }
598          *         },
599          *         infobox: {
600          *             fontSize: 12,
601          *             intl: {
602          *                 enabled: true,
603          *                 options: {
604          *                     minimumFractionDigits: 4,
605          *                     maximumFractionDigits: 5
606          *                 }
607          *             }
608          *         }
609          *     });
610          *
611          *     var p = board.create('point', [0.1, 0.1], {});
612          *
613          *     })();
614          *
615          * </script><pre>
616          *
617          */
618         intl: {
619             enabled: false
620         },
621 
622         /**
623          * If set to true, the ratio between horizontal and vertical unit sizes
624          * stays constant - independent of size changes of the hosting HTML div element.
625          * <p>
626          * If the aspect ration of the hosting div changes, JSXGraphs will change
627          * the user supplied bounding box accordingly.
628          * This is necessary if circles should look like circles and not
629          * like ellipses. It is recommended to set keepAspectRatio = true
630          * for geometric applets.
631          * <p>
632          * For function plotting keepAspectRatio = false
633          * might be the better choice.
634          *
635          * @name JXG.Board#keepAspectRatio
636          * @see JXG.Board#boundingBox
637          * @see JXG.Board#maxBoundingBox
638          * @see JXG.Board#setBoundingBox
639          * @type Boolean
640          * @default false
641          */
642         keepAspectRatio: false,
643 
644         /**
645          * Control using the keyboard to change the construction.
646          * <ul>
647          * <li> enabled: true / false
648          * <li> dx: horizontal shift amount per key press
649          * <li> dy: vertical shift amount per key press
650          * <li> panShift: zoom if shift key is pressed
651          * <li> panCtrl: zoom if ctrl key is pressed
652          * </ul>
653          *
654          * @example
655          * var board = JXG.JSXGraph.initBoard("jxgbox", {boundingbox: [-5,5,5,-5],
656          *     axis: true,
657          *     showCopyright:true,
658          *     showNavigation:true,
659          *     keyboard: {
660          *         enabled: true,
661          *         dy: 30,
662          *         panShift: true,
663          *         panCtrl: false
664          *     }
665          * });
666          *
667          * </pre><div id="JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266" class="jxgbox" style="width: 300px; height: 300px;"></div>
668          * <script type="text/javascript">
669          *     (function() {
670          *         var board = JXG.JSXGraph.initBoard('JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266',
671          *             {boundingbox: [-5,5,5,-5],
672          *         axis: true,
673          *         showCopyright:true,
674          *         showNavigation:true,
675          *         keyboard: {
676          *             enabled: true,
677          *             dy: 30,
678          *             panShift: true,
679          *             panCtrl: false
680          *         }
681          *     });
682          *
683          *     })();
684          *
685          * </script><pre>
686          *
687          *
688          * @see JXG.Board#keyDownListener
689          * @see JXG.Board#keyFocusInListener
690          * @see JXG.Board#keyFocusOutListener
691          *
692          * @name JXG.Board#keyboard
693          * @type Object
694          * @default <tt>{enabled: true, dx: 10, dy:10, panShift: true, panCtrl: false}</tt>
695          */
696         keyboard: {
697             enabled: true,
698             dx: 10,
699             dy: 10,
700             panShift: true,
701             panCtrl: false
702         },
703 
704         /**
705          * If enabled, user activities are logged in array "board.userLog".
706          *
707          * @name JXG.Board#logging
708          * @type Object
709          * @default <tt>{enabled: false}</tt>
710          *
711          * @example
712          * var board = JXG.JSXGraph.initBoard(BOARDID,
713          *          {
714          *              boundingbox: [-8, 8, 8,-8],
715          *              axis: true,
716          *              logging: {enabled: true},
717          *              showcopyright: false,
718          *              shownavigation: false
719          *          });
720          * var A = board.create('point', [-4, 0], { name: 'A' });
721          * var B = board.create('point', [1, 2], { name: 'B' });
722          * var showUserLog = function() {
723          *     var txt = '';
724          *
725          *     for (let i = 0; i < board.userLog.length; i++) {
726          *         txt += JSON.stringify(board.userLog[i]) + '\n';
727          *     }
728          *     alert(txt);
729          * };
730          * var but = board.create('button', [4, 4, 'Show user log', showUserLog]);
731          *
732          * </pre><div id="JXGe152375c-f478-41aa-a9e6-e104403fc75d" class="jxgbox" style="width: 300px; height: 300px;"></div>
733          * <script type="text/javascript">
734          *     (function() {
735          *         var board = JXG.JSXGraph.initBoard('JXGe152375c-f478-41aa-a9e6-e104403fc75d',
736          *             {boundingbox: [-8, 8, 8,-8], axis: true, logging: {enabled: true},
737          *              showcopyright: false, shownavigation: false});
738          *     var A = board.create('point', [-4, 0], { name: 'A' });
739          *     var B = board.create('point', [1, 2], { name: 'B' });
740          *     var showUserLog = function() {
741          *         var txt = '';
742          *
743          *         for (let i = 0; i < board.userLog.length; i++) {
744          *             txt += JSON.stringify(board.userLog[i]) + '\n';
745          *         }
746          *         alert(txt);
747          *     };
748          *     var but = board.create('button', [4, 4, 'Show user log', showUserLog]);
749          *
750          *     })();
751          *
752          * </script><pre>
753          *
754          *
755          * @see JXG.Board#userLog
756          */
757         logging: {
758             enabled: false
759         },
760 
761         /**
762          * Change redraw strategy in SVG rendering engine.
763          * <p>
764          * This optimization seems to be <b>obsolete</b> in newer browsers (from 2021 on, at least)
765          * and even slow down the constructions. Therefore, the default is set to 'none' since v1.2.4.
766          * <p>
767          * If set to 'svg', before every redrawing of the JSXGraph construction
768          * the SVG sub-tree of the DOM tree is taken out of the DOM.
769          *
770          * If set to 'all', before every redrawing of the JSXGraph construction the
771          * complete DOM tree is taken out of the DOM.
772          * If set to 'none' the redrawing is done in-place.
773          *
774          * Using 'svg' or 'all' speeds up the update process considerably. The risk
775          * is that if there is an exception, only a white div or window is left.
776          *
777          *
778          * @name JXG.Board#minimizeReflow
779          * @type String
780          * @default 'none'
781          */
782         minimizeReflow: 'none',
783 
784         /**
785          * Maximal bounding box of the visible area in user coordinates.
786          * It is an array consisting of four values:
787          * [x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>]
788          *
789          * The bounding box of the canvas must be inside of this maximal
790          * bounding box.
791          *
792          * @name JXG.Board#maxBoundingBox
793          * @type Array
794          * @see JXG.Board#boundingBox
795          * @default [-Infinity, Infinity, Infinity, -Infinity]
796          *
797          * @example
798          * var board = JXG.JSXGraph.initBoard('jxgbox', {
799          *         boundingBox: [-5, 5, 5, -5],
800          *         maxBoundingBox: [-8, 8, 8, -8],
801          *         pan: {enabled: true},
802          *         axis: true
803          *     });
804          *
805          * </pre><div id="JXG065e2750-217c-48ed-a52b-7d7df6de7055" class="jxgbox" style="width: 300px; height: 300px;"></div>
806          * <script type="text/javascript">
807          *     (function() {
808          *         var board = JXG.JSXGraph.initBoard('JXG065e2750-217c-48ed-a52b-7d7df6de7055', {
809          *             showcopyright: false, shownavigation: false,
810          *             boundingbox: [-5,5,5,-5],
811          *             maxboundingbox: [-8,8,8,-8],
812          *             pan: {enabled: true},
813          *             axis:true
814          *         });
815          *
816          *     })();
817          *
818          * </script><pre>
819          *
820          */
821         maxBoundingBox: [-Infinity, Infinity, Infinity, -Infinity],
822 
823         /**
824          * Maximum frame rate of the board, i.e. maximum number of updates per second
825          * triggered by move events.
826          *
827          * @name JXG.Board#maxFrameRate
828          * @type Number
829          * @default 40
830          */
831         maxFrameRate: 40,
832 
833         /**
834          * Maximum number of digits in automatic label generation.
835          * For example, if set to 1 automatic point labels end at "Z".
836          * If set to 2, point labels end at "ZZ".
837          *
838          * @name JXG.Board#maxNameLength
839          * @see JXG.Board#generateName
840          * @type Number
841          * @default 1
842          */
843         maxNameLength: 1,
844 
845         /**
846          * Element which listens to move events of the pointing device.
847          * This allows to drag elements of a JSXGraph construction outside of the board.
848          * Especially, on mobile devices this enhances the user experience.
849          * However, it is recommended to allow dragging outside of the JSXGraph board only
850          * in certain constructions where users may not "loose" points outside of the board.
851          * In such a case, points may become unreachable.
852          * <p>
853          * A situation where dragging outside of the board is uncritical is for example if
854          * only sliders are used to interact with the construction.
855          * <p>
856          * Possible values for this attributes are:
857          * <ul>
858          * <li> an element specified by document.getElementById('some id');
859          * <li> null: to use the JSXGraph container div element
860          * <li> document
861          * </ul>
862          * <p>
863          * Since the introduction of this attribute "moveTarget", the value "document" has become sort of
864          * default on touch devices like smartphones. However, it is no longer the case that the document listens to
865          * move events, but there is the new feature "setPointerCapture", which is also implicitly enabled on certain devices.
866          * In future versions, JSXGraph may adopt this new standard and distinguish only two cases:
867          * <ul>
868          * <li>null: no pointerCapture
869          * <li>document: use pointerCapture
870          * </ul>
871          * <p>
872          * This attribute is immutable.
873          * It can be changed as follows:
874          *
875          * @example
876          * board.setAttribute({moveTarget: null});
877          * board.removeEventHandlers();
878          * board.addEventHandlers();
879          *
880          * @name JXG.Board#moveTarget
881          * @type Object
882          * @description HTML node or document
883          * @default null
884          *
885          * @example
886          *     var board = JXG.JSXGraph.initBoard('jxgbox', {
887          *         boundingbox: [-5,5,5,-5],
888          *         axis: true,
889          *         moveTarget: document
890          *     });
891          *
892          * </pre><div id="JXG973457e5-c63f-4516-8570-743f2cc560e1" class="jxgbox" style="width: 300px; height: 300px;"></div>
893          * <script type="text/javascript">
894          *     (function() {
895          *         var board = JXG.JSXGraph.initBoard('JXG973457e5-c63f-4516-8570-743f2cc560e1',
896          *             {boundingbox: [-5,5,5,-5],
897          *             axis: true,
898          *             moveTarget: document
899          *         });
900          *
901          *     })();
902          *
903          * </script><pre>
904          *
905          *
906          */
907         moveTarget: null,
908 
909         /**
910          * A number that will be added to the absolute position of the board used in mouse coordinate
911          * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.
912          *
913          * @name JXG.Board#offsetX
914          * @see JXG.Board#offsetY
915          * @type Number
916          * @default 0
917          */
918         offsetX: 0,
919 
920         /**
921          * A number that will be added to the absolute position of the board used in mouse coordinate
922          * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.
923          *
924          * @name JXG.Board#offsetY
925          * @see JXG.Board#offsetX
926          * @type Number
927          * @default 0
928          */
929         offsetY: 0,
930 
931         /**
932          * Control the possibilities for panning interaction (i.e. moving the origin).
933          *
934          * Possible sub-attributes with default values are:
935          * <pre>
936          * pan: {
937          *   enabled: true   // Allow panning
938          *   needTwoFingers: false, // panning is done with two fingers on touch devices
939          *   needShift: true, // mouse panning needs pressing of the shift key
940          * }
941          * </pre>
942          *
943          * @name JXG.Board#pan
944          * @see JXG.Board#browserPan
945          *
946          * @type Object
947          */
948         pan: {
949             enabled: true,
950             needShift: true,
951             needTwoFingers: false
952         },
953 
954         /**
955          * Allow user interaction by registering pointer events (including mouse and
956          * touch events), fullscreen, keyboard, resize, and zoom events.
957          * The latter events are essentially mouse wheel events.
958          * Decide if JSXGraph listens to these events.
959          * <p>
960          * Using a Boolean value turns on all events (or not), supplying an object of
961          * the form
962          * <pre>
963          *  {
964          *     fullscreen: true / false,
965          *     keyboard: true / false,
966          *     pointer: true / false,
967          *     resize: true / false,
968          *     wheel: true / false
969          *  }
970          * </pre>
971          * activates individual event handlers. If an event is NOT given,
972          * it will be activated.
973          * <p>This attribute is immutable. Please use
974          * {@link JXG.Board#addEventHandlers()} and
975          * {@link JXG.Board#removeEventHandlers()} directly.
976          *
977          * @name JXG.Board#registerEvents
978          * @see JXG.Board#keyboard
979          * @see JXG.Board#registerResizeEvent
980          * @see JXG.Board#registerFullscreenEvent
981          * @type Boolean
982          * @default true
983          */
984         registerEvents: true,
985 
986         // /**
987         //  * Listen to fullscreen event.
988         //  *
989         //  * <p>This attribute is immutable. Please use
990         //  * {@link JXG.Board#addFullscreenEventHandlers()} and
991         //  * {@link JXG.Board#removeEventHandlers()} directly.
992         //  *
993         //  * @name JXG.Board#registerFullscreenEvent
994         //  * @see JXG.Board#registerEvents
995         //  * @see JXG.Board#registerResizeEvent
996         //  * @type Boolean
997         //  * @default true
998         //  */
999         // registerFullscreenEvent: true,
1000 
1001         // /**
1002         //  * Listen to resize events, i.e. start "resizeObserver" or handle the resize event with
1003         //  * "resizeListener". This is independent from the mouse, touch, pointer events.
1004         //  *
1005         //  * <p>This attribute is immutable. Please use
1006         //  * {@link JXG.Board#addResizeEventHandlers()} and
1007         //  * {@link JXG.Board#removeEventHandlers()} directly.
1008         //  * <p>
1009         //  * This attribute just starts a resizeObserver. If the resizeObserver reacts
1010         //  * to size changed is controled wuth {@link JXG.Board#resize}.
1011         //  *
1012         //  * @name JXG.Board#registerResizeEvent
1013         //  * @see JXG.Board#resize
1014         //  * @see JXG.Board#registerEvents
1015         //  * @see JXG.Board#registerFullscreenEvent
1016         //  * @type Boolean
1017         //  * @default true
1018         //  */
1019         // registerResizeEvent: true,
1020 
1021         /**
1022          * Default rendering engine. Possible values are 'svg', 'canvas', 'vml', 'no', or 'auto'.
1023          * If the rendering engine is not available JSXGraph tries to detect a different engine.
1024          *
1025          * <p>
1026          * In case of 'canvas' it is advisable to call 'board.update()' after all elements have been
1027          * constructed. This ensures that all elements are drawn with their intended visual appearance.
1028          *
1029          * <p>
1030          * This attribute is immutable.
1031          *
1032          * @name JXG.Board#renderer
1033          * @type String
1034          * @default 'auto'
1035          */
1036         renderer: 'auto',
1037 
1038         /**
1039          * Control if JSXGraph reacts to resizing of the JSXGraph container element
1040          * by the user / browser.
1041          * The attribute "throttle" determines the minimal time in msec between to
1042          * resize calls.
1043          *
1044          * @see JXG.Board#startResizeObserver
1045          * @see JXG.Board#resizeListener
1046          *
1047          * @name JXG.Board#resize
1048          * @type Object
1049          * @default <tt>{enabled: true, throttle: 10}</tt>
1050          *
1051          * @example
1052          *     var board = JXG.JSXGraph.initBoard('jxgbox', {
1053          *         boundingbox: [-5,5,5,-5],
1054          *         keepAspectRatio: true,
1055          *         axis: true,
1056          *         resize: {enabled: true, throttle: 200}
1057          *     });
1058          *
1059          * </pre><div id="JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3" class="jxgbox" style="width: 300px; height: 300px;"></div>
1060          * <script type="text/javascript">
1061          *     (function() {
1062          *         var board = JXG.JSXGraph.initBoard('JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3', {
1063          *             boundingbox: [-5,5,5,-5],
1064          *             keepAspectRatio: true,
1065          *             axis: true,
1066          *             resize: {enabled: true, throttle: 200}
1067          *         });
1068          *
1069          *     })();
1070          *
1071          * </script><pre>
1072          *
1073          *
1074          */
1075         resize: {
1076             enabled: true,
1077             throttle: 10
1078         },
1079 
1080         /**
1081          * Attributes to control the screenshot function.
1082          * The following attributes can be set:
1083          * <ul>
1084          *  <li>scale: scaling factor (default=1.0)
1085          *  <li>type: format of the screenshot image. Default: png
1086          *  <li>symbol: Unicode symbol which is shown in the navigation bar. Default: '\u2318'
1087          *  <li>css: CSS rules to format the div element containing the screen shot image
1088          *  <li>cssButton: CSS rules to format the close button of the div element containing the screen shot image
1089          * </ul>
1090          * The screenshot will fail if the board contains text elements or foreign objects
1091          * containing SVG again.
1092          *
1093          * @name JXG.Board#screenshot
1094          * @type Object
1095          */
1096         screenshot: {
1097             scale: 1,
1098             type: 'png',
1099             symbol: '\u2318', //'\u22b9', //'\u26f6',
1100             css: 'background-color:#eeeeee; opacity:1.0; border:2px solid black; border-radius:10px; text-align:center',
1101             cssButton: 'padding: 4px 10px; border: solid #356AA0 1px; border-radius: 5px; position: absolute; right: 2ex; top: 2ex; background-color: rgba(255, 255, 255, 0.3);'
1102         },
1103 
1104         /**
1105          * Control the possibilities for a selection rectangle.
1106          * Starting a selection event triggers the "startselecting" event.
1107          * When the mouse pointer is released, the "stopselecting" event is fired.
1108          * The "stopselecting" event is supplied by the user.
1109          * <p>
1110          * So far it works in SVG renderer only.
1111          * <p>
1112          * Possible sub-attributes with default values are:
1113          * <pre>
1114          * selection: {
1115          *   enabled: false,
1116          *   name: 'selectionPolygon',
1117          *   needShift: false,  // mouse selection needs pressing of the shift key
1118          *   needCtrl: true,    // mouse selection needs pressing of the shift key
1119          *   fillColor: '#ffff00'
1120          * }
1121          * </pre>
1122          * <p>
1123          * Board events triggered by selection manipulation:
1124          * 'startselecting', 'stopselecting', 'mousestartselecting', 'mousestopselecting',
1125          * 'pointerstartselecting', 'pointerstopselecting', 'touchstartselecting', 'touchstopselecting'.
1126          *
1127          * @example
1128          * board.on('stopselecting', function(){
1129          *     var box = board.stopSelectionMode(),
1130          *     // bbox has the coordinates of the selectionr rectangle.
1131          *     // Attention: box[i].usrCoords have the form [1, x, y], i.e.
1132          *     // are homogeneous coordinates.
1133          *     bbox = box[0].usrCoords.slice(1).concat(box[1].usrCoords.slice(1));
1134          *     // Set a new bounding box
1135          *     board.setBoundingBox(bbox, false);
1136          * });
1137          *
1138          * @name JXG.Board#selection
1139          *
1140          * @see JXG.Board#startSelectionMode
1141          * @see JXG.Board#stopSelectionMode
1142          *
1143          * @type Object
1144          * @default
1145          */
1146         selection: {
1147             enabled: false,
1148             name: 'selectionPolygon',
1149             needShift: false,
1150             needCtrl: true,
1151             fillColor: '#ffff00',
1152 
1153             // immutable:
1154             visible: false,
1155             withLines: false,
1156             vertices: {
1157                 visible: false
1158             }
1159         },
1160 
1161         /**
1162          * Show a button which allows to clear all traces of a board.
1163          * This button can be accessed by JavaScript or CSS with
1164          * the ID <tt>"{board_id}_navigation_button_cleartraces"</tt> or by the CSS classes
1165          * <tt>JXG_navigation_button"</tt> or
1166          * <tt>JXG_navigation_button_cleartraces"</tt>.
1167          *
1168          * @name JXG.Board#showClearTraces
1169          * @type Boolean
1170          * @default false
1171          * @see JXG.AbstractRenderer#drawNavigationBar
1172          */
1173         showClearTraces: false,
1174 
1175         /**
1176          * Show copyright string in canvas.
1177          *
1178          * @name JXG.Board#showCopyright
1179          * @type Boolean
1180          * @default true
1181          */
1182         showCopyright: true,
1183 
1184         /**
1185          * Show a button in the navigation bar to start fullscreen mode.
1186          * This button can be accessed by JavaScript or CSS with
1187          * the ID <tt>"{board_id}_navigation_button_fullscreen"</tt> or by the CSS classes
1188          * <tt>JXG_navigation_button"</tt> or
1189          * <tt>JXG_navigation_button_fullscreen"</tt>.
1190          *
1191          * @name JXG.Board#showFullscreen
1192          * @type Boolean
1193          * @see JXG.Board#fullscreen
1194          * @default false
1195          * @see JXG.AbstractRenderer#drawNavigationBar
1196          * @see JXG.AbstractRenderer#drawNavigationBar
1197          */
1198         showFullscreen: false,
1199 
1200         /**
1201          * If true, the infobox is shown on mouse/pen over for all points
1202          * which have set their attribute showInfobox to 'inherit'.
1203          * If a point has set its attribute showInfobox to false or true,
1204          * that value will have priority over this value.
1205          *
1206          * @name JXG.Board#showInfobox
1207          * @see Point#showInfobox
1208          * @type Boolean
1209          * @default true
1210          */
1211         showInfobox: true,
1212 
1213         /**
1214          * Display of navigation arrows and zoom buttons in the navigation bar.
1215          * <p>
1216          * The navigation bar has the
1217          * the ID <tt>"{board_id}_navigation"</tt> and the CSS class
1218          * <tt>JXG_navigation"</tt>.
1219          * The individual buttons can be accessed by JavaScript or CSS with
1220          * the ID <tt>"{board_id}_navigation_button_{type}"</tt> or by the CSS classes
1221          * <tt>JXG_navigation_button"</tt> or
1222          * <tt>JXG_navigation_button_{type}"</tt>, where <tt>{type}</tt>
1223          * is one of <tt>left</tt>, <tt>right</tt>, or <tt>up</tt>, <tt>down</tt>,
1224          * <tt>in</tt>, <tt>100</tt>, or <tt>out</tt>,
1225          * <tt>fullscreen</tt>, <tt>screenshot</tt>, <tt>cleartraces</tt>, <tt>reload</tt>.
1226          *
1227          * @name JXG.Board#showNavigation
1228          * @type Boolean
1229          * @default true
1230          * @see JXG.AbstractRenderer#drawNavigationBar
1231          */
1232         showNavigation: true,
1233 
1234         /**
1235          * Show a button in the navigation bar to force reload of a construction.
1236          * Works only with the JessieCode tag.
1237          * This button can be accessed by JavaScript or CSS with
1238          * the ID <tt>"{board_id}_navigation_button_reload"</tt> or by the CSS classes
1239          * <tt>JXG_navigation_button"</tt> or
1240          * <tt>JXG_navigation_button_reload"</tt>.
1241          *
1242          * @name JXG.Board#showReload
1243          * @type Boolean
1244          * @default false
1245          * @see JXG.AbstractRenderer#drawNavigationBar
1246          */
1247         showReload: false,
1248 
1249         /**
1250          * Show a button in the navigation bar to enable screenshots.
1251          * This button can be accessed by JavaScript or CSS with
1252          * the ID <tt>"{board_id}_navigation_button_screenshot"</tt> or by the CSS classes
1253          * <tt>JXG_navigation_button"</tt> or
1254          * <tt>JXG_navigation_button_screenshot"</tt>.
1255          *
1256          * @name JXG.Board#showScreenshot
1257          * @type Boolean
1258          * @default false
1259          * @see JXG.AbstractRenderer#drawNavigationBar
1260          */
1261         showScreenshot: false,
1262 
1263         /**
1264          * Display of zoom buttons in the navigation bar. To show zoom buttons, additionally
1265          * showNavigation has to be set to true.
1266          * <p>
1267          * The individual buttons can be accessed by JavaScript or CSS with
1268          * the ID <tt>"{board_id}_navigation_button_{type}"</tt> or by the CSS classes
1269          * <tt>JXG_navigation_button"</tt> or
1270          * <tt>JXG_navigation_button_{type}"</tt>, where <tt>{type}</tt>
1271          * is <tt>in</tt>, <tt>100</tt>, or <tt>out</tt>.
1272          *
1273          * @name JXG.Board#showZoom
1274          * @type Boolean
1275          * @default true
1276          * @see JXG.AbstractRenderer#drawNavigationBar
1277          */
1278         showZoom: true,
1279 
1280         /**
1281          * If true the first element of the set JXG.board.objects having hasPoint==true is taken as drag element.
1282          *
1283          * @name JXG.Board#takeFirst
1284          * @type Boolean
1285          * @default false
1286          */
1287         takeFirst: false,
1288 
1289         /**
1290         * If true, when read from a file or string - the size of the div can be changed by the construction text.
1291         *
1292         * @name JXG.Board#takeSizeFromFile
1293         * @type Boolean
1294         * @default false
1295         */
1296         takeSizeFromFile: false,
1297 
1298         /**
1299          * Set a visual theme for a board. At the moment this attribute is immutable.
1300          * Available themes are
1301          * <ul>
1302          * <li> 'default'
1303          * <li> 'mono_thin': a black / white theme using thin strokes. Restricted to 2D.
1304          * </ul>
1305          *
1306          * @name JXG.Board#theme
1307          * @type String
1308          * @default 'default'
1309          * @example
1310          *  const board = JXG.JSXGraph.initBoard('jxgbox', {
1311          *      boundingbox: [-5, 5, 5, -5], axis: true,
1312          *      theme: 'mono_thin'
1313          *  });
1314          *
1315          *  var a = board.create('slider', [[1, 4], [3, 4], [-10, 1, 10]]);
1316          *  var p1 = board.create('point', [1, 2]);
1317          *  var ci1 = board.create('circle', [p1, 0.7]);
1318          *  var cu = board.create('functiongraph', ['x^2']);
1319          *  var l1 = board.create('line', [2, 3, -1]);
1320          *  var l2 = board.create('line', [-5, -3, -1], { dash: 2 });
1321          *  var i1 = board.create('intersection', [l1, l2]);
1322          *  var pol = board.create('polygon', [[1, 0], [4, 0], [3.5, 1]]);
1323          *  var an = board.create('angle', [pol.vertices[1], pol.vertices[0], pol.vertices[2]]);
1324          *  var se = board.create('sector', [pol.vertices[1], pol.vertices[2], pol.vertices[0]]);
1325          *  var ci1 = board.create('circle', [[-3, -3], 0.7], { center: { visible: true } });
1326          *
1327          * </pre><div id="JXG1c5f7a2a-176b-4410-ac06-8593f1a09879" class="jxgbox" style="width: 300px; height: 300px;"></div>
1328          * <script type="text/javascript">
1329          *     (function() {
1330          *         var board = JXG.JSXGraph.initBoard('JXG1c5f7a2a-176b-4410-ac06-8593f1a09879',
1331          *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false,
1332          *              theme: 'mono_thin' });
1333          *
1334          *    var a = board.create('slider', [[1, 4], [3, 4], [-10, 1, 10]]);
1335          *    var p1 = board.create('point', [1, 2]);
1336          *    var ci1 = board.create('circle', [p1, 0.7]);
1337          *    var cu = board.create('functiongraph', ['x^2']);
1338          *    var l1 = board.create('line', [2, 3, -1]);
1339          *    var l2 = board.create('line', [-5, -3, -1], { dash: 2 });
1340          *    var i1 = board.create('intersection', [l1, l2]);
1341          *    var pol = board.create('polygon', [[1, 0], [4, 0], [3.5, 1]]);
1342          *    var an = board.create('angle', [pol.vertices[1], pol.vertices[0], pol.vertices[2]]);
1343          *    var se = board.create('sector', [pol.vertices[1], pol.vertices[2], pol.vertices[0]]);
1344          *    var ci1 = board.create('circle', [[-3, -3], 0.7], { center: { visible: true } });
1345          *
1346          *     })();
1347          *
1348          * </script><pre>
1349          *
1350          */
1351         theme: 'default',
1352 
1353         /**
1354          * Title string for the board.
1355          * Primarily used in an invisible text element which is adressed by
1356          * the attribute 'aria-labelledby' from the JSXGraph container.
1357          * JSXGraph creates a new div-element with id "{containerid}_ARIAlabel"
1358          * containing this string.
1359          *
1360          * @name JXG.Board#title
1361          * @see JXG.Board#description
1362          * @type String
1363          * @default ''
1364          *
1365          */
1366         title: '',
1367 
1368         /**
1369          *
1370          * Set a viewport of the board. viewport is determined by an array of the form '[left, top, right, bottom]'.
1371          * whose entries determine an inner margin (i.e. a padding) of the board. The entries of the array have to be given
1372          * as numbers or strings. In the latter case the units 'px' or '%' are supported.
1373          * The viewport can be individually controlled for each element, too.
1374          *
1375          * @type {Array|String}
1376          * @name JXG.Board#viewport
1377          * @default [0, 0, 0, 0]
1378          * @see JXG.GeometryElement#viewport
1379          */
1380         viewport: [0, 0, 0, 0],
1381 
1382         /**
1383          * Control the possibilities for zoom interaction.
1384          *
1385          * Possible sub-attributes with default values are:
1386          * <pre>
1387          * zoom: {
1388          *   enabled: true,  // turns off zooming completely, if set to false.
1389          *   factorX: 1.25,  // horizontal zoom factor (multiplied to {@link JXG.Board#zoomX})
1390          *   factorY: 1.25,  // vertical zoom factor (multiplied to {@link JXG.Board#zoomY})
1391          *   wheel: true,    // allow zooming by mouse wheel
1392          *   needShift: true,  // mouse wheel zooming needs pressing of the shift key
1393          *   min: 0.001,       // minimal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomOut
1394          *   max: 1000.0,      // maximal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomIn
1395          *
1396          *   pinch: true,      // pinch-to-zoom gesture for proportional zoom
1397          *   pinchHorizontal: true, // Horizontal pinch-to-zoom zooms horizontal axis. Only available if keepaspectratio:false
1398          *   pinchVertical: true,   // Vertical pinch-to-zoom zooms vertical axis only. Only available if keepaspectratio:false
1399          *   pinchSensitivity: 7    // Sensitivity (in degrees) for recognizing horizontal or vertical pinch-to-zoom gestures.
1400          * }
1401          * </pre>
1402          *
1403          * If the zoom buttons are visible, zooming by clicking the buttons is still possible, regardless of zoom.enabled:true/false.
1404          * If this should be prevented, set showZoom:false.
1405          *
1406          * Deprecated: zoom.eps which is superseded by zoom.min
1407          *
1408          * @name JXG.Board#zoom
1409          * @type Object
1410          * @default See above
1411          * @see JXG.Board#showZoom
1412          *
1413          */
1414         zoom: {
1415             enabled: true,
1416             factorX: 1.25,
1417             factorY: 1.25,
1418             wheel: true,
1419             needShift: true,
1420             min: 0.0001,
1421             max: 10000.0,
1422             pinch: true,
1423             pinchHorizontal: true,
1424             pinchVertical: true,
1425             pinchSensitivity: 7
1426         },
1427 
1428         // /**
1429         //  * Additional zoom factor multiplied to {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}.
1430         //  *
1431         //  * @name JXG.Board#zoomFactor
1432         //  * @type Number
1433         //  * @default 1.0
1434         //  */
1435         // zoomFactor: 1,
1436 
1437         /**
1438          * Zoom factor in horizontal direction.
1439          *
1440          * @name JXG.Board#zoomX
1441          * @see JXG.Board#zoomY
1442          * @type Number
1443          * @default 1.0
1444          */
1445         zoomX: 1,
1446 
1447         /**
1448          * Zoom factor in vertical direction.
1449          *
1450          * @name JXG.Board#zoomY
1451          * @see JXG.Board#zoomX
1452          * @type Number
1453          * @default 1.0
1454          */
1455         zoomY: 1
1456 
1457         /**#@-*/
1458     },
1459 
1460     /**
1461      * Options that are used by the navigation bar.
1462      *
1463      * Default values are
1464      * <pre>
1465      * JXG.Option.navbar: {
1466      *   strokeColor: '#333333',
1467      *   fillColor: 'transparent',
1468      *   highlightFillColor: '#aaaaaa',
1469      *   padding: '2px',
1470      *   position: 'absolute',
1471      *   fontSize: '14px',
1472      *   cursor: 'pointer',
1473      *   zIndex: '100',
1474      *   right: '5px',
1475      *   bottom: '5px'
1476      * },
1477      * </pre>
1478      * These settings are overruled by the CSS class 'JXG_navigation'.
1479      * @deprecated
1480      * @type Object
1481      * @name JXG.Options#navbar
1482      *
1483      */
1484     navbar: {
1485         strokeColor: '#333333', //'#aaaaaa',
1486         fillColor: 'transparent', //#f5f5f5',
1487         highlightFillColor: '#aaaaaa',
1488         padding: '2px',
1489         position: 'absolute',
1490         fontSize: '14px',
1491         cursor: 'pointer',
1492         zIndex: '100',
1493         right: '5px',
1494         bottom: '5px'
1495         //border: 'none 1px black',
1496         //borderRadius: '4px'
1497     },
1498 
1499     /*
1500      *  Generic options used by {@link JXG.GeometryElement}
1501      */
1502     elements: {
1503         /**#@+
1504          * @visprop
1505          */
1506         // This is a meta tag: http://code.google.com/p/jsdoc-toolkit/wiki/MetaTags
1507 
1508         /**
1509          * Determines the elements border-style.
1510          * Possible values are:
1511          * <ul><li>0 for a solid line</li>
1512          * <li>1 for a dotted line</li>
1513          * <li>2 for a line with small dashes</li>
1514          * <li>3 for a line with medium dashes</li>
1515          * <li>4 for a line with big dashes</li>
1516          * <li>5 for a line with alternating medium and big dashes and large gaps</li>
1517          * <li>6 for a line with alternating medium and big dashes and small gaps</li>
1518          * <li>7 for a dotted line. Needs {@link JXG.GeometryElement#linecap} set to "round" for round dots.</li>
1519          * </ul>
1520          * The dash patterns are defined in {@link JXG.AbstractRenderer#dashArray}.
1521          *
1522          * @type Number
1523          * @name JXG.GeometryElement#dash
1524          * @default 0
1525          *
1526          * @see JXG.GeometryElement#lineCap
1527          * @see JXG.AbstractRenderer#dashArray
1528          */
1529         dash: 0,
1530 
1531         /**
1532          * If true, the dash pattern is multiplied by strokeWidth / 2.
1533          * @name JXG.GeometryElement#dashScale
1534          * @type Boolean
1535          * @default false
1536          *
1537          * @see JXG.GeometryElement#dash
1538          * @see JXG.AbstractRenderer#dashArray
1539          */
1540         dashScale: false,
1541 
1542         /**
1543          * If draft.draft: true the element will be drawn in grey scale colors (as default)
1544          * to visualize that it's only a draft.
1545          *
1546          * @name JXG.GeometryElement#draft
1547          * @type Object
1548          * @default <tt>{@link JXG.Options.elements.draft#draft}</tt>
1549          */
1550         draft: {
1551             draft: false,
1552             strokeColor: '#565656',
1553             fillColor: '#565656',
1554             strokeOpacity: 0.8,
1555             fillOpacity: 0.8,
1556             strokeWidth: 1
1557         },
1558 
1559         /**
1560          * If the element is dragged it will be moved on mousedown or touchstart to the
1561          * top of its layer. Works only for SVG renderer and for simple elements
1562          * consisting of one SVG node.
1563          * @example
1564          * var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});
1565          * var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});
1566          *
1567          * </pre><div id="JXG38449fee-1ab4-44de-b7d1-43caa1f50f86" class="jxgbox" style="width: 300px; height: 300px;"></div>
1568          * <script type="text/javascript">
1569          *     (function() {
1570          *         var board = JXG.JSXGraph.initBoard('JXG38449fee-1ab4-44de-b7d1-43caa1f50f86',
1571          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
1572          *     var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});
1573          *     var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});
1574          *
1575          *     })();
1576          *
1577          * </script><pre>
1578          *
1579          * @type Boolean
1580          * @default false
1581          * @name JXG.GeometryElement#dragToTopOfLayer
1582          */
1583         dragToTopOfLayer: false,
1584 
1585         /**
1586          * The fill color of this geometry element.
1587          * @type String
1588          * @name JXG.GeometryElement#fillColor
1589          * @see JXG.GeometryElement#highlightFillColor
1590          * @see JXG.GeometryElement#fillOpacity
1591          * @see JXG.GeometryElement#highlightFillOpacity
1592          * @default JXG.palette.red
1593          */
1594         fillColor: Color.palette.red,
1595 
1596         /**
1597          * Opacity for fill color.
1598          * @type Number
1599          * @name JXG.GeometryElement#fillOpacity
1600          * @see JXG.GeometryElement#fillColor
1601          * @see JXG.GeometryElement#highlightFillColor
1602          * @see JXG.GeometryElement#highlightFillOpacity
1603          * @default 1
1604          */
1605         fillOpacity: 1,
1606 
1607         /**
1608          * If true the element is fixed and can not be dragged around. The element
1609          * will be repositioned on zoom and moveOrigin events.
1610          * @type Boolean
1611          * @default false
1612          * @name JXG.GeometryElement#fixed
1613          */
1614         fixed: false,
1615 
1616         /**
1617          * If true the element is fixed and can not be dragged around. The element
1618          * will even stay at its position on zoom and moveOrigin events.
1619          * Only free elements like points, texts, images, curves can be frozen.
1620          * For slider elements, the subobjects point1 and point2 have to be "frozen".
1621          *
1622          * @type Boolean
1623          * @default false
1624          * @name JXG.GeometryElement#frozen
1625          *
1626          * @example
1627          * var txt = board.create('text', [1, 2, 'Hello'], {frozen: true, fontSize: 24});
1628          * var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {
1629          *     name:'a',
1630          *     point1: {frozen: true},
1631          *     point2: {frozen: true}
1632          * });
1633          *
1634          * </pre><div id="JXG02f88c9d-8c0a-4174-9219-f0ea43749159" class="jxgbox" style="width: 300px; height: 300px;"></div>
1635          * <script type="text/javascript">
1636          *     (function() {
1637          *         var board = JXG.JSXGraph.initBoard('JXG02f88c9d-8c0a-4174-9219-f0ea43749159',
1638          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
1639          *     var txt = board.create('text', [1, 2, 'Hello'], {frozen: true, fontSize: 24});
1640          *     var sli = board.create('slider', [[-4, 4], [-1.5, 4], [-10, 1, 10]], {
1641          *         name:'a',
1642          *         point1: {frozen: true},
1643          *         point2: {frozen: true}
1644          *     });
1645          *
1646          *     })();
1647          *
1648          * </script><pre>
1649          *
1650          */
1651         frozen: false,
1652 
1653         /**
1654          * Gradient type. Possible values are 'linear'. 'radial' or null.
1655          *
1656          * @example
1657          *     var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});
1658          *     var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});
1659          *     var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});
1660          *
1661          *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1662          *                 fillOpacity: 1,
1663          *                 fillColor: 'yellow',
1664          *                 gradient: 'linear',
1665          *                 gradientSecondColor: 'blue',
1666          *                 gradientAngle: function() { return a.Value(); },
1667          *                 gradientStartOffset: function() { return b.Value(); },
1668          *                 gradientEndOffset: function() { return c.Value(); },
1669          *                 hasInnerPoints: true
1670          *         });
1671          *
1672          * </pre><div id="JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0" class="jxgbox" style="width: 300px; height: 300px;"></div>
1673          * <script type="text/javascript">
1674          *     (function() {
1675          *         var board = JXG.JSXGraph.initBoard('JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0',
1676          *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});
1677          *         var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});
1678          *         var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});
1679          *         var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});
1680          *
1681          *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1682          *                     fillOpacity: 1,
1683          *                     fillColor: 'yellow',
1684          *                     gradient: 'linear',
1685          *                     gradientSecondColor: 'blue',
1686          *                     gradientAngle: function() { return a.Value(); },
1687          *                     gradientStartOffset: function() { return b.Value(); },
1688          *                     gradientEndOffset: function() { return c.Value(); },
1689          *                     hasInnerPoints: true
1690          *             });
1691          *
1692          *     })();
1693          *
1694          * </script><pre>
1695          *
1696          * @example
1697          *     var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});
1698          *     var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});
1699          *     var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});
1700          *     var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});
1701          *     var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});
1702          *     var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});
1703          *
1704          *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1705          *                 fillOpacity: 1,
1706          *                 fillColor: 'yellow',
1707          *                 gradient: 'radial',
1708          *                 gradientSecondColor: 'blue',
1709          *                 gradientCX: function() { return cx.Value(); },
1710          *                 gradientCY: function() { return cx.Value(); },
1711          *                 gradientR: function() { return r.Value(); },
1712          *                 gradientFX: function() { return fx.Value(); },
1713          *                 gradientFY: function() { return fx.Value(); },
1714          *                 gradientFR: function() { return fr.Value(); },
1715          *                 gradientStartOffset: function() { return o1.Value(); },
1716          *                 gradientEndOffset: function() { return o2.Value(); },
1717          *                 hasInnerPoints: true
1718          *     });
1719          *
1720          * </pre><div id="JXG6081ca7f-0d09-4525-87ac-325a02fe2225" class="jxgbox" style="width: 300px; height: 300px;"></div>
1721          * <script type="text/javascript">
1722          *     (function() {
1723          *         var board = JXG.JSXGraph.initBoard('JXG6081ca7f-0d09-4525-87ac-325a02fe2225',
1724          *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});
1725          *         var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});
1726          *         var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});
1727          *         var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});
1728          *         var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});
1729          *         var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});
1730          *         var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});
1731          *
1732          *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1733          *                     fillOpacity: 1,
1734          *                     fillColor: 'yellow',
1735          *                     gradient: 'radial',
1736          *                     gradientSecondColor: 'blue',
1737          *                     gradientCX: function() { return cx.Value(); },
1738          *                     gradientCY: function() { return cx.Value(); },
1739          *                     gradientR: function() { return r.Value(); },
1740          *                     gradientFX: function() { return fx.Value(); },
1741          *                     gradientFY: function() { return fx.Value(); },
1742          *                     gradientFR: function() { return fr.Value(); },
1743          *                     gradientStartOffset: function() { return o1.Value(); },
1744          *                     gradientEndOffset: function() { return o2.Value(); },
1745          *                     hasInnerPoints: true
1746          *         });
1747          *
1748          *     })();
1749          *
1750          * </script><pre>
1751          *
1752          *
1753          * @type String
1754          * @name JXG.GeometryElement#gradient
1755          * @see JXG.GeometryElement#gradientSecondColor
1756          * @see JXG.GeometryElement#gradientSecondOpacity
1757          * @default null
1758          */
1759         gradient: null,
1760 
1761         /**
1762          * Angle (in radians) of the gradiant in case the gradient is of type 'linear'.
1763          * If the angle is 0, the first color is on the left and the second color is on the right.
1764          * If the angle is π/2 the first color is on top and the second color at the
1765          * bottom.
1766          * @type Number
1767          * @name JXG.GeometryElement#gradientAngle
1768          * @see JXG.GeometryElement#gradient
1769          * @default 0
1770          */
1771         gradientAngle: 0,
1772 
1773         /**
1774          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1775          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1776          * For radial gradients in canvas this is the value 'x1'.
1777          * Takes a value between 0 and 1.
1778          * @type Number
1779          * @name JXG.GeometryElement#gradientCX
1780          * @see JXG.GeometryElement#gradient
1781          * @see JXG.GeometryElement#gradientCY
1782          * @see JXG.GeometryElement#gradientR
1783          * @default 0.5
1784          */
1785         gradientCX: 0.5,
1786 
1787         /**
1788          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1789          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1790          * For radial gradients in canvas this is the value 'y1'.
1791          * Takes a value between 0 and 1.
1792          * @type Number
1793          * @name JXG.GeometryElement#gradientCY
1794          * @see JXG.GeometryElement#gradient
1795          * @see JXG.GeometryElement#gradientCX
1796          * @see JXG.GeometryElement#gradientR
1797          * @default 0.5
1798          */
1799         gradientCY: 0.5,
1800 
1801         /**
1802          * The gradientEndOffset attribute is a number (ranging from 0 to 1) which indicates where the second gradient stop is placed,
1803          * see the SVG specification for more information.
1804          * For linear gradients, this attribute represents a location along the gradient vector.
1805          * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.
1806          * @type Number
1807          * @name JXG.GeometryElement#gradientEndOffset
1808          * @see JXG.GeometryElement#gradient
1809          * @see JXG.GeometryElement#gradientStartOffset
1810          * @default 1.0
1811          */
1812         gradientEndOffset: 1.0,
1813 
1814         /**
1815          * ‘fx’ and ‘fy’ define the focal point for the radial gradient.
1816          * The gradient will be drawn such that the 0% gradient stop is mapped to (fx, fy).
1817          * For radial gradients in canvas this is the value 'x0'.
1818          * Takes a value between 0 and 1.
1819          * @type Number
1820          * @name JXG.GeometryElement#gradientFX
1821          * @see JXG.GeometryElement#gradient
1822          * @see JXG.GeometryElement#gradientFY
1823          * @see JXG.GeometryElement#gradientFR
1824          * @default 0.5
1825          */
1826         gradientFX: 0.5,
1827 
1828         /**
1829          * y-coordinate of the circle center for the second color in case of gradient 'radial'. (The attribute fy in SVG)
1830          * For radial gradients in canvas this is the value 'y0'.
1831          * Takes a value between 0 and 1.
1832          * @type Number
1833          * @name JXG.GeometryElement#gradientFY
1834          * @see JXG.GeometryElement#gradient
1835          * @see JXG.GeometryElement#gradientFX
1836          * @see JXG.GeometryElement#gradientFR
1837          * @default 0.5
1838          */
1839         gradientFY: 0.5,
1840 
1841         /**
1842          * This attribute defines the radius of the start circle of the radial gradient.
1843          * The gradient will be drawn such that the 0% <stop> is mapped to the perimeter of the start circle.
1844          * For radial gradients in canvas this is the value 'r0'.
1845          * Takes a value between 0 and 1.
1846          * @type Number
1847          * @name JXG.GeometryElement#gradientFR
1848          * @see JXG.GeometryElement#gradient
1849          * @see JXG.GeometryElement#gradientFX
1850          * @see JXG.GeometryElement#gradientFY
1851          * @default 0.0
1852          */
1853         gradientFR: 0.0,
1854 
1855         /**
1856          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1857          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1858          * For radial gradients in canvas this is the value 'r1'.
1859          * Takes a value between 0 and 1.
1860          * @type Number
1861          * @name JXG.GeometryElement#gradientR
1862          * @see JXG.GeometryElement#gradient
1863          * @see JXG.GeometryElement#gradientCX
1864          * @see JXG.GeometryElement#gradientCY
1865          * @default 0.5
1866          */
1867         gradientR: 0.5,
1868 
1869         /**
1870          * Second color for gradient.
1871          * @type String
1872          * @name JXG.GeometryElement#gradientSecondColor
1873          * @see JXG.GeometryElement#gradient
1874          * @see JXG.GeometryElement#gradientSecondOpacity
1875          * @default '#ffffff'
1876          */
1877         gradientSecondColor: '#ffffff',
1878 
1879         /**
1880          * Opacity of second gradient color. Takes a value between 0 and 1.
1881          * @type Number
1882          * @name JXG.GeometryElement#gradientSecondOpacity
1883          * @see JXG.GeometryElement#gradient
1884          * @see JXG.GeometryElement#gradientSecondColor
1885          * @default 1
1886          */
1887         gradientSecondOpacity: 1,
1888 
1889         /**
1890          * The gradientStartOffset attribute is a number (ranging from 0 to 1) which indicates where the first gradient stop is placed,
1891          * see the SVG specification for more information.
1892          * For linear gradients, this attribute represents a location along the gradient vector.
1893          * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.
1894          * @type Number
1895          * @name JXG.GeometryElement#gradientStartOffset
1896          * @see JXG.GeometryElement#gradient
1897          * @see JXG.GeometryElement#gradientEndOffset
1898          * @default 0.0
1899          */
1900         gradientStartOffset: 0.0,
1901 
1902         /**
1903          * @type Boolean
1904          * @default true
1905          * @name JXG.GeometryElement#highlight
1906          */
1907         highlight: true,
1908 
1909         /**
1910          * The fill color of the given geometry element when the mouse is pointed over it.
1911          * @type String
1912          * @name JXG.GeometryElement#highlightFillColor
1913          * @see JXG.GeometryElement#fillColor
1914          * @see JXG.GeometryElement#fillOpacity
1915          * @see JXG.GeometryElement#highlightFillOpacity
1916          * @default 'none'
1917          */
1918         highlightFillColor: 'none',
1919 
1920         /**
1921          * Opacity for fill color when the object is highlighted.
1922          * @type Number
1923          * @name JXG.GeometryElement#highlightFillOpacity
1924          * @see JXG.GeometryElement#fillColor
1925          * @see JXG.GeometryElement#highlightFillColor
1926          * @see JXG.GeometryElement#fillOpacity
1927          * @default 1
1928          */
1929         highlightFillOpacity: 1,
1930 
1931         /**
1932          * The stroke color of the given geometry element when the user moves the mouse over it.
1933          * @type String
1934          * @name JXG.GeometryElement#highlightStrokeColor
1935          * @see JXG.GeometryElement#strokeColor
1936          * @see JXG.GeometryElement#strokeWidth
1937          * @see JXG.GeometryElement#strokeOpacity
1938          * @see JXG.GeometryElement#highlightStrokeOpacity
1939          * @default '#c3d9ff'
1940          */
1941         highlightStrokeColor: '#c3d9ff',
1942 
1943         /**
1944          * Opacity for stroke color when the object is highlighted.
1945          * @type Number
1946          * @name JXG.GeometryElement#highlightStrokeOpacity
1947          * @see JXG.GeometryElement#strokeColor
1948          * @see JXG.GeometryElement#highlightStrokeColor
1949          * @see JXG.GeometryElement#strokeWidth
1950          * @see JXG.GeometryElement#strokeOpacity
1951          * @default 1
1952          */
1953         highlightStrokeOpacity: 1,
1954 
1955         /**
1956          * Width of the element's stroke when the mouse is pointed over it.
1957          * @type Number
1958          * @name JXG.GeometryElement#highlightStrokeWidth
1959          * @see JXG.GeometryElement#strokeColor
1960          * @see JXG.GeometryElement#highlightStrokeColor
1961          * @see JXG.GeometryElement#strokeOpacity
1962          * @see JXG.GeometryElement#highlightStrokeOpacity
1963          * @see JXG.GeometryElement#highlightFillColor
1964          * @default 2
1965          */
1966         highlightStrokeWidth: 2,
1967 
1968         /**
1969          * @name JXG.GeometryElement#isLabel
1970          * @default false
1971          * @private
1972         */
1973         // By default, an element is not a label. Do not change this.
1974         isLabel: false,
1975 
1976         /**
1977          * Display layer which will contain the element.
1978          * @name JXG.GeometryElement#layer
1979          * @see JXG.Options#layer
1980          * @default See {@link JXG.Options#layer}
1981          */
1982         layer: 0,
1983 
1984         /**
1985          * Line endings (linecap) of a stroke element, i.e. line, circle, curve.
1986          * Possible values are:
1987          * <ul>
1988          * <li> 'butt',
1989          * <li> 'round',
1990          * <li> 'square'.
1991          * </ul>
1992          * Not available for VML renderer.
1993          *
1994          * @name JXG.GeometryElement#lineCap
1995          * @type String
1996          * @default 'butt'
1997          */
1998         lineCap: 'butt',
1999 
2000         /**
2001          * If this is set to true, the element is updated in every update
2002          * call of the board. If set to false, the element is updated only after
2003          * zoom events or more generally, when the bounding box has been changed.
2004          * Examples for the latter behavior should be axes.
2005          * @type Boolean
2006          * @default true
2007          * @see JXG.GeometryElement#needsRegularUpdate
2008          * @name JXG.GeometryElement#needsRegularUpdate
2009          */
2010         needsRegularUpdate: true,
2011 
2012         /**
2013          * Precision options for JSXGraph elements.
2014          * This attributes takes either the value 'inherit' or an object of the form:
2015          * <pre>
2016          * precision: {
2017          *      touch: 30,
2018          *      mouse: 4,
2019          *      pen: 4
2020          * }
2021          * </pre>
2022          *
2023          * In the first case, the global, JSXGraph-wide values of JXGraph.Options.precision
2024          * are taken.
2025          *
2026          * @type {String|Object}
2027          * @name JXG.GeometryElement#precision
2028          * @see JXG.Options#precision
2029          * @default 'inherit'
2030          */
2031         precision: 'inherit',
2032 
2033         /**
2034          * A private element will be inaccessible in certain environments, e.g. a graphical user interface.
2035          *
2036          * @name JXG.GeometryElement#priv
2037          * @type Boolean
2038          * @default false
2039          */
2040         priv: false,
2041 
2042         /**
2043          * Determines whether two-finger manipulation may rotate this object.
2044          * If set to false, the object can only be scaled and translated.
2045          * <p>
2046          * In case the element is a polygon or line and it has the attribute "rotatable:false",
2047          * moving the element with two fingers results in a rotation or translation.
2048          * <p>
2049          * If an element is set to be neither scalable nor rotatable, it can only be translated.
2050          * <p>
2051          * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints
2052          * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have
2053          * snapToGrid disabled.
2054          *
2055          * @type Boolean
2056          * @default true
2057          * @name JXG.GeometryElement#rotatable
2058          * @see JXG.GeometryElement#scalable
2059          */
2060         rotatable: true,
2061 
2062         /**
2063          * Determines whether two-finger manipulation of this object may change its size.
2064          * If set to false, the object is only rotated and translated.
2065          * <p>
2066          * In case the element is a horizontal or vertical line having ticks, "scalable:true"
2067          * enables zooming of the board by dragging ticks lines. This feature is enabled,
2068          * for the ticks element of the line element the attribute "fixed" has to be false
2069          * and the line element's scalable attribute has to be true.
2070          * <p>
2071          * In case the element is a polygon or line and it has the attribute "scalable:false",
2072          * moving the element with two fingers results in a rotation or translation.
2073          * <p>
2074          * If an element is set to be neither scalable nor rotatable, it can only be translated.
2075          * <p>
2076          * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints
2077          * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have
2078          * snapToGrid disabled.
2079          *
2080          * @type Boolean
2081          * @default true
2082          * @name JXG.GeometryElement#scalable
2083          * @see JXG.Ticks#fixed
2084          * @see JXG.GeometryElement#rotatable
2085          */
2086         scalable: true,
2087 
2088         /**
2089          * If enabled:true the (stroke) element will get a customized shadow.
2090          * <p>
2091          * Customize <i>color</i> and <i>opacity</i>:
2092          * If the object's RGB stroke color is <tt>[r,g,b]</tt> and its opacity is <tt>op</i>, and
2093          * the shadow parameters <i>color</i> is given as <tt>[r', g', b']</tt> and <i>opacity</i> as <tt>op'</tt>
2094          * the shadow will receive the RGB color
2095          * <center>
2096          * <tt>[blend*r + r', blend*g + g', blend*b + b'] </tt>
2097          * </center>
2098          * and its opacity will be equal to <tt>op * op'</tt>.
2099          * Further, the parameters <i>blur</i> and <i>offset</i> can be adjusted.
2100          * <p>
2101          * This attribute is only available with SVG, not with canvas.
2102          *
2103          * @type Object
2104          * @name JXG.GeometryElement#shadow
2105          * @default shadow: {
2106          *   enabled: false,
2107          *   color: [0, 0, 0],
2108          *   opacity: 1,
2109          *   blur: 3,
2110          *   blend: 0.1,
2111          *   offset: [5, 5]
2112          * }
2113          *
2114          * @example
2115          * board.options.line.strokeWidth = 2
2116          * // No shadow
2117          * var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});
2118          *
2119          * // Default shadow
2120          * var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});
2121          *
2122          * // No shadow
2123          * var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});
2124          *
2125          * // Shadow uses same color as line
2126          * var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',
2127          *             shadow: {enabled: true, color: '#000000', blend: 1}
2128          *         });
2129          *
2130          * // Shadow color as a mixture between black and the line color, additionally set opacity
2131          * var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',
2132          *             shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}
2133          *         });
2134          *
2135          * // Use different value for blur and offset [dx, dy]
2136          * var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',
2137          *             shadow: {enabled: true, offset:[0, 25], blur: 6}
2138          *         });
2139          *
2140          * </pre><div id="JXG1185a9fa-0fa5-425f-8c15-55b56e1be958" class="jxgbox" style="width: 300px; height: 300px;"></div>
2141          * <script type="text/javascript">
2142          *     (function() {
2143          *         var board = JXG.JSXGraph.initBoard('JXG1185a9fa-0fa5-425f-8c15-55b56e1be958',
2144          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2145          *     board.options.line.strokeWidth = 2
2146          *     // No shadow
2147          *     var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});
2148          *
2149          *     // Default shadow
2150          *     var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});
2151          *
2152          *     // No shadow
2153          *     var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});
2154          *
2155          *     // Shadow uses same color as line
2156          *     var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',
2157          *                 shadow: {enabled: true, color: '#000000', blend: 1}
2158          *             });
2159          *
2160          *     // Shadow color as a mixture between black and the line color, additionally set opacity
2161          *     var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',
2162          *                 shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}
2163          *             });
2164          *
2165          *     // Use different value for blur and offset [dx, dy]
2166          *     var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',
2167          *                 shadow: {enabled: true, offset:[0, 25], blur: 6}
2168          *             });
2169          *
2170          *     })();
2171          *
2172          * </script><pre>
2173          *
2174          */
2175         shadow: {
2176             enabled: false,
2177             color: [0, 0, 0],
2178             opacity: 1,
2179             blur: 3,
2180             blend: 0.1,
2181             offset: [5, 5]
2182         },
2183 
2184         /**
2185          * Snaps the element or its parents to the grid. Currently only relevant for points, circles,
2186          * and lines. Points are snapped to grid directly, on circles and lines it's only the parent
2187          * points that are snapped
2188          * @type Boolean
2189          * @default false
2190          * @name JXG.GeometryElement#snapToGrid
2191          */
2192         snapToGrid: false,
2193 
2194         /**
2195          * The stroke color of the given geometry element.
2196          * @type String
2197          * @name JXG.GeometryElement#strokeColor
2198          * @see JXG.GeometryElement#highlightStrokeColor
2199          * @see JXG.GeometryElement#strokeWidth
2200          * @see JXG.GeometryElement#strokeOpacity
2201          * @see JXG.GeometryElement#highlightStrokeOpacity
2202          * @default JXG.palette.blue
2203          */
2204         strokeColor: Color.palette.blue,
2205 
2206         /**
2207          * Opacity for element's stroke color.
2208          * @type Number
2209          * @name JXG.GeometryElement#strokeOpacity
2210          * @see JXG.GeometryElement#strokeColor
2211          * @see JXG.GeometryElement#highlightStrokeColor
2212          * @see JXG.GeometryElement#strokeWidth
2213          * @see JXG.GeometryElement#highlightStrokeOpacity
2214          * @default 1
2215          */
2216         strokeOpacity: 1,
2217 
2218         /**
2219          * Width of the element's stroke.
2220          * @type Number
2221          * @name JXG.GeometryElement#strokeWidth
2222          * @see JXG.GeometryElement#strokeColor
2223          * @see JXG.GeometryElement#highlightStrokeColor
2224          * @see JXG.GeometryElement#strokeOpacity
2225          * @see JXG.GeometryElement#highlightStrokeOpacity
2226          * @default 2
2227          */
2228         strokeWidth: 2,
2229 
2230         /**
2231          * Controls if an element can get the focus with the tab key.
2232          * tabindex corresponds to the HTML attribute of the same name.
2233          * See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">description at MDN</a>.
2234          * The additional value "null" completely disables focus of an element.
2235          * The value will be ignored if keyboard control of the board is not enabled or
2236          * the element is fixed or not visible.
2237          *
2238          * @name JXG.GeometryElement#tabindex
2239          * @type Number
2240          * @default 0
2241          * @see JXG.Board#keyboard
2242          * @see JXG.GeometryElement#fixed
2243          * @see JXG.GeometryElement#visible
2244          */
2245         tabindex: 0,
2246 
2247         /**
2248          * If true the element will be traced, i.e. on every movement the element will be copied
2249          * to the background. Use {@link JXG.GeometryElement#clearTrace} to delete the trace elements.
2250          *
2251          * The calling of element.setAttribute({trace:false}) additionally
2252          * deletes all traces of this element. By calling
2253          * element.setAttribute({trace:'pause'})
2254          * the removal of already existing traces can be prevented.
2255          *
2256          * The visual appearance of the trace can be influenced by {@link JXG.GeometryElement#traceAttributes}.
2257          *
2258          * @see JXG.GeometryElement#clearTrace
2259          * @see JXG.GeometryElement#traces
2260          * @see JXG.GeometryElement#numTraces
2261          * @see JXG.GeometryElement#traceAttributes
2262          * @type Boolean|String
2263          * @default false
2264          * @name JXG.GeometryElement#trace
2265          */
2266         trace: false,
2267 
2268         /**
2269          * Extra visual properties for traces of an element
2270          * @type Object
2271          * @see JXG.GeometryElement#trace
2272          * @name JXG.GeometryElement#traceAttributes
2273          * @default <tt>{}</tt>
2274          *
2275          * @example
2276          * JXG.Options.elements.traceAttributes = {
2277          *     size: 2
2278          * };
2279          *
2280          * const board = JXG.JSXGraph.initBoard(BOARDID, {
2281          *     boundingbox: [-4, 4, 4, -4],
2282          *     keepaspectratio: true
2283          * });
2284          *
2285          * var p = board.create('point', [0.0, 2.0], {
2286          *     trace: true,
2287          *     size: 10,
2288          *     traceAttributes: {
2289          *         color: 'black',
2290          *         face: 'x'
2291          *     }
2292          * });
2293          *
2294          * </pre><div id="JXG504889cb-bb6f-4b65-85db-3ad555c08bcf" class="jxgbox" style="width: 300px; height: 300px;"></div>
2295          * <script type="text/javascript">
2296          *     (function() {
2297          *     JXG.Options.elements.traceAttributes = {
2298          *         size: 2
2299          *     };
2300          *         var board = JXG.JSXGraph.initBoard('JXG504889cb-bb6f-4b65-85db-3ad555c08bcf',
2301          *             {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: true, showClearTraces: true});
2302          *
2303          *     var p = board.create('point', [0.0, 2.0], {
2304          *         trace: true,
2305          *         size: 10,
2306          *         traceAttributes: {
2307          *             color: 'black',
2308          *             face: 'x'
2309          *         }
2310          *     });
2311          *
2312          *     })();
2313          *
2314          * </script><pre>
2315          *
2316          */
2317         traceAttributes: {},
2318 
2319         /**
2320          * Transition duration (in milliseconds) for certain cahnges of properties like color and opacity.
2321          * The properties can be set in the attribute transitionProperties
2322          * Works in SVG renderer, only.
2323          * @type Number
2324          * @name JXG.GeometryElement#transitionDuration
2325          * @see JXG.GeometryElement#transitionProperties
2326          * @see JXG.GeometryElement#strokeColor
2327          * @see JXG.GeometryElement#highlightStrokeColor
2328          * @see JXG.GeometryElement#strokeOpacity
2329          * @see JXG.GeometryElement#highlightStrokeOpacity
2330          * @see JXG.GeometryElement#fillColor
2331          * @see JXG.GeometryElement#highlightFillColor
2332          * @see JXG.GeometryElement#fillOpacity
2333          * @see JXG.GeometryElement#highlightFillOpacity
2334          * @default 100 {@link JXG.Options.elements#transitionDuration}
2335          */
2336         transitionDuration: 100,
2337 
2338         /**
2339          * Properties which change smoothly in the time set in transitionDuration.
2340          * Possible values are
2341          * ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry']
2342          * (and maybe more) for geometry elements and
2343          * ['color', 'opacity', 'all'] for HTML texts.
2344          *
2345          * @type Array
2346          * @name JXG.GeometryElement#transitionProperties
2347          * @see JXG.GeometryElement#transitionDuration
2348          *
2349          *
2350          * @example
2351          * var p1 = board.create("point", [0, 2], {
2352          *     name: "A",
2353          *     highlightStrokeWidth: 10,
2354          *     transitionDuration: 1000,
2355          *     transitionProperties: ['width', 'height', 'stroke-width',
2356          *         'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });
2357          *
2358          * </pre><div id="JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b" class="jxgbox" style="width: 300px; height: 300px;"></div>
2359          * <script type="text/javascript">
2360          *     (function() {
2361          *         var board = JXG.JSXGraph.initBoard('JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b',
2362          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2363          *     var p1 = board.create("point", [0, 2], {
2364          *         name: "A",
2365          *         highlightStrokeWidth: 20,
2366          *         transitionDuration: 1000,
2367          *         transitionProperties: ['width', 'height', 'stroke-width',
2368          *             'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });
2369          *
2370          *     })();
2371          *
2372          * </script><pre>
2373          *
2374          */
2375         transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width'],
2376 
2377         /**
2378          * If false the element won't be visible on the board, otherwise it is shown.
2379          * @type Boolean
2380          * @name JXG.GeometryElement#visible
2381          * @see JXG.GeometryElement#hideElement
2382          * @see JXG.GeometryElement#showElement
2383          * @default true
2384          */
2385         visible: true,
2386 
2387         /**
2388          * Set individual viewport for an element. If not set to 'inherit', to
2389          * use the board-wide viewport, an array of the form '[left, top, right, bottom]' has to be given.
2390          *
2391          * @type {Array|String}
2392          * @name JXG.GeometryElement#viewport
2393          * @default 'inherit'
2394          * @see JXG.Board#viewport
2395          */
2396         viewport: 'inherit',
2397 
2398         /**
2399          * If true a label will display the element's name.
2400          * Using this to suppress labels is more efficient than visible:false.
2401          *
2402          * @name JXG.GeometryElement#withLabel
2403          * @type Boolean
2404          * @default false
2405          */
2406         withLabel: false
2407 
2408         // close the meta tag
2409         /**#@-*/
2410     },
2411 
2412     /*
2413      *  Generic options used by {@link JXG.Ticks}
2414      */
2415     ticks: {
2416         /**#@+
2417          * @visprop
2418          */
2419 
2420         /**
2421          * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
2422          * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
2423          * The third parameter is a null, number or a string. In the latter two cases, this value is taken.
2424          * Returns a string.
2425          *
2426          * @type function
2427          * @name Ticks#generateLabelText
2428          *
2429          * @example
2430          * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,
2431          *     defaultAxes: {
2432          *         x: {
2433          *                 margin: -4,
2434          *                 ticks: {
2435          *                     minTicksDistance: 0,
2436          *                     minorTicks:4,
2437          *                     ticksDistance: 3,
2438          *                     scale: Math.PI,
2439          *                     scaleSymbol: 'π',
2440          *                     insertTicks: true
2441          *                 }
2442          *              },
2443          *         y: {}
2444          *     }
2445          * });
2446          *
2447          * // Generate a logarithmic labelling of the vertical axis.
2448          * board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {
2449          *     var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2])),
2450          *         distance, labelText;
2451          *     return this.formatLabelText(value);
2452          * };
2453          *
2454          * </pre><div id="JXG3d2203ee-a797-416a-a33c-409581fafdd7" class="jxgbox" style="width: 300px; height: 300px;"></div>
2455          * <script type="text/javascript">
2456          *     (function() {
2457          *         var board = JXG.JSXGraph.initBoard('JXG3d2203ee-a797-416a-a33c-409581fafdd7',
2458          *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,
2459          *         defaultAxes: {
2460          *             x: {
2461          *                     margin: -4,
2462          *                     ticks: {
2463          *                         minTicksDistance: 0,
2464          *                         minorTicks:4,
2465          *                         ticksDistance: 3,
2466          *                         scale: Math.PI,
2467          *                         scaleSymbol: 'π',
2468          *                         insertTicks: true
2469          *                     }
2470          *                  },
2471          *             y: {}
2472          *         }
2473          *     });
2474          *
2475          *     // Generate a logarithmic labelling of the vertical axis.
2476          *     board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {
2477          *         var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2])),
2478          *             distance, labelText;
2479          *         return this.formatLabelText(value);
2480          *     };
2481          *
2482          *     })();
2483          *
2484          * </script><pre>
2485          *
2486          */
2487         generateLabelText: null,
2488 
2489         /**
2490          * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
2491          * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
2492          *
2493          * @deprecated Use {@link JGX.Options@generateLabelText}
2494          * @type function
2495          * @name Ticks#generateLabelValue
2496          */
2497         generateLabelValue: null,
2498 
2499         /**
2500          * Draw labels yes/no
2501          *
2502          * @type Boolean
2503          * @name Ticks#drawLabels
2504          * @default false
2505          */
2506         drawLabels: false,
2507 
2508         /**
2509          * Attributes for the ticks labels
2510          *
2511          * @name Ticks#label
2512          * @type Object
2513          * @default <tt>{}</tt>
2514          *
2515          */
2516         label: {
2517         },
2518 
2519         /**
2520         * Format tick labels that were going to have scientific notation
2521         * like 5.00e+6 to look like 5•10⁶.
2522         *
2523         * @example
2524         * var board = JXG.JSXGraph.initBoard("jxgbox", {
2525         *     boundingbox: [-500000, 500000, 500000, -500000],
2526         *     axis: true,
2527         *     defaultAxes: {
2528         *         x: {
2529         *             scalable: true,
2530         *             ticks: {
2531         *                 beautifulScientificTickLabels: true
2532         *           },
2533         *         },
2534         *         y: {
2535         *             scalable: true,
2536         *             ticks: {
2537         *                 beautifulScientificTickLabels: true
2538         *           },
2539         *         }
2540         *     },
2541         * });
2542         *
2543         * </pre><div id="JXGc1e46cd1-e025-4002-80aa-b450869fdaa2" class="jxgbox" style="width: 300px; height: 300px;"></div>
2544         * <script type="text/javascript">
2545         *     (function() {
2546         *     var board = JXG.JSXGraph.initBoard('JXGc1e46cd1-e025-4002-80aa-b450869fdaa2', {
2547         *         boundingbox: [-500000, 500000, 500000, -500000],
2548         *         showcopyright: false, shownavigation: false,
2549         *         axis: true,
2550         *         defaultAxes: {
2551         *             x: {
2552         *                 scalable: true,
2553         *                 ticks: {
2554         *                     beautifulScientificTickLabels: true
2555         *               },
2556         *             },
2557         *             y: {
2558         *                 scalable: true,
2559         *                 ticks: {
2560         *                     beautifulScientificTickLabels: true
2561         *               },
2562         *             }
2563         *         },
2564         *     });
2565         *
2566         *     })();
2567         *
2568         * </script><pre>
2569         *
2570         * @name Ticks#beautifulScientificTickLabels
2571         * @type Boolean
2572         * @default false
2573         */
2574         beautifulScientificTickLabels: false,
2575 
2576         /**
2577          * Use the unicode character 0x2212, i.e. the HTML entity &minus; as minus sign.
2578          * That is −1 instead of -1.
2579          *
2580          * @type Boolean
2581          * @name Ticks#useUnicodeMinus
2582          * @default true
2583          */
2584         useUnicodeMinus: true,
2585 
2586         /**
2587          * Determine the position of the tick with value 0. 'left' means point1 of the line, 'right' means point2,
2588          * and 'middle' is equivalent to the midpoint of the defining points. This attribute is ignored if the parent
2589          * line is of type axis.
2590          *
2591          * @type String
2592          * @name Ticks#anchor
2593          * @default 'left'
2594          *
2595          * @example
2596          * var li = board.create('segment', [[-4, -3], [4, 2]]);
2597          * var t = board.create('ticks', [li], {
2598          *     // drawZero: true,
2599          *     anchor: 'left',
2600          *     drawLabels: true,
2601          *     minorTicks: 0,
2602          *     label: {
2603          *         anchorX: 'middle',
2604          *         anchorY: 'top',
2605          *         offset: [0, -5]
2606          *     }
2607          * });
2608          *
2609          *
2610          * </pre><div id="JXG3dd23f77-a31d-4649-b0f0-7472722158d8" class="jxgbox" style="width: 300px; height: 300px;"></div>
2611          * <script type="text/javascript">
2612          *     (function() {
2613          *         var board = JXG.JSXGraph.initBoard('JXG3dd23f77-a31d-4649-b0f0-7472722158d8',
2614          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2615          *     var li = board.create('segment', [[-4, -3], [4, 2]]);
2616          *     var t = board.create('ticks', [li], {
2617          *         // drawZero: true,
2618          *         anchor: 'left',
2619          *         drawLabels: true,
2620          *         minorTicks: 0,
2621          *         label: {
2622          *             anchorX: 'middle',
2623          *             anchorY: 'top',
2624          *             offset: [0, -5]
2625          *         }
2626          *     });
2627          *
2628          *
2629          *     })();
2630          *
2631          * </script><pre>
2632          *
2633          * @example
2634          * var li = board.create('segment', [[-4, -3], [4, 2]]);
2635          * var t = board.create('ticks', [li], {
2636          *     drawZero: true,
2637          *     anchor: 'middle',
2638          *     drawLabels: true,
2639          *     minorTicks: 0,
2640          *     label: {
2641          *         anchorX: 'middle',
2642          *         anchorY: 'top',
2643          *         offset: [0, -5]
2644          *     }
2645          * });
2646          *
2647          * </pre><div id="JXG430914fd-4e12-44de-b510-e3cc2fd473e0" class="jxgbox" style="width: 300px; height: 300px;"></div>
2648          * <script type="text/javascript">
2649          *     (function() {
2650          *         var board = JXG.JSXGraph.initBoard('JXG430914fd-4e12-44de-b510-e3cc2fd473e0',
2651          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2652          *     var li = board.create('segment', [[-4, -3], [4, 2]]);
2653          *     var t = board.create('ticks', [li], {
2654          *         drawZero: true,
2655          *         anchor: 'middle',
2656          *         drawLabels: true,
2657          *         minorTicks: 0,
2658          *         label: {
2659          *             anchorX: 'middle',
2660          *             anchorY: 'top',
2661          *             offset: [0, -5]
2662          *         }
2663          *     });
2664          *
2665          *     })();
2666          *
2667          * </script><pre>
2668          *
2669          */
2670         anchor: 'left',
2671 
2672         /**
2673          * Draw the zero tick, that lies at line.point1?
2674          *
2675          * @type Boolean
2676          * @name Ticks#drawZero
2677          * @default false
2678          *
2679          * @example
2680          * var li = board.create('segment', [[-4, 2], [4, 2]]);
2681          * var t = board.create('ticks', [li], {
2682          *     drawZero: false,
2683          *     anchor: 'middle',
2684          *     drawLabels: true,
2685          *     minorTicks: 0,
2686          *     label: {
2687          *         anchorX: 'middle',
2688          *         anchorY: 'top',
2689          *         offset: [0, -5]
2690          *     }
2691          * });
2692          *
2693          * var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2694          * var t2 = board.create('ticks', [li2], {
2695          *     drawZero: true,
2696          *     anchor: 'middle',
2697          *     drawLabels: true,
2698          *     minorTicks: 0,
2699          *     label: {
2700          *         anchorX: 'middle',
2701          *         anchorY: 'top',
2702          *         offset: [0, -5]
2703          *     }
2704          * });
2705          *
2706          * </pre><div id="JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1" class="jxgbox" style="width: 300px; height: 300px;"></div>
2707          * <script type="text/javascript">
2708          *     (function() {
2709          *         var board = JXG.JSXGraph.initBoard('JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1',
2710          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
2711          *     var li = board.create('segment', [[-4, 2], [4, 2]]);
2712          *     var t = board.create('ticks', [li], {
2713          *         drawZero: false,
2714          *         anchor: 'middle',
2715          *         drawLabels: true,
2716          *         minorTicks: 0,
2717          *         label: {
2718          *             anchorX: 'middle',
2719          *             anchorY: 'top',
2720          *             offset: [0, -5]
2721          *         }
2722          *     });
2723          *
2724          *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2725          *     var t2 = board.create('ticks', [li2], {
2726          *         drawZero: true,
2727          *         anchor: 'middle',
2728          *         drawLabels: true,
2729          *         minorTicks: 0,
2730          *         label: {
2731          *             anchorX: 'middle',
2732          *             anchorY: 'top',
2733          *             offset: [0, -5]
2734          *         }
2735          *     });
2736          *
2737          *     })();
2738          *
2739          * </script><pre>
2740          *
2741          */
2742         drawZero: false,
2743 
2744         /**
2745          * Let JSXGraph determine the distance between ticks automatically.
2746          * If <tt>true</tt>, the attribute <tt>ticksDistance</tt> is ignored.
2747          * The distance between ticks is affected by the size of the board and
2748          * the attribute <tt>minTicksDistance</tt> (in pixel).
2749          *
2750          * @type Boolean
2751          * @name Ticks#insertTicks
2752          * @see Ticks#ticksDistance
2753          * @see Ticks#minTicksDistance
2754          * @default false
2755          * @example
2756          * // Create an axis providing two coord pairs.
2757          *   var p1 = board.create('point', [0, 0]);
2758          *   var p2 = board.create('point', [50, 25]);
2759          *   var l1 = board.create('line', [p1, p2]);
2760          *   var t = board.create('ticks', [l1], {
2761          *      insertTicks: true,
2762          *      majorHeight: -1,
2763          *      label: {
2764          *          offset: [4, -9]
2765          *      },
2766          *      drawLabels: true
2767          *  });
2768          * </pre><div class="jxgbox" id="JXG2f6fb842-40bd-4223-aa28-3e9369d2097f" style="width: 300px; height: 300px;"></div>
2769          * <script type="text/javascript">
2770          * (function () {
2771          *   var board = JXG.JSXGraph.initBoard('JXG2f6fb842-40bd-4223-aa28-3e9369d2097f', {
2772          *     boundingbox: [-100, 70, 70, -100], axis: true, showcopyright: false, shownavigation: true});
2773          *   var p1 = board.create('point', [0, 0]);
2774          *   var p2 = board.create('point', [50, 25]);
2775          *   var l1 = board.create('line', [p1, p2]);
2776          *   var t = board.create('ticks', [l1], {insertTicks: true, majorHeight: -1, label: {offset: [4, -9]}, drawLabels: true});
2777          * })();
2778          * </script><pre>
2779          */
2780         insertTicks: false,
2781 
2782         /**
2783          * Minimum distance in pixel of equidistant ticks in case insertTicks==true.
2784          * @name Ticks#minTicksDistance
2785          * @type Number
2786          * @default 10
2787          * @see Ticks#insertTicks
2788          */
2789         minTicksDistance: 10,
2790 
2791         /**
2792          * Total height of a minor tick. If negative the full height of the board is taken.
2793          *
2794          * @type Number
2795          * @name Ticks#minorHeight
2796          * @default 4
2797          */
2798         minorHeight: 4,
2799 
2800         /**
2801          * Total height of a major tick. If negative the full height of the board is taken.
2802          *
2803          * @type Number
2804          * @name Ticks#majorHeight
2805          * @default 10
2806          */
2807         majorHeight: 10,
2808 
2809         /**
2810          * Decides in which direction minor ticks are visible. Possible values are either the constants
2811          * 0=false or 1=true or a function returning 0 or 1.
2812          *
2813          * In case of [0,1] the tick is only visible to the right of the line. In case of
2814          * [1,0] the tick is only visible to the left of the line.
2815          *
2816          * @type Array
2817          * @name Ticks#tickEndings
2818          * @see Ticks#majorTickEndings
2819          * @default [1, 1]
2820          */
2821         tickEndings: [1, 1],
2822 
2823         /**
2824          * Decides in which direction major ticks are visible. Possible values are either the constants
2825          * 0=false or 1=true or a function returning 0 or 1.
2826          *
2827          * In case of [0,1] the tick is only visible to the right of the line. In case of
2828          * [1,0] the tick is only visible to the left of the line.
2829          *
2830         * @example
2831         *         var board = JXG.JSXGraph.initBoard("jxgbox", {
2832         *             boundingbox: [-5, 5, 5, -5],
2833         *             axis: true,
2834         *             defaultAxes: {
2835         *                 x: {
2836         *                     ticks: {
2837         *                         majorTickEndings: [1, 0],
2838         *                         ignoreInfiniteTickEndings: false
2839         *                     }
2840         *                 },
2841         *                 y: {
2842         *                     ticks: {
2843         *                         majorTickEndings: [0, 1],
2844         *                         ignoreInfiniteTickEndings: false
2845         *                     }
2846         *                 }
2847         *             }
2848         *         });
2849         *
2850         *         var p = board.create('point', [1, 1]);
2851         *         var l = board.create('line', [1, -1, 1]);
2852         *
2853         * </pre><div id="JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1" class="jxgbox" style="width: 300px; height: 300px;"></div>
2854         * <script type="text/javascript">
2855         *     (function() {
2856         *         var board = JXG.JSXGraph.initBoard('JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1',
2857         *             {   showcopyright: false, shownavigation: false,
2858         *                 boundingbox: [-5, 5, 5, -5],
2859         *                 axis: true,
2860         *                 defaultAxes: {
2861         *                     x: {
2862         *                         ticks: {
2863         *                             majorTickEndings: [1, 0],
2864         *                             ignoreInfiniteTickEndings: false
2865         *                         }
2866         *                     },
2867         *                     y: {
2868         *                         ticks: {
2869         *                             majorTickEndings: [0, 1],
2870         *                             ignoreInfiniteTickEndings: false
2871         *                         }
2872         *                     }
2873         *                 }
2874         *             });
2875         *
2876         *             var p = board.create('point', [1, 1]);
2877         *             var l = board.create('line', [1, -1, 1]);
2878         *
2879         *     })();
2880         *
2881         * </script><pre>
2882         *
2883         * @type Array
2884          * @name Ticks#majorTickEndings
2885          * @see Ticks#tickEndings
2886          * @see Ticks#ignoreInfiniteTickEndings
2887          * @default [1, 1]
2888          */
2889         majorTickEndings: [1, 1],
2890 
2891         /**
2892          * If true, ignore the tick endings attribute for infinite (full height) ticks.
2893          * This affects major and minor ticks.
2894          *
2895          * @type Boolean
2896          * @name Ticks#ignoreInfiniteTickEndings
2897          * @see Ticks#tickEndings
2898          * @see Ticks#majorTickEndings
2899          * @default true
2900          */
2901         ignoreInfiniteTickEndings: true,
2902 
2903         /**
2904          * The number of minor ticks between two major ticks.
2905          * @type Number
2906          * @name Ticks#minorTicks
2907          * @default 4
2908          */
2909         minorTicks: 4,
2910 
2911         /**
2912          * By default, i.e. if ticksPerLabel==false, labels are generated for major ticks, only.
2913          * If ticksPerLabel is set to a(n integer) number, this denotes the number of minor ticks
2914          * between two labels.
2915          *
2916          * @type {Number|Boolean}
2917          * @name Ticks#ticksPerLabel
2918          * @default false
2919          *
2920          * @example
2921          * const board = JXG.JSXGraph.initBoard('jxgbox', {
2922          *     boundingbox: [-4, 4, 4, -4],
2923          *     axis: true,
2924          *     defaultAxes: {
2925          *         x: {
2926          *             ticks: {
2927          *                 minorTicks: 7,
2928          *                 ticksPerLabel: 4,
2929          *                 minorHeight: 20,
2930          *             }
2931          *         },
2932          *         y: {
2933          *             ticks: {
2934          *                 minorTicks: 3,
2935          *                 ticksPerLabel: 2,
2936          *                 minorHeight: 20
2937          *             }
2938          *         }
2939          *     }
2940          * });
2941          *
2942          * </pre><div id="JXGbc45a421-c867-4b0a-9b8d-2b2576020690" class="jxgbox" style="width: 300px; height: 300px;"></div>
2943          * <script type="text/javascript">
2944          *     (function() {
2945          *         var board = JXG.JSXGraph.initBoard('JXGbc45a421-c867-4b0a-9b8d-2b2576020690',
2946          *             {showcopyright: false, shownavigation: false,
2947          *              boundingbox: [-4, 4, 4, -4],
2948          *         axis: true,
2949          *         defaultAxes: {
2950          *             x: {
2951          *                 ticks: {
2952          *                     minorTicks: 7,
2953          *                     ticksPerLabel: 4,
2954          *                     minorHeight: 20,
2955          *                 }
2956          *             },
2957          *             y: {
2958          *                 ticks: {
2959          *                     minorTicks: 3,
2960          *                     ticksPerLabel: 2,
2961          *                     minorHeight: 20
2962          *                 }
2963          *             }
2964          *         }
2965          *     });
2966          *     })();
2967          *
2968          * </script><pre>
2969          */
2970         ticksPerLabel: false,
2971 
2972         /**
2973          * Scale the ticks but not the tick labels.
2974          * @type Number
2975          * @default 1
2976          * @name Ticks#scale
2977          * @see Ticks#scaleSymbol
2978          *
2979          * @example
2980          * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,
2981          *     defaultAxes: {
2982          *         x : {
2983          *                 margin: -4,
2984          *                 ticks: {
2985          *                     minTicksDistance: 0,
2986          *                     minorTicks:4,
2987          *                     ticksDistance: 3,
2988          *                     scale: Math.PI,
2989          *                     scaleSymbol: 'π',
2990          *                     insertTicks: true
2991          *                 }
2992          *              },
2993          *         y : {}
2994          *     }
2995          * });
2996          *
2997          * </pre><div id="JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a" class="jxgbox" style="width: 300px; height: 300px;"></div>
2998          * <script type="text/javascript">
2999          *     (function() {
3000          *         var board = JXG.JSXGraph.initBoard('JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a',
3001          *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,
3002          *         defaultAxes: {
3003          *             x : {
3004          *                     margin: -4,
3005          *                     ticks: {
3006          *                         minTicksDistance: 0,
3007          *                         minorTicks:4,
3008          *                         ticksDistance: 3,
3009          *                         scale: Math.PI,
3010          *                         scaleSymbol: 'π',
3011          *                         insertTicks: true
3012          *                     }
3013          *                  },
3014          *             y : {
3015          *                  }
3016          *         }
3017          *     });
3018          *
3019          *     })();
3020          *
3021          * </script><pre>
3022          */
3023         scale: 1,
3024 
3025         /**
3026          * A string that is appended to every tick, used to represent the scale
3027          * factor given in {@link Ticks#scale}.
3028          *
3029          * @type String
3030          * @default ''
3031          * @name Ticks#scaleSymbol
3032          * @see Ticks#scale
3033          */
3034         scaleSymbol: '',
3035 
3036         /**
3037          * User defined labels for special ticks. Instead of the i-th tick's position, the i-th string stored in this array
3038          * is shown. If the number of strings in this array is less than the number of special ticks, the tick's position is
3039          * shown as a fallback.
3040          *
3041          * @type Array
3042          * @name Ticks#labels
3043          * @default []
3044          */
3045         labels: [],
3046 
3047         /**
3048          * The maximum number of characters a tick label can use.
3049          *
3050          * @type Number
3051          * @name Ticks#maxLabelLength
3052          * @see Ticks#digits
3053          * @default 5
3054          */
3055         maxLabelLength: 5,
3056 
3057         /**
3058          * If a label exceeds {@link Ticks#maxLabelLength} this determines the precision used to shorten the tick label.
3059          * Deprecated! Replaced by the attribute <tt>digits</tt>.
3060          *
3061          * @type Number
3062          * @name Ticks#precision
3063          * @see Ticks#maxLabelLength
3064          * @see Ticks#digits
3065          * @deprecated
3066          * @default 3
3067          */
3068         precision: 3,
3069 
3070         /**
3071          * If a label exceeds {@link Ticks#maxLabelLength} this determines the number of digits used to shorten the tick label.
3072          *
3073          * @type Number
3074          * @name Ticks#digits
3075          * @see Ticks#maxLabelLength
3076          * @deprecated
3077          * @default 3
3078          */
3079         digits: 3,
3080 
3081         /**
3082          * The default distance (in user coordinates, not  pixels) between two ticks. Please be aware that this value does not have
3083          * to be used if {@link Ticks#insertTicks} is set to true.
3084          *
3085          * @type Number
3086          * @name Ticks#ticksDistance
3087          * @see Ticks#insertTicks
3088          * @default 1
3089          */
3090         ticksDistance: 1,
3091 
3092         /**
3093          * Tick face for major ticks of finite length.  By default (face: '|') this is a straight line.
3094          * Possible other values are '<' and '>'. These faces are used in
3095          * {@link JXG.Hatch} for hatch marking parallel lines.
3096          * @type String
3097          * @name Ticks#face
3098          * @see hatch
3099          * @default '|'
3100          * @example
3101          *   var p1 = board.create('point', [0, 3]);
3102          *   var p2 = board.create('point', [1, 3]);
3103          *   var l1 = board.create('line', [p1, p2]);
3104          *   var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});
3105          *
3106          * </pre><div id="JXG950a568a-1264-4e3a-b61d-b6881feecf4b" class="jxgbox" style="width: 300px; height: 300px;"></div>
3107          * <script type="text/javascript">
3108          *     (function() {
3109          *         var board = JXG.JSXGraph.initBoard('JXG950a568a-1264-4e3a-b61d-b6881feecf4b',
3110          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
3111          *       var p1 = board.create('point', [0, 3]);
3112          *       var p2 = board.create('point', [1, 3]);
3113          *       var l1 = board.create('line', [p1, p2]);
3114          *       var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});
3115          *
3116          *     })();
3117          *
3118          * </script><pre>
3119          *
3120          */
3121         face: '|',
3122 
3123         strokeOpacity: 1,
3124         strokeWidth: 1,
3125         strokeColor: '#000000',
3126         highlightStrokeColor: '#888888',
3127         fillColor: 'none',
3128         highlightFillColor: 'none',
3129         visible: 'inherit',
3130 
3131         /**
3132          * Whether line boundaries should be included or not in the lower and upper bounds when
3133          * creating ticks. In mathematical terms: if a segment considered as interval is open (includeBoundaries:false)
3134          * or closed (includeBoundaries:true). In case of open interval, the interval is shortened by a small
3135          * ε.
3136          *
3137          * @type Boolean
3138          * @name Ticks#includeBoundaries
3139          * @default false
3140          *
3141          * @example
3142          * var li = board.create('segment', [[-4, 2], [4, 2]]);
3143          * var t = board.create('ticks', [li], {
3144          *     includeBoundaries: true,
3145          *     drawZero: true,
3146          *     anchor: 'middle',
3147          *     drawLabels: true,
3148          *     minorTicks: 0,
3149          *     label: {
3150          *         anchorX: 'middle',
3151          *         anchorY: 'top',
3152          *         offset: [0, -5]
3153          *     }
3154          * });
3155          *
3156          * var li2 = board.create('segment', [[-4, -2], [4, -2]]);
3157          * var t2 = board.create('ticks', [li2], {
3158          *     includeBoundaries: false,
3159          *     drawZero: true,
3160          *     anchor: 'middle',
3161          *     drawLabels: true,
3162          *     minorTicks: 0,
3163          *     label: {
3164          *         anchorX: 'middle',
3165          *         anchorY: 'top',
3166          *         offset: [0, -5]
3167          *     }
3168          * });
3169          *
3170          * </pre><div id="JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96" class="jxgbox" style="width: 300px; height: 300px;"></div>
3171          * <script type="text/javascript">
3172          *     (function() {
3173          *         var board = JXG.JSXGraph.initBoard('JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96',
3174          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
3175          *     var li = board.create('segment', [[-4, 2], [4, 2]]);
3176          *     var t = board.create('ticks', [li], {
3177          *         includeBoundaries: true,
3178          *         drawZero: true,
3179          *         anchor: 'middle',
3180          *         drawLabels: true,
3181          *         minorTicks: 0,
3182          *         label: {
3183          *             anchorX: 'middle',
3184          *             anchorY: 'top',
3185          *             offset: [0, -5]
3186          *         }
3187          *     });
3188          *
3189          *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);
3190          *     var t2 = board.create('ticks', [li2], {
3191          *         includeBoundaries: false,
3192          *         drawZero: true,
3193          *         anchor: 'middle',
3194          *         drawLabels: true,
3195          *         minorTicks: 0,
3196          *         label: {
3197          *             anchorX: 'middle',
3198          *             anchorY: 'top',
3199          *             offset: [0, -5]
3200          *         }
3201          *     });
3202          *
3203          *     })();
3204          *
3205          * </script><pre>
3206          *
3207          */
3208         includeBoundaries: false,
3209 
3210         /**
3211          * Set the ticks type.
3212          * Possible values are 'linear' or 'polar'.
3213          *
3214          * @type String
3215          * @name Ticks#type
3216          * @default 'linear'
3217          *
3218          * @example
3219          * var ax = board.create('axis', [[0,0], [1,0]], {
3220          *              needsRegularUpdate: false,
3221          *              ticks: {
3222          *                      type: 'linear',
3223          *                      majorHeight: 0
3224          *                  }
3225          *              });
3226          * var ay = board.create('axis', [[0,0], [0,1]], {
3227          *              ticks: {
3228          *                      type: 'polar'
3229          *                  }
3230          *              });
3231          *
3232          * var p = board.create('point', [3, 2]);
3233          *
3234          * </pre><div id="JXG9ab0b50c-b486-4f95-9698-c0dd276155ff" class="jxgbox" style="width: 300px; height: 300px;"></div>
3235          * <script type="text/javascript">
3236          *     (function() {
3237          *         var board = JXG.JSXGraph.initBoard('JXG9ab0b50c-b486-4f95-9698-c0dd276155ff',
3238          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
3239          *     var ax = board.create('axis', [[0,0], [1,0]], { needsRegularUpdate: false, ticks: { type: 'linear', majorHeight: 0}});
3240          *     var ay = board.create('axis', [[0,0], [0,1]], { ticks: { type: 'polar'}});
3241          *
3242          *     var p = board.create('point', [3, 2]);
3243          *
3244          *     })();
3245          *
3246          * </script><pre>
3247          *
3248          */
3249         type: 'linear',
3250 
3251         /**
3252          * Internationalization support for ticks labels.
3253          * @name intl
3254          * @memberOf Ticks.prototype
3255          * @default <pre>{
3256          *    enabled: 'inherit',
3257          *    options: {}
3258          * }</pre>
3259          * @see JXG.Board#intl
3260          * @see Text#intl
3261          *
3262                   * @example
3263          * // Here, locale is disabled in general, but enabled for the horizontal
3264          * // axis and the infobox.
3265          * const board = JXG.JSXGraph.initBoard(BOARDID, {
3266          *     boundingbox: [-0.5, 0.5, 0.5, -0.5],
3267          *     intl: {
3268          *         enabled: false,
3269          *         locale: 'de-DE'
3270          *     },
3271          *     keepaspectratio: true,
3272          *     axis: true,
3273          *     defaultAxes: {
3274          *         x: {
3275          *             ticks: {
3276          *                 intl: {
3277          *                         enabled: true,
3278          *                         options: {
3279          *                             style: 'unit',
3280          *                             unit: 'kilometer-per-hour',
3281          *                             unitDisplay: 'narrow'
3282          *                         }
3283          *                 }
3284          *             }
3285          *         },
3286          *         y: {
3287          *             ticks: {
3288          *             }
3289          *         }
3290          *     },
3291          *     infobox: {
3292          *         fontSize: 12,
3293          *         intl: {
3294          *             enabled: true,
3295          *             options: {
3296          *                 minimumFractionDigits: 4,
3297          *                 maximumFractionDigits: 5
3298          *             }
3299          *         }
3300          *     }
3301          * });
3302          *
3303          * var p = board.create('point', [0.1, 0.1], {});
3304          *
3305          * </pre><div id="JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe" class="jxgbox" style="width: 600px; height: 300px;"></div>
3306          * <script type="text/javascript">
3307          *     (function() {
3308          *     var board = JXG.JSXGraph.initBoard('JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe', {
3309          *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,
3310          *         intl: {
3311          *             enabled: false,
3312          *             locale: 'de-DE'
3313          *         },
3314          *         keepaspectratio: true,
3315          *         axis: true,
3316          *         defaultAxes: {
3317          *             x: {
3318          *                 ticks: {
3319          *                     intl: {
3320          *                             enabled: true,
3321          *                             options: {
3322          *                                 style: 'unit',
3323          *                                 unit: 'kilometer-per-hour',
3324          *                                 unitDisplay: 'narrow'
3325          *                             }
3326          *                     }
3327          *                 }
3328          *             },
3329          *             y: {
3330          *                 ticks: {
3331          *                 }
3332          *             }
3333          *         },
3334          *         infobox: {
3335          *             fontSize: 12,
3336          *             intl: {
3337          *                 enabled: true,
3338          *                 options: {
3339          *                     minimumFractionDigits: 4,
3340          *                     maximumFractionDigits: 5
3341          *                 }
3342          *             }
3343          *         }
3344          *     });
3345          *
3346          *     var p = board.create('point', [0.1, 0.1], {});
3347          *
3348          *     })();
3349          *
3350          * </script><pre>
3351          *
3352          */
3353         intl: {
3354             enabled: 'inherit',
3355             options: {}
3356         },
3357 
3358         // TODO implementation and documentation
3359         minorTicksInArrow: false,
3360         majorTicksInArrow: true,
3361         labelInArrow: true,
3362         minorTicksInMargin: false,
3363         majorTicksInMargin: true,
3364         labelInMargin: true
3365 
3366         // close the meta tag
3367         /**#@-*/
3368     },
3369 
3370     /*
3371      *  Generic options used by {@link JXG.Hatch}
3372      */
3373     hatch: {
3374         drawLabels: false,
3375         drawZero: true,
3376         majorHeight: 20,
3377         anchor: 'middle',
3378         face: '|',
3379         strokeWidth: 2,
3380         strokeColor: Color.palette.blue,
3381         /**
3382          * The default distance (in user coordinates, not  pixels) between two hatch symbols.
3383          *
3384          * @type Number
3385          * @name Hatch#ticksDistance
3386          * @default 0.2
3387          */
3388         ticksDistance: 0.2
3389     },
3390 
3391     /**
3392      * Precision options, defining how close a pointer device (mouse, finger, pen) has to be
3393      * to an object such that the object is highlighted or can be dragged.
3394      * These values are board-wide and can be overwritten for individual elements by
3395      * changing their precision attribute.
3396      *
3397      * The default values are
3398      * <pre>
3399      * JXG.Options.precision: {
3400      *   touch: 30,
3401      *   touchMax: 100,
3402      *   mouse: 4,
3403      *   pen: 4,
3404      *   epsilon: 0.0001,
3405      *   hasPoint: 4
3406      * }
3407      * </pre>
3408      *
3409      * @type Object
3410      * @name JXG.Options#precision
3411      * @see JXG.GeometryElement#precision
3412      */
3413     precision: {
3414         touch: 30,
3415         touchMax: 100,
3416         mouse: 4,
3417         pen: 4,
3418         epsilon: 0.0001, // Unused
3419         hasPoint: 4
3420     },
3421 
3422     /**
3423      * Default ordering of the layers.
3424      * The numbering starts from 0 and the highest layer number is numlayers-1.
3425      *
3426      * The default values are
3427      * <pre>
3428      * JXG.Options.layer: {
3429      *   numlayers: 20, // only important in SVG
3430      *   text: 9,
3431      *   point: 9,
3432      *   glider: 9,
3433      *   arc: 8,
3434      *   line: 7,
3435      *   circle: 6,
3436      *   curve: 5,
3437      *   turtle: 5,
3438      *   polygon: 3,
3439      *   sector: 3,
3440      *   angle: 3,
3441      *   integral: 3,
3442      *   axis: 2,
3443      *   ticks: 2,
3444      *   grid: 1,
3445      *   image: 0,
3446      *   trace: 0
3447      * }
3448      * </pre>
3449      * @type Object
3450      * @name JXG.Options#layer
3451      */
3452     layer: {
3453         numlayers: 20, // only important in SVG
3454         unused9: 19,
3455         unused8: 18,
3456         unused7: 17,
3457         unused6: 16,
3458         unused5: 15,
3459         unused4: 14,
3460         unused3: 13,
3461         unused2: 12,
3462         unused1: 11,
3463         unused0: 10,
3464         text: 9,
3465         point: 9,
3466         glider: 9,
3467         arc: 8,
3468         line: 7,
3469         circle: 6,
3470         curve: 5,
3471         turtle: 5,
3472         polygon: 3,
3473         sector: 3,
3474         angle: 3,
3475         integral: 3,
3476         axis: 2,
3477         ticks: 2,
3478         grid: 1,
3479         image: 0,
3480         trace: 0
3481     },
3482 
3483     /* special angle options */
3484     angle: {
3485         /**#@+
3486          * @visprop
3487          */
3488 
3489         withLabel: true,
3490 
3491         /**
3492          * Radius of the sector, displaying the angle.
3493          * The radius can be given as number (in user coordinates)
3494          * or as string 'auto'. In the latter case, the angle
3495          * is set to an value between 20 and 50 px.
3496          *
3497          * @type {Number|String}
3498          * @name Angle#radius
3499          * @default 'auto'
3500          * @visprop
3501          */
3502         radius: 'auto',
3503 
3504         /**
3505          * Display type of the angle field. Possible values are
3506          * 'sector' or 'sectordot' or 'square' or 'none'.
3507          *
3508          * @type String
3509          * @default 'sector'
3510          * @name Angle#type
3511          * @visprop
3512          */
3513         type: 'sector',
3514 
3515         /**
3516          * Display type of the angle field in case of a right angle. Possible values are
3517          * 'sector' or 'sectordot' or 'square' or 'none'.
3518          *
3519          * @type String
3520          * @default square
3521          * @name Angle#orthoType
3522          * @see Angle#orthoSensitivity
3523          * @visprop
3524          */
3525         orthoType: 'square',
3526 
3527         /**
3528          * Sensitivity (in degrees) to declare an angle as right angle.
3529          * If the angle measure is inside this distance from a rigth angle, the orthoType
3530          * of the angle is used for display.
3531          *
3532          * @type Number
3533          * @default 1.0
3534          * @name Angle#orthoSensitivity
3535          * @see Angle#orthoType
3536          * @visprop
3537          */
3538         orthoSensitivity: 1.0,
3539 
3540         fillColor: Color.palette.orange,
3541         highlightFillColor: Color.palette.orange,
3542         strokeColor: Color.palette.orange,
3543         // fillColor: '#ff7f00',
3544         // highlightFillColor: '#ff7f00',
3545         // strokeColor: '#ff7f00',
3546 
3547         fillOpacity: 0.3,
3548         highlightFillOpacity: 0.3,
3549 
3550         /**
3551          * @name Angle#radiuspoint
3552          * @type Object
3553          * @deprecated
3554          */
3555         radiuspoint: {
3556             withLabel: false,
3557             visible: false,
3558             name: ''
3559         },
3560 
3561         /**
3562          * @name Angle#pointsquare
3563          * @type Object
3564          * @deprecated
3565          */
3566         pointsquare: {
3567             withLabel: false,
3568             visible: false,
3569             name: ''
3570         },
3571 
3572         /**
3573          * Attributes of the dot point marking right angles.
3574          * @name Angle#dot
3575          * @type Object
3576          * @default <tt>{face: 'o', size: 2}</tt>
3577          */
3578         dot: {
3579             visible: false,
3580             strokeColor: 'none',
3581             fillColor: '#000000',
3582             size: 2,
3583             face: 'o',
3584             withLabel: false,
3585             name: ''
3586         },
3587 
3588         label: {
3589             position: 'top',
3590             offset: [0, 0],
3591             strokeColor: Color.palette.blue
3592         },
3593 
3594         /**
3595          * Attributes for sub-element arc. In general, the arc will run through the first point and
3596          * thus will not have the same radius as the angle sector.
3597          *
3598          * @type Arc
3599          * @name Angle#arc
3600          * @default '{visible:false}'
3601          */
3602         arc: {
3603             visible: false,
3604             fillColor: 'none'
3605         }
3606 
3607         /**#@-*/
3608     },
3609 
3610     /* special arc options */
3611     arc: {
3612         /**#@+
3613          * @visprop
3614          */
3615 
3616         /**
3617          * Type of arc. Possible values are 'minor', 'major', and 'auto'.
3618          *
3619          * @type String
3620          * @name Arc#selection
3621          * @default 'auto'
3622          */
3623         selection: 'auto',
3624 
3625         /**
3626          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
3627          *
3628          * @see JXG.GeometryElement#hasPoint
3629          * @name Arc#hasInnerPoints
3630          * @type Boolean
3631          * @default false
3632          */
3633         hasInnerPoints: false,
3634 
3635         label: {
3636             anchorX: 'auto',
3637             anchorY: 'auto'
3638         },
3639         firstArrow: false,
3640         lastArrow: false,
3641         fillColor: 'none',
3642         highlightFillColor: 'none',
3643         strokeColor: Color.palette.blue,
3644         highlightStrokeColor: '#c3d9ff',
3645         useDirection: false,
3646 
3647         /**
3648          * Attributes for center point.
3649          *
3650          * @type Point
3651          * @name Arc#center
3652          */
3653         center: {
3654         },
3655 
3656         /**
3657          * Attributes for radius point.
3658          *
3659          * @type Point
3660          * @name Arc#radiusPoint
3661          */
3662         radiusPoint: {
3663         },
3664 
3665         /**
3666          * Attributes for angle point.
3667          *
3668          * @type Point
3669          * @name Arc#anglePoint
3670          */
3671         anglePoint: {
3672         }
3673 
3674         /**#@-*/
3675     },
3676 
3677     /* special arrow options */
3678     arrow: {
3679         /**#@+
3680          * @visprop
3681          */
3682 
3683         firstArrow: false,
3684 
3685         lastArrow: {
3686             type: 1,
3687             highlightSize: 6,
3688             size: 6
3689         }
3690 
3691         /**#@-*/
3692     },
3693 
3694     /* special arrowparallel options */
3695     arrowparallel: {
3696         /**#@+
3697          * @visprop
3698          */
3699 
3700         firstArrow: false,
3701 
3702         lastArrow: {
3703             type: 1,
3704             highlightSize: 6,
3705             size: 6
3706         }
3707 
3708         /**#@-*/
3709     },
3710 
3711     /* special axis options */
3712     axis: {
3713         /**#@+
3714          * @visprop
3715          */
3716 
3717         name: '',                            // By default, do not generate names for axes.
3718         needsRegularUpdate: false,           // Axes only updated after zooming and moving of the origin.
3719         strokeWidth: 1,
3720         lastArrow: {
3721             type: 1,
3722             highlightSize: 8,
3723             size: 8
3724         },
3725         strokeColor: '#666666',
3726         highlightStrokeWidth: 1,
3727         highlightStrokeColor: '#888888',
3728 
3729         /**
3730          * Is used to define the behaviour of the axis.
3731          * Settings in this attribute only have an effect if the axis is exactly horizontal or vertical.
3732          * Possible values are:
3733          * <ul>
3734          *     <li><tt>'static'</tt>: Standard behavior of the axes as know in JSXGraph.
3735          *     <li><tt>'fixed'</tt>: The axis is placed in a fixed position. Depending on the attribute <tt>anchor</tt>, it is positioned to the right or left of the edge of the board as seen from the axis with a distance defined in <tt>distanceBoarder</tt>. The axis will stay at the given position, when the user navigates through the board.
3736          *     <li><tt>'sticky'</tt>: This mixes the two settings <tt>static</tt> and <tt>fixed</tt>. When the user navigates in the board, the axis remains in the visible area (taking into account <tt>anchor</tt> and <tt>anchorDist</tt>). If the axis itself is in the visible area, the axis can be moved by navigation.
3737          * </ul>
3738          *
3739          * @type {String}
3740          * @name Axis#position
3741          * @default 'static'
3742          * @see Axis#anchor
3743          * @see Axis#anchorDist
3744          *
3745          * @example // Use navigation to see effect.
3746          *  var axis1, axis2, circle;
3747          *
3748          *  board.create('axis', [[0,0],[1,0]],{
3749          *      position: 'fixed',
3750          *      anchor: 'right',
3751          *      anchorDist: '0.1fr'
3752          *  });
3753          *
3754          *  board.create('axis', [[0,0],[0,1]], {
3755          *      position: 'fixed',
3756          *      anchor: 'left',
3757          *      anchorDist: 1
3758          *  });
3759          *
3760          * </pre><div id="JXG6dff2f81-65ce-46a3-bea0-8ce25cc1cb4a" class="jxgbox" style="width: 300px; height: 300px;"></div>
3761          * <script type="text/javascript">
3762          *     (function() {
3763          *      var board = JXG.JSXGraph.initBoard('JXG6dff2f81-65ce-46a3-bea0-8ce25cc1cb4a',
3764          *             {boundingbox: [-1, 10, 10,-1], axis: false, showcopyright: false, shownavigation: true});
3765          *
3766          *      board.create('axis', [[0,0],[1,0]],{
3767          *          position: 'fixed',
3768          *          anchor: 'right',
3769          *          anchorDist: '0.1fr'
3770          *      });
3771          *
3772          *      board.create('axis', [[0,0],[0,1]], {
3773          *          position: 'fixed',
3774          *          anchor: 'left',
3775          *          anchorDist: 1
3776          *      });
3777          *
3778          *      board.create('circle', [[5,5], 2.5]);
3779          *     })();
3780          *
3781          * </script><pre>
3782          *
3783          * @example // Use navigation to see effect.
3784          *      board.create('axis', [[0,0],[1,0]],{
3785          *          position: 'sticky',
3786          *          anchor: 'right',
3787          *          anchorDist: '0.2fr'
3788          *      });
3789          *
3790          *      board.create('axis', [[0,0],[0,1]], {
3791          *          position: 'sticky',
3792          *          anchor: 'right left',
3793          *          anchorDist: '75px'
3794          *      });
3795          *
3796          * </pre><div id="JXG42a90935-80aa-4a6b-8adf-279deef84485" class="jxgbox" style="width: 300px; height: 300px;"></div>
3797          * <script type="text/javascript">
3798          *     (function() {
3799          *          var board = JXG.JSXGraph.initBoard('JXG42a90935-80aa-4a6b-8adf-279deef84485',
3800          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: true});
3801          *          board.create('axis', [[0,0],[1,0]],{
3802          *              position: 'sticky',
3803          *              anchor: 'right',
3804          *              anchorDist: '0.2fr'
3805          *          });
3806          *
3807          *          board.create('axis', [[0,0],[0,1]], {
3808          *              position: 'sticky',
3809          *              anchor: 'right left',
3810          *              anchorDist: '75px'
3811          *          });
3812          *
3813          *          board.create('functiongraph', [function(x){ return 1/(x-5) + 2;}]);
3814          *     })();
3815          *
3816          * </script><pre>
3817          *
3818          */
3819         position: 'static',
3820 
3821         /**
3822          * Position is used in cases: <tt>position=='sticky'</tt> or <tt>position=='fixed'</tt>.
3823          * Possible values are <tt>'right'</tt>, <tt>'left'</tt>, <tt>'right left'</tt>. Left and right indicate the side as seen from the axis.
3824          * It is used in combination with the attribute position to decide on which side of the board the axis should stick or be fixed.
3825          *
3826          * @type {String}
3827          * @name Axis#anchor
3828          * @default ''
3829          * @example
3830          *  board.create('axis', [[0,0],[0,1]],{
3831          *      position: 'fixed',
3832          *      anchor: 'left',
3833          *      anchorDist: 2,
3834          *      strokeColor : 'green',
3835          *      ticks: {
3836          *          majorHeight: 7,
3837          *          drawZero: true,
3838          *      }
3839          *  });
3840          *
3841          *  board.create('axis', [[0,0],[0,1]], {
3842          *      position: 'fixed',
3843          *      anchor: 'right',
3844          *      anchorDist: 2,
3845          *      strokeColor : 'blue',
3846          *      ticks: {
3847          *          majorHeight: 7,
3848          *          drawZero: true,
3849          *      }
3850          *  });
3851          *
3852          *  board.create('axis', [[0,0],[0,-1]], {
3853          *      position: 'fixed',
3854          *      anchor: 'left',
3855          *      anchorDist: 4,
3856          *      strokeColor : 'red',
3857          *      ticks:{
3858          *          majorHeight: 7,
3859          *          drawZero: true,
3860          *      }
3861          *  });
3862          *
3863          * </pre><div id="JXG11448b49-02b4-48d4-b0e0-8f06a94e909c" class="jxgbox" style="width: 300px; height: 300px;"></div>
3864          * <script type="text/javascript">
3865          *     (function() {
3866          *      var board = JXG.JSXGraph.initBoard('JXG11448b49-02b4-48d4-b0e0-8f06a94e909c',
3867          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: true});
3868          *
3869          *      board.create('axis', [[0,0],[0,1]],{
3870          *          position: 'fixed',
3871          *          anchor: 'left',
3872          *          anchorDist: 4,
3873          *          strokeColor : 'green',
3874          *          ticks: {
3875          *              majorHeight: 7,
3876          *              drawZero: true,
3877          *          }
3878          *      });
3879          *
3880          *      board.create('axis', [[0,0],[0,1]], {
3881          *          position: 'fixed',
3882          *          anchor: 'right',
3883          *          anchorDist: 2,
3884          *          strokeColor : 'blue',
3885          *          ticks: {
3886          *              majorHeight: 7,
3887          *              drawZero: true,
3888          *          }
3889          *      });
3890          *
3891          *      board.create('axis', [[0,0],[0,-1]], {
3892          *          position: 'fixed',
3893          *          anchor: 'left',
3894          *          anchorDist: 4,
3895          *          strokeColor : 'red',
3896          *          ticks:{
3897          *              majorHeight: 7,
3898          *              drawZero: true,
3899          *          }
3900          *      });
3901          *
3902          *     })();
3903          *
3904          * </script><pre>
3905          */
3906         anchor: '',
3907 
3908         /**
3909          * Used to define at which distance to the edge of the board the axis should stick or be fixed.
3910          * This only has an effect if <tt>position=='sticky'</tt> or <tt>position=='fixed'</tt>.
3911          * There are the following possibilities:
3912          * <ul>
3913          *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as usrCoords.
3914          *     <li>Strings with the unit 'px' are interpreted as screen pixels.
3915          *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)
3916          * </ul>
3917          *
3918          * @type {Number|String}
3919          * @name Axis#anchorDist
3920          * @default '10%'
3921          */
3922         anchorDist: '10%',
3923 
3924         /**
3925          * If set to true, the tick labels of the axis are automatically positioned in the narrower area between the axis and the side of the board.
3926          * Settings in this attribute only have an effect if the axis is exactly horizontal or vertical.
3927          * This option overrides <tt>offset</tt>, <tt>anchorX</tt> and <tt>anchorY</tt> of axis tick labels.
3928          *
3929          * @type {Boolean}
3930          * @name Axis#ticksAutoPos
3931          * @default false
3932          * @example
3933          * // Navigate to see an effect.
3934          * board.create('axis', [[0, 0], [1, 0]], {
3935          *     position: 'sticky',
3936          *     anchor: 'left right',
3937          *     anchorDist: '0.1',
3938          *     ticksAutoPos: true,
3939          * });
3940          *
3941          * board.create('axis', [[0, 0], [0, 1]], {
3942          *     position: 'sticky',
3943          *     anchor: 'left right',
3944          *     anchorDist: '0.1',
3945          *     ticksAutoPos: true,
3946          * });
3947          *
3948          * </pre><div id="JXG557c9b5d-e1bd-4d3b-8362-ff7a863255f3" class="jxgbox" style="width: 300px; height: 300px;"></div>
3949          * <script type="text/javascript">
3950          *     (function() {
3951          *         var board = JXG.JSXGraph.initBoard('JXG557c9b5d-e1bd-4d3b-8362-ff7a863255f3',
3952          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
3953          *
3954          *     board.create('axis', [[0, 0], [1, 0]], {
3955          *         position: 'sticky',
3956          *         anchor: 'left right',
3957          *         anchorDist: '0.1',
3958          *         ticksAutoPos: true,
3959          *     });
3960          *
3961          *     board.create('axis', [[0, 0], [0, 1]], {
3962          *         position: 'sticky',
3963          *         anchor: 'left right',
3964          *         anchorDist: '0.1',
3965          *         ticksAutoPos: true,
3966          *     });
3967          *
3968          *     })();
3969          *
3970          * </script><pre>
3971          */
3972         ticksAutoPos: false,
3973 
3974         /**
3975          * Defines, when <tt>ticksAutoPos</tt> takes effect.
3976          * There are the following possibilities:
3977          * <ul>
3978          *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as usrCoords.
3979          *     <li>Strings with the unit 'px' are interpreted as screen pixels.
3980          *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)
3981          * </ul>
3982          *
3983          * @type {Number|String}
3984          * @name Axis#ticksAutoPosThreshold
3985          * @default '5%'
3986          */
3987         ticksAutoPosThreshold: '5%',
3988 
3989         /**
3990          * Show / hide ticks.
3991          *
3992          * Deprecated. Suggested alternative is "ticks: {visible: false}"
3993          *
3994          * @type Boolean
3995          * @name Axis#withTicks
3996          * @default true
3997          * @deprecated
3998          */
3999         withTicks: true,
4000         straightFirst: true,
4001         straightLast: true,
4002         margin: -4,
4003         withLabel: false,
4004         scalable: false,
4005 
4006         /**
4007          * Attributes for ticks of the axis.
4008          *
4009          * @type Ticks
4010          * @name Axis#ticks
4011          */
4012         ticks: {
4013             label: {
4014                 offset: [4, -12 + 3],     // This seems to be a good offset for 12 point fonts
4015                 parse: false,
4016                 needsRegularUpdate: false,
4017                 display: 'internal',
4018                 visible: 'inherit',
4019                 layer: 9
4020             },
4021             visible: 'inherit',
4022             needsRegularUpdate: false,
4023             strokeWidth: 1,
4024             strokeColor: '#666666',
4025             highlightStrokeColor: '#888888',
4026             drawLabels: true,
4027             drawZero: false,
4028             insertTicks: true,
4029             minTicksDistance: 5,
4030             minorHeight: 10,          // if <0: full width and height
4031             majorHeight: -1,          // if <0: full width and height
4032             tickEndings: [0, 1],
4033             majorTickEndings: [1, 1],
4034             minorTicks: 4,
4035             ticksDistance: 1,         // TODO doc
4036             strokeOpacity: 0.25
4037         },
4038 
4039         /**
4040          * Attributes for first point the axis.
4041          *
4042          * @type Point
4043          * @name Axis#point1
4044          */
4045         point1: {                  // Default values for point1 if created by line
4046             needsRegularUpdate: false,
4047             visible: false
4048         },
4049 
4050         /**
4051          * Attributes for second point the axis.
4052          *
4053          * @type Point
4054          * @name Axis#point2
4055          */
4056         point2: {                  // Default values for point2 if created by line
4057             needsRegularUpdate: false,
4058             visible: false
4059         },
4060 
4061         tabindex: -1,
4062 
4063         /**
4064          * Attributes for the axis label.
4065          *
4066          * @type Label
4067          * @name Axis#label
4068          */
4069         label: {
4070             position: 'lft',
4071             offset: [10, 10]
4072         }
4073 
4074         /**#@-*/
4075     },
4076 
4077     /* special options for angle bisector of 3 points */
4078     bisector: {
4079         /**#@+
4080          * @visprop
4081          */
4082 
4083         strokeColor: '#000000', // Bisector line
4084 
4085         /**
4086          * Attributes for the helper point of the bisector.
4087          *
4088          * @type Point
4089          * @name Bisector#point
4090          */
4091         point: {               // Bisector point
4092             visible: false,
4093             fixed: false,
4094             withLabel: false,
4095             name: ''
4096         }
4097 
4098         /**#@-*/
4099     },
4100 
4101     /* special options for the 2 bisectors of 2 lines */
4102     bisectorlines: {
4103         /**#@+
4104          * @visprop
4105          */
4106 
4107         /**
4108          * Attributes for first line.
4109          *
4110          * @type Line
4111          * @name Bisectorlines#line1
4112          */
4113         line1: {               //
4114             strokeColor: '#000000'
4115         },
4116 
4117         /**
4118          * Attributes for second line.
4119          *
4120          * @type Line
4121          * @name Bisectorlines#line2
4122          */
4123         line2: {               //
4124             strokeColor: '#000000'
4125         }
4126 
4127         /**#@-*/
4128     },
4129 
4130     /* special options for boxplot curves */
4131     boxplot: {
4132         /**#@+
4133          * @visprop
4134          */
4135 
4136         /**
4137          *  Direction of the box plot: 'vertical' or 'horizontal'
4138          *
4139          * @type String
4140          * @name Boxplot#dir
4141          * @default 'vertical'
4142          */
4143         dir: 'vertical',
4144 
4145         /**
4146          * Relative width of the maximum and minimum quantile
4147          *
4148          * @type Number
4149          * @name Boxplot#smallWidth
4150          * @default 0.5
4151          */
4152         smallWidth: 0.5,
4153 
4154         strokeWidth: 2,
4155         strokeColor: Color.palette.blue,
4156         fillColor: Color.palette.blue,
4157         fillOpacity: 0.2,
4158         highlightStrokeWidth: 2,
4159         highlightStrokeColor: Color.palette.blue,
4160         highlightFillColor: Color.palette.blue,
4161         highlightFillOpacity: 0.1
4162 
4163         /**#@-*/
4164     },
4165 
4166     /* special button options */
4167     button: {
4168         /**#@+
4169          * @visprop
4170          */
4171 
4172         /**
4173          * Control the attribute "disabled" of the HTML button.
4174          *
4175          * @name disabled
4176          * @memberOf Button.prototype
4177          *
4178          * @type Boolean
4179          * @default false
4180          */
4181         disabled: false,
4182 
4183         display: 'html'
4184 
4185         /**#@-*/
4186     },
4187 
4188     /* special cardinal spline options */
4189     cardinalspline: {
4190         /**#@+
4191          * @visprop
4192          */
4193 
4194         /**
4195          * Controls if the data points of the cardinal spline when given as
4196          * arrays should be converted into {@link JXG.Points}.
4197          *
4198          * @name createPoints
4199          * @memberOf Cardinalspline.prototype
4200          *
4201          * @see Cardinalspline#points
4202          *
4203          * @type Boolean
4204          * @default true
4205          */
4206         createPoints: true,
4207 
4208         /**
4209          * If set to true, the supplied coordinates are interpreted as
4210          * [[x_0, y_0], [x_1, y_1], p, ...].
4211          * Otherwise, if the data consists of two arrays of equal length,
4212          * it is interpreted as
4213          * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]
4214          *
4215          * @name isArrayOfCoordinates
4216          * @memberOf Cardinalspline.prototype
4217          * @type Boolean
4218          * @default true
4219          */
4220         isArrayOfCoordinates: true,
4221 
4222         /**
4223          * Attributes for the points generated by Cardinalspline in cases
4224          * {@link createPoints} is set to true
4225          *
4226          * @name points
4227          * @memberOf Cardinalspline.prototype
4228          *
4229          * @see Cardinalspline#createPoints
4230          * @type Object
4231          */
4232         points: {
4233             strokeOpacity: 0.05,
4234             fillOpacity: 0.05,
4235             highlightStrokeOpacity: 1.0,
4236             highlightFillOpacity: 1.0,
4237             withLabel: false,
4238             name: '',
4239             fixed: false
4240         }
4241 
4242         /**#@-*/
4243     },
4244 
4245     /* special chart options */
4246     chart: {
4247         /**#@+
4248          * @visprop
4249          */
4250 
4251         chartStyle: 'line',
4252         colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],
4253         highlightcolors: null,
4254         fillcolor: null,
4255         highlightonsector: false,
4256         highlightbysize: false,
4257 
4258         fillOpacity: 0.6,
4259         withLines: false,
4260 
4261         label: {
4262         }
4263         /**#@-*/
4264     },
4265 
4266     /* special html slider options */
4267     checkbox: {
4268         /**#@+
4269          * @visprop
4270          */
4271 
4272         /**
4273          * Control the attribute "disabled" of the HTML checkbox.
4274          *
4275          * @name disabled
4276          * @memberOf Checkbox.prototype
4277          *
4278          * @type Boolean
4279          * @default false
4280          */
4281         disabled: false,
4282 
4283         /**
4284          * Control the attribute "checked" of the HTML checkbox.
4285          *
4286          * @name checked
4287          * @memberOf Checkbox.prototype
4288          *
4289          * @type Boolean
4290          * @default false
4291          */
4292         checked: false,
4293 
4294         display: 'html'
4295 
4296         /**#@-*/
4297     },
4298 
4299     /*special circle options */
4300     circle: {
4301         /**#@+
4302          * @visprop
4303          */
4304 
4305         /**
4306          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
4307          *
4308          * @see JXG.GeometryElement#hasPoint
4309          * @name Circle#hasInnerPoints
4310          * @type Boolean
4311          * @default false
4312          */
4313         hasInnerPoints: false,
4314 
4315         fillColor: 'none',
4316         highlightFillColor: 'none',
4317         strokeColor: Color.palette.blue,
4318         highlightStrokeColor: '#c3d9ff',
4319 
4320         /**
4321          * Attributes for center point.
4322          *
4323          * @type Point
4324          * @name Circle#center
4325          */
4326         center: {
4327             visible: false,
4328             withLabel: false,
4329             fixed: false,
4330 
4331             fillColor: Color.palette.red,
4332             strokeColor: Color.palette.red,
4333             highlightFillColor: '#c3d9ff',
4334             highlightStrokeColor: '#c3d9ff',
4335             layer: 9,
4336 
4337             name: ''
4338         },
4339 
4340         /**
4341          * Attributes for center point.
4342          *
4343          * @type Point
4344          * @name Circle#point2
4345          */
4346         point2: {
4347             fillColor: Color.palette.red,
4348             strokeColor: Color.palette.red,
4349             highlightFillColor: '#c3d9ff',
4350             highlightStrokeColor: '#c3d9ff',
4351             layer: 9,
4352 
4353             visible: false,
4354             withLabel: false,
4355             fixed: false,
4356             name: ''
4357         },
4358 
4359         /**
4360          * Attributes for circle label.
4361          *
4362          * @type Label
4363          * @name Circle#label
4364          */
4365         label: {
4366             position: 'urt'
4367         }
4368         /**#@-*/
4369     },
4370 
4371     /* special options for circumcircle of 3 points */
4372     circumcircle: {
4373         /**#@+
4374          * @visprop
4375          */
4376 
4377         fillColor: 'none',
4378         highlightFillColor: 'none',
4379         strokeColor: Color.palette.blue,
4380         highlightStrokeColor: '#c3d9ff',
4381 
4382         /**
4383          * Attributes for center point.
4384          *
4385          * @type Point
4386          * @name Circumcircle#center
4387          */
4388         center: {               // center point
4389             visible: false,
4390             fixed: false,
4391             withLabel: false,
4392             fillColor: Color.palette.red,
4393             strokeColor: Color.palette.red,
4394             highlightFillColor: '#c3d9ff',
4395             highlightStrokeColor: '#c3d9ff',
4396             name: ''
4397         }
4398         /**#@-*/
4399     },
4400 
4401     circumcirclearc: {
4402         /**#@+
4403          * @visprop
4404          */
4405 
4406         fillColor: 'none',
4407         highlightFillColor: 'none',
4408         strokeColor: Color.palette.blue,
4409         highlightStrokeColor: '#c3d9ff',
4410 
4411         /**
4412          * Attributes for center point.
4413          *
4414          * @type Point
4415          * @name CircumcircleArc#center
4416          */
4417         center: {
4418             visible: false,
4419             withLabel: false,
4420             fixed: false,
4421             name: ''
4422         }
4423         /**#@-*/
4424     },
4425 
4426     /* special options for circumcircle sector of 3 points */
4427     circumcirclesector: {
4428         /**#@+
4429          * @visprop
4430          */
4431 
4432         useDirection: true,
4433         fillColor: Color.palette.yellow,
4434         highlightFillColor: Color.palette.yellow,
4435         fillOpacity: 0.3,
4436         highlightFillOpacity: 0.3,
4437         strokeColor: Color.palette.blue,
4438         highlightStrokeColor: '#c3d9ff',
4439 
4440         /**
4441          * Attributes for center point.
4442          *
4443          * @type Point
4444          * @name Circle#point
4445          */
4446         point: {
4447             visible: false,
4448             fixed: false,
4449             withLabel: false,
4450             name: ''
4451         }
4452         /**#@-*/
4453     },
4454 
4455     /* special options for comb */
4456     comb: {
4457         /**#@+
4458          * @visprop
4459          */
4460 
4461         /**
4462          * Frequency of comb elements.
4463          *
4464          * @type Number
4465          * @name Comb#frequency
4466          * @default 0.2
4467          */
4468         frequency: 0.2,
4469 
4470         /**
4471          * Width of the comb.
4472          *
4473          * @type Number
4474          * @name Comb#width
4475          * @default 0.4
4476          */
4477         width: 0.4,
4478 
4479         /**
4480          * Angle - given in radians - under which comb elements are positioned.
4481          *
4482          * @type Number
4483          * @name Comb#angle
4484          * @default Math.PI / 3 (i.e. π /3  or 60^° degrees)
4485          */
4486         angle: Math.PI / 3,
4487 
4488         /**
4489          * Should the comb go right to left instead of left to right.
4490          *
4491          * @type Boolean
4492          * @name Comb#reverse
4493          * @default false
4494          */
4495         reverse: false,
4496 
4497         /**
4498          * Attributes for first defining point of the comb.
4499          *
4500          * @type Point
4501          * @name Comb#point1
4502          */
4503         point1: {
4504             visible: false,
4505             withLabel: false,
4506             fixed: false,
4507             name: ''
4508         },
4509 
4510         /**
4511          * Attributes for second defining point of the comb.
4512          *
4513          * @type Point
4514          * @name Comb#point2
4515          */
4516         point2: {
4517             visible: false,
4518             withLabel: false,
4519             fixed: false,
4520             name: ''
4521         },
4522 
4523         // /**
4524         //  * Attributes for the curve displaying the comb.
4525         //  *
4526         //  * @type Curve
4527         //  * @name Comb#curve
4528         //  */
4529         // curve: {
4530         //     strokeWidth: 1,
4531         //     strokeColor: '#0000ff',
4532         //     fillColor: 'none'
4533         // },
4534         strokeWidth: 1,
4535         strokeColor: '#0000ff',
4536         fillColor: 'none'
4537     },
4538 
4539     /* special conic options */
4540     conic: {
4541         /**#@+
4542          * @visprop
4543          */
4544 
4545         fillColor: 'none',
4546         highlightFillColor: 'none',
4547         strokeColor: Color.palette.blue,
4548         highlightStrokeColor: '#c3d9ff',
4549 
4550         /**
4551          * Attributes for foci points.
4552          *
4553          * @type Point
4554          * @name Conic#foci
4555          */
4556         foci: {
4557             // points
4558             fixed: false,
4559             visible: false,
4560             withLabel: false,
4561             name: ''
4562         },
4563 
4564         /**
4565          * Attributes for center point.
4566          *
4567          * @type Point
4568          * @name Conic#center
4569          */
4570         center: {
4571             visible: false,
4572             withLabel: false,
4573             name: ''
4574         },
4575 
4576         /**
4577          * Attributes for five points defining the conic, if some of them are given as coordinates.
4578          *
4579          * @type Point
4580          * @name Conic#point
4581          */
4582         point: {
4583             withLabel: false,
4584             name: ''
4585         },
4586 
4587         /**
4588          * Attributes for parabola line in case the line is given by two
4589          * points or coordinate pairs.
4590          *
4591          * @type Line
4592          * @name Conic#line
4593          */
4594         line: {
4595             visible: false
4596         }
4597 
4598         /**#@-*/
4599     },
4600 
4601     /* special curve options */
4602     curve: {
4603         /**#@+
4604          * @visprop
4605          */
4606 
4607         strokeWidth: 1,
4608         strokeColor: Color.palette.blue,
4609         fillColor: 'none',
4610         fixed: true,
4611 
4612         /**
4613          * The curveType is set in {@link JXG.Curve#generateTerm} and used in {@link JXG.Curve#updateCurve}.
4614          * Possible values are <ul>
4615          * <li>'none'</li>
4616          * <li>'plot': Data plot</li>
4617          * <li>'parameter': we can not distinguish function graphs and parameter curves</li>
4618          * <li>'functiongraph': function graph</li>
4619          * <li>'polar'</li>
4620          * <li>'implicit' (not yet)</li></ul>
4621          * Only parameter and plot are set directly. Polar is set with {@link JXG.GeometryElement#setAttribute} only.
4622          * @name Curve#curveType
4623          * @type String
4624          * @default null
4625          */
4626         curveType: null,
4627 
4628         /**
4629          * If true use a recursive bisection algorithm.
4630          * It is slower, but usually the result is better. It tries to detect jumps
4631          * and singularities.
4632          *
4633          * @name Curve#doAdvancedPlot
4634          * @type Boolean
4635          * @default true
4636          */
4637         doAdvancedPlot: true,
4638 
4639         /**
4640          * If true use the algorithm by Gillam and Hohenwarter, which was default until version 0.98.
4641          *
4642          * @name Curve#doAdvancedPlotOld
4643          * @see Curve#doAdvancedPlot
4644          * @type Boolean
4645          * @default false
4646          * @deprecated
4647          */
4648         doAdvancedPlotOld: false,   // v1
4649 
4650         /**
4651          * Configure arrow head at the start position for curve.
4652          * Recommended arrow head type is 7.
4653          *
4654          * @name Curve#firstArrow
4655          * @type Boolean | Object
4656          * @default false
4657          * @see Line#firstArrow for options
4658          */
4659         firstArrow: false,
4660 
4661         /**
4662          * The data points of the curve are not connected with straight lines but with bezier curves.
4663          * @name Curve#handDrawing
4664          * @type Boolean
4665          * @default false
4666          */
4667         handDrawing: false,
4668 
4669         /**
4670          * Attributes for curve label.
4671          *
4672          * @type Label
4673          * @name Curve#label
4674          */
4675         label: {
4676             position: 'lft'
4677         },
4678 
4679         /**
4680          * Configure arrow head at the end position for curve.
4681          * Recommended arrow head type is 7.
4682          *
4683          * @name Curve#lastArrow
4684          * @see Line#lastArrow for options
4685          * @type Boolean | Object
4686          * @default false
4687          */
4688         lastArrow: false,
4689 
4690         /**
4691          * Line endings (linecap) of a curve stroke.
4692          * Possible values are:
4693          * <ul>
4694          * <li> 'butt',
4695          * <li> 'round',
4696          * <li> 'square'.
4697          * </ul>
4698          *
4699          * @name JXG.Curve#lineCap
4700          * @type String
4701          * @default 'round'
4702          */
4703         lineCap: 'round',
4704 
4705         /**
4706          * Number of points used for plotting triggered by up events
4707          * (i.e. high quality plotting) in case
4708          * {@link Curve#doAdvancedPlot} is false.
4709          *
4710          * @name Curve#numberPointsHigh
4711          * @see Curve#doAdvancedPlot
4712          * @type Number
4713          * @default 1600
4714          */
4715         numberPointsHigh: 1600,  // Number of points on curves after mouseUp
4716 
4717         /**
4718          * Number of points used for plotting triggered by move events
4719          * (i.e. lower quality plotting but fast) in case
4720          * {@link Curve#doAdvancedPlot} is false.
4721          *
4722          * @name Curve#numberPointsLow
4723          * @see Curve#doAdvancedPlot
4724          * @type Number
4725          * @default 400
4726          */
4727         numberPointsLow: 400,    // Number of points on curves after mousemove
4728 
4729         /**
4730          * Select the version of the plot algorithm.
4731          * <ul>
4732          * <li> Version 1 is very outdated
4733          * <li> Version 2 is the default version in JSXGraph v0.99.*, v1.0, and v1.1, v1.2.0
4734          * <li> Version 3 is an internal version that was never published in  a stable version.
4735          * <li> Version 4 is available since JSXGraph v1.2.0
4736          * </ul>
4737          * Version 4 plots correctly logarithms if the function term is supplied as string (i.e. as JessieCode)
4738          *
4739          * @example
4740          *   var c = board.create('functiongraph', ["log(x)"]);
4741          *
4742          * @name Curve#plotVersion
4743          * @type Number
4744          * @default 2
4745          */
4746         plotVersion: 2,
4747 
4748         /**
4749          * Configure arrow head at the start position for curve.
4750          * Recommended arrow head type is 7.
4751          *
4752          * @name Curve#recursionDepthHigh
4753          * @see Curve#doAdvancedPlot
4754          * @type Number
4755          * @default 17
4756          */
4757         recursionDepthHigh: 17,
4758 
4759         /**
4760          * Number of points used for plotting triggered by move events in case
4761          * (i.e. lower quality plotting but fast)
4762          * {@link Curve#doAdvancedPlot} is true.
4763          *
4764          * @name Curve#recursionDepthLow
4765          * @see Curve#doAdvancedPlot
4766          * @type Number
4767          * @default 13
4768          */
4769         recursionDepthLow: 15
4770 
4771         /**#@-*/
4772     },
4773 
4774     /* special foreignObject options */
4775     foreignobject: {
4776         /**#@+
4777          * @visprop
4778          */
4779 
4780         fixed: true,
4781         visible: true,
4782         needsRegularUpdate: false,
4783 
4784         /**
4785          * List of attractor elements. If the distance of the foreignobject is less than
4786          * attractorDistance the foreignobject is made to glider of this element.
4787          *
4788          * @name ForeignObject#attractors
4789          *
4790          * @type Array
4791          * @default empty
4792          */
4793         attractors: []
4794 
4795         /**#@-*/
4796     },
4797 
4798     /* special functiongraph options */
4799     functiongraph: {
4800         /**#@+
4801          * @visprop
4802          */
4803 
4804 
4805         /**#@-*/
4806     },
4807 
4808     /* special glider options */
4809     glider: {
4810         /**#@+
4811          * @visprop
4812          */
4813 
4814         label: {}
4815         /**#@-*/
4816     },
4817 
4818     /* special grid options */
4819     grid: {
4820         /**#@+
4821          * @visprop
4822          */
4823 
4824         needsRegularUpdate: false,
4825         hasGrid: false,  // Used in standardoptions
4826 
4827         /**
4828          * Deprecated. Use {@link Grid#majorStep} instead.
4829          *
4830          * @deprecated
4831          * @type {Number|String}
4832          * @name Grid#gridX
4833          * @default null
4834          */
4835         gridX: null,
4836 
4837         /**
4838          * Deprecated. Use {@link Grid#majorStep} instead.
4839          *
4840          * @deprecated
4841          * @type {Number|String}
4842          * @name Grid#gridY
4843          * @default null
4844          */
4845         gridY: null,
4846 
4847         /**
4848          * Distance of major grid elements. There are three possibilities:
4849          * <ul>
4850          *     <li>If it is set to 'auto' the distance of the major grid equals the distance of majorTicks of the corresponding axis.
4851          *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as distance in usrCoords.
4852          *     <li>Strings with the unit 'px' are interpreted as distance in screen pixels.
4853          *     <li>Strings with the unit '%' or 'fr' are interpreted as a ratio to the width/height of the board. (e.g. 50% = 0.5fr)
4854          * </ul>
4855          * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.
4856          * These are used as distance in x- and y-direction.
4857          *
4858          * @type {Number|String|Array}
4859          * @name Grid#majorStep
4860          * @default 'auto'
4861          * @see JXG.Ticks#getDistanceMajorTicks
4862          */
4863         majorStep: 'auto',
4864 
4865         /**
4866          * Number of elements in minor grid between elements of the major grid. There are three possibilities:
4867          * <ul>
4868          *     <li>If set to 'auto', the number minor elements is equal to the number of minorTicks of the corresponding axis.
4869          *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as quantity.
4870          * </ul>
4871          * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.
4872          * These are used as number in x- and y-direction.
4873          *
4874          * @type {Number|String|Array}
4875          * @name Grid#minorElements
4876          * @default 0
4877          */
4878         minorElements: 0,
4879 
4880         /**
4881          * To print a quadratic grid with same distance of major grid elements in x- and y-direction.
4882          * <tt>'min'</tt> or <tt>true</tt> will set both distances of major grid elements in x- and y-direction to the primarily lesser value,
4883          * <tt>'max'</tt> to the primarily greater value.
4884          *
4885          * @type {Boolean|String}
4886          * @name Grid#forceSquare
4887          * @default false
4888          */
4889         forceSquare: false,
4890 
4891         /**
4892          * To decide whether major or minor grid elements on boundaries of the boundingBox shall be shown, half-ones as well.
4893          *
4894          * @type {Boolean}
4895          * @name Grid#includeBoundaries
4896          * @default false
4897          */
4898         includeBoundaries: false,
4899 
4900         /**
4901          * This object contains the attributes for major grid elements.
4902          *
4903          * @see Grid#major_size
4904          * @see Grid#major_face
4905          * @see Grid#major_margin
4906          * @see Grid#major_drawZero
4907          * @see Grid#major_polygonVertices
4908          *
4909          * @name Grid#major
4910          * @type Object
4911          */
4912         major: {
4913 
4914             /**
4915              * Size of major grid elements. There are the following possibilities:
4916              * <ul>
4917              *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as size in pixels.
4918              *     <li>Strings with additional '%' (e.g. '95%') are interpreted as the ratio of used space for one element.
4919              * </ul>
4920              * Unused for 'line' and 'point', which will use the value of strokeWidth.
4921              * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.
4922              * These are used as size in x- and y-direction.
4923              *
4924              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#major}: <tt>major: {size: ...}</tt></i></b><br>
4925              *
4926              * @type {Number|String|Array}
4927              * @name Grid#major_size
4928              * @default 5
4929              */
4930             size: 5,
4931 
4932             /**
4933              * Appearance of major grid element.
4934              * There are different styles which differ in appearance.
4935              * Possible values are (comparing to {@link Point#face})
4936              * <table>
4937              * <tr><th>Input</th><th>Output</th><th>Fillable by fillColor,...</th></tr>
4938              * <tr><td>point, .</td><td>.</td><td>no</td></tr>
4939              * <tr><td>line</td><td>−</td><td>no</td></tr>
4940              * <tr><td>cross, x</td><td>x</td><td>no</td></tr>
4941              * <tr><td>circle, o</td><td>o</td><td>yes</td></tr>
4942              * <tr><td>square, []</td><td>[]</td><td>yes</td></tr>
4943              * <tr><td>plus, +</td><td>+</td><td>no</td></tr>
4944              * <tr><td>minus, -</td><td>-</td><td>no</td></tr>
4945              * <tr><td>divide, |</td><td>|</td><td>no</td></tr>
4946              * <tr><td>diamond, <></td><td><></td><td>yes</td></tr>
4947              * <tr><td>diamond2, <<>></td><td><> (bigger)</td><td>yes</td></tr>
4948              * <tr><td>triangleup, ^, a, A</td><td>^</td><td>no</td></tr>
4949              * <tr><td>triangledown, v</td><td>v</td><td>no</td></tr>
4950              * <tr><td>triangleleft, <</td><td> <</td><td>no</td></tr>
4951              * <tr><td>triangleright, ></td><td>></td><td>no</td></tr>
4952              * <tr><td>regularPolygon, regpol</td><td>⬡</td><td>yes</td></tr>
4953              * </table>
4954              *
4955              * <br><b><i>This attribute is a sub-entry of {@link Grid#major}: <tt>major: {face: ...}</tt></i></b><br>
4956              *
4957              * @type {String}
4958              * @name Grid#major_face
4959              * @default 'line'
4960              */
4961             face: 'line',
4962 
4963             /**
4964              * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
4965              * ends exactly at the border, if negative there is a margin to the inside, if positive the line
4966              * ends outside of the canvas (which is invisible).
4967              *
4968              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#major}: <tt>major: {margin: ...}</tt></i></b><br>
4969              *
4970              * @name Grid#major_margin
4971              * @type Number
4972              * @default 0
4973              */
4974             margin: 0,
4975 
4976             /**
4977              * This attribute determines whether the grid elements located at <tt>x=0</tt>, <tt>y=0</tt>
4978              * and especially at <tt>(0, 0)</tt> are displayed.
4979              * <ul>
4980              *     <li>If <tt>false</tt>, then all these elements are hidden.
4981              *     <li>If <tt>true</tt>, all these elements are shown.
4982              *     <li>If an object of the following form is given, the three cases can be distinguished individually:<br>
4983              *     <tt>{x: true|false, y: true|false, origin: true|false}</tt>
4984              * </ul>
4985              *
4986              * <br><b><i>This attribute is a sub-entry of {@link Grid#major}: <tt>major: {drawZero: ...}</tt></i></b><br>
4987              *
4988              * @type {Boolean|Object}
4989              * @name Grid#major_drawZero
4990              * @default false
4991              */
4992             drawZero: false,
4993 
4994             /**
4995              * Number of vertices for face 'polygon'.
4996              *
4997              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#major}: <tt>major: {polygonVertices: ...}</tt></i></b><br>
4998              *
4999              * @type {Number}
5000              * @name Grid#major_polygonVertices
5001              * @default 6
5002              */
5003             polygonVertices: 6,
5004 
5005             strokeColor: '#c0c0c0', // same in old grid
5006             strokeWidth: 1,         // same in old grid
5007             strokeOpacity: 0.5,     // same in old grid
5008             highlight: false
5009         },
5010 
5011         /**
5012          * This object contains the attributes for minor grid elements.
5013          *
5014          * @see Grid#minor_size
5015          * @see Grid#minor_face
5016          * @see Grid#minor_margin
5017          * @see Grid#minor_drawZero
5018          * @see Grid#minor_polygonVertices
5019          *
5020          * @name Grid#minor
5021          * @type Object
5022          */
5023         minor: {
5024 
5025             /**
5026              * @class
5027              * @ignore
5028              */
5029             visible: 'inherit',
5030 
5031             /**
5032              * Size of minor grid elements. There are the following possibilities:
5033              * <ul>
5034              *     <li>Numbers or strings which are numbers (e.g. '10') are interpreted as size in pixels.
5035              *     <li>Strings with additional '%' (e.g. '95%') are interpreted as the ratio of used space for one element.
5036              * </ul>
5037              * Unused for 'line' and 'point', which will use the value of strokeWidth.
5038              * Instead of one value you can provide two values as an array <tt>[x, y]</tt> here.
5039              * These are used as size in x- and y-direction.
5040              *
5041              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#minor}: <tt>minor: {size: ...}</tt></i></b><br>
5042              *
5043              * @type {Number|String|Array}
5044              * @name Grid#minor_size
5045              * @default 5
5046              */
5047             size: 3,
5048 
5049             /**
5050              * Appearance of minor grid elements. Same options as for major grid elements.
5051              *
5052              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#minor}: <tt>minor: {face: ...}</tt></i></b><br>
5053              *
5054              * @type {String}
5055              * @name Grid#minor_face
5056              * @default 'point'
5057              * @see Grid#major_face
5058              */
5059             face: 'point',
5060 
5061             /**
5062              * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
5063              * ends exactly at the border, if negative there is a margin to the inside, if positive the line
5064              * ends outside of the canvas (which is invisible).
5065              *
5066              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#minor}: <tt>minor: {margin: ...}</tt></i></b><br>
5067              *
5068              * @name Grid#minor_margin
5069              * @type Number
5070              * @default 0
5071              */
5072             margin: 0,
5073 
5074              /**
5075               * This attribute determines whether the minor grid elements located at <tt>x=0</tt> and <tt>y=0</tt> are displayed.
5076               * <ul>
5077               *     <li>If <tt>false</tt>, then all these elements are hidden.
5078               *     <li>If <tt>true</tt>, all these elements are shown.
5079               *     <li>If an object of the following form is given, the three cases can be distinguished individually:<br>
5080               *     <tt>{x: true|false, y: true|false}</tt>
5081               * </ul>
5082               *
5083               * <br><b><i>This attribute is a sub-entry of {@link Grid#minor}: <tt>minor: {drawZero: ...}</tt></i></b><br>
5084               *
5085               * @type {Boolean|Object}
5086               * @name Grid#minor_drawZero
5087               * @default false
5088               */
5089             drawZero: false,
5090 
5091             /**
5092              * Number of vertices for face 'polygon'.
5093              *
5094              * <br><br><b><i>This attribute is a sub-entry of {@link Grid#minor}: <tt>minor: {polygonVertices: ...}</tt></i></b><br>
5095              *
5096              * @type {Number}
5097              * @name Grid#minor_polygonVertices
5098              * @default 6
5099              */
5100             polygonVertices: 6,
5101 
5102             strokeColor: '#c0c0c0',
5103             strokeWidth: 1,
5104             strokeOpacity: 0.25,
5105             highlight: false
5106         },
5107 
5108         /**
5109          * @class
5110          * @ignore
5111          * @deprecated
5112          */
5113         snapToGrid: false,
5114 
5115         /**
5116          * Use a predefined theme for grid.
5117          * Attributes can be overwritten by explicitly set the specific value.
5118          *
5119          * @type {Number}
5120          * @default 0
5121          * @see Grid#themes
5122          */
5123         theme: 0,
5124 
5125         /**
5126          * Array of theme attributes.
5127          * The index of the entry is the number of the theme.
5128          *
5129          * @type {Array}
5130          * @name Grid#themes
5131          * @private
5132          *
5133          * @example
5134          * // Theme 1
5135          * // quadratic grid appearance with distance of major grid elements set to the primarily greater one
5136          *
5137          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5138          *     boundingbox: [-4, 4, 4, -4], axis: true,
5139          *     defaultAxes: {
5140          *         x: { ticks: {majorHeight: 10} },
5141          *         y: { ticks: {majorHeight: 10} }
5142          *     },
5143          *     grid: { theme: 1, color: 'grey' },
5144          * });
5145          * </pre> <div id="JXGb8d606c4-7c67-4dc0-9941-3b3bd0932898" class="jxgbox" style="width: 300px; height: 200px;"></div>
5146          * <script type="text/javascript">
5147          *     (function() {
5148          *         var board = JXG.JSXGraph.initBoard('JXGb8d606c4-7c67-4dc0-9941-3b3bd0932898',
5149          *             {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: false,
5150          *                 defaultAxes: {
5151          *                     x: { ticks: {majorHeight: 10} },
5152          *                     y: { ticks: {majorHeight: 10} }
5153          *                 },
5154          *                grid: { theme: 1, color: 'grey' },
5155          *             });
5156          *     })();
5157          * </script> <pre>
5158          *
5159          * @example
5160          * // Theme 2
5161          * // lines and subtile points in between
5162          *
5163          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5164          *     boundingbox: [-4, 4, 4, -4], axis: false,
5165          *     grid: { theme: 2, minorElements: 4, color: 'grey' },
5166          * });
5167          * </pre> <div id="JXG4e11e6e3-472a-48e0-b7d0-f80d397c769b" class="jxgbox" style="width: 300px; height: 300px;"></div>
5168          * <script type="text/javascript">
5169          *     (function() {
5170          *         var board = JXG.JSXGraph.initBoard('JXG4e11e6e3-472a-48e0-b7d0-f80d397c769b',
5171          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5172          *                 grid: { theme: 2, minorElements: 4, color: 'grey' },
5173          *             })
5174          *     })();
5175          * </script> <pre>
5176          *
5177          * @example
5178          * // Theme 3
5179          * // lines and thinner lines in between
5180          *
5181          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5182          *     boundingbox: [-4, 4, 4, -4], axis: false,
5183          *     grid: { theme: 4, minorElements: 4, color: 'grey' },
5184          * });
5185          * </pre> <div id="JXG334814a3-03a7-4231-a5a7-a42d3b8dc2de" class="jxgbox" style="width: 300px; height: 300px;"></div>
5186          * <script type="text/javascript">
5187          *     (function() {
5188          *         var board = JXG.JSXGraph.initBoard('JXG334814a3-03a7-4231-a5a7-a42d3b8dc2de',
5189          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5190          *                 grid: { theme: 4, minorElements: 4, color: 'grey' }
5191          *         });
5192          *     })();
5193          * </script> <pre>
5194          *
5195          * @example
5196          * // Theme 4
5197          * // lines with more subtle grid of '+'s plotted in between
5198          *
5199          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5200          *     boundingbox: [-4, 4, 4, -4], axis: false,
5201          *     grid: { theme: 5, minorElements: 4, color: 'grey' },
5202          * });
5203          * </pre> <div id="JXG9e2bb29c-d998-428c-9432-4a7bf6cd9222" class="jxgbox" style="width: 300px; height: 300px;"></div>
5204          * <script type="text/javascript">
5205          *     (function() {
5206          *         var board = JXG.JSXGraph.initBoard('JXG9e2bb29c-d998-428c-9432-4a7bf6cd9222',
5207          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5208          *                 grid: { theme: 5, minorElements: 4, color: 'grey' },
5209          *             });
5210          *     })();
5211          * </script> <pre>
5212          *
5213          * @example
5214          * // Theme 5
5215          * // grid of '+'s and more subtile points in between
5216          *
5217          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5218          *     boundingbox: [-4, 4, 4, -4], axis: false,
5219          *     grid: { theme: 6, minorElements: 4, color: 'grey' },
5220          * });
5221          * </pre> <div id="JXG6a967d83-4179-4827-9e97-63fbf1e872c8" class="jxgbox" style="width: 300px; height: 300px;"></div>
5222          * <script type="text/javascript">
5223          *     (function() {
5224          *         var board = JXG.JSXGraph.initBoard('JXG6a967d83-4179-4827-9e97-63fbf1e872c8',
5225          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5226          *                 grid: { theme: 6, minorElements: 4, color: 'grey' },
5227          *         });
5228          *     })();
5229          * </script> <pre>
5230          *
5231          * @example
5232          * // Theme 6
5233          * // grid of circles with subtile points in between
5234          *
5235          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5236          *     boundingbox: [-4, 4, 4, -4], axis: false,
5237          *     grid: { theme: 3, minorElements: 4, strokeColor: 'grey' },
5238          * });
5239          * </pre> <div id="JXG28bee3da-a7ef-4590-9a18-38d1b99d09ce" class="jxgbox" style="width: 300px; height: 300px;"></div>
5240          * <script type="text/javascript">
5241          *     (function() {
5242          *         var board = JXG.JSXGraph.initBoard('JXG28bee3da-a7ef-4590-9a18-38d1b99d09ce',
5243          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5244          *                 grid: { theme: 3, minorElements: 4, strokeColor: 'grey' },
5245          *         });
5246          *     })();
5247          * </script> <pre>
5248          *
5249          * @example
5250          * // Theme 7
5251          * // lines and subtile points in between, also plotted on axes
5252          *
5253          * const board = JXG.JSXGraph.initBoard('jxgbox', {
5254          *     boundingbox: [-4, 4, 4, -4], axis: false,
5255          *     grid: { theme: 7, minorElements: 4, color: 'grey' },
5256          * });
5257          * </pre> <div id="JXG7a787274-7f7e-4e10-b59c-f99f1aff35e7" class="jxgbox" style="width: 300px; height: 300px;"></div>
5258          * <script type="text/javascript">
5259          *     (function() {
5260          *         var board = JXG.JSXGraph.initBoard('JXG7a787274-7f7e-4e10-b59c-f99f1aff35e7',
5261          *             {boundingbox: [-4, 4, 4, -4], axis: false, showcopyright: false, shownavigation: false,
5262          *                 grid: { theme: 7, minorElements: 4, color: 'grey' },
5263          *         });
5264          *     })();
5265          * </script> <pre>
5266          */
5267         themes: [
5268             {
5269                 // default values
5270             },
5271 
5272             {   // Theme 1: quadratic grid appearance with distance of major grid elements in x- and y-direction set to the primarily smaller one
5273                 forceSquare: 'min'
5274             },
5275 
5276             {   // Theme 2: lines and subtile points in between
5277                 minor: {
5278                     size: 3,
5279                     strokeColor: '#101010'
5280                 },
5281                 minorElements: 'auto'
5282             },
5283 
5284             {   // Theme 3: lines and thinner lines in between
5285                 minor: {
5286                     face: 'line'
5287                 },
5288                 minorElements: 'auto'
5289             },
5290 
5291             {   // Theme 4: lines with more subtle grid of '+'s plotted in between
5292                 minor: {
5293                     face: '+',
5294                     size: '95%'
5295                 },
5296                 minorElements: 'auto'
5297             },
5298 
5299             {   // Theme 5: grid of '+'s and more subtile points in between
5300                 major: {
5301                     face: '+',
5302                     size: 10,
5303                     strokeOpacity: 1
5304                 },
5305                 minor: {
5306                     size: 3
5307                 },
5308                 minorElements: 'auto'
5309             },
5310 
5311             {   // Theme 6: grid of circles with subtile points in between
5312                 major: {
5313                     face: 'circle',
5314                     size: 5
5315                 },
5316                 minor: {
5317                     size: 3
5318                 },
5319                 minorElements: 'auto'
5320             },
5321 
5322             { // Theme 7: lines and subtile points in between, also plotted on axes
5323                 major: {
5324                     drawZero: true
5325                 },
5326                 minor: {
5327                     size: 3,
5328                     drawZero: true
5329                 },
5330                 minorElements: 4
5331             }
5332         ]
5333 
5334         /**#@-*/
5335     },
5336 
5337     group: {
5338         needsRegularUpdate: true
5339     },
5340 
5341     /* special html slider options */
5342     htmlslider: {
5343         /**#@+
5344          * @visprop
5345          */
5346 
5347         // /**
5348         //  *
5349         //  * These affect the DOM element input type="range".
5350         //  * The other attributes affect the DOM element div containing the range element.
5351         //  */
5352         widthRange: 100,
5353         widthOut: 34,
5354         step: 0.01,
5355 
5356         frozen: true,
5357         isLabel: false,
5358         strokeColor: '#000000',
5359         display: 'html',
5360         anchorX: 'left',
5361         anchorY: 'middle',
5362         withLabel: false
5363 
5364         /**#@-*/
5365     },
5366 
5367     /* special image options */
5368     image: {
5369         /**#@+
5370          * @visprop
5371          */
5372 
5373         imageString: null,
5374         fillOpacity: 1.0,
5375         highlightFillOpacity: 0.6,
5376 
5377 
5378         /**
5379          * Defines the CSS class used by the image. CSS attributes defined in
5380          * this class will overwrite the corresponding JSXGraph attributes, e.g.
5381          * opacity.
5382          * The default CSS class is defined in jsxgraph.css.
5383          *
5384          * @name Image#cssClass
5385          *
5386          * @see Image#highlightCssClass
5387          * @type String
5388          * @default 'JXGimage'
5389          */
5390         cssClass: 'JXGimage',
5391 
5392         /**
5393          * Defines the CSS class used by the image when highlighted.
5394          * CSS attributes defined in this class will overwrite the
5395          * corresponding JSXGraph attributes, e.g. highlightFillOpacity.
5396          * The default CSS class is defined in jsxgraph.css.
5397          *
5398          * @name Image#highlightCssClass
5399          *
5400          * @see Image#cssClass
5401          * @type String
5402          * @default 'JXGimageHighlight'
5403          */
5404         highlightCssClass: 'JXGimageHighlight',
5405 
5406         /**
5407          * Image rotation in degrees.
5408          *
5409          * @name Image#rotate
5410          * @type Number
5411          * @default 0
5412          */
5413         rotate: 0,
5414 
5415         /**
5416          * Defines together with {@link Image#snapSizeY} the grid the image snaps on to.
5417          * The image will only snap on user coordinates which are
5418          * integer multiples to snapSizeX in x and snapSizeY in y direction.
5419          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5420          * of the default ticks of the default x axes of the board.
5421          *
5422          * @name Image#snapSizeX
5423          *
5424          * @see Point#snapToGrid
5425          * @see Image#snapSizeY
5426          * @see JXG.Board#defaultAxes
5427          * @type Number
5428          * @default 1
5429          */
5430         snapSizeX: 1,
5431 
5432         /**
5433          * Defines together with {@link Image#snapSizeX} the grid the image snaps on to.
5434          * The image will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
5435          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5436          * of the default ticks of the default y axes of the board.
5437          *
5438          * @name Image#snapSizeY
5439          *
5440          * @see Point#snapToGrid
5441          * @see Image#snapSizeX
5442          * @see JXG.Board#defaultAxes
5443          * @type Number
5444          * @default 1
5445          */
5446         snapSizeY: 1,
5447 
5448         /**
5449          * List of attractor elements. If the distance of the image is less than
5450          * attractorDistance the image is made to glider of this element.
5451          *
5452          * @name Image#attractors
5453          *
5454          * @type Array
5455          * @default empty
5456          */
5457         attractors: []
5458 
5459         /**#@-*/
5460     },
5461 
5462     /* special implicitcurve options */
5463     implicitcurve: {
5464         /**#@+
5465          * @visprop
5466          */
5467 
5468         /**
5469          * Defines the margin (in user coordinates) around the JSXGraph board in which the
5470          * implicit curve is plotted.
5471          *
5472          * @name ImplicitCurve#margin
5473          * @type {Number|Function}
5474          * @default 1
5475          */
5476         margin: 1,
5477 
5478         /**
5479          * Horizontal resolution: distance (in pixel) between vertical lines to search for components of the implicit curve.
5480          * A small number increases the running time. For large number components may be missed.
5481          * Minimum value is 0.01.
5482          *
5483          * @name ImplicitCurve#resolution_outer
5484          * @type {Number|Function}
5485          * @default 5
5486          */
5487         resolution_outer: 5,
5488 
5489         /**
5490          * Vertical resolution (in pixel) to search for components of the implicit curve.
5491          * A small number increases the running time. For large number components may be missed.
5492          * Minimum value is 0.01.
5493          *
5494          * @name ImplicitCurve#resolution_inner
5495          * @type {Number|Function}
5496          * @default 5
5497          */
5498         resolution_inner: 5,
5499 
5500         /**
5501          * Maximum iterations for one component of the implicit curve.
5502          *
5503          * @name ImplicitCurve#max_steps
5504          * @type {Number|Function}
5505          * @default 1024
5506          */
5507         max_steps: 1024,
5508 
5509         /**
5510          * Angle α<sub>0</sub> between two successive tangents: determines the smoothness of
5511          * the curve.
5512          *
5513          * @name ImplicitCurve#alpha_0
5514          * @type {Number|Function}
5515          * @default 0.05
5516          */
5517         alpha_0: 0.05,
5518 
5519         /**
5520          * Tolerance to find starting points for the tracing phase of a component.
5521          *
5522          * @name ImplicitCurve#tol_0
5523          * @type {Number|Function}
5524          * @default JXG.Math.eps
5525          */
5526         tol_u0: Mat.eps,
5527 
5528         /**
5529          * Tolerance for the Newton steps.
5530          *
5531          * @name ImplicitCurve#tol_newton
5532          * @type {Number|Function}
5533          * @default 1.0e-7
5534          */
5535         tol_newton: 1.0e-7,
5536 
5537         /**
5538          * Tolerance for cusp / bifurcation detection.
5539          *
5540          * @name ImplicitCurve#tol_cusp
5541          * @type {Number|Function}
5542          * @default 0.05
5543          */
5544         tol_cusp: 0.05,
5545 
5546         /**
5547          * If two points are closer than this value, we bail out of the tracing phase for that
5548          * component.
5549          *
5550          * @name ImplicitCurve#tol_progress
5551          * @type {Number|Function}
5552          * @default 0.0001
5553          */
5554         tol_progress: 0.0001,
5555 
5556         /**
5557          * Half of the box size (in user units) to search for existing line segments in the quadtree.
5558          *
5559          * @name ImplicitCurve#qdt_box
5560          * @type {Number|Function}
5561          * @default 0.2
5562          */
5563         qdt_box: 0.2,
5564 
5565         /**
5566          * Inverse of desired number of Newton steps.
5567          *
5568          * @name ImplicitCurve#kappa_0
5569          * @type {Number|Function}
5570          * @default 0.2
5571          */
5572         kappa_0: 0.2,
5573 
5574         /**
5575          * Allowed distance (in user units) of predictor point to curve.
5576          *
5577          * @name ImplicitCurve#delta_0
5578          * @type {Number|Function}
5579          * @default 0.05
5580          */
5581         delta_0: 0.05,
5582 
5583         /**
5584          * Initial step width (in user units).
5585          *
5586          * @name ImplicitCurve#h_initial
5587          * @type {Number|Function}
5588          * @default 0.1
5589          */
5590         h_initial: 0.1,
5591 
5592         /**
5593          * If h is below this threshold (in user units), we bail out
5594          * of the tracing phase of that component.
5595          *
5596          * @name ImplicitCurve#h_critical
5597          * @type {Number|Function}
5598          * @default 0.001
5599          */
5600         h_critical: 0.001,
5601 
5602         /**
5603          * Maximum step width (in user units).
5604          *
5605          * @name ImplicitCurve#h_max
5606          * @type {Number|Function}
5607          * @default 1
5608          */
5609         h_max: 1,
5610 
5611         /**
5612          * Allowed distance (in user units multiplied by actual step width) to detect loop.
5613          *
5614          * @name ImplicitCurve#loop_dist
5615          * @type {Number|Function}
5616          * @default 0.09
5617          */
5618         loop_dist: 0.09,
5619 
5620         /**
5621          * Minimum acos of angle to detect loop.
5622          *
5623          * @name ImplicitCurve#loop_dir
5624          * @type {Number|Function}
5625          * @default 0.99
5626          */
5627         loop_dir: 0.99,
5628 
5629         /**
5630          * Use Gosper's loop detector.
5631          *
5632          * @name ImplicitCurve#loop_detection
5633          * @type {Boolean|Function}
5634          * @default true
5635          */
5636         loop_detection: true
5637 
5638         /**#@-*/
5639     },
5640 
5641     /* special options for incircle of 3 points */
5642     incircle: {
5643         /**#@+
5644          * @visprop
5645          */
5646 
5647         fillColor: 'none',
5648         highlightFillColor: 'none',
5649         strokeColor: Color.palette.blue,
5650         highlightStrokeColor: '#c3d9ff',
5651 
5652         /**
5653          * Attributes of circle center.
5654          *
5655          * @type Point
5656          * @name Incircle#center
5657          */
5658         center: {               // center point
5659             visible: false,
5660             fixed: false,
5661             withLabel: false,
5662             fillColor: Color.palette.red,
5663             strokeColor: Color.palette.red,
5664             highlightFillColor: '#c3d9ff',
5665             highlightStrokeColor: '#c3d9ff',
5666             name: ''
5667         }
5668         /**#@-*/
5669     },
5670 
5671     inequality: {
5672         /**#@+
5673          * @visprop
5674          */
5675 
5676         fillColor: Color.palette.red,
5677         fillOpacity: 0.2,
5678         strokeColor: 'none',
5679 
5680         /**
5681          * By default an inequality is less (or equal) than. Set inverse to <tt>true</tt> will consider the inequality
5682          * greater (or equal) than.
5683          *
5684          * @type Boolean
5685          * @default false
5686          * @name Inequality#inverse
5687          * @visprop
5688          */
5689         inverse: false
5690         /**#@-*/
5691     },
5692 
5693     infobox: {
5694         /**#@+
5695          * @visprop
5696          */
5697 
5698         /**
5699          * Horizontal offset in pixel of the infobox text from its anchor point.
5700          *
5701          * @type Number
5702          * @default -20
5703          * @name JXG.Board.infobox#distanceX
5704          * @visprop
5705          */
5706         distanceX: -20,
5707 
5708         /**
5709          * Vertical offset in pixel of the infobox text from its anchor point.
5710          *
5711          * @type Number
5712          * @default 25
5713          * @name JXG.Board.infobox#distanceY
5714          * @visprop
5715          */
5716         distanceY: 25,
5717 
5718         /**
5719          * Internationalization support for infobox text.
5720          *
5721          * @name JXG.Board.infobox#intl
5722          * @type object
5723          * @default <pre>{
5724          *    enabled: 'inherit',
5725          *    options: {}
5726          * }</pre>
5727          * @visprop
5728          * @see JXG.Board#intl
5729          * @see Text#intl
5730          */
5731         intl: {
5732             enabled: 'inherit',
5733             options: {}
5734         },
5735 
5736         fontSize: 12,
5737         isLabel: false,
5738         strokeColor: '#bbbbbb',
5739         display: 'html',             // 'html' or 'internal'
5740         anchorX: 'left',             //  'left', 'middle', or 'right': horizontal alignment
5741         //  of the text.
5742         anchorY: 'middle',           //  'top', 'middle', or 'bottom': vertical alignment
5743         //  of the text.
5744         cssClass: 'JXGinfobox',
5745         rotate: 0,                   // works for non-zero values only in combination
5746         // with display=='internal'
5747         visible: true,
5748         parse: false,
5749         transitionDuration: 0,
5750         needsRegularUpdate: false,
5751         tabindex: null,
5752         viewport: [0, 0, 0, 0]
5753 
5754         /**#@-*/
5755     },
5756 
5757     /* special options for integral */
5758     integral: {
5759         /**#@+
5760          * @visprop
5761          */
5762 
5763         axis: 'x',        // 'x' or 'y'
5764         withLabel: true,    // Show integral value as text
5765         fixed: true,
5766         strokeWidth: 0,
5767         strokeOpacity: 0,
5768         fillColor: Color.palette.red,
5769         fillOpacity: 0.3,
5770         highlightFillColor: Color.palette.red,
5771         highlightFillOpacity: 0.2,
5772 
5773         /**
5774          * Attributes of the (left) starting point of the integral.
5775          *
5776          * @type Point
5777          * @name Integral#curveLeft
5778          * @see Integral#baseLeft
5779          */
5780         curveLeft: {    // Start point
5781             visible: true,
5782             withLabel: false,
5783             color: Color.palette.red,
5784             fillOpacity: 0.8,
5785             layer: 9
5786         },
5787 
5788         /**
5789          * Attributes of the (left) base point of the integral.
5790          *
5791          * @type Point
5792          * @name Integral#baseLeft
5793          * @see Integral#curveLeft
5794          */
5795         baseLeft: {    // Start point
5796             visible: false,
5797             fixed: false,
5798             withLabel: false,
5799             name: ''
5800         },
5801 
5802         /**
5803          * Attributes of the (right) end point of the integral.
5804          *
5805          * @type Point
5806          * @name Integral#curveRight
5807          * @see Integral#baseRight
5808          */
5809         curveRight: {      // End point
5810             visible: true,
5811             withLabel: false,
5812             color: Color.palette.red,
5813             fillOpacity: 0.8,
5814             layer: 9
5815         },
5816 
5817         /**
5818          * Attributes of the (right) base point of the integral.
5819          *
5820          * @type Point
5821          * @name Integral#baseRight
5822          * @see Integral#curveRight
5823          */
5824         baseRight: {      // End point
5825             visible: false,
5826             fixed: false,
5827             withLabel: false,
5828             name: ''
5829         },
5830 
5831         /**
5832          * Attributes for integral label.
5833          *
5834          * @type Label
5835          * @name Integral#label
5836          * @default <pre>{
5837          *      fontSize: 20,
5838          *      digits: 4,
5839          *      intl: {
5840          *          enabled: false,
5841          *          options: {}
5842          *      }
5843          *    }</pre>
5844          */
5845         label: {
5846             fontSize: 20,
5847             digits: 4,
5848             intl: {
5849                 enabled: false,
5850                 options: {}
5851             }
5852         }
5853         /**#@-*/
5854     },
5855 
5856     /* special input options */
5857     input: {
5858         /**#@+
5859          * @visprop
5860          */
5861 
5862         /**
5863          * Control the attribute "disabled" of the HTML input field.
5864          *
5865          * @name disabled
5866          * @memberOf Input.prototype
5867          *
5868          * @type Boolean
5869          * @default false
5870          */
5871         disabled: false,
5872 
5873         /**
5874          * Control the attribute "maxlength" of the HTML input field.
5875          *
5876          * @name maxlength
5877          * @memberOf Input.prototype
5878          *
5879          * @type Number
5880          * @default 524288 (as in HTML)
5881          */
5882         maxlength: 524288,
5883 
5884         display: 'html'
5885 
5886         /**#@-*/
5887     },
5888 
5889     /* special intersection point options */
5890     intersection: {
5891         /**#@+
5892          * @visprop
5893          */
5894 
5895         /**
5896          * Used in {@link JXG.Intersection}.
5897          * This flag sets the behaviour of intersection points of e.g.
5898          * two segments. If true, the intersection is treated as intersection of lines. If false
5899          * the intersection point exists if the segments intersect setwise.
5900          *
5901          * @name Intersection.alwaysIntersect
5902          * @type Boolean
5903          * @default true
5904          */
5905         alwaysIntersect: true
5906 
5907         /**#@-*/
5908     },
5909 
5910     /* special label options */
5911     label: {
5912         /**#@+
5913          * @visprop
5914          */
5915 
5916         visible: 'inherit',
5917         strokeColor: '#000000',
5918         strokeOpacity: 1,
5919         highlightStrokeOpacity: 0.666666,
5920         highlightStrokeColor: '#000000',
5921 
5922         fixed: true,
5923 
5924         /**
5925          * Possible string values for the position of a label for
5926          * label anchor points are:
5927          * <ul>
5928          * <li> 'first' (lines only)
5929          * <li> 'last' (lines only)
5930          * <li> 'lft'
5931          * <li> 'rt'
5932          * <li> 'top'
5933          * <li> 'bot'
5934          * <li> 'ulft'
5935          * <li> 'urt'
5936          * <li> 'llft'
5937          * <li> 'lrt'
5938          * </ul>
5939          * This is relevant for non-points: line, circle, curve.
5940          *
5941          * The names have been borrowed from <a href="https://www.tug.org/metapost.html">MetaPost</a>.
5942          *
5943          * @name Label#position
5944          * @see Label#offset
5945          * @type String
5946          * @default 'urt'
5947          */
5948         position: 'urt',
5949 
5950         /**
5951          *  Label offset from label anchor.
5952          *  The label anchor is determined by {@link Label#position}
5953          *
5954          * @name Label#offset
5955          * @see Label#position
5956          * @type Array
5957          * @default [10,10]
5958          */
5959         offset: [10, 10],
5960 
5961         /**
5962          * Automatic position of label text. When called first, the positioning algorithm
5963          * starts at the position defined by offset.
5964          * The algorithm tries to find a position with the least number of
5965          * overlappings with other elements, while retaining the distance
5966          * to the anchor element.
5967          *
5968          * @name Label#autoPosition
5969          * @see Label#offset
5970          * @type Boolean
5971          * @default false
5972          *
5973          * @example
5974          * 	var p1 = board.create('point', [-2, 1], {id: 'A'});
5975          * 	var p2 = board.create('point', [-0.85, 1], {
5976          *      name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}
5977          *  });
5978          * 	var p3 = board.create('point', [-1, 1.2], {
5979          *      name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}
5980          *  });
5981          *  var c = board.create('circle', [p1, p2]);
5982          * 	var l = board.create('line', [p1, p2]);
5983          *
5984          * </pre><div id="JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2" class="jxgbox" style="width: 300px; height: 300px;"></div>
5985          * <script type="text/javascript">
5986          *     (function() {
5987          *         var board = JXG.JSXGraph.initBoard('JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2',
5988          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
5989          *     	var p1 = board.create('point', [-2, 1], {id: 'A'});
5990          *     	var p2 = board.create('point', [-0.85, 1], {name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}});
5991          *     	var p3 = board.create('point', [-1, 1.2], {name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}});
5992          *      var c = board.create('circle', [p1, p2]);
5993          *     	var l = board.create('line', [p1, p2]);
5994          *
5995          *     })();
5996          *
5997          * </script><pre>
5998          *
5999          *
6000          */
6001         autoPosition: false,
6002 
6003         /**
6004          * The auto position algorithm tries to put a label to a conflict-free
6005          * position around it's anchor element. For this, the algorithm tests 12 positions
6006          * around the anchor element starting at a distance from the anchor
6007          * defined here (in pixel).
6008          *
6009          * @name Label#autoPositionMinDistance
6010          * @see Label#autoPosition
6011          * @see Label#autoPositionMaxDistance
6012          * @type Number
6013          * @default 12
6014          *
6015          */
6016         autoPositionMinDistance: 12,
6017 
6018         /**
6019          * The auto position algorithm tries to put a label to a conflict-free
6020          * position around it's anchor element. For this, the algorithm tests 12 positions
6021          * around the anchor element up to a distance from the anchor
6022          * defined here (in pixel).
6023          *
6024          * @name Label#autoPositionMaxDistance
6025          * @see Label#autoPosition
6026          * @see Label#autoPositionMinDistance
6027          * @type Number
6028          * @default 28
6029          *
6030          */
6031         autoPositionMaxDistance: 28
6032 
6033         /**#@-*/
6034     },
6035 
6036     /* special legend options */
6037     legend: {
6038         /**
6039          * @visprop
6040          */
6041 
6042         /**
6043          * Default style of a legend element. The only possible value is 'vertical'.
6044          * @name Legend#style
6045          * @type String
6046          * @default 'vertical'
6047          */
6048         style: 'vertical',
6049 
6050         /**
6051          * Label names of a legend element.
6052          * @name Legend#labels
6053          * @type Array
6054          * @default "['1', '2', '3', '4', '5', '6', '7', '8']"
6055          */
6056         labels: ['1', '2', '3', '4', '5', '6', '7', '8'],
6057 
6058         /**
6059          * (Circular) array of label colors.
6060          * @name Legend#colors
6061          * @type Array
6062          * @default "['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00']"
6063          */
6064         colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],
6065 
6066         /**
6067          * Height (in px) of one legend entry
6068          * @name Legend#rowHeight
6069          * @type Number
6070          * @default 20
6071          *
6072          */
6073         rowHeight: 20,
6074 
6075         strokeWidth: 5
6076 
6077         /**#@-*/
6078     },
6079 
6080     /* special line options */
6081     line: {
6082         /**#@+
6083          * @visprop
6084          */
6085 
6086         /**
6087          * Configure the arrow head at the position of its first point or the corresponding
6088          * intersection with the canvas border
6089          *
6090          * The attribute firstArrow can be a Boolean or an object with the following sub-attributes:
6091          * <pre>
6092          * {
6093          *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.
6094          *      size: 6, // size of the arrow head. Default value is 6.
6095          *               // This value is multiplied with the strokeWidth of the line
6096          *               // Exception: for type=7 size is ignored
6097          *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value
6098          * }
6099          * </pre>
6100          * type=7 is the default for curves if firstArrow: true
6101          * <p>
6102          * An arrow head can be turned off with line.setAttribute({firstArrow: false}).
6103          *
6104          * @example
6105          *     board.options.line.lastArrow = false;
6106          *     board.options.line.firstArrow = {size: 10, highlightSize: 10};
6107          *     board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};
6108          *     board.options.line.strokeWidth = 4;
6109          *     board.options.line.highlightStrokeWidth = 4;
6110          *
6111          *     board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});
6112          *     board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});
6113          *     board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});
6114          *     board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});
6115          *     board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});
6116          *     board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});
6117          *     board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});
6118          *
6119          * </pre><div id="JXGc94a93da-c942-4204-8bb6-b39726cbb09b" class="jxgbox" style="width: 300px; height: 300px;"></div>
6120          * <script type="text/javascript">
6121          *     (function() {
6122          *         var board = JXG.JSXGraph.initBoard('JXGc94a93da-c942-4204-8bb6-b39726cbb09b',
6123          *             {boundingbox: [-6, 6, 4,-4], axis: false, showcopyright: false, shownavigation: false});
6124          *         board.options.line.lastArrow = false;
6125          *         board.options.line.firstArrow = {size: 10, highlightSize: 10};
6126          *         board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};
6127          *         board.options.line.strokeWidth = 4;
6128          *         board.options.line.highlightStrokeWidth = 4;
6129          *
6130          *         board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});
6131          *         board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});
6132          *         board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});
6133          *         board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});
6134          *         board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});
6135          *         board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});
6136          *         board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});
6137          *
6138          *     })();
6139          *
6140          * </script><pre>
6141          *
6142          * @name Line#firstArrow
6143          * @see Line#lastArrow
6144          * @see Line#touchFirstPoint
6145          * @type Boolean | Object
6146          * @default false
6147          */
6148         firstArrow: false,
6149 
6150         /**
6151          * Configure the arrow head at the position of its second point or the corresponding
6152          * intersection with the canvas border.
6153          *
6154          * The attribute lastArrow can be a Boolean or an object with the following sub-attributes:
6155          * <pre>
6156          * {
6157          *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.
6158          *      size: 6, // size of the arrow head. Default value is 6.
6159          *               // This value is multiplied with the strokeWidth of the line.
6160          *               // Exception: for type=7 size is ignored
6161          *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value is 6.
6162          * }
6163          * </pre>
6164          * type=7 is the default for curves if lastArrow: true
6165          * <p>
6166          * An arrow head can be turned off with line.setAttribute({lastArrow: false}).
6167          *
6168          * @example
6169          *     var p1 = board.create('point', [-5, 2], {size:1});
6170          *     var p2 = board.create('point', [5, 2], {size:10});
6171          *     var li = board.create('segment', ['A','B'],
6172          *         {name:'seg',
6173          *          strokeColor:'#000000',
6174          *          strokeWidth:1,
6175          *          highlightStrokeWidth: 5,
6176          *          lastArrow: {type: 2, size: 8, highlightSize: 6},
6177          *          touchLastPoint: true,
6178          *          firstArrow: {type: 3, size: 8}
6179          *         });
6180          *
6181          * </pre><div id="JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3" class="jxgbox" style="width: 300px; height: 300px;"></div>
6182          * <script type="text/javascript">
6183          *     (function() {
6184          *         var board = JXG.JSXGraph.initBoard('JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3',
6185          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
6186          *         var p1 = board.create('point', [-5, 2], {size:1});
6187          *         var p2 = board.create('point', [5, 2], {size:10});
6188          *         var li = board.create('segment', ['A','B'],
6189          *             {name:'seg',
6190          *              strokeColor:'#000000',
6191          *              strokeWidth:1,
6192          *              highlightStrokeWidth: 5,
6193          *              lastArrow: {type: 2, size: 8, highlightSize: 6},
6194          *              touchLastPoint: true,
6195          *              firstArrow: {type: 3, size: 8}
6196          *             });
6197          *     })();
6198          *
6199          * </script>
6200          *
6201          * @example
6202          *     board.options.line.strokeWidth = 4;
6203          *     board.options.line.highlightStrokeWidth = 4;
6204          *     board.options.line.firstArrow = false;
6205          *     board.options.line.lastArrow = {size: 10, highlightSize: 10};
6206          *     board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};
6207          *
6208          *     board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});
6209          *     board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});
6210          *     board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});
6211          *     board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});
6212          *     board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});
6213          *     board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});
6214          *     board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});
6215          *
6216          * </pre><div id="JXGca206b1c-e319-4899-8b90-778f53fd926d" class="jxgbox" style="width: 300px; height: 300px;"></div>
6217          * <script type="text/javascript">
6218          *     (function() {
6219          *         var board = JXG.JSXGraph.initBoard('JXGca206b1c-e319-4899-8b90-778f53fd926d',
6220          *             {boundingbox: [-6, 6, 6,-4], axis: false, showcopyright: false, shownavigation: false});
6221          *         board.options.line.strokeWidth = 4;
6222          *         board.options.line.highlightStrokeWidth = 4;
6223          *         board.options.line.firstArrow = false;
6224          *         board.options.line.lastArrow = {size: 10, highlightSize: 10};
6225          *         board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};
6226          *
6227          *         board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});
6228          *         board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});
6229          *         board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});
6230          *         board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});
6231          *         board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});
6232          *         board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});
6233          *         board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});
6234          *     })();
6235          *
6236          * </script><pre>
6237          *
6238          * @name Line#lastArrow
6239          * @see Line#firstArrow
6240          * @see Line#touchLastPoint
6241          * @type Boolean | Object
6242          * @default false
6243          */
6244         lastArrow: false,
6245 
6246         /**
6247          * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
6248          * ends exactly at the border, if negative there is a margin to the inside, if positive the line
6249          * ends outside of the canvas (which is invisible).
6250          *
6251          * @name Line#margin
6252          * @type Number
6253          * @default 0
6254          */
6255         margin: 0,
6256 
6257         /**
6258          * If true, line stretches infinitely in direction of its first point.
6259          * Otherwise it ends at point1.
6260          *
6261          * @name Line#straightFirst
6262          * @see Line#straightLast
6263          * @type Boolean
6264          * @default true
6265          */
6266         straightFirst: true,
6267 
6268         /**
6269          * If true, line stretches infinitely in direction of its second point.
6270          * Otherwise it ends at point2.
6271          *
6272          * @name Line#straightLast
6273          * @see Line#straightFirst
6274          * @type Boolean
6275          * @default true
6276          */
6277         straightLast: true,
6278 
6279         fillColor: 'none',           // Important for VML on IE
6280         highlightFillColor: 'none',  // Important for VML on IE
6281         strokeColor: Color.palette.blue,
6282         highlightStrokeColor: '#c3d9ff',
6283         withTicks: false,
6284 
6285         /**
6286          * Attributes for first defining point of the line.
6287          *
6288          * @type Point
6289          * @name Line#point1
6290          */
6291         point1: {                  // Default values for point1 if created by line
6292             fillColor: Color.palette.red,
6293             strokeColor: Color.palette.red,
6294             highlightFillColor: '#c3d9ff',
6295             highlightStrokeColor: '#c3d9ff',
6296             layer: 9,
6297 
6298             visible: false,
6299             withLabel: false,
6300             fixed: false,
6301             name: ''
6302         },
6303 
6304         /**
6305          * Attributes for second defining point of the line.
6306          *
6307          * @type Point
6308          * @name Line#point2
6309          */
6310         point2: {                  // Default values for point2 if created by line
6311             fillColor: Color.palette.red,
6312             strokeColor: Color.palette.red,
6313             highlightFillColor: '#c3d9ff',
6314             highlightStrokeColor: '#c3d9ff',
6315             layer: 9,
6316 
6317             visible: false,
6318             withLabel: false,
6319             fixed: false,
6320             name: ''
6321         },
6322 
6323         /**
6324          * Attributes for ticks of the line.
6325          *
6326          * @name Line#ticks
6327          * @type Object
6328          * @see Ticks
6329          */
6330         ticks: {
6331             drawLabels: true,
6332             label: {
6333                 offset: [4, -12 + 3] // This seems to be a good offset for 12 point fonts
6334             },
6335             drawZero: false,
6336             insertTicks: false,
6337             ticksDistance: 1,
6338             minTicksDistance: 50,
6339             minorHeight: 4,          // if <0: full width and height
6340             majorHeight: -1,         // if <0: full width and height
6341             minorTicks: 4,
6342             strokeOpacity: 0.3,
6343             visible: 'inherit'
6344         },
6345 
6346         /**
6347          * Attributes for the line label.
6348          *
6349          * @type Object
6350          * @name Line#label
6351          * @see Label
6352          */
6353         label: {
6354             position: 'llft'
6355         },
6356 
6357         /**
6358          * If set to true, the point will snap to a grid defined by
6359          * {@link Point#snapSizeX} and {@link Point#snapSizeY}.
6360          *
6361          * @see Point#snapSizeX
6362          * @see Point#snapSizeY
6363          * @type Boolean
6364          * @name Line#snapToGrid
6365          * @default false
6366          */
6367         snapToGrid: false,
6368 
6369         /**
6370          * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.
6371          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
6372          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
6373          * of the default ticks of the default x axes of the board.
6374          *
6375          * @see Point#snapToGrid
6376          * @see Point#snapSizeY
6377          * @see JXG.Board#defaultAxes
6378          * @type Number
6379          * @name Line#snapSizeX
6380          * @default 1
6381          */
6382         snapSizeX: 1,
6383 
6384         /**
6385          * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.
6386          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
6387          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
6388          * of the default ticks of the default y axes of the board.
6389          *
6390          * @see Point#snapToGrid
6391          * @see Point#snapSizeX
6392          * @see JXG.Board#defaultAxes
6393          * @type Number
6394          * @name Line#snapSizeY
6395          * @default 1
6396          */
6397         snapSizeY: 1,
6398 
6399         /**
6400          * If set to true, {@link Line#firstArrow} is set to true and the point is visible,
6401          * the arrow head will just touch the circle line of the start point of the line.
6402          *
6403          * @see Line#firstArrow
6404          * @type Boolean
6405          * @name Line#touchFirstPoint
6406          * @default false
6407          */
6408         touchFirstPoint: false,
6409 
6410         /**
6411          * If set to true, {@link Line#lastArrow} is set to true and the point is visible,
6412          * the arrow head will just touch the circle line of the start point of the line.
6413          * @see Line#firstArrow
6414          * @type Boolean
6415          * @name Line#touchLastPoint
6416          * @default false
6417          */
6418         touchLastPoint: false
6419 
6420         /**#@-*/
6421     },
6422 
6423     /* special options for locus curves */
6424     locus: {
6425         /**#@+
6426          * @visprop
6427          */
6428 
6429         translateToOrigin: false,
6430         translateTo10: false,
6431         stretch: false,
6432         toOrigin: null,
6433         to10: null
6434         /**#@-*/
6435     },
6436 
6437     /* special measurement options */
6438     measurement: {
6439         /**#@+
6440          * @visprop
6441          */
6442 
6443         baseUnit: '',
6444         units: {},
6445         dim: null,
6446 
6447         showPrefix: true,
6448         showSuffix: true,
6449 
6450         prefix: '',
6451         suffix: '',
6452 
6453         formatPrefix: function (txt) { return txt; },
6454         formatSuffix: function (txt) { return txt; },
6455 
6456         formatCoords: function (x, y, z) {
6457             return '(' + x + ', ' + y + ')';
6458         },
6459         formatDirection: function (x, y) {
6460             return '(' + x + ', ' + y + ')';
6461         }
6462 
6463         /**#@-*/
6464     },
6465 
6466     /* special metapost spline options */
6467     metapostspline: {
6468         /**#@+
6469          * @visprop
6470          */
6471 
6472         /**
6473           * Controls if the data points of the cardinal spline when given as
6474           * arrays should be converted into {@link JXG.Points}.
6475           *
6476           * @name createPoints
6477           * @memberOf Metapostspline.prototype
6478           *
6479           * @see Metapostspline#points
6480           *
6481           * @type Boolean
6482           * @default true
6483           */
6484         createPoints: true,
6485 
6486         /**
6487          * If set to true, the supplied coordinates are interpreted as
6488          * [[x_0, y_0], [x_1, y_1], p, ...].
6489          * Otherwise, if the data consists of two arrays of equal length,
6490          * it is interpreted as
6491          * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]
6492          *
6493          * @name isArrayOfCoordinates
6494          * @memberOf Metapostspline.prototype
6495          * @type Boolean
6496          * @default true
6497          */
6498         isArrayOfCoordinates: true,
6499 
6500         /**
6501          * Attributes for the points generated by Metapost spline in cases
6502          * {@link createPoints} is set to true
6503          *
6504          * @name points
6505          * @memberOf Metapostspline.prototype
6506          *
6507          * @see Metapostspline#createPoints
6508          * @type Object
6509          */
6510         points: {
6511             strokeOpacity: 0.5,
6512             fillOpacity: 0.5,
6513             highlightStrokeOpacity: 1.0,
6514             highlightFillOpacity: 1.0,
6515             withLabel: false,
6516             name: '',
6517             fixed: false
6518         }
6519 
6520         /**#@-*/
6521     },
6522 
6523     /* special mirrorelement options */
6524     mirrorelement: {
6525         /**#@+
6526          * @visprop
6527          */
6528 
6529         fixed: true,
6530 
6531         /**
6532          * Attributes of mirror point, i.e. the point along which the element is mirrored.
6533          *
6534          * @type Point
6535          * @name mirrorelement#point
6536          */
6537         point: {},
6538 
6539         /**
6540          * Attributes of circle center, i.e. the center of the circle,
6541          * if a circle is the mirror element and the transformation type is 'Euclidean'
6542          *
6543          * @type Point
6544          * @name mirrorelement#center
6545          */
6546         center: {},
6547 
6548         /**
6549          * Type of transformation. Possible values are 'Euclidean', 'projective'.
6550          *
6551          * If the value is 'Euclidean', the mirror element of a circle is again a circle,
6552          * otherwise it is a conic section.
6553          *
6554          * @type String
6555          * @name mirrorelement#type
6556          * @default 'Euclidean'
6557          */
6558         type: 'Euclidean'
6559 
6560         /**#@-*/
6561     },
6562 
6563     /* special nonreflexangle options */
6564     nonreflexangle: {
6565         /**#@+
6566          * @visprop
6567          */
6568 
6569         /**#@-*/
6570     },
6571 
6572     // /* special options for Msector of 3 points */
6573     // msector: {
6574     //     strokeColor: '#000000', // Msector line
6575     //     point: {               // Msector point
6576     //         visible: false,
6577     //         fixed: false,
6578     //         withLabel: false,
6579     //         name: ''
6580     //     }
6581     // },
6582 
6583     /* special options for normal lines */
6584     normal: {
6585         /**#@+
6586          * @visprop
6587          */
6588 
6589         strokeColor: '#000000', //  normal line
6590 
6591         /**
6592          * Attributes of helper point of normal.
6593          *
6594          * @type Point
6595          * @name Normal#point
6596          */
6597         point: {
6598             visible: false,
6599             fixed: false,
6600             withLabel: false,
6601             name: ''
6602         }
6603         /**#@-*/
6604     },
6605 
6606     /* special options for orthogonal projection points */
6607     orthogonalprojection: {
6608         /**#@+
6609          * @visprop
6610          */
6611 
6612 
6613         /**#@-*/
6614     },
6615 
6616     /* special options for parallel lines */
6617     parallel: {
6618         /**#@+
6619          * @visprop
6620          */
6621 
6622         strokeColor: '#000000', // Parallel line
6623 
6624         /**
6625          * Attributes of helper point of normal.
6626          *
6627          * @type Point
6628          * @name Parallel#point
6629          */
6630         point: {
6631             visible: false,
6632             fixed: false,
6633             withLabel: false,
6634             name: ''
6635         },
6636 
6637         label: {
6638             position: 'llft'
6639         }
6640         /**#@-*/
6641     },
6642 
6643     /* special parallelogram options */
6644     parallelogram: {
6645         parallelpoint: {
6646             withLabel: false,
6647             name: ''
6648         }
6649     },
6650 
6651     /* special parallelpoint options */
6652     parallelpoint: {
6653     },
6654 
6655     /* special perpendicular options */
6656     perpendicular: {
6657         /**#@+
6658          * @visprop
6659          */
6660 
6661         strokeColor: '#000000', // Perpendicular line
6662         straightFirst: true,
6663         straightLast: true
6664         /**#@-*/
6665     },
6666 
6667     /* special perpendicular options */
6668     perpendicularsegment: {
6669         /**#@+
6670          * @visprop
6671          */
6672 
6673         strokeColor: '#000000', // Perpendicular segment
6674         straightFirst: false,
6675         straightLast: false,
6676         point: {               // Perpendicular point
6677             visible: false,
6678             fixed: true,
6679             withLabel: false,
6680             name: ''
6681         }
6682         /**#@-*/
6683     },
6684 
6685     /* special point options */
6686     point: {
6687         /**#@+
6688          * @visprop
6689          */
6690 
6691         withLabel: true,
6692         label: {},
6693 
6694         /**
6695          * This attribute was used to determined the point layout. It was derived from GEONExT and was
6696          * replaced by {@link Point#face} and {@link Point#size}.
6697          *
6698          * @name Point#style
6699          *
6700          * @see Point#face
6701          * @see Point#size
6702          * @type Number
6703          * @default 5
6704          * @deprecated
6705          */
6706         style: 5,
6707 
6708         /**
6709          * There are different point styles which differ in appearance.
6710          * Posssible values are
6711          * <table>
6712          * <tr><th>Input</th><th>Output</th></tr>
6713          * <tr><td>cross</td><td>x</td></tr>
6714          * <tr><td>circle</td><td>o</td></tr>
6715          * <tr><td>square, []</td><td>[]</td></tr>
6716          * <tr><td>plus</td><td>+</td></tr>
6717          * <tr><td>minus</td><td>-</td></tr>
6718          * <tr><td>divide</td><td>|</td></tr>
6719          * <tr><td>diamond</td><td><></td></tr>
6720          * <tr><td>diamond2</td><td><> (bigger)</td></tr>
6721          * <tr><td>triangleup</td><td>^, a, A</td></tr>
6722          * <tr><td>triangledown</td><td>v</td></tr>
6723          * <tr><td>triangleleft</td><td><</td></tr>
6724          * <tr><td>triangleright</td><td>></td></tr>
6725          * </table>
6726          *
6727          * @name Point#face
6728          *
6729          * @type String
6730          * @see JXG.Point#setStyle
6731          * @default circle
6732          */
6733         face: 'o',
6734 
6735         /**
6736          * Size of a point, either in pixel or user coordinates.
6737          * Means radius resp. half the width of a point (depending on the face).
6738          *
6739          * @name Point#size
6740          *
6741          * @see Point#face
6742          * @see JXG.Point#setStyle
6743          * @see Point#sizeUnit
6744          * @type Number
6745          * @default 3
6746          */
6747         size: 3,
6748 
6749         /**
6750          * Unit for size.
6751          * Possible values are 'screen' and 'user.
6752          *
6753          * @name Point#sizeUnit
6754          *
6755          * @see Point#size
6756          * @type String
6757          * @default 'screen'
6758          */
6759         sizeUnit: 'screen',
6760 
6761         strokeWidth: 2,
6762 
6763         transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry'],
6764         fillColor: Color.palette.red,
6765         strokeColor: Color.palette.red,
6766         highlightFillColor: '#c3d9ff',
6767         highlightStrokeColor: '#c3d9ff',
6768         // strokeOpacity: 1.0,
6769         // fillOpacity: 1.0,
6770         // highlightFillOpacity: 0.5,
6771         // highlightStrokeOpacity: 0.5,
6772 
6773         // fillColor: '#ff0000',
6774         // highlightFillColor: '#eeeeee',
6775         // strokeWidth: 2,
6776         // strokeColor: '#ff0000',
6777         // highlightStrokeColor: '#c3d9ff',
6778 
6779         /**
6780          * If true, the point size changes on zoom events.
6781          *
6782          * @type Boolean
6783          * @name Point#zoom
6784          * @default false
6785          *
6786          */
6787         zoom: false,             // Change the point size on zoom
6788 
6789         /**
6790          * If true, the infobox is shown on mouse/pen over, if false not.
6791          * If the value is 'inherit', the value of
6792          * {@link JXG.Board#showInfobox} is taken.
6793          *
6794          * @name Point#showInfobox
6795          * @see JXG.Board#showInfobox
6796          * @type Boolean|String
6797          * @description true | false | 'inherit'
6798          * @default true
6799          */
6800         showInfobox: 'inherit',
6801 
6802         /**
6803          * Truncating rule for the digits in the infobox.
6804          * <ul>
6805          * <li>'auto': done automatically by JXG.autoDigits()
6806          * <li>'none': no truncation
6807          * <li>number: truncate after "number digits" with JXG.toFixed()
6808          * </ul>
6809          *
6810          * @name Point#infoboxDigits
6811          *
6812          * @type String| Number
6813          * @default 'auto'
6814          * @see JXG#autoDigits
6815          * @see JXG#toFixed
6816          */
6817         infoboxDigits: 'auto',
6818 
6819         draft: false,
6820 
6821         /**
6822          * List of attractor elements. If the distance of the point is less than
6823          * attractorDistance the point is made to glider of this element.
6824          *
6825          * @name Point#attractors
6826          *
6827          * @type Array
6828          * @default empty
6829          */
6830         attractors: [],
6831 
6832         /**
6833          * Unit for attractorDistance and snatchDistance, used for magnetized points and for snapToPoints.
6834          * Possible values are 'screen' and 'user'.
6835          *
6836          * @name Point#attractorUnit
6837          *
6838          * @see Point#attractorDistance
6839          * @see Point#snatchDistance
6840          * @see Point#snapToPoints
6841          * @see Point#attractors
6842          * @type String
6843          * @default 'user'
6844          */
6845         attractorUnit: 'user',    // 'screen', 'user'
6846 
6847         /**
6848          * If the distance of the point to one of its attractors is less
6849          * than this number the point will be a glider on this
6850          * attracting element.
6851          * If set to zero nothing happens.
6852          *
6853          * @name Point#attractorDistance
6854          *
6855          * @type Number
6856          * @default 0.0
6857          */
6858         attractorDistance: 0.0,
6859 
6860         /**
6861          * If the distance of the point to one of its attractors is at least
6862          * this number the point will be released from being a glider on the
6863          * attracting element.
6864          * If set to zero nothing happens.
6865          *
6866          * @name Point#snatchDistance
6867          *
6868          * @type Number
6869          * @default 0.0
6870          */
6871         snatchDistance: 0.0,
6872 
6873         /**
6874          * If set to true, the point will snap to a grid of integer multiples of
6875          * {@link Point#snapSizeX} and {@link Point#snapSizeY} (in user coordinates).
6876          * <p>
6877          * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY
6878          * (given in user coordinates, not pixels) or are the intersection points
6879          * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.
6880          *
6881          * @name Point#snapToGrid
6882          *
6883          * @see Point#snapSizeX
6884          * @see Point#snapSizeY
6885          * @type Boolean
6886          * @default false
6887          */
6888         snapToGrid: false,
6889 
6890         /**
6891          * If set to true, the point will only snap to (possibly invisibly) grid points
6892          * when within {@link Point#attractorDistance} of such a grid point.
6893          * <p>
6894          * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY
6895          * (given in user coordinates, not pixels) or are the intersection points
6896          * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.
6897          *
6898          * @name Point#attractToGrid
6899          *
6900          * @see Point#attractorDistance
6901          * @see Point#attractorUnit
6902          * @see Point#snapToGrid
6903          * @see Point#snapSizeX
6904          * @see Point#snapSizeY
6905          * @type Boolean
6906          * @default false
6907          *
6908          * @example
6909          * board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });
6910          *
6911          * </pre><div id="JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6" class="jxgbox" style="width: 300px; height: 300px;"></div>
6912          * <script type="text/javascript">
6913          *     (function() {
6914          *         var board = JXG.JSXGraph.initBoard('JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6',
6915          *             {boundingbox: [-1, 4, 7,-4], axis: true, showcopyright: false, shownavigation: false});
6916          *     board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });
6917          *
6918          *     })();
6919          *
6920          * </script><pre>
6921          *
6922          */
6923         attractToGrid: false,
6924 
6925         /**
6926          * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.
6927          * It is given in user coordinates, not in pixels.
6928          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
6929          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
6930          * of the default ticks of the default x axes of the board.
6931          *
6932          * @name Point#snapSizeX
6933          *
6934          * @see Point#snapToGrid
6935          * @see Point#snapSizeY
6936          * @see JXG.Board#defaultAxes
6937          * @type Number
6938          * @default 1
6939          */
6940         snapSizeX: 1,
6941 
6942         /**
6943          * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.
6944          * It is given in user coordinates, not in pixels.
6945          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
6946          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
6947          * of the default ticks of the default y axes of the board.
6948          *
6949          * @name Point#snapSizeY
6950          *
6951          * @see Point#snapToGrid
6952          * @see Point#snapSizeX
6953          * @see JXG.Board#defaultAxes
6954          * @type Number
6955          * @default 1
6956          */
6957         snapSizeY: 1,
6958 
6959         /**
6960          * If set to true, the point will snap to the nearest point in distance of
6961          * {@link Point#attractorDistance}.
6962          *
6963          * @name Point#snapToPoints
6964          *
6965          * @see Point#attractorDistance
6966          * @type Boolean
6967          * @default false
6968          */
6969         snapToPoints: false,
6970 
6971         /**
6972          * List of elements which are ignored by snapToPoints.
6973          * @name Point#ignoredSnapToPoints
6974          *
6975          * @type Array
6976          * @default empty
6977          */
6978         ignoredSnapToPoints: []
6979 
6980         /**#@-*/
6981     },
6982 
6983     /* special polygon options */
6984     polygon: {
6985         /**#@+
6986          * @visprop
6987          */
6988 
6989         /**
6990          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
6991          *
6992          * @see JXG.GeometryElement#hasPoint
6993          * @name Polygon#hasInnerPoints
6994          * @type Boolean
6995          * @default false
6996          */
6997         hasInnerPoints: false,
6998 
6999         fillColor: Color.palette.yellow,
7000         highlightFillColor: Color.palette.yellow,
7001         // fillColor: '#00ff00',
7002         // highlightFillColor: '#00ff00',
7003         fillOpacity: 0.3,
7004         highlightFillOpacity: 0.2,
7005 
7006         /**
7007          * Is the polygon bordered by lines?
7008          *
7009          * @type Boolean
7010          * @name Polygon#withLines
7011          * @default true
7012          */
7013         withLines: true,
7014 
7015         /**
7016          * Attributes for the polygon border lines.
7017          *
7018          * @type Line
7019          * @name Polygon#borders
7020          */
7021         borders: {
7022             withLabel: false,
7023             strokeWidth: 1,
7024             highlightStrokeWidth: 1,
7025             // Polygon layer + 1
7026             layer: 5,
7027             label: {
7028                 position: 'top'
7029             },
7030             visible: 'inherit'
7031         },
7032 
7033         /**
7034          * By default, the strokewidths of the borders of a polygon are not changed during highlighting (only strokeColor and strokeOpacity are changed
7035          * to highlightStrokeColor, and highlightStrokeOpacity).
7036          * However, strokewidth is changed to highlightStrokewidth if an individual border gets the focus.
7037          * <p>
7038          * With this attribute set to true, also the borders change strokeWidth if the polygon itself gets the focus.
7039          *
7040          * @type Boolean
7041          * @name Polygon#highlightByStrokeWidth
7042          * @default false
7043          */
7044         highlightByStrokeWidth: false,
7045 
7046         /**
7047          * Attributes for the polygon vertices.
7048          *
7049          * @type Point
7050          * @name Polygon#vertices
7051          */
7052         vertices: {
7053             layer: 9,
7054             withLabel: false,
7055             name: '',
7056             strokeColor: Color.palette.red,
7057             fillColor: Color.palette.red,
7058             fixed: false,
7059             visible: 'inherit'
7060         },
7061 
7062         /**
7063          * Attributes for the polygon label.
7064          *
7065          * @type Label
7066          * @name Polygon#label
7067          */
7068         label: {
7069             offset: [0, 0]
7070         }
7071 
7072         /**#@-*/
7073     },
7074 
7075     /* special polygonal chain options
7076     */
7077     polygonalchain: {
7078         /**#@+
7079          * @visprop
7080          */
7081 
7082         fillColor: 'none',
7083         highlightFillColor: 'none'
7084 
7085         /**#@-*/
7086     },
7087 
7088     /* special prescribed angle options
7089     * Not yet implemented. But angle.setAngle(val) is implemented.
7090 
7091     */
7092     prescribedangle: {
7093         /**#@+
7094          * @visprop
7095          */
7096 
7097         /**
7098          * Attributes for the helper point of the prescribed angle.
7099          *
7100          * @type Point
7101          * @name Prescribedangle#anglePoint
7102          * @ignore
7103          */
7104         anglePoint: {
7105             size: 2,
7106             visible: false,
7107             withLabel: false
7108         }
7109 
7110         /**#@-*/
7111     },
7112 
7113     /* special reflection options */
7114     reflection: {
7115         /**#@+
7116          * @visprop
7117          */
7118 
7119         fixed: true,
7120 
7121         /**
7122          * Attributes of circle center, i.e. the center of the circle,
7123          * if a circle is the mirror element and the transformation type is 'Euclidean'
7124          *
7125          * @type center
7126          * @name Reflection#center
7127          */
7128         center: {},
7129 
7130         /**
7131          * Type of transformation. Possible values are 'Euclidean', 'projective'.
7132          *
7133          * If the value is 'Euclidean', the reflected element of a circle is again a circle,
7134          * otherwise it is a conic section.
7135          *
7136          * @type String
7137          * @name Reflection#type
7138          * @default 'Euclidean'
7139          */
7140         type: 'Euclidean'
7141 
7142         /**#@-*/
7143     },
7144 
7145     /* special reflexangle options */
7146     reflexangle: {
7147         /**#@+
7148          * @visprop
7149          */
7150 
7151         /**#@-*/
7152     },
7153 
7154     /* special regular polygon options */
7155     regularpolygon: {
7156         /**#@+
7157          * @visprop
7158          */
7159 
7160         /**
7161          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
7162          * @see JXG.GeometryElement#hasPoint
7163          *
7164          * @name RegularPolygon#hasInnerPoints
7165          * @type Boolean
7166          * @default false
7167          */
7168         hasInnerPoints: false,
7169         fillColor: Color.palette.yellow,
7170         highlightFillColor: Color.palette.yellow,
7171         fillOpacity: 0.3,
7172         highlightFillOpacity: 0.2,
7173 
7174         /**
7175          * Is the polygon bordered by lines?
7176          *
7177          * @type Boolean
7178          * @name RegularPolygon#withLines
7179          * @default true
7180          */
7181         withLines: true,
7182 
7183         /**
7184          * Attributes for the polygon border lines.
7185          *
7186          * @type Line
7187          * @name RegularPolygon#borders
7188          */
7189         borders: {
7190             withLabel: false,
7191             strokeWidth: 1,
7192             highlightStrokeWidth: 1,
7193             // Polygon layer + 1
7194             layer: 5,
7195             label: {
7196                 position: 'top'
7197             }
7198         },
7199 
7200         /**
7201          * Attributes for the polygon vertices.
7202          *
7203          * @type Point
7204          * @name RegularPolygon#vertices
7205          */
7206         vertices: {
7207             layer: 9,
7208             withLabel: true,
7209             strokeColor: Color.palette.red,
7210             fillColor: Color.palette.red,
7211             fixed: false
7212         },
7213 
7214         /**
7215          * Attributes for the polygon label.
7216          *
7217          * @type Label
7218          * @name RegularPolygon#label
7219          */
7220         label: {
7221             offset: [0, 0]
7222         }
7223 
7224         /**#@-*/
7225     },
7226 
7227     /* special options for riemann sums */
7228     riemannsum: {
7229         /**#@+
7230          * @visprop
7231          */
7232 
7233         withLabel: false,
7234         fillOpacity: 0.3,
7235         fillColor: Color.palette.yellow
7236 
7237         /**#@-*/
7238     },
7239 
7240     /* special sector options */
7241     sector: {
7242         /**#@+
7243          * @visprop
7244          */
7245 
7246         fillColor: Color.palette.yellow,
7247         highlightFillColor: Color.palette.yellow,
7248         // fillColor: '#00ff00',
7249         // highlightFillColor: '#00ff00',
7250 
7251         fillOpacity: 0.3,
7252         highlightFillOpacity: 0.3,
7253         highlightOnSector: false,
7254         highlightStrokeWidth: 0,
7255 
7256         /**
7257          * Type of sector. Possible values are 'minor', 'major', and 'auto'.
7258          *
7259          * @type String
7260          * @name Sector#selection
7261          * @default 'auto'
7262          */
7263         selection: 'auto',
7264 
7265         /**
7266          * Attributes for sub-element arc. It is only available, if the sector is defined by three points.
7267          *
7268          * @type Arc
7269          * @name Sector#arc
7270          * @default '{visible:false}'
7271          */
7272         arc: {
7273             visible: false,
7274             fillColor: 'none',
7275             withLabel: false,
7276             name: '',
7277 
7278             center: {
7279                 visible: false,
7280                 withLabel: false,
7281                 name: ''
7282             },
7283 
7284             radiusPoint: {
7285                 visible: false,
7286                 withLabel: false,
7287                 name: ''
7288             },
7289 
7290             anglePoint: {
7291                 visible: false,
7292                 withLabel: false,
7293                 name: ''
7294             }
7295         },
7296 
7297         /**
7298          * Attributes for helper point radiuspoint in case it is provided by coordinates.
7299          *
7300          * @type Point
7301          * @name Sector#radiusPoint
7302          */
7303         radiusPoint: {
7304             visible: false,
7305             withLabel: false
7306         },
7307 
7308         /**
7309          * Attributes for helper point center in case it is provided by coordinates.
7310          *
7311          * @type Point
7312          * @name Sector#center
7313          */
7314         center: {
7315             visible: false,
7316             withLabel: false
7317         },
7318 
7319         /**
7320          * Attributes for helper point anglepoint in case it is provided by coordinates.
7321          *
7322          * @type Point
7323          * @name Sector#anglePoint
7324          */
7325         anglePoint: {
7326             visible: false,
7327             withLabel: false
7328         },
7329 
7330         /**
7331          * Attributes for the sector label.
7332          *
7333          * @type Label
7334          * @name Sector#label
7335          */
7336         label: {
7337             offset: [0, 0],
7338             anchorX: 'auto',
7339             anchorY: 'auto'
7340         }
7341 
7342         /**#@-*/
7343     },
7344 
7345     /* special segment options */
7346     segment: {
7347         /**#@+
7348          * @visprop
7349          */
7350 
7351         label: {
7352             position: 'top'
7353         }
7354         /**#@-*/
7355     },
7356 
7357     semicircle: {
7358         /**#@+
7359          * @visprop
7360          */
7361 
7362         /**
7363          * Attributes for center point of the semicircle.
7364          *
7365          * @type Point
7366          * @name Semicircle#center
7367          */
7368         center: {
7369             visible: false,
7370             withLabel: false,
7371             fixed: false,
7372             fillColor: Color.palette.red,
7373             strokeColor: Color.palette.red,
7374             highlightFillColor: '#eeeeee',
7375             highlightStrokeColor: Color.palette.red,
7376             name: ''
7377         }
7378 
7379         /**#@-*/
7380     },
7381 
7382     /* special slider options */
7383     slider: {
7384         /**#@+
7385          * @visprop
7386          */
7387 
7388         /**
7389          * The slider only returns integer multiples of this value, e.g. for discrete values set this property to <tt>1</tt>. For
7390          * continuous results set this to <tt>-1</tt>.
7391          *
7392          * @memberOf Slider.prototype
7393          * @name snapWidth
7394          * @type Number
7395          */
7396         snapWidth: -1,      // -1 = deactivated
7397 
7398         /**
7399          * List of values to snap to. If the glider is within snapValueDistance
7400          * (in user coordinate units) of one of these points,
7401          * then the glider snaps to that point.
7402          *
7403          * @memberOf Slider.prototype
7404          * @name snapValues
7405          * @type Array
7406          * @see Slider#snapValueDistance
7407          * @default empty
7408          *
7409          * @example
7410          *         var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {
7411          *             name: 'n',
7412          *             snapWidth: 1,
7413          *             snapValues: [1, 22, 77, 100],
7414          *             snapValueDistance: 5
7415          *         });
7416          *
7417          *         var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {
7418          *             name: 'k',
7419          *             snapWidth: 0.1,
7420          *             snapValues: [-3, -1, 1, 3],
7421          *             snapValueDistance: 0.4
7422          *         });
7423          *
7424          * </pre><div id="JXG9be68014-4e14-479a-82b4-e92d9b8f6eef" class="jxgbox" style="width: 300px; height: 300px;"></div>
7425          * <script type="text/javascript">
7426          *     (function() {
7427          *         var board = JXG.JSXGraph.initBoard('JXG9be68014-4e14-479a-82b4-e92d9b8f6eef',
7428          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
7429          *             var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {
7430          *                 name: 'n',
7431          *                 snapWidth: 1,
7432          *                 snapValues: [1, 22, 77, 100],
7433          *                 snapValueDistance: 5
7434          *             });
7435          *
7436          *             var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {
7437          *                 name: 'k',
7438          *                 snapWidth: 0.1,
7439          *                 snapValues: [-3, -1, 1, 3],
7440          *                 snapValueDistance: 0.4
7441          *             });
7442          *
7443          *     })();
7444          *
7445          * </script><pre>
7446          *
7447          */
7448         snapValues: [],
7449 
7450         /**
7451          * If the difference between the slider value and one of the elements of snapValues is less
7452          * than this number (in user coordinate units), the slider will snap to that value.
7453          *
7454          * @memberOf Slider.prototype
7455          * @name snapValueDistance
7456          * @type Number
7457          * @see Slider#snapValues
7458          * @default 0.0
7459          */
7460         snapValueDistance: 0.0,
7461 
7462         /**
7463          * The precision of the slider value displayed in the optional text.
7464          * Replaced by the attribute "digits".
7465          *
7466          * @memberOf Slider.prototype
7467          * @name precision
7468          * @type Number
7469          * @deprecated
7470          * @see Slider#digits
7471          * @default 2
7472          */
7473         precision: 2,
7474 
7475         /**
7476          * The number of digits of the slider value displayed in the optional text.
7477          *
7478          * @memberOf Slider.prototype
7479          * @name digits
7480          * @type Number
7481          * @default 2
7482          */
7483         digits: 2,
7484 
7485         /**
7486          * Internationalization support for slider labels.
7487          *
7488          * @name intl
7489          * @memberOf Slider.prototype
7490          * @type object
7491          * @default <pre>{
7492          *    enabled: 'inherit',
7493          *    options: {}
7494          * }</pre>
7495          * @see JXG.Board#intl
7496          * @see Text#intl
7497          *
7498          * @example
7499          * var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {
7500          *     name: 'α',
7501          *     snapWidth: 1,
7502          *     intl: {
7503          *         enabled: true,
7504          *         options: {
7505          *             style: 'unit',
7506          *             unit: 'degree',
7507          *         }
7508          *     }
7509          * });
7510          *
7511          * </pre><div id="JXGb49a9779-c0c8-419d-9173-c67232cfd65c" class="jxgbox" style="width: 300px; height: 300px;"></div>
7512          * <script type="text/javascript">
7513          *     (function() {
7514          *         var board = JXG.JSXGraph.initBoard('JXGb49a9779-c0c8-419d-9173-c67232cfd65c',
7515          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
7516          *     var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {
7517          *         name: 'α',
7518          *         snapWidth: 1,
7519          *         intl: {
7520          *             enabled: true,
7521          *             options: {
7522          *                 style: 'unit',
7523          *                 unit: 'degree',
7524          *             }
7525          *         }
7526          *     });
7527          *
7528          *     })();
7529          *
7530          * </script><pre>
7531          *
7532          */
7533         intl: {
7534             enabled: 'inherit',
7535             options: {}
7536         },
7537 
7538         firstArrow: false,
7539         lastArrow: false,
7540 
7541         /**
7542          * Show slider ticks.
7543          *
7544          * @type Boolean
7545          * @name Slider#withTicks
7546          * @default true
7547          */
7548         withTicks: true,
7549 
7550         /**
7551          * Show slider label.
7552          *
7553          * @type Boolean
7554          * @name Slider#withLabel
7555          * @default true
7556          */
7557         withLabel: true,
7558 
7559         /**
7560          * If not null, this replaces the part "name = " in the slider label.
7561          * Possible types: string, number or function.
7562          * @type String
7563          * @name suffixLabel
7564          * @memberOf Slider.prototype
7565          * @default null
7566          * @see JXG.Slider#unitLabel
7567          * @see JXG.Slider#postLabel
7568          */
7569         suffixLabel: null,
7570 
7571         /**
7572          * If not null, this is appended to the value in the slider label.
7573          * Possible types: string, number or function.
7574          * @type String
7575          * @name unitLabel
7576          * @memberOf Slider.prototype
7577          * @default null
7578          * @see JXG.Slider#suffixLabel
7579          * @see JXG.Slider#postLabel
7580          */
7581         unitLabel: null,
7582 
7583         /**
7584          * If not null, this is appended to the value and to unitLabel in the slider label.
7585          * Possible types: string, number or function.
7586          * @type String
7587          * @name postLabel
7588          * @memberOf Slider.prototype
7589          * @default null
7590          * @see JXG.Slider#suffixLabel
7591          * @see JXG.Slider#unitLabel
7592          */
7593         postLabel: null,
7594 
7595         layer: 9,
7596         showInfobox: false,
7597         name: '',
7598         visible: true,
7599         strokeColor: '#000000',
7600         highlightStrokeColor: '#888888',
7601         fillColor: '#ffffff',
7602         highlightFillColor: 'none',
7603 
7604         /**
7605          * Size of slider point.
7606          *
7607          * @type Number
7608          * @name Slider#size
7609          * @default 6
7610          * @see Point#size
7611          */
7612         size: 6,
7613 
7614         /**
7615          * Attributes for first (left) helper point defining the slider position.
7616          *
7617          * @type Point
7618          * @name Slider#point1
7619          */
7620         point1: {
7621             needsRegularUpdate: false,
7622             showInfobox: false,
7623             withLabel: false,
7624             visible: false,
7625             fixed: true,
7626             name: ''
7627         },
7628 
7629         /**
7630          * Attributes for second (right) helper point defining the slider position.
7631          *
7632          * @type Point
7633          * @name Slider#point2
7634          */
7635         point2: {
7636             needsRegularUpdate: false,
7637             showInfobox: false,
7638             withLabel: false,
7639             visible: false,
7640             fixed: true,
7641             name: ''
7642         },
7643 
7644         /**
7645          * Attributes for the base line of the slider.
7646          *
7647          * @type Line
7648          * @name Slider#baseline
7649          */
7650         baseline: {
7651             needsRegularUpdate: false,
7652             visible: 'inherit',
7653             fixed: true,
7654             scalable: false,
7655             tabindex: null,
7656             name: '',
7657             strokeWidth: 1,
7658             strokeColor: '#000000',
7659             highlightStrokeColor: '#888888'
7660         },
7661 
7662         /**
7663          * Attributes for the ticks of the base line of the slider.
7664          *
7665          * @type Ticks
7666          * @name Slider#ticks
7667          */
7668         ticks: {
7669             needsRegularUpdate: false,
7670             fixed: true,
7671 
7672             // Label drawing
7673             drawLabels: false,
7674             digits: 2,
7675             includeBoundaries: true,
7676             drawZero: true,
7677             label: {
7678                 offset: [-4, -14],
7679                 display: 'internal'
7680             },
7681 
7682             minTicksDistance: 30,
7683             insertTicks: true,
7684             ticksDistance: 1,      // Not necessary, since insertTicks = true
7685             minorHeight: 4,        // if <0: full width and height
7686             majorHeight: 5,        // if <0: full width and height
7687             minorTicks: 0,
7688             strokeOpacity: 1,
7689             strokeWidth: 1,
7690             tickEndings: [0, 1],
7691             majortickEndings: [0, 1],
7692             strokeColor: '#000000',
7693             visible: 'inherit'
7694         },
7695 
7696         /**
7697          * Attributes for the highlighting line of the slider.
7698          *
7699          * @type Line
7700          * @name Slider#highline
7701          */
7702         highline: {
7703             strokeWidth: 3,
7704             visible: 'inherit',
7705             fixed: true,
7706             tabindex: null,
7707             name: '',
7708             strokeColor: '#000000',
7709             highlightStrokeColor: '#888888'
7710         },
7711 
7712         /**
7713          * Attributes for the slider label.
7714          *
7715          * @type Label
7716          * @name Slider#label
7717          */
7718         label: {
7719             visible: 'inherit',
7720             strokeColor: '#000000'
7721         },
7722 
7723         /**
7724          * If true, 'up' events on the baseline will trigger slider moves.
7725          *
7726          * @type Boolean
7727          * @name Slider#moveOnUp
7728          * @default true
7729          */
7730         moveOnUp: true
7731 
7732         /**#@-*/
7733     },
7734 
7735     /* special vector field options */
7736     slopefield: {
7737         /**#@+
7738          * @visprop
7739          */
7740 
7741         strokeWidth: 0.5,
7742         highlightStrokeWidth: 0.5,
7743         highlightStrokeColor: Color.palette.blue,
7744         highlightStrokeOpacity: 0.8,
7745 
7746         /**
7747          * Set length of the vectors in user coordinates. This in contrast to vector fields, where this attribute just scales the vector.
7748          * @name scale
7749          * @memberOf Slopefield.prototype
7750          * @type {Number|Function}
7751          * @see Vectorfield.scale
7752          * @default 1
7753          */
7754         scale: 1,
7755 
7756         /**
7757          * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.
7758          * Fields are:
7759          * <ul>
7760          *  <li> enabled: Boolean
7761          *  <li> size: length of the arrow head legs (in pixel)
7762          *  <li> angle: angle of the arrow head legs In radians.
7763          * </ul>
7764          * @name arrowhead
7765          * @memberOf Slopefield.prototype
7766          * @type {Object}
7767          * @default <tt>{enabled: false, size: 5, angle: Math.PI * 0.125}</tt>
7768          */
7769         arrowhead: {
7770             enabled: false,
7771             size: 5,
7772             angle: Math.PI * 0.125
7773         }
7774 
7775         /**#@-*/
7776     },
7777 
7778     /* special options for slope triangle */
7779     slopetriangle: {
7780         /**#@+
7781          * @visprop
7782          */
7783 
7784         fillColor: Color.palette.red,
7785         fillOpacity: 0.4,
7786         highlightFillColor: Color.palette.red,
7787         highlightFillOpacity: 0.3,
7788 
7789         borders: {
7790             lastArrow: {
7791                 type: 1,
7792                 size: 6
7793             }
7794         },
7795 
7796         /**
7797          * Attributes for the gliding helper point.
7798          *
7799          * @type Point
7800          * @name Slopetriangle#glider
7801          */
7802         glider: {
7803             fixed: true,
7804             visible: false,
7805             withLabel: false
7806         },
7807 
7808         /**
7809          * Attributes for the base line.
7810          *
7811          * @type Line
7812          * @name Slopetriangle#baseline
7813          */
7814         baseline: {
7815             visible: false,
7816             withLabel: false,
7817             name: ''
7818         },
7819 
7820         /**
7821          * Attributes for the base point.
7822          *
7823          * @type Point
7824          * @name Slopetriangle#basepoint
7825          */
7826         basepoint: {
7827             visible: false,
7828             withLabel: false,
7829             name: ''
7830         },
7831 
7832         /**
7833          * Attributes for the tangent.
7834          * The tangent is constructed by slop triangle if the construction
7835          * is based on a glider, solely.
7836          *
7837          * @type Line
7838          * @name Slopetriangle#tangent
7839          */
7840         tangent: {
7841             visible: false,
7842             withLabel: false,
7843             name: ''
7844         },
7845 
7846         /**
7847          * Attributes for the top point.
7848          *
7849          * @type Point
7850          * @name Slopetriangle#toppoint
7851          */
7852         toppoint: {
7853             visible: false,
7854             withLabel: false,
7855             name: ''
7856         },
7857 
7858         /**
7859          * Attributes for the slope triangle label.
7860          *
7861          * @type Label
7862          * @name Slopetriangle#label
7863          */
7864         label: {
7865             visible: true,
7866             position: 'first'
7867         }
7868         /**#@-*/
7869     },
7870 
7871     /* special options for smartlabel of angle */
7872     smartlabelangle: {
7873         cssClass: 'smart-label-solid smart-label-angle',
7874         highlightCssClass:'smart-label-solid smart-label-angle',
7875         anchorX: 'left',
7876         anchorY: 'middle',
7877 
7878         unit: '',
7879         prefix: '',
7880         suffix: '',
7881 
7882         measure: 'deg',
7883         useMathJax: true
7884     },
7885 
7886     /* special options for smartlabel of circle */
7887     smartlabelcircle: {
7888         /**#@+
7889          * @visprop
7890          */
7891 
7892         /**
7893          * CSS classes for the smart label. Available classes are:
7894          * <ul>
7895          * <li> 'smart-label-solid'
7896          * <li> 'smart-label-outline'
7897          * <li> 'smart-label-pure'
7898          * </ul>
7899          *
7900          * By default, an additional class is given specific for the element type.
7901          * Available classes are 'smart-label-angle', 'smart-label-circle',
7902          * 'smart-label-line', 'smart-label-point', 'smart-label-polygon'.
7903          *
7904          * @example
7905          *  cssClass: 'smart-label-solid smart-label-point'
7906          *
7907          * @type String
7908          * @name Smartlabel#cssClass
7909          * @see Smartlabel#highlightCssClass
7910          * @default <ul>
7911          *  <li> 'smart-label-solid smart-label-circle' for circles</li>
7912          *  <li> 'smart-label-solid smart-label-point' for points</li>
7913          *  <li> ...</li>
7914          * </ul>
7915          */
7916         cssClass: 'smart-label-solid smart-label-circle',
7917 
7918         /**
7919          * CSS classes for the smart label when highlighted.
7920          *
7921          * @type String
7922          * @name Smartlabel#highlightCssClass
7923          * @see Smartlabel#cssClass
7924          * @default <ul>
7925          *  <li> 'smart-label-solid smart-label-circle' for circles</li>
7926          *  <li> 'smart-label-solid smart-label-point' for points</li>
7927          *  <li> ...</li>
7928          * </ul>
7929          */
7930         highlightCssClass:'smart-label-solid smart-label-circle',
7931         anchorX: 'middle',
7932         useMathJax: true,
7933 
7934         /**
7935          * Measurement unit appended to the output text. For areas, the unit is squared automatically.
7936          * Comes directly after the measurement value.
7937          *
7938          * @type {String|Function}
7939          * @name Smartlabel#unit
7940          * @default ''
7941          */
7942         unit: '',
7943 
7944         /**
7945          * Prefix text for the smartlabel. Comes before the measurement value.
7946          *
7947          * @type {String|Function}
7948          * @name Smartlabel#prefix
7949          * @default ''
7950          */
7951         prefix: '',
7952 
7953         /**
7954          * Suffix text for the smartlabel. Comes after unit.
7955          *
7956          * @type {String|Function}
7957          * @name Smartlabel#suffix
7958          * @default ''
7959          */
7960         suffix: '',
7961 
7962         /**
7963          * Type of measurement.
7964          * Available values are:
7965          *  <ul>
7966          *  <li> 'deg', 'rad' for angles</li>
7967          *  <li> 'area', 'perimeter', 'radius' for circles</li>
7968          *  <li> 'length', 'slope' for lines</li>
7969          *  <li> 'area', 'perimeter' for polygons</li>
7970          * </ul>
7971          * Dependent on this value, i.e. the type of measurement, the label is
7972          * positioned differently on the object.
7973          *
7974          * @type String
7975          * @name Smartlabel#measure
7976          * @default <ul>
7977          *   <li> 'radius' for circles</li>
7978          *   <li> 'length' for lines</li>
7979          *   <li> 'area' for polygons</li>
7980          *   <li> 'deg' for angles</li>
7981          * </ul>
7982          */
7983         measure: 'radius'
7984 
7985         /**#@-*/
7986     },
7987 
7988     /* special options for smartlabel of line */
7989     smartlabelline: {
7990         cssClass: 'smart-label-solid smart-label-line',
7991         highlightCssClass:'smart-label-solid smart-label-line',
7992         anchorX: 'middle',
7993 
7994         useMathJax: true,
7995 
7996         unit: '',
7997         measure: 'length'
7998     },
7999 
8000     /* special options for smartlabel of point */
8001     smartlabelpoint: {
8002         /**#@+
8003          * @visprop
8004          */
8005 
8006         cssClass: 'smart-label-solid smart-label-point',
8007         highlightCssClass:'smart-label-solid smart-label-point',
8008         anchorX: 'middle',
8009         anchorY: 'top',
8010 
8011         useMathJax: true,
8012 
8013         /**
8014          * Display of point coordinates either as row vector or column vector.
8015          * Available values are 'row' or 'column'.
8016          * @type String
8017          * @name Smartlabel#dir
8018          * @default 'row'
8019          */
8020         dir: 'row',
8021 
8022         /**
8023          * Supply a unit suffix.
8024          *
8025          * @type String
8026          * @name Smartlabel#unit
8027          * @default ''
8028          */
8029         unit: ''
8030 
8031         /**#@-*/
8032     },
8033 
8034     /* special options for smartlabel of polygon */
8035     smartlabelpolygon: {
8036         cssClass: 'smart-label-solid smart-label-polygon',
8037         highlightCssClass:'smart-label-solid smart-label-polygon',
8038         anchorX: 'middle',
8039 
8040         useMathJax: true,
8041 
8042         unit: '',
8043         measure: 'area'
8044     },
8045 
8046     /* special options for step functions */
8047     stepfunction: {
8048         /**#@+
8049          * @visprop
8050          */
8051 
8052         /**#@-*/
8053     },
8054 
8055     /* special tangent options */
8056     tangent: {
8057     },
8058 
8059     /* special tape measure options */
8060     tapemeasure: {
8061         /**#@+
8062          * @visprop
8063          */
8064 
8065         strokeColor: '#000000',
8066         strokeWidth: 2,
8067         highlightStrokeColor: '#000000',
8068 
8069         /**
8070          * Show tape measure ticks.
8071          *
8072          * @type Boolean
8073          * @name Tapemeasure#withTicks
8074          * @default true
8075          */
8076         withTicks: true,
8077 
8078         /**
8079          * Show tape measure label.
8080          *
8081          * @type Boolean
8082          * @name Tapemeasure#withLabel
8083          * @default true
8084          */
8085         withLabel: true,
8086 
8087         /**
8088          * Text rotation in degrees.
8089          *
8090          * @name Tapemeasure#rotate
8091          * @type Number
8092          * @default 0
8093          */
8094         rotate: 0,
8095 
8096         /**
8097          * The precision of the tape measure value displayed in the optional text.
8098          * Replaced by the attribute digits
8099          *
8100          * @memberOf Tapemeasure.prototype
8101          * @name precision
8102          * @type Number
8103          * @deprecated
8104          * @see Tapemeasure#digits
8105          * @default 2
8106          */
8107         precision: 2,
8108 
8109         /**
8110          * The precision of the tape measure value displayed in the optional text.
8111          * @memberOf Tapemeasure.prototype
8112          * @name digits
8113          * @type Number
8114          * @default 2
8115          */
8116         digits: 2,
8117 
8118         /**
8119          * Attributes for first helper point defining the tape measure position.
8120          *
8121          * @type Point
8122          * @name Tapemeasure#point1
8123          */
8124         point1: {
8125             visible: 'inherit',
8126             strokeColor: '#000000',
8127             fillColor: '#ffffff',
8128             fillOpacity: 0.0,
8129             highlightFillOpacity: 0.1,
8130             size: 6,
8131             snapToPoints: true,
8132             attractorUnit: 'screen',
8133             attractorDistance: 20,
8134             showInfobox: false,
8135             withLabel: false,
8136             name: ''
8137         },
8138 
8139         /**
8140          * Attributes for second helper point defining the tape measure position.
8141          *
8142          * @type Point
8143          * @name Tapemeasure#point2
8144          */
8145         point2: {
8146             visible: 'inherit',
8147             strokeColor: '#000000',
8148             fillColor: '#ffffff',
8149             fillOpacity: 0.0,
8150             highlightFillOpacity: 0.1,
8151             size: 6,
8152             snapToPoints: true,
8153             attractorUnit: 'screen',
8154             attractorDistance: 20,
8155             showInfobox: false,
8156             withLabel: false,
8157             name: ''
8158         },
8159 
8160         /**
8161          * Attributes for the ticks of the tape measure.
8162          *
8163          * @type Ticks
8164          * @name Tapemeasure#ticks
8165          */
8166         ticks: {
8167             drawLabels: false,
8168             drawZero: true,
8169             insertTicks: true,
8170             ticksDistance: 0.1, // Ignored, since insertTicks=true
8171             minorHeight: 8,
8172             majorHeight: 16,
8173             minorTicks: 4,
8174             tickEndings: [0, 1],
8175             majorTickEndings: [0, 1],
8176             strokeOpacity: 1,
8177             strokeWidth: 1,
8178             strokeColor: '#000000',
8179             visible: 'inherit',
8180             label: {
8181                 anchorY: 'top',
8182                 anchorX: 'middle',
8183                 offset: [0, -10]
8184             }
8185         },
8186 
8187         /**
8188          * Attributes for the tape measure label.
8189          *
8190          * @type Label
8191          * @name Tapemeasure#label
8192          */
8193         label: {
8194             position: 'top'
8195         }
8196         /**#@-*/
8197     },
8198 
8199     /* special text options */
8200     text: {
8201         /**#@+
8202          * @visprop
8203          */
8204 
8205         /**
8206          * The font size in pixels.
8207          *
8208          * @name fontSize
8209          * @memberOf Text.prototype
8210          * @default 12
8211          * @type Number
8212          * @see Text#fontUnit
8213          */
8214         fontSize: 12,
8215 
8216         /**
8217          * CSS unit for the font size of a text element. Usually, this will be the default value 'px' but
8218          * for responsive application, also 'vw', 'vh', vmax', 'vmin' or 'rem' might be useful.
8219          *
8220          * @name fontUnit
8221          * @memberOf Text.prototype
8222          * @default 'px'
8223          * @type String
8224          * @see Text#fontSize
8225          *
8226          * @example
8227          * var txt = board.create('text', [2, 2, "hello"], {fontSize: 8, fontUnit: 'vmin'});
8228          *
8229          * </pre><div id="JXG2da7e972-ac62-416b-a94b-32559c9ec9f9" class="jxgbox" style="width: 300px; height: 300px;"></div>
8230          * <script type="text/javascript">
8231          *     (function() {
8232          *         var board = JXG.JSXGraph.initBoard('JXG2da7e972-ac62-416b-a94b-32559c9ec9f9',
8233          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
8234          *     var txt = board.create('text', [2, 2, "hello"], {fontSize: 8, fontUnit: 'vmin'});
8235          *
8236          *     })();
8237          *
8238          * </script><pre>
8239          *
8240          */
8241         fontUnit: 'px',
8242 
8243         /**
8244          * If the text content is solely a number and
8245          * this attribute is true (default) then the number is formatted
8246          * according to the number of digits
8247          * given by the attribute 'digits' and convert into a fraction if 'toFraction'
8248          * is true.
8249          * <p>
8250          * Otherwise, display the raw number.
8251          *
8252          * @name formatNumber
8253          * @memberOf Text.prototype
8254          * @default true
8255          * @type Boolean
8256          *
8257          */
8258         formatNumber: true,
8259 
8260         /**
8261          * Used to round texts given by a number.
8262          *
8263          * @name digits
8264          * @memberOf Text.prototype
8265          * @default 2
8266          * @type Number
8267          */
8268         digits: 2,
8269 
8270         /**
8271          * Internationalization support for texts consisting of a number only.
8272          * <p>
8273          * Setting the local overwrites the board-wide locale set in the board attributes.
8274          * The JSXGraph attribute digits is overruled by the
8275          * Intl attributes "minimumFractionDigits" and "maximumFractionDigits".
8276          * See <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat">https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat/NumberFormat</a>
8277          * for more information about possible options.
8278          * <p>
8279          * See below for an example where the text is composed from a string and a locale formatted number.
8280          *
8281          * @name intl
8282          * @memberOf Text.prototype
8283          * @type object
8284          * @default <pre>{
8285          *    enabled: 'inherit',
8286          *    options: {}
8287          * }</pre>
8288          * @see JXG.Board#intl
8289          *
8290          * @example
8291          * var t = board.create('text', [1, 2, -Math.PI*100], {
8292          *         digits: 2,
8293          *         intl: {
8294          *                 enabled: true,
8295          *                 options: {
8296          *                     style: 'unit',
8297          *                     unit: 'celsius'
8298          *                 }
8299          *             }
8300          *     });
8301          *
8302          * </pre><div id="JXGb7162923-1beb-4e56-8817-19aa66e226d1" class="jxgbox" style="width: 300px; height: 300px;"></div>
8303          * <script type="text/javascript">
8304          *     (function() {
8305          *         var board = JXG.JSXGraph.initBoard('JXGb7162923-1beb-4e56-8817-19aa66e226d1',
8306          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
8307          *     var t = board.create('text', [1, 2, -Math.PI*100], {
8308          *             digits: 2,
8309          *             intl: {
8310          *                     enabled: true,
8311          *                     options: {
8312          *                         style: 'unit',
8313          *                         unit: 'celsius'
8314          *                     }
8315          *                 }
8316          *         });
8317          *
8318          *     })();
8319          *
8320          * </script><pre>
8321          *
8322          *
8323          * @example
8324          * var t = board.create('text', [0.05, -0.2, ''], {
8325          *     intl: {
8326          *         enabled: true,
8327          *         locale: 'it-IT',
8328          *         options: {
8329          *             style: 'unit',
8330          *             unit: 'kilometer-per-hour',
8331          *             unitDisplay: 'narrow',
8332          *             maximumFractionDigits: 2
8333          *         }
8334          *     }
8335          * });
8336          *
8337          * // Set dynamic text consisting of text and number.
8338          * t.setText(function() {
8339          *     var txt = 'Speed: ',
8340          *         number = t.X();
8341          *
8342          *     // Add formatted number to variable txt
8343          *     // with fallback if locale is not supported.
8344          *     if (t.useLocale()) {
8345          *         txt += t.formatNumberLocale(number);
8346          *     } else {
8347          *         txt += JXG.toFixed(number, 2);
8348          *     }
8349          *     return txt;
8350          * });
8351          *
8352          * </pre><div id="JXG560aeb1c-55fb-45da-8ad5-d3ad26216056" class="jxgbox" style="width: 300px; height: 300px;"></div>
8353          * <script type="text/javascript">
8354          *     (function() {
8355          *         var board = JXG.JSXGraph.initBoard('JXG560aeb1c-55fb-45da-8ad5-d3ad26216056',
8356          *             {boundingbox: [-0.5, 0.5, 0.5, -0.5], axis: true, showcopyright: false, shownavigation: false});
8357          *     var t = board.create('text', [0.3, -0.3, ''], {
8358          *         intl: {
8359          *             enabled: true,
8360          *             locale: 'it-IT',
8361          *             options: {
8362          *                 style: 'unit',
8363          *                 unit: 'kilometer-per-hour',
8364          *                 unitDisplay: 'narrow',
8365          *                 maximumFractionDigits: 2
8366          *             }
8367          *         }
8368          *     });
8369          *
8370          *     // Set dynamic text consisting of text and number.
8371          *     t.setText(function() {
8372          *         var txt = 'Speed: ',
8373          *             number = t.X();
8374          *
8375          *         // Add formatted number to variable txt
8376          *         if (t.useLocale()) {
8377          *             txt += t.formatNumberLocale(number);
8378          *         } else {
8379          *             txt += JXG.toFixed(number, 2);
8380          *         }
8381          *         return txt;
8382          *     });
8383          *
8384          *     })();
8385          *
8386          * </script><pre>
8387          *
8388          */
8389         intl: {
8390             enabled: 'inherit',
8391             options: {}
8392         },
8393 
8394         /**
8395          * If set to true, the text is parsed and evaluated.
8396          * For labels parse==true results in converting names of the form k_a to subscripts.
8397          * If the text is given by string and parse==true, the string is parsed as
8398          * JessieCode expression.
8399          *
8400          * @name parse
8401          * @memberOf Text.prototype
8402          * @default true
8403          * @type Boolean
8404          */
8405         parse: true,
8406 
8407         /**
8408          * If set to true and caja's sanitizeHTML function can be found it
8409          * will be used to sanitize text output.
8410          *
8411          * @name useCaja
8412          * @memberOf Text.prototype
8413          * @default false
8414          * @type Boolean
8415          */
8416         useCaja: false,
8417 
8418         /**
8419          * If enabled, the text will be handled as label. Intended for internal use.
8420          *
8421          * @name isLabel
8422          * @memberOf Text.prototype
8423          * @default false
8424          * @type Boolean
8425          */
8426         isLabel: false,
8427 
8428         strokeColor: '#000000',
8429         highlightStrokeColor: '#000000',
8430         highlightStrokeOpacity: 0.666666,
8431 
8432         /**
8433          * Default CSS properties of the HTML text element.
8434          * <p>
8435          * The CSS properties which are set here, are handed over to the style property
8436          * of the HTML text element. That means, they have higher property than any
8437          * CSS class.
8438          * <p>
8439          * If a property which is set here should be overruled by a CSS class
8440          * then this property should be removed here.
8441          * <p>
8442          * The reason, why this attribute should be kept to its default value at all,
8443          * is that screen dumps of SVG boards with <tt>board.renderer.dumpToCanvas()</tt>
8444          * will ignore the font-family if it is set in a CSS class.
8445          * It has to be set explicitly as style attribute.
8446          * <p>
8447          * In summary, the order of priorities from high to low is
8448          * <ol>
8449          *  <li> JXG.Options.text.cssStyle
8450          *  <li> JXG.Options.text.cssDefaultStyle
8451          *  <li> JXG.Options.text.cssClass
8452          * </ol>
8453          * @example
8454          * If all texts should get its font-family from the default CSS class
8455          * before initializing the board
8456          * <pre>
8457          *   JXG.Options.text.cssDefaultStyle = '';
8458          *   JXG.Options.text.highlightCssDefaultStyle = '';
8459          * </pre>
8460          * should be called.
8461          *
8462          * @name cssDefaultStyle
8463          * @memberOf Text.prototype
8464          * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'
8465          * @type String
8466          * @see Text#highlightCssDefaultStyle
8467          * @see Text#cssStyle
8468          * @see Text#highlightCssStyle
8469          */
8470         cssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',
8471 
8472         /**
8473          * Default CSS properties of the HTML text element in case of highlighting.
8474          * <p>
8475          * The CSS properties which are set here, are handed over to the style property
8476          * of the HTML text element. That means, they have higher property than any
8477          * CSS class.
8478          * @example
8479          * If all texts should get its font-family from the default CSS class
8480          * before initializing the board
8481          * <pre>
8482          *   JXG.Options.text.cssDefaultStyle = '';
8483          *   JXG.Options.text.highlightCssDefaultStyle = '';
8484          * </pre>
8485          * should be called.
8486          *
8487          * @name highlightCssDefaultStyle
8488          * @memberOf Text.prototype
8489          * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'
8490          * @type String
8491          * @see Text#cssDefaultStyle
8492          * @see Text#cssStyle
8493          * @see Text#highlightCssStyle
8494         */
8495         highlightCssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',
8496 
8497         /**
8498          * CSS properties of the HTML text element.
8499          * <p>
8500          * The CSS properties which are set here, are handed over to the style property
8501          * of the HTML text element. That means, they have higher property than any
8502          * CSS class.
8503          *
8504          * @name cssStyle
8505          * @memberOf Text.prototype
8506          * @default  ''
8507          * @type String
8508          * @see Text#cssDefaultStyle
8509          * @see Text#highlightCssDefaultStyle
8510          * @see Text#highlightCssStyle
8511         */
8512         cssStyle: '',
8513 
8514         /**
8515          * CSS properties of the HTML text element in case of highlighting.
8516          * <p>
8517          * The CSS properties which are set here, are handed over to the style property
8518          * of the HTML text element. That means, they have higher property than any
8519          * CSS class.
8520          *
8521          * @name highlightCssStyle
8522          * @memberOf Text.prototype
8523          * @default  ''
8524          * @type String
8525          * @see Text#cssDefaultStyle
8526          * @see Text#highlightCssDefaultStyle
8527          * @see Text#cssStyle
8528         */
8529         highlightCssStyle: '',
8530 
8531         transitionProperties: ['color', 'opacity'],
8532 
8533         /**
8534          * If true, the input will be given to ASCIIMathML before rendering.
8535          *
8536          * @name useASCIIMathML
8537          * @memberOf Text.prototype
8538          * @default false
8539          * @type Boolean
8540          */
8541         useASCIIMathML: false,
8542 
8543         /**
8544          * If true, MathJax will be used to render the input string.
8545          * Supports MathJax 2 as well as Mathjax 3.
8546          * It is recommended to use this option together with the option
8547          * "parse: false". Otherwise, 4 backslashes (e.g. \\\\alpha) are needed
8548          * instead of two (e.g. \\alpha).
8549          *
8550          * @name useMathJax
8551          * @memberOf Text.prototype
8552          * @default false
8553          * @type Boolean
8554          * @see Text#parse
8555          *
8556          * @example
8557          *  // Before loading MathJax, it has to be configured something like this:
8558          * window.MathJax = {
8559          *   tex: {
8560          *     inlineMath: [ ['$','$'], ["\\(","\\)"] ],
8561          *     displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
8562          *     packages: ['base', 'ams']
8563          *   },
8564          *   options: {
8565          *     ignoreHtmlClass: 'tex2jax_ignore',
8566          *     processHtmlClass: 'tex2jax_process'
8567          *   }
8568          * };
8569          *
8570          * // Display style
8571          * board.create('text',[ 2,2,  function(){return '$$X=\\frac{2}{x}$$'}], {
8572          *     fontSize: 15, color:'green', useMathJax: true});
8573          *
8574          * // Inline style
8575          * board.create('text',[-2,2,  function(){return '$X_A=\\frac{2}{x}$'}], {
8576          *     fontSize: 15, color:'green', useMathJax: true});
8577          *
8578          * var A = board.create('point', [-2, 0]);
8579          * var B = board.create('point', [1, 0]);
8580          * var C = board.create('point', [0, 1]);
8581          *
8582          * var graph = board.create('ellipse', [A, B, C], {
8583          *         fixed: true,
8584          *         withLabel: true,
8585          *         strokeColor: 'black',
8586          *         strokeWidth: 2,
8587          *         fillColor: '#cccccc',
8588          *         fillOpacity: 0.3,
8589          *         highlightStrokeColor: 'red',
8590          *         highlightStrokeWidth: 3,
8591          *         name: '$1=\\frac{(x-h)^2}{a^2}+\\frac{(y-k)^2}{b^2}$',
8592          *         label: {useMathJax: true}
8593          *     });
8594          *
8595          * var nvect1 = board.create('text', [-4, -3, '\\[\\overrightarrow{V}\\]'],
8596          * {
8597          *   fontSize: 24, parse: false
8598          * });
8599          * var nvect1 = board.create('text', [-2, -4, function() {return '$\\overrightarrow{G}$';}],
8600          * {
8601          *   fontSize: 24, useMathJax: true
8602          * });
8603          *
8604          * </pre>
8605          * <script>
8606          * window.MathJax = {
8607          *   tex: {
8608          *     inlineMath: [ ['$','$'], ["\\(","\\)"] ],
8609          *     displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
8610          *     packages: ['base', 'ams']
8611          *   },
8612          *   options: {
8613          *     ignoreHtmlClass: 'tex2jax_ignore',
8614          *     processHtmlClass: 'tex2jax_process'
8615          *   }
8616          * };
8617          * </script>
8618          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
8619          * <div id="JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9" class="jxgbox" style="width: 400px; height: 400px;"></div>
8620          * <script type="text/javascript">
8621          *     (function() {
8622          *         var board = JXG.JSXGraph.initBoard('JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9',
8623          *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});
8624          *     // Display style
8625          *     board.create('text',[ 2,2,  function(){return '$$X=\\frac{2}{x}$$'}], {
8626          *         fontSize: 15, color:'green', useMathJax: true});
8627          *
8628          *     // Inline style
8629          *     board.create('text',[-2,2,  function(){return '$X_A=\\frac{2}{x}$'}], {
8630          *         fontSize: 15, color:'green', useMathJax: true});
8631          *
8632          *     var A = board.create('point', [-2, 0]);
8633          *     var B = board.create('point', [1, 0]);
8634          *     var C = board.create('point', [0, 1]);
8635          *
8636          *     var graph = board.create('ellipse', [A, B, C], {
8637          *             fixed: true,
8638          *             withLabel: true,
8639          *             strokeColor: 'black',
8640          *             strokeWidth: 2,
8641          *             fillColor: '#cccccc',
8642          *             fillOpacity: 0.3,
8643          *             highlightStrokeColor: 'red',
8644          *             highlightStrokeWidth: 3,
8645          *             name: '$1=\\frac{(x-h)^2}{a^2}+\\frac{(y-k)^2}{b^2}$',
8646          *             label: {useMathJax: true}
8647          *         });
8648          *
8649          *     var nvect1 = board.create('text', [-4, -3, '\\[\\overrightarrow{V}\\]'],
8650          *     {
8651          *       fontSize: 24, parse: false
8652          *     });
8653          *     var nvect1 = board.create('text', [-2, -4, function() {return '$\\overrightarrow{G}$';}],
8654          *     {
8655          *       fontSize: 24, useMathJax: true
8656          *     });
8657          *     })();
8658          *
8659          * </script><pre>
8660          *
8661          *
8662          * @example
8663          * // Load MathJax:
8664          * // <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"<</script>
8665          *
8666          * // function and its derivative
8667          * var f1 = function(x) { return x * x * x; },
8668          * graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),
8669          *
8670          * A = board.create('glider', [0.5, f1(0.5), graph1], {
8671          *             name: 'f(x)',
8672          *             color: 'black',
8673          *             face:'x',
8674          *             fixed: true,
8675          *             size: 3,
8676          *             label: {offset: [-30, 10], fontSize: 15}
8677          *         }),
8678          * B = board.create('glider', [0.7, f1(0.7), graph1], {
8679          *             name: 'f(x+Δx)',
8680          *             size: 3,
8681          *             label: {offset: [-60, 10], fontSize: 15}
8682          *         }),
8683          *
8684          * secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),
8685          * a_h_segment = board.create('segment', [A, [
8686          *                     function(){ return B.X() > A.X() ? B.X() : A.X()},
8687          *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}
8688          *                 ]],{ name: 'Δx', dash: 1, color: 'black'});
8689          *
8690          * b_v_segment = board.create('segment', [B, [
8691          *                     function(){ return B.X() > A.X() ? B.X() : A.X()},
8692          *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}
8693          *                 ]],{ name: 'Δy', dash: 1, color: 'black'}),
8694          *
8695          * ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2
8696          *     ], {visible: false});
8697          *
8698          * board.create('text', [0, 0, function() {return '\\[\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\]'}], {
8699          *     anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'
8700          * });
8701          *
8702          * mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});
8703          * board.create('text', [0, 0, function() {return '\\[\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\]'}], {
8704          *     anchor: mb, useMathJax: true, fixed: true, color: 'green'
8705          * });
8706          *
8707          * dval = board.create('text',[0.1, 0.8,
8708          *     function(){
8709          *         return '\\[\\frac{\\Delta_y}{\\Delta_x}=\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +
8710          *             '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\]';
8711          *     }],{fontSize: 15, useMathJax: true});
8712          *
8713          * </pre>
8714          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
8715          * <div id="JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621" class="jxgbox" style="width: 400px; height: 400px;"></div>
8716          * <script type="text/javascript">
8717          *     (function() {
8718          *         var board = JXG.JSXGraph.initBoard('JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621',
8719          *             {boundingbox: [-0.1, 1.1, 1.1, -0.1], axis: true, showcopyright: false, shownavigation: false});
8720          *     // function and its derivative
8721          *     var f1 = function(x) { return x * x * x; },
8722          *     graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),
8723          *
8724          *     A = board.create('glider', [0.5, f1(0.5), graph1], {
8725          *                 name: 'f(x)',
8726          *                 color: 'black',
8727          *                 face:'x',
8728          *                 fixed: true,
8729          *                 size: 3,
8730          *                 label: {offset: [-30, 10], fontSize: 15}
8731          *             }),
8732          *     B = board.create('glider', [0.7, f1(0.7), graph1], {
8733          *                 name: 'f(x+Δx)',
8734          *                 size: 3,
8735          *                 label: {offset: [-60, 10], fontSize: 15}
8736          *             }),
8737          *
8738          *     secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),
8739          *     a_h_segment = board.create('segment', [A, [
8740          *                         function(){ return B.X() > A.X() ? B.X() : A.X()},
8741          *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}
8742          *                     ]],{ name: 'Δx', dash: 1, color: 'black'});
8743          *
8744          *     b_v_segment = board.create('segment', [B, [
8745          *                         function(){ return B.X() > A.X() ? B.X() : A.X()},
8746          *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}
8747          *                     ]],{ name: 'Δy', dash: 1, color: 'black'}),
8748          *
8749          *     ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2
8750          *         ], {visible: false});
8751          *
8752          *     board.create('text', [0, 0, function() {return '\\[\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\]'}], {
8753          *         anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'
8754          *     });
8755          *
8756          *     mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});
8757          *     board.create('text', [0, 0, function() {return '\\[\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\]'}], {
8758          *         anchor: mb, useMathJax: true, fixed: true, color: 'green'
8759          *     });
8760          *
8761          *     dval = board.create('text',[0.1, 0.8,
8762          *         function(){
8763          *             return '\\[\\frac{\\Delta_y}{\\Delta_x}=\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +
8764          *                 '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\]';
8765          *         }],{fontSize: 15, useMathJax: true});
8766          *
8767          *     })();
8768          *
8769          * </script><pre>
8770          *
8771          * @example
8772          * var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1, 10, 11, -2], axis: true});
8773          * board.options.text.useMathjax = true;
8774          *
8775          * a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
8776          *     suffixlabel:'\\(t_1=\\)',
8777          *     unitLabel: ' \\(\\text{ ms}\\)',
8778          *     snapWidth:0.01}),
8779          *
8780          * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
8781          * text1 = board.create('text', [5, 1, function(){
8782          *             return '\\(a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}\\)';
8783          *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});
8784          *
8785          * </pre><div id="JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6" class="jxgbox" style="width: 300px; height: 300px;"></div>
8786          * <script type="text/javascript">
8787          *     (function() {
8788          *         var board = JXG.JSXGraph.initBoard('JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6',
8789          *             {boundingbox: [-1, 10, 11, -2], axis: true, showcopyright: false, shownavigation: false});
8790          *     board.options.text.useMathjax = true;
8791          *
8792          *     a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
8793          *         suffixlabel:'\\(t_1=\\)',
8794          *         unitLabel: ' \\(\\text{ ms}\\)',
8795          *         snapWidth:0.01}),
8796          *
8797          *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
8798          *     text1 = board.create('text', [5, 1, function(){
8799          *                 return '\\(a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}\\)';
8800          *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});
8801          *
8802          *     })();
8803          *
8804          * </script><pre>
8805          *
8806          */
8807         useMathJax: false,
8808 
8809         /**
8810          *
8811          * If true, KaTeX will be used to render the input string.
8812          * For this feature, katex.min.js and katex.min.css have to be included.
8813          * <p>
8814          * The example below does not work, because there is a conflict with
8815          * the MathJax library which is used below.
8816          * </p>
8817          *
8818          * @name useKatex
8819          * @memberOf Text.prototype
8820          * @default false
8821          * @type Boolean
8822          *
8823          *
8824          * @example
8825          * JXG.Options.text.useKatex = true;
8826          *
8827          * const board = JXG.JSXGraph.initBoard('jxgbox', {
8828          *     boundingbox: [-2, 5, 8, -5], axis:true
8829          * });
8830          *
8831          * var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
8832          *     suffixlabel:'t_1=',
8833          *     unitLabel: ' \\text{ ms}',
8834          *     snapWidth:0.01});
8835          *
8836          * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
8837          * text1 = board.create('text', [5, 1, function(){
8838          *             return 'a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}';
8839          *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});
8840          *
8841          * </pre>
8842          * <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.13.10/dist/katex.min.css" integrity="sha384-0cCFrwW/0bAk1Z/6IMgIyNU3kfTcNirlObr4WjrUU7+hZeD6ravdYJ3kPWSeC31M" crossorigin="anonymous">
8843          * <script src="https://cdn.jsdelivr.net/npm/katex@0.13.10/dist/katex.min.js" integrity="sha384-dtFDxK2tSkECx/6302Z4VN2ZRqt6Gis+b1IwCjJPrn0kMYFQT9rbtyQWg5NFWAF7" crossorigin="anonymous"></script>
8844          * <div id="JXG497f065c-cfc1-44c3-ba21-5fa581668869" class="jxgbox" style="width: 300px; height: 300px;"></div>
8845          * <script type="text/javascript">
8846          *     (function() {
8847          *         var board = JXG.JSXGraph.initBoard('JXG497f065c-cfc1-44c3-ba21-5fa581668869',
8848          *             {boundingbox: [-2, 5, 8, -5], axis: true, showcopyright: false, shownavigation: false});
8849          *     board.options.useKatex = true;
8850          *     var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
8851          *         suffixlabel:'t_1=',
8852          *         unitLabel: ' \\text{ ms}',
8853          *         snapWidth:0.01});
8854          *
8855          *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
8856          *     text1 = board.create('text', [5, 1, function(){
8857          *                 return 'a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}';
8858          *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});
8859          *
8860          *     })();
8861          *
8862          * </script><pre>
8863          */
8864         useKatex: false,
8865 
8866         /**
8867          * Object or function returning an object that contains macros for KaTeX.
8868          *
8869          * @name katexMacros
8870          * @memberOf Text.prototype
8871          * @default <tt>{}</tt>
8872          * @type Object
8873          *
8874          * @example
8875          * // to globally apply macros to all text elements use:
8876          * JXG.Options.text.katexMacros = {'\\jxg': 'JSXGraph is awesome'};
8877          *
8878          * const board = JXG.JSXGraph.initBoard('jxgbox', {
8879          *     boundingbox: [-2, 5, 8, -5], axis:true
8880          * });
8881          *
8882          * // This macro only get applied to the p ('text') element
8883          * var p = board.create('text', [1, 0, '\\jsg \\sR '], { katexMacros: {'\\sR':'\\mathbb{R}'} });
8884          */
8885         katexMacros: {},
8886 
8887         /**
8888          * Display number as integer + nominator / denominator. Works together
8889          * with MathJax, KaTex or as plain text.
8890          * @name toFraction
8891          * @memberOf Text.prototype
8892          * @type Boolean
8893          * @default false
8894          * @see JXG#toFraction
8895          *
8896          * @example
8897          *  board.create('text', [2, 2, 2 / 7], { anchorY: 'top', toFraction: true, useMathjax: true });
8898          *  board.create('text', [2, -2, 2 / 19], { toFraction: true, useMathjax: false });
8899          *
8900          * </pre><div id="JXGc10fe0b6-15ac-42b6-890f-2593b427d493" class="jxgbox" style="width: 300px; height: 300px;"></div>
8901          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
8902          * <script type="text/javascript">
8903          *     (function() {
8904          *         var board = JXG.JSXGraph.initBoard('JXGc10fe0b6-15ac-42b6-890f-2593b427d493',
8905          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
8906          *             board.create('text', [2, 2, 2 / 7], { anchorY: 'top', toFraction: true, useMathjax: true });
8907          *             board.create('text', [2, -2, 2 / 19], { toFraction: true, useMathjax: false });
8908          *
8909          *     })();
8910          *
8911          * </script><pre>
8912          *
8913          */
8914         toFraction: false,
8915 
8916         /**
8917          * Determines the rendering method of the text. Possible values
8918          * include <tt>'html'</tt> and <tt>'internal</tt>.
8919          *
8920          * @name display
8921          * @memberOf Text.prototype
8922          * @default 'html'
8923          * @type String
8924          */
8925         display: 'html',
8926 
8927         /**
8928          * Anchor element {@link Point}, {@link Text} or {@link Image} of the text.
8929          * If it exists, the coordinates of the text are relative
8930          * to this anchor element. In this case, only numbers are possible coordinates,
8931          * functions are not supported.
8932          *
8933          * @name anchor
8934          * @memberOf Text.prototype
8935          * @default null
8936          * @type Object
8937          */
8938         anchor: null,
8939 
8940         /**
8941          * The horizontal alignment of the text. Possible values include <tt>'auto'</tt>, <tt>'left'</tt>,
8942          * <tt>'middle'</tt>, and <tt>'right'</tt>.
8943          *
8944          * @name anchorX
8945          * @memberOf Text.prototype
8946          * @default 'left'
8947          * @type String
8948          */
8949         anchorX: 'left',
8950 
8951         /**
8952          * The vertical alignment of the text. Possible values include <tt>'auto</tt>, <tt>'top'</tt>, <tt>'middle'</tt>, and
8953          * <tt>'bottom'</tt>.
8954          * For MathJax or KaTeX, 'top' is recommended.
8955          *
8956          * @name anchorY
8957          * @memberOf Text.prototype
8958          * @default 'middle'
8959          * @type String
8960          */
8961         anchorY: 'middle',
8962 
8963         /**
8964          * CSS class of the text in non-highlighted view.
8965          *
8966          * @name cssClass
8967          * @memberOf Text.prototype
8968          * @type String
8969          * @default 'JXGtext'
8970          */
8971         cssClass: 'JXGtext',
8972 
8973         /**
8974          * CSS class of the text in highlighted view.
8975          *
8976          * @name highlightCssClass
8977          * @memberOf Text.prototype
8978          * @type String
8979          * @default 'JXGtext'
8980          */
8981         highlightCssClass: 'JXGtext',
8982 
8983         /**
8984          * Sensitive area for dragging the text.
8985          * Possible values are 'all', or something else.
8986          * If set to 'small', a sensitivity margin at the right and left border is taken.
8987          * This may be extended to left, right, ... in the future.
8988          *
8989          * @name Text#dragArea
8990          * @type String
8991          * @default 'all'
8992          */
8993         dragArea: 'all',
8994 
8995         withLabel: false,
8996 
8997         /**
8998          * Text rotation in degrees.
8999          * Works for non-zero values only in combination with display=='internal'.
9000          *
9001          * @name Text#rotate
9002          * @type Number
9003          * @default 0
9004          */
9005         rotate: 0,
9006 
9007         /**
9008          * @name Text#visible
9009          * @type Boolean
9010          * @default true
9011          */
9012         visible: true,
9013 
9014         /**
9015          * Defines together with {@link Text#snapSizeY} the grid the text snaps on to.
9016          * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
9017          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
9018          * of the default ticks of the default x axes of the board.
9019          *
9020          * @name snapSizeX
9021          * @memberOf Text.prototype
9022          *
9023          * @see Point#snapToGrid
9024          * @see Text#snapSizeY
9025          * @see JXG.Board#defaultAxes
9026          * @type Number
9027          * @default 1
9028          */
9029         snapSizeX: 1,
9030 
9031         /**
9032          * Defines together with {@link Text#snapSizeX} the grid the text snaps on to.
9033          * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
9034          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
9035          * of the default ticks of the default y axes of the board.
9036          *
9037          * @name snapSizeY
9038          * @memberOf Text.prototype
9039          *
9040          * @see Point#snapToGrid
9041          * @see Text#snapSizeX
9042          * @see JXG.Board#defaultAxes
9043          * @type Number
9044          * @default 1
9045          */
9046         snapSizeY: 1,
9047 
9048         /**
9049          * List of attractor elements. If the distance of the text is less than
9050          * attractorDistance the text is made to glider of this element.
9051          *
9052          * @name attractors
9053          * @memberOf Text.prototype
9054          * @type Array
9055          * @default empty
9056          */
9057         attractors: []
9058 
9059         /**#@-*/
9060     },
9061 
9062     /* special options for trace curves */
9063     tracecurve: {
9064         /**#@+
9065          * @visprop
9066          */
9067         strokeColor: '#000000',
9068         fillColor: 'none',
9069 
9070         /**
9071          * The number of evaluated data points.
9072          * @memberOf Tracecurve.prototype
9073          * @default 100
9074          * @name numberPoints
9075          * @type Number
9076          */
9077         numberPoints: 100
9078 
9079         /**#@-*/
9080     },
9081 
9082     /* special turtle options */
9083     turtle: {
9084         /**#@+
9085          * @visprop
9086          */
9087 
9088         strokeWidth: 1,
9089         fillColor: 'none',
9090         strokeColor: '#000000',
9091 
9092         /**
9093          * Attributes for the turtle arrow.
9094          *
9095          * @type Curve
9096          * @name Turtle#arrow
9097          */
9098         arrow: {
9099             strokeWidth: 2,
9100             withLabel: false,
9101             strokeColor: Color.palette.red,
9102             lastArrow: true
9103         }
9104         /**#@-*/
9105     },
9106 
9107     /* special vector field options */
9108     vectorfield: {
9109         /**#@+
9110          * @visprop
9111          */
9112 
9113         strokeWidth: 0.5,
9114         highlightStrokeWidth: 0.5,
9115         highlightStrokeColor: Color.palette.blue,
9116         highlightStrokeOpacity: 0.8,
9117 
9118         /**
9119          * Scaling factor of the vectors. This in contrast to slope fields, where this attribute sets the vector to the given length.
9120          * @name scale
9121          * @memberOf Vectorfield.prototype
9122          * @type {Number|Function}
9123          * @see Slopefield.scale
9124          * @default 1
9125          */
9126         scale: 1,
9127 
9128         /**
9129          * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.
9130          * Fields are:
9131          * <ul>
9132          *  <li> enabled: Boolean
9133          *  <li> size: length of the arrow head legs (in pixel)
9134          *  <li> angle: angle of the arrow head legs In radians.
9135          * </ul>
9136          * @name arrowhead
9137          * @memberOf Vectorfield.prototype
9138          * @type {Object}
9139          * @default <tt>{enabled: true, size: 5, angle: Math.PI * 0.125}</tt>
9140          */
9141         arrowhead: {
9142             enabled: true,
9143             size: 5,
9144             angle: Math.PI * 0.125
9145         }
9146 
9147         /**#@-*/
9148     },
9149 
9150     /**
9151      * Abbreviations of attributes. Setting the shortcut means setting abbreviated properties
9152      * to the same value.
9153      * It is used in {@link JXG.GeometryElement#setAttribute} and in
9154      * the constructor {@link JXG.GeometryElement}.
9155      * Attention: In Options.js abbreviations are not allowed.
9156      * @type Object
9157      * @name JXG.Options#shortcuts
9158      *
9159      */
9160     shortcuts: {
9161         color: ['strokeColor', 'fillColor'],
9162         opacity: ['strokeOpacity', 'fillOpacity'],
9163         highlightColor: ['highlightStrokeColor', 'highlightFillColor'],
9164         highlightOpacity: ['highlightStrokeOpacity', 'highlightFillOpacity'],
9165         strokeWidth: ['strokeWidth', 'highlightStrokeWidth']
9166     }
9167 };
9168 
9169     /**
9170      * Holds all possible properties and the according validators for geometry elements.
9171      * A validator is either a function
9172      * which takes one parameter and returns true, if the value is valid for the property,
9173      * or it is false if no validator is required.
9174      */
9175     JXG.Validator = (function () {
9176         var i,
9177             validatePixel = function (v) {
9178                 return (/^[0-9]+px$/).test(v);
9179             },
9180             validateDisplay = function (v) {
9181                 return (v  === 'html' || v === 'internal');
9182             },
9183             validateColor = function (v) {
9184                 // for now this should do it...
9185                 return Type.isString(v);
9186             },
9187             validatePointFace = function (v) {
9188                 return Type.exists(JXG.normalizePointFace(v));
9189             },
9190             validateInteger = function (v) {
9191                 return (Math.abs(v - Math.round(v)) < Mat.eps);
9192             },
9193             validateNotNegativeInteger = function (v) {
9194                 return validateInteger(v) && v >= 0;
9195             },
9196             validatePositiveInteger = function (v) {
9197                 return validateInteger(v) && v > 0;
9198             },
9199             validateScreenCoords = function (v) {
9200                 return v.length >= 2 && validateInteger(v[0]) && validateInteger(v[1]);
9201             },
9202             validateRenderer = function (v) {
9203                 return (v === 'vml' || v === 'svg' || v === 'canvas' || v === 'no');
9204             },
9205             validatePositive = function (v) {
9206                 return v > 0;
9207             },
9208             validateNotNegative = function (v) {
9209                 return v >= 0;
9210             },
9211             v = {},
9212             validators = {
9213                 attractorDistance: validateNotNegative,
9214                 color: validateColor,
9215                 // defaultDistance: Type.isNumber,
9216                 display: validateDisplay,
9217                 doAdvancedPlot: false,
9218                 draft: false,
9219                 drawLabels: false,
9220                 drawZero: false,
9221                 face: validatePointFace,
9222                 factor: Type.isNumber,
9223                 fillColor: validateColor,
9224                 fillOpacity: Type.isNumber,
9225                 firstArrow: false,
9226                 fontSize: validateInteger,
9227                 dash: validateInteger,
9228                 gridX: Type.isNumber,
9229                 gridY: Type.isNumber,
9230                 // POI: Do we have to add something here?
9231                 hasGrid: false,
9232                 highlightFillColor: validateColor,
9233                 highlightFillOpacity: Type.isNumber,
9234                 highlightStrokeColor: validateColor,
9235                 highlightStrokeOpacity: Type.isNumber,
9236                 insertTicks: false,
9237                 //: validateScreenCoords,
9238                 lastArrow: false,
9239                 layer: validateNotNegativeInteger,
9240                 majorHeight: validateInteger,
9241                 minorHeight: validateInteger,
9242                 minorTicks: validateNotNegative,
9243                 minTicksDistance: validatePositiveInteger,
9244                 numberPointsHigh: validatePositiveInteger,
9245                 numberPointsLow: validatePositiveInteger,
9246                 opacity: Type.isNumber,
9247                 radius: Type.isNumber,
9248                 RDPsmoothing: false,
9249                 renderer: validateRenderer,
9250                 right: validatePixel,
9251                 showCopyright: false,
9252                 showInfobox: false,
9253                 showNavigation: false,
9254                 size: validateNotNegative, //validateInteger,
9255                 snapSizeX: validatePositive,
9256                 snapSizeY: validatePositive,
9257                 snapWidth: Type.isNumber,
9258                 snapToGrid: false,
9259                 snatchDistance: validateNotNegative,
9260                 straightFirst: false,
9261                 straightLast: false,
9262                 stretch: false,
9263                 strokeColor: validateColor,
9264                 strokeOpacity: Type.isNumber,
9265                 strokeWidth: validateNotNegative, //validateInteger,
9266                 takeFirst: false,
9267                 takeSizeFromFile: false,
9268                 to10: false,
9269                 toOrigin: false,
9270                 translateTo10: false,
9271                 translateToOrigin: false,
9272                 useASCIIMathML: false,
9273                 useDirection: false,
9274                 useMathJax: false,
9275                 withLabel: false,
9276                 withTicks: false,
9277                 zoom: false
9278             };
9279 
9280         // this seems like a redundant step but it makes sure that
9281         // all properties in the validator object have lower case names
9282         // and the validator object is easier to read.
9283         for (i in validators) {
9284             if (validators.hasOwnProperty(i)) {
9285                 v[i.toLowerCase()] = validators[i];
9286             }
9287         }
9288 
9289         return v;
9290     }());
9291 
9292     /**
9293      * All point faces can be defined with more than one name, e.g. a cross faced point can be given
9294      * by face equal to 'cross' or equal to 'x'. This method maps all possible values to fixed ones to
9295      * simplify if- and switch-clauses regarding point faces. The translation table is as follows:
9296      * <table>
9297      * <tr><th>Input</th><th>Output</th></tr>
9298      * <tr><td>cross</td><td>x</td></tr>
9299      * <tr><td>circle</td><td>o</td></tr>
9300      * <tr><td>square, []</td><td>[]</td></tr>
9301      * <tr><td>plus</td><td>+</td></tr>
9302      * <tr><td>minus</td><td>-</td></tr>
9303      * <tr><td>divide</td><td>|</td></tr>
9304      * <tr><td>diamond</td><td><></td></tr>
9305      * <tr><td>triangleup</td><td>^, a, A</td></tr>
9306      * <tr><td>triangledown</td><td>v</td></tr>
9307      * <tr><td>triangleleft</td><td><</td></tr>
9308      * <tr><td>triangleright</td><td>></td></tr>
9309      * </table>
9310      * @param {String} s A string which should determine a valid point face.
9311      * @returns {String} Returns a normalized string or undefined if the given string is not a valid
9312      * point face.
9313      */
9314     JXG.normalizePointFace = function (s) {
9315         var map = {
9316             cross: 'x',
9317             x: 'x',
9318             circle: 'o',
9319             o: 'o',
9320             square: '[]',
9321             '[]': '[]',
9322             plus: '+',
9323             '+': '+',
9324             divide: '|',
9325             '|': '|',
9326             minus: '-',
9327             '-': '-',
9328             diamond: '<>',
9329             '<>': '<>',
9330             diamond2: '<<>>',
9331             '<<>>': '<<>>',
9332             triangleup: '^',
9333             A: '^',
9334             a: '^',
9335             '^': '^',
9336             triangledown: 'v',
9337             v: 'v',
9338             triangleleft: '<',
9339             '<': '<',
9340             triangleright: '>',
9341             '>': '>'
9342         };
9343 
9344         return map[s];
9345     };
9346 
9347 
9348     /**
9349      * Apply the options stored in this object to all objects on the given board.
9350      * @param {JXG.Board} board The board to which objects the options will be applied.
9351      */
9352     JXG.useStandardOptions = function (board) {
9353         var el, t, p, copyProps,
9354             o = JXG.Options,
9355             boardHadGrid = board.hasGrid;
9356 
9357         board.options.grid.hasGrid = o.grid.hasGrid;
9358         board.options.grid.gridX = o.grid.gridX;
9359         board.options.grid.gridY = o.grid.gridY;
9360         // POI: Do we have to add something here?
9361         board.options.grid.gridColor = o.grid.gridColor;
9362         board.options.grid.gridOpacity = o.grid.gridOpacity;
9363         board.options.grid.gridDash = o.grid.gridDash;
9364         board.options.grid.snapToGrid = o.grid.snapToGrid;
9365         board.options.grid.snapSizeX = o.grid.SnapSizeX;
9366         board.options.grid.snapSizeY = o.grid.SnapSizeY;
9367         board.takeSizeFromFile = o.takeSizeFromFile;
9368 
9369         copyProps = function (p, o) {
9370             p.visProp.fillcolor = o.fillColor;
9371             p.visProp.highlightfillcolor = o.highlightFillColor;
9372             p.visProp.strokecolor = o.strokeColor;
9373             p.visProp.highlightstrokecolor = o.highlightStrokeColor;
9374         };
9375 
9376         for (el in board.objects) {
9377             if (board.objects.hasOwnProperty(el)) {
9378                 p = board.objects[el];
9379                 if (p.elementClass === Const.OBJECT_CLASS_POINT) {
9380                     copyProps(p, o.point);
9381                 } else if (p.elementClass === Const.OBJECT_CLASS_LINE) {
9382                     copyProps(p, o.line);
9383 
9384                     for (t = 0; t < p.ticks.length; t++) {
9385                         p.ticks[t].majorTicks = o.line.ticks.majorTicks;
9386                         p.ticks[t].minTicksDistance = o.line.ticks.minTicksDistance;
9387                         p.ticks[t].visProp.minorheight = o.line.ticks.minorHeight;
9388                         p.ticks[t].visProp.majorheight = o.line.ticks.majorHeight;
9389                     }
9390                 } else if (p.elementClass === Const.OBJECT_CLASS_CIRCLE) {
9391                     copyProps(p, o.circle);
9392                 } else if (p.type === Const.OBJECT_TYPE_ANGLE) {
9393                     copyProps(p, o.angle);
9394                 } else if (p.type === Const.OBJECT_TYPE_ARC) {
9395                     copyProps(p, o.arc);
9396                 } else if (p.type === Const.OBJECT_TYPE_POLYGON) {
9397                     copyProps(p, o.polygon);
9398                 } else if (p.type === Const.OBJECT_TYPE_CONIC) {
9399                     copyProps(p, o.conic);
9400                 } else if (p.type === Const.OBJECT_TYPE_CURVE) {
9401                     copyProps(p, o.curve);
9402                 } else if (p.type === Const.OBJECT_TYPE_SECTOR) {
9403                     p.arc.visProp.fillcolor = o.sector.fillColor;
9404                     p.arc.visProp.highlightfillcolor = o.sector.highlightFillColor;
9405                     p.arc.visProp.fillopacity = o.sector.fillOpacity;
9406                     p.arc.visProp.highlightfillopacity = o.sector.highlightFillOpacity;
9407                 }
9408             }
9409         }
9410 
9411         board.fullUpdate();
9412         if (boardHadGrid && !board.hasGrid) {
9413             board.removeGrids(board);
9414         } else if (!boardHadGrid && board.hasGrid) {
9415             board.create('grid', []);
9416         }
9417     };
9418 
9419     /**
9420      * Converts all color values to greyscale and calls useStandardOption to put them onto the board.
9421      * @param {JXG.Board} board The board to which objects the options will be applied.
9422      * @see #useStandardOptions
9423      */
9424     JXG.useBlackWhiteOptions = function (board) {
9425         var o = JXG.Options;
9426         o.point.fillColor = Color.rgb2bw(o.point.fillColor);
9427         o.point.highlightFillColor = Color.rgb2bw(o.point.highlightFillColor);
9428         o.point.strokeColor = Color.rgb2bw(o.point.strokeColor);
9429         o.point.highlightStrokeColor = Color.rgb2bw(o.point.highlightStrokeColor);
9430 
9431         o.line.fillColor = Color.rgb2bw(o.line.fillColor);
9432         o.line.highlightFillColor = Color.rgb2bw(o.line.highlightFillColor);
9433         o.line.strokeColor = Color.rgb2bw(o.line.strokeColor);
9434         o.line.highlightStrokeColor = Color.rgb2bw(o.line.highlightStrokeColor);
9435 
9436         o.circle.fillColor = Color.rgb2bw(o.circle.fillColor);
9437         o.circle.highlightFillColor = Color.rgb2bw(o.circle.highlightFillColor);
9438         o.circle.strokeColor = Color.rgb2bw(o.circle.strokeColor);
9439         o.circle.highlightStrokeColor = Color.rgb2bw(o.circle.highlightStrokeColor);
9440 
9441         o.arc.fillColor = Color.rgb2bw(o.arc.fillColor);
9442         o.arc.highlightFillColor = Color.rgb2bw(o.arc.highlightFillColor);
9443         o.arc.strokeColor = Color.rgb2bw(o.arc.strokeColor);
9444         o.arc.highlightStrokeColor = Color.rgb2bw(o.arc.highlightStrokeColor);
9445 
9446         o.polygon.fillColor = Color.rgb2bw(o.polygon.fillColor);
9447         o.polygon.highlightFillColor  = Color.rgb2bw(o.polygon.highlightFillColor);
9448 
9449         o.sector.fillColor = Color.rgb2bw(o.sector.fillColor);
9450         o.sector.highlightFillColor  = Color.rgb2bw(o.sector.highlightFillColor);
9451 
9452         o.curve.strokeColor = Color.rgb2bw(o.curve.strokeColor);
9453         o.grid.gridColor = Color.rgb2bw(o.grid.gridColor);
9454 
9455         JXG.useStandardOptions(board);
9456     };
9457 
9458 // needs to be exported
9459 JXG.Options.normalizePointFace = JXG.normalizePointFace;
9460 
9461 export default JXG.Options;
9462