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