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