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