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