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