1 /*
  2     Copyright 2008-2023
  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";
 36 import Const from "./base/constants";
 37 import Mat from "./math/math";
 38 import Color from "./utils/color";
 39 import Type from "./utils/type";
 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 (<sub>1</sub>, y<sub>1</sub>)
 98          * to the lower right corner (x<sub>2</sub>, y<sub>2</sub>).
 99          *
100          * @name JXG.Board#boundingBox
101          * @type Array
102          * @see JXG.Board#maxBoundingBox
103          * @see JXG.Board#keepAspectRatio
104          *
105          * @default [-5, 5, 5, -5]
106          * @example
107          * var board = JXG.JSXGraph.initBoard('jxgbox', {
108          *         boundingbox: [-5, 5, 5, -5],
109          *         axis: true
110          *     });
111          */
112         boundingBox: [-5, 5, 5, -5],
113 
114         /**
115          * Enable browser scrolling on touch interfaces if the user double taps into an empty region
116          * of the board.
117          *
118          * <ul>
119          * <li> Implemented for pointer touch devices - not with mouse, pen or old iOS touch.
120          * <li> It only works if browserPan:true
121          * <li> One finger action by the settings "pan.enabled:true" and "pan.needTwoFingers:false" has priority
122          * </ul>
123          *
124          * @name JXG.Board#browserPan
125          * @see JXG.Board#pan
126          * @type Boolean
127          * @default false
128          *
129          * @example
130          * const board = JXG.JSXGraph.initBoard('jxgbox', {
131          *     boundingbox: [-5, 5, 5, -5], axis: true,
132          *     pan: {
133          *         enabled: true,
134          *         needTwoFingers: true,
135          *     },
136          *     browserPan: true,
137          *     zoom: {
138          *         enabled: false
139          *     }
140          * });
141          *
142          * var p1 = board.create('point', [1, -1]);
143          * var p2 = board.create('point', [2.5, -2]);
144          * var li1 = board.create('line', [p1, p2]);
145          *
146          * </pre><div id="JXGcd50c814-be81-4280-9458-d73e50cece8d" class="jxgbox" style="width: 300px; height: 300px;"></div>
147          * <script type="text/javascript">
148          *     (function() {
149          *         var board = JXG.JSXGraph.initBoard('JXGcd50c814-be81-4280-9458-d73e50cece8d',
150          *             {showcopyright: false, shownavigation: false,
151          *              axis: true,
152          *              pan: {
153          *                enabled: true,
154          *                needTwoFingers: true,
155          *             },
156          *             browserPan: true,
157          *             zoom: {
158          *               enabled: false
159          *             }
160          *          });
161          *
162          *     var p1 = board.create('point', [1, -1]);
163          *     var p2 = board.create('point', [2.5, -2]);
164          *     var li1 = board.create('line', [p1, p2]);
165          *
166          *     })();
167          *
168          * </script><pre>
169          *
170          *
171          */
172         browserPan: false,
173 
174         /**
175          * Attributes for the default axes in case of the attribute
176          * axis:true in {@link JXG.JSXGraph#initBoard}.
177          *
178          * @name JXG.Board#defaultAxes
179          * @type Object
180          * @default {x: {name:'x'}, y: {name: 'y'}}
181          *
182          * @example
183          * const board = JXG.JSXGraph.initBoard('id', {
184          *     boundingbox: [-5, 5, 5, -5], axis:true,
185          *     defaultAxes: {
186          *         x: {
187          *           name: 'Distance (mi)',
188          *           withLabel: true,
189          *           label: {
190          *             position: 'rt',
191          *             offset: [-5, 15],
192          *             anchorX: 'right'
193          *           }
194          *         },
195          *         y: {
196          *           withLabel: true,
197          *           name: 'Y',
198          *           label: {
199          *             position: 'rt',
200          *             offset: [-20, -5],
201          *             anchorY: 'top'
202          *           }
203          *         }
204          *     }
205          * });
206          *
207          * </pre><div id="JXGc3af5eb8-7401-4476-80b5-379ecbd068c6" class="jxgbox" style="width: 300px; height: 300px;"></div>
208          * <script type="text/javascript">
209          *     (function() {
210          *     var board = JXG.JSXGraph.initBoard('JXGc3af5eb8-7401-4476-80b5-379ecbd068c6', {
211          *         showcopyright: false, shownavigation: false,
212          *         boundingbox: [-5, 5, 5, -5], axis:true,
213          *         defaultAxes: {
214          *             x: {
215          *               name: 'Distance (mi)',
216          *               withLabel: true,
217          *               label: {
218          *                 position: 'rt',
219          *                 offset: [-5, 15],
220          *                 anchorX: 'right'
221          *               }
222          *             },
223          *             y: {
224          *               withLabel: true,
225          *               name: 'Y',
226          *               label: {
227          *                 position: 'rt',
228          *                 offset: [-20, -5],
229          *                 anchorY: 'top'
230          *               }
231          *             }
232          *         }
233          *     });
234          *
235          *     })();
236          *
237          * </script><pre>
238          *
239          */
240         defaultAxes: {
241             x: {
242                 name: 'x',
243                 fixed: true,
244                 ticks: {
245                     label: {
246                         visible: 'inherit',
247                         anchorX: 'middle',
248                         anchorY: 'top',
249                         fontSize: 12,
250                         offset: [0, -3]
251                     },
252                     tickEndings: [0, 1],
253                     majorTickEndings: [1, 1],
254                     drawZero: false,
255                     needsRegularUpdate: false,
256                     visible: 'inherit'
257                 }
258             },
259             y: {
260                 name: 'y',
261                 fixed: true,
262                 ticks: {
263                     label: {
264                         visible: 'inherit',
265                         anchorX: 'right',
266                         anchorY: 'middle',
267                         fontSize: 12,
268                         offset: [-6, 0]
269                     },
270                     tickEndings: [1, 0],
271                     majorTickEndings: [1, 1],
272                     drawZero: false,
273                     needsRegularUpdate: false,
274                     visible: 'inherit'
275                 }
276             }
277         },
278 
279         /**
280          * Description string for the board.
281          * Primarily used in an invisible text element which is adressed by
282          * the attribute 'aria-describedby' from the JSXGraph container.
283          * JSXGraph creates a new div-element with id "{containerid}_ARIAdescription"
284          * containing this string.
285          *
286          * @name JXG.Board#description
287          * @see JXG.Board#title
288          * @type String
289          * @default ''
290          *
291          */
292         description: '',
293 
294         /**
295          * Supply the document object. Defaults to window.document
296          *
297          * @name JXG.Board#document
298          * @type DOM object
299          * @default false (meaning window.document)
300          */
301         document: false,
302 
303         /**
304          * Control the possibilities for dragging objects.
305          *
306          * Possible sub-attributes with default values are:
307          * <pre>
308          * drag: {
309          *   enabled: true   // Allow dragging
310          * }
311          * </pre>
312          *
313          * @name JXG.Board#drag
314          * @type Object
315          * @default {enabled: true}
316          */
317         drag: {
318             enabled: true
319         },
320 
321         /**
322          * Attribute(s) to control the fullscreen icon. The attribute "showFullscreen"
323          * controls if the icon is shown.
324          * The following attribute(s) can be set:
325          * <ul>
326          *  <li> symbol (String): Unicode symbol which is shown in the navigation bar.  Default: svg code for '\u26f6', other
327          * possibilities are the unicode symbols '\u26f6' and '\u25a1'. However, '\u26f6' is not supported by MacOS and iOS.
328          *  <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.
329          * Default value is 0.85.
330          *  <li> id (String): Id of the HTML element which is brought to full screen or null if the JSXgraph div is taken.
331          * 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.
332          * </ul>
333          *
334          * @example
335          * var board = JXG.JSXGraph.initBoard('35bec5a2-fd4d-11e8-ab14-901b0e1b8723',
336          *             {boundingbox: [-8, 8, 8,-8], axis: true,
337          *             showcopyright: false,
338          *             showFullscreen: true,
339          *             fullscreen: {
340          *                  symbol: '\u22c7',
341          *                  scale: 0.95
342          *              }
343          *             });
344          * var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});
345          *
346          * </pre><div id="JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723" class="jxgbox" style="width: 300px; height: 300px;"></div>
347          * <script type="text/javascript">
348          *     (function() {
349          *         var board = JXG.JSXGraph.initBoard('JXGa35bec5a2-fd4d-11e8-ab14-901b0e1b8723',
350          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false,
351          *              showFullscreen: true,
352          *              fullscreen: {
353          *                  symbol: '\u22c7',
354          *                  scale: 0.95
355          *                  }
356          *             });
357          *     var pol = board.create('polygon', [[0, 1], [3,4], [1,-4]], {fillColor: 'yellow'});
358          *     })();
359          *
360          * </script><pre>
361          *
362          * @name JXG.Board#fullscreen
363          * @default svg code
364          * @see JXG.Board#showFullscreen
365          * @see JXG.AbstractRenderer#drawNavigationBar
366          * @type Object
367          */
368         fullscreen: {
369             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>',
370             // symbol: '\u26f6', // '\u26f6' (not supported by MacOS),
371             scale: 0.85,
372             id: null
373         },
374 
375         /**
376          * If set true and
377          * hasPoint() is true for both an element and it's label,
378          * the element (and not the label) is taken as drag element.
379          * <p>
380          * If set false and hasPoint() is true for both an element and it's label,
381          * the label is taken (if it is on a higher layer than the element)
382          * <p>
383          * Meanwhile, this feature might be irrelevant.
384          * @name JXG.Board#ignoreLabels
385          * @type Booelan
386          * @default true
387          */
388         ignoreLabels: true,
389 
390         /**
391          * Support for internationalization of number formatting. This affects
392          * <ul>
393          *  <li> axis labels
394          *  <li> infobox
395          *  <li> texts consisting of numbers only
396          *  <li> smartlabel elements
397          *  <li> slider labels
398          *  <li> tapemeasure elements
399          *  <li> integral element labels
400          * </ul>
401          * 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>
402          * for an overview on the possibilities and the options.
403          * <p>
404          * User generated texts consisting of texts AND numbers have to be internationalized by the user, see
405          * {@link Text#intl}.
406          * Language locale and options can be individually controlled for each element by its intl attribute.
407          * If no locale is set, the default language of the browser is used.
408          *
409          * @name JXG.Board#intl
410          * @type Object
411          * @default {enabled: false}
412          * @see Integral#label
413          * @see Slider#intl
414          * @see Text#intl
415          * @see Ticks#intl
416          * @see JXG.Board.infobox
417          *
418          * @example
419          * // Set the board-wide locale and use individual
420          * // options for a text.
421          * const board = JXG.JSXGraph.initBoard(BOARDID, {
422          *     axis: true,
423          *     intl: {
424          *         enabled: true,
425          *         locale: 'de-DE'
426          *     },
427          *     boundingbox:[-0.5, 0.5, 0.5, -0.5]
428          * });
429          *
430          * var t = board.create('text', [0.05, 0.2, -Math.PI*100], {
431          *         digits: 2,
432          *         intl: {
433          *                 enabled: true,
434          *                 options: {
435          *                     style: 'unit',
436          *                     unit: 'celsius'
437          *                 }
438          *             }
439          *     });
440          *
441          * </pre><div id="JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9" class="jxgbox" style="width: 300px; height: 300px;"></div>
442          * <script type="text/javascript">
443          *     (function() {
444          *     var board = JXG.JSXGraph.initBoard('JXGcbb0305d-92e2-4628-a58a-d0d515c8fec9', {
445          *         axis: true, showcopyright: false, shownavigation: false,
446          *         intl: {
447          *             enabled: true,
448          *             locale: 'de-DE'
449          *         },
450          *     boundingbox:[-0.5, 0.5, 0.5, -0.5]
451          *     });
452          *     var t = board.create('text', [0.05, 0.2, -Math.PI*100], {
453          *         digits: 2,
454          *         intl: {
455          *                 enabled: true,
456          *                 options: {
457          *                     style: 'unit',
458          *                     unit: 'celsius'
459          *                 }
460          *             }
461          *     });
462          *
463          *     })();
464          *
465          * </script><pre>
466          *
467          * @example
468          * // Here, locale is disabled in general, but enabled for the horizontal
469          * // axis and the infobox.
470          * const board = JXG.JSXGraph.initBoard(BOARDID, {
471          *     boundingbox: [-0.5, 0.5, 0.5, -0.5],
472          *     intl: {
473          *         enabled: false,
474          *         locale: 'de-DE'
475          *     },
476          *     keepaspectratio: true,
477          *     axis: true,
478          *     defaultAxes: {
479          *         x: {
480          *             ticks: {
481          *                 intl: {
482          *                         enabled: true,
483          *                         options: {
484          *                             style: 'unit',
485          *                             unit: 'kilometer-per-hour',
486          *                             unitDisplay: 'narrow'
487          *                         }
488          *                 }
489          *             }
490          *         },
491          *         y: {
492          *             ticks: {
493          *             }
494          *         }
495          *     },
496          *     infobox: {
497          *         fontSize: 12,
498          *         intl: {
499          *             enabled: true,
500          *             options: {
501          *                 minimumFractionDigits: 4,
502          *                 maximumFractionDigits: 5
503          *             }
504          *         }
505          *     }
506          * });
507          *
508          * var p = board.create('point', [0.1, 0.1], {});
509          *
510          * </pre><div id="JXG07d5d95c-9324-4fc4-aad3-098e433f195f" class="jxgbox" style="width: 600px; height: 300px;"></div>
511          * <script type="text/javascript">
512          *     (function() {
513          *     var board = JXG.JSXGraph.initBoard('JXG07d5d95c-9324-4fc4-aad3-098e433f195f', {
514          *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,
515          *         intl: {
516          *             enabled: false,
517          *             locale: 'de-DE'
518          *         },
519          *         keepaspectratio: true,
520          *         axis: true,
521          *         defaultAxes: {
522          *             x: {
523          *                 ticks: {
524          *                     intl: {
525          *                             enabled: true,
526          *                             options: {
527          *                                 style: 'unit',
528          *                                 unit: 'kilometer-per-hour',
529          *                                 unitDisplay: 'narrow'
530          *                             }
531          *                     }
532          *                 }
533          *             },
534          *             y: {
535          *                 ticks: {
536          *                 }
537          *             }
538          *         },
539          *         infobox: {
540          *             fontSize: 12,
541          *             intl: {
542          *                 enabled: true,
543          *                 options: {
544          *                     minimumFractionDigits: 4,
545          *                     maximumFractionDigits: 5
546          *                 }
547          *             }
548          *         }
549          *     });
550          *
551          *     var p = board.create('point', [0.1, 0.1], {});
552          *
553          *     })();
554          *
555          * </script><pre>
556          *
557          */
558         intl: {
559             enabled: false
560         },
561 
562         /**
563          * If set to true, the ratio between horizontal and vertical unit sizes
564          * stays constant - independent of size changes of the hosting HTML div element.
565          * <p>
566          * If the aspect ration of the hosting div changes, JSXGraphs will change
567          * the user supplied bounding box accordingly.
568          * This is necessary if circles should look like circles and not
569          * like ellipses. It is recommended to set keepAspectRatio = true
570          * for geometric applets.
571          * <p>
572          * For function plotting keepAspectRatio = false
573          * might be the better choice.
574          *
575          * @name JXG.Board#keepAspectRatio
576          * @see JXG.Board#boundingBox
577          * @see JXG.Board#maxBoundingBox
578          * @see JXG.Board#setBoundingBox
579          * @type Boolean
580          * @default false
581          */
582         keepAspectRatio: false,
583 
584         /**
585          * Control using the keyboard to change the construction.
586          * <ul>
587          * <li> enabled: true / false
588          * <li> dx: horizontal shift amount per key press
589          * <li> dy: vertical shift amount per key press
590          * <li> panShift: zoom if shift key is pressed
591          * <li> panCtrl: zoom if ctrl key is pressed
592          * </ul>
593          *
594          * @example
595          * var board = JXG.JSXGraph.initBoard("jxgbox", {boundingbox: [-5,5,5,-5],
596          *     axis: true,
597          *     showCopyright:true,
598          *     showNavigation:true,
599          *     keyboard: {
600          *         enabled: true,
601          *         dy: 30,
602          *         panShift: true,
603          *         panCtrl: false
604          *     }
605          * });
606          *
607          * </pre><div id="JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266" class="jxgbox" style="width: 300px; height: 300px;"></div>
608          * <script type="text/javascript">
609          *     (function() {
610          *         var board = JXG.JSXGraph.initBoard('JXGb1d3aab6-ced2-4fe9-8fa5-b0accc8c7266',
611          *             {boundingbox: [-5,5,5,-5],
612          *         axis: true,
613          *         showCopyright:true,
614          *         showNavigation:true,
615          *         keyboard: {
616          *             enabled: true,
617          *             dy: 30,
618          *             panShift: true,
619          *             panCtrl: false
620          *         }
621          *     });
622          *
623          *     })();
624          *
625          * </script><pre>
626          *
627          *
628          * @see JXG.Board#keyDownListener
629          * @see JXG.Board#keyFocusInListener
630          * @see JXG.Board#keyFocusOutListener
631          *
632          * @name JXG.Board#keyboard
633          * @type Object
634          * @default {enabled: true, dx: 10, dy:10, panShift: true, panCtrl: false}
635          */
636         keyboard: {
637             enabled: true,
638             dx: 10,
639             dy: 10,
640             panShift: true,
641             panCtrl: false
642         },
643 
644         /**
645          * If enabled, user activities are logged in array "board.userLog".
646          *
647          * @name JXG.Board#logging
648          * @type Object
649          * @default {enabled: false}
650          *
651          * @example
652          * var board = JXG.JSXGraph.initBoard(BOARDID,
653          *          {
654          *              boundingbox: [-8, 8, 8,-8],
655          *              axis: true,
656          *              logging: {enabled: true},
657          *              showcopyright: false,
658          *              shownavigation: false
659          *          });
660          * var A = board.create('point', [-4, 0], { name: 'A' });
661          * var B = board.create('point', [1, 2], { name: 'B' });
662          * var showUserLog = function() {
663          *     var txt = '';
664          *
665          *     for (let i = 0; i < board.userLog.length; i++) {
666          *         txt += JSON.stringify(board.userLog[i]) + '\n';
667          *     }
668          *     alert(txt);
669          * };
670          * var but = board.create('button', [4, 4, 'Show user log', showUserLog]);
671          *
672          * </pre><div id="JXGe152375c-f478-41aa-a9e6-e104403fc75d" class="jxgbox" style="width: 300px; height: 300px;"></div>
673          * <script type="text/javascript">
674          *     (function() {
675          *         var board = JXG.JSXGraph.initBoard('JXGe152375c-f478-41aa-a9e6-e104403fc75d',
676          *             {boundingbox: [-8, 8, 8,-8], axis: true, logging: {enabled: true},
677          *              showcopyright: false, shownavigation: false});
678          *     var A = board.create('point', [-4, 0], { name: 'A' });
679          *     var B = board.create('point', [1, 2], { name: 'B' });
680          *     var showUserLog = function() {
681          *         var txt = '';
682          *
683          *         for (let i = 0; i < board.userLog.length; i++) {
684          *             txt += JSON.stringify(board.userLog[i]) + '\n';
685          *         }
686          *         alert(txt);
687          *     };
688          *     var but = board.create('button', [4, 4, 'Show user log', showUserLog]);
689          *
690          *     })();
691          *
692          * </script><pre>
693          *
694          *
695          * @see JXG.Board#userLog
696          */
697         logging: {
698             enabled: false
699         },
700 
701         /**
702          * Change redraw strategy in SVG rendering engine.
703          * <p>
704          * This optimization seems to be <b>obsolete</b> in newer browsers (from 2021 on, at least)
705          * and even slow down the constructions. Therefore, the default is set to 'none' since v1.2.4.
706          * <p>
707          * If set to 'svg', before every redrawing of the JSXGraph construction
708          * the SVG sub-tree of the DOM tree is taken out of the DOM.
709          *
710          * If set to 'all', before every redrawing of the JSXGraph construction the
711          * complete DOM tree is taken out of the DOM.
712          * If set to 'none' the redrawing is done in-place.
713          *
714          * Using 'svg' or 'all' speeds up the update process considerably. The risk
715          * is that if there is an exception, only a white div or window is left.
716          *
717          *
718          * @name JXG.Board#minimizeReflow
719          * @type String
720          * @default 'none'
721          */
722         minimizeReflow: 'none',
723 
724         /**
725          * Maximal bounding box of the visible area in user coordinates.
726          * It is an array consisting of four values:
727          * [x<sub>1</sub>, y<sub>1</sub>, x<sub>2</sub>, y<sub>2</sub>]
728          *
729          * The bounding box of the canvas must be inside of this maximal
730          * bounding box.
731          *
732          * @name JXG.Board#maxBoundingBox
733          * @type Array
734          * @see JXG.Board#boundingBox
735          * @default [-Infinity, Infinity, Infinity, -Infinity]
736          *
737          * @example
738          * var board = JXG.JSXGraph.initBoard('jxgbox', {
739          *         boundingBox: [-5, 5, 5, -5],
740          *         maxBoundingBox: [-8, 8, 8, -8],
741          *         pan: {enabled: true},
742          *         axis: true
743          *     });
744          *
745          * </pre><div id="JXG065e2750-217c-48ed-a52b-7d7df6de7055" class="jxgbox" style="width: 300px; height: 300px;"></div>
746          * <script type="text/javascript">
747          *     (function() {
748          *         var board = JXG.JSXGraph.initBoard('JXG065e2750-217c-48ed-a52b-7d7df6de7055', {
749          *             showcopyright: false, shownavigation: false,
750          *             boundingbox: [-5,5,5,-5],
751          *             maxboundingbox: [-8,8,8,-8],
752          *             pan: {enabled: true},
753          *             axis:true
754          *         });
755          *
756          *     })();
757          *
758          * </script><pre>
759          *
760          */
761         maxBoundingBox: [-Infinity, Infinity, Infinity, -Infinity],
762 
763         /**
764          * Maximum frame rate of the board, i.e. maximum number of updates per second
765          * triggered by move events.
766          *
767          * @name JXG.Board#maxFrameRate
768          * @type Number
769          * @default 40
770          */
771         maxFrameRate: 40,
772 
773         /**
774          * Maximum number of digits in automatic label generation.
775          * For example, if set to 1 automatic point labels end at "Z".
776          * If set to 2, point labels end at "ZZ".
777          *
778          * @name JXG.Board#maxNameLength
779          * @see JXG.Board#generateName
780          * @type Number
781          * @default 1
782          */
783         maxNameLength: 1,
784 
785         /**
786          * Element which listens to move events of the pointing device.
787          * This allows to drag elements of a JSXGraph construction outside of the board.
788          * Especially, on mobile devices this enhances the user experience.
789          * However, it is recommended to allow dragging outside of the JSXGraph board only
790          * in certain constructions where users may not "loose" points outside of the board.
791          * In such a case, points may become unreachable.
792          * <p>
793          * A situation where dragging outside of the board is uncritical is for example if
794          * only sliders are used to interact with the construction.
795          * <p>
796          * Possible values for this attributes are:
797          * <ul>
798          * <li> an element specified by document.getElementById('some id');
799          * <li> null: to use the JSXGraph container div element
800          * <li> document
801          * </ul>
802          * <p>
803          * Since the introduction of this attribute "moveTarget", the value "document" has become sort of
804          * default on touch devices like smartphones. However, it is no longer the case that the document listens to
805          * move events, but there is the new feature "setPointerCapture", which is also implicitly enabled on certain devices.
806          * In future versions, JSXGraph may adopt this new standard and distinguish only two cases:
807          * <ul>
808          * <li>null: no pointerCapture
809          * <li>document: use pointerCapture
810          * </ul>
811          * <p>
812          * This attribute is immutable.
813          * It can be changed as follows:
814          *
815          * @example
816          * board.setAttribute({moveTarget: null});
817          * board.removeEventHandlers();
818          * board.addEventHandlers();
819          *
820          * @name JXG.Board#moveTarget
821          * @type HTML node or document
822          * @default null
823          *
824          * @example
825          *     var board = JXG.JSXGraph.initBoard('jxgbox', {
826          *         boundingbox: [-5,5,5,-5],
827          *         axis: true,
828          *         moveTarget: document
829          *     });
830          *
831          * </pre><div id="JXG973457e5-c63f-4516-8570-743f2cc560e1" class="jxgbox" style="width: 300px; height: 300px;"></div>
832          * <script type="text/javascript">
833          *     (function() {
834          *         var board = JXG.JSXGraph.initBoard('JXG973457e5-c63f-4516-8570-743f2cc560e1',
835          *             {boundingbox: [-5,5,5,-5],
836          *             axis: true,
837          *             moveTarget: document
838          *         });
839          *
840          *     })();
841          *
842          * </script><pre>
843          *
844          *
845          */
846         moveTarget: null,
847 
848         /**
849          * A number that will be added to the absolute position of the board used in mouse coordinate
850          * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.
851          *
852          * @name JXG.Board#offsetX
853          * @see JXG.Board#offsetY
854          * @type Number
855          * @default 0
856          */
857         offsetX: 0,
858 
859         /**
860          * A number that will be added to the absolute position of the board used in mouse coordinate
861          * calculations in {@link JXG.Board#getCoordsTopLeftCorner}.
862          *
863          * @name JXG.Board#offsetY
864          * @see JXG.Board#offsetX
865          * @type Number
866          * @default 0
867          */
868         offsetY: 0,
869 
870         /**
871          * Control the possibilities for panning interaction (i.e. moving the origin).
872          *
873          * Possible sub-attributes with default values are:
874          * <pre>
875          * pan: {
876          *   enabled: true   // Allow panning
877          *   needTwoFingers: false, // panning is done with two fingers on touch devices
878          *   needShift: true, // mouse panning needs pressing of the shift key
879          * }
880          * </pre>
881          *
882          * @name JXG.Board#pan
883          * @see JXG.Board#browserPan
884          *
885          * @type Object
886          */
887         pan: {
888             enabled: true,
889             needShift: true,
890             needTwoFingers: false
891         },
892 
893         /**
894          * Allow user interaction by registering mouse, pointer, keyboard or touch events.
895          * Decide if JSXGraph listens to these events. Keyboard events can then turned off
896          * separately with the keyboard attribute.
897          *
898          * <p>This attribute is immutable. Please use
899          * {@link JXG.Board#addEventHandlers()} and
900          * {@link JXG.Board#removeEventHandlers()} directly.
901          *
902          * @name JXG.Board#registerEvents
903          * @see JXG.Board#keyboard
904          * @see JXG.Board#registerResizeEvent
905          * @see JXG.Board#registerFullscreenEvent
906          * @type Boolean
907          * @default true
908          */
909         registerEvents: true,
910 
911         /**
912          * Listen to fullscreen event.
913          *
914          * <p>This attribute is immutable. Please use
915          * {@link JXG.Board#addFullscreenEventHandlers()} and
916          * {@link JXG.Board#removeEventHandlers()} directly.
917          *
918          * @name JXG.Board#registerFullscreenEvent
919          * @see JXG.Board#registerEvents
920          * @see JXG.Board#registerResizeEvent
921          * @type Boolean
922          * @default true
923          */
924         registerFullscreenEvent: true,
925 
926         /**
927          * Listen to resize events, i.e. start "resizeObserver" or handle the resize event with
928          * "resizeListener". This is independent from the mouse, touch, pointer events.
929          *
930          * <p>This attribute is immutable. Please use
931          * {@link JXG.Board#addResizeEventHandlers()} and
932          * {@link JXG.Board#removeEventHandlers()} directly.
933          * <p>
934          * This attribute just starts a resizeObserver. If the resizeObserver reacts
935          * to size changed is controled wuth {@link JXG.Board#resize}.
936          *
937          * @name JXG.Board#registerResizeEvent
938          * @see JXG.Board#resize
939          * @see JXG.Board#registerEvents
940          * @see JXG.Board#registerFullscreenEvent
941          * @type Boolean
942          * @default true
943          */
944         registerResizeEvent: true,
945 
946         /**
947          * Default rendering engine. Possible values are 'svg', 'canvas', 'vml', 'no', or 'auto'.
948          * If the rendering engine is not available JSXGraph tries to detect a different engine.
949          *
950          * <p>
951          * In case of 'canvas' it is advisable to call 'board.update()' after all elements have been
952          * constructed. This ensures that all elements are drawn with their intended visual appearance.
953          *
954          * <p>
955          * This attribute is immutable.
956          *
957          * @name JXG.Board#renderer
958          * @type String
959          * @default 'auto'
960          */
961         renderer: 'auto',
962 
963         /**
964          * Control if JSXGraph reacts to resizing of the JSXGraph container element
965          * by the user / browser.
966          * The attribute "throttle" determines the minimal time in msec between to
967          * resize calls.
968          *
969          * @see JXG.Board#startResizeObserver
970          * @see JXG.Board#resizeListener
971          *
972          * @name JXG.Board#resize
973          * @type Object
974          * @default {enabled: true, throttle: 10}
975          *
976          * @example
977          *     var board = JXG.JSXGraph.initBoard('jxgbox', {
978          *         boundingbox: [-5,5,5,-5],
979          *         keepAspectRatio: true,
980          *         axis: true,
981          *         resize: {enabled: true, throttle: 200}
982          *     });
983          *
984          * </pre><div id="JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3" class="jxgbox" style="width: 300px; height: 300px;"></div>
985          * <script type="text/javascript">
986          *     (function() {
987          *         var board = JXG.JSXGraph.initBoard('JXGb55d4608-5d71-4bc3-b332-18c15fbda8c3', {
988          *             boundingbox: [-5,5,5,-5],
989          *             keepAspectRatio: true,
990          *             axis: true,
991          *             resize: {enabled: true, throttle: 200}
992          *         });
993          *
994          *     })();
995          *
996          * </script><pre>
997          *
998          *
999          */
1000         resize: {
1001             enabled: true,
1002             throttle: 10
1003         },
1004 
1005         /**
1006          * Attributes to control the screenshot function.
1007          * The following attributes can be set:
1008          * <ul>
1009          *  <li>scale: scaling factor (default=1.0)
1010          *  <li>type: format of the screenshot image. Default: png
1011          *  <li>symbol: Unicode symbol which is shown in the navigation bar. Default: '\u2318'
1012          *  <li>css: CSS rules to format the div element containing the screen shot image
1013          *  <li>cssButton: CSS rules to format the close button of the div element containing the screen shot image
1014          * </ul>
1015          * The screenshot will fail if the board contains text elements or foreign objects
1016          * containing SVG again.
1017          *
1018          * @name JXG.Board#screenshot
1019          * @type Object
1020          */
1021         screenshot: {
1022             scale: 1,
1023             type: 'png',
1024             symbol: '\u2318', //'\u22b9', //'\u26f6',
1025             css: 'background-color:#eeeeee; opacity:1.0; border:2px solid black; border-radius:10px; text-align:center',
1026             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);'
1027         },
1028 
1029         /**
1030          * Control the possibilities for a selection rectangle.
1031          * Starting a selection event triggers the "startselecting" event.
1032          * When the mouse pointer is released, the "stopselecting" event is fired.
1033          * The "stopselecting" event is supplied by the user.
1034          * <p>
1035          * So far it works in SVG renderer only.
1036          * <p>
1037          * Possible sub-attributes with default values are:
1038          * <pre>
1039          * selection: {
1040          *   enabled: false,
1041          *   name: 'selectionPolygon',
1042          *   needShift: false,  // mouse selection needs pressing of the shift key
1043          *   needCtrl: true,    // mouse selection needs pressing of the shift key
1044          *   fillColor: '#ffff00'
1045          * }
1046          * </pre>
1047          * <p>
1048          * Board events triggered by selection manipulation:
1049          * 'startselecting', 'stopselecting', 'mousestartselecting', 'mousestopselecting',
1050          * 'pointerstartselecting', 'pointerstopselecting', 'touchstartselecting', 'touchstopselecting'.
1051          *
1052          * @example
1053          * board.on('stopselecting', function(){
1054          *     var box = board.stopSelectionMode(),
1055          *     // bbox has the coordinates of the selectionr rectangle.
1056          *     // Attention: box[i].usrCoords have the form [1, x, y], i.e.
1057          *     // are homogeneous coordinates.
1058          *     bbox = box[0].usrCoords.slice(1).concat(box[1].usrCoords.slice(1));
1059          *     // Set a new bounding box
1060          *     board.setBoundingBox(bbox, false);
1061          * });
1062          *
1063          * @name JXG.Board#selection
1064          *
1065          * @see JXG.Board#startSelectionMode
1066          * @see JXG.Board#stopSelectionMode
1067          *
1068          * @type Object
1069          * @default
1070          */
1071         selection: {
1072             enabled: false,
1073             name: 'selectionPolygon',
1074             needShift: false,
1075             needCtrl: true,
1076             fillColor: '#ffff00',
1077 
1078             // immutable:
1079             visible: false,
1080             withLines: false,
1081             vertices: {
1082                 visible: false
1083             }
1084         },
1085 
1086         /**
1087          * Show a button which allows to clear all traces of a board.
1088          *
1089          * @name JXG.Board#showClearTraces
1090          * @type Boolean
1091          * @default false
1092          * @see JXG.AbstractRenderer#drawNavigationBar
1093          */
1094         showClearTraces: false,
1095 
1096         /**
1097          * Show copyright string in canvas.
1098          *
1099          * @name JXG.Board#showCopyright
1100          * @type Boolean
1101          * @default true
1102          */
1103         showCopyright: true,
1104 
1105         /**
1106          * Show a button in the navigation bar to start fullscreen mode.
1107          *
1108          * @name JXG.Board#showFullscreen
1109          * @type Boolean
1110          * @see JXG.Board#fullscreen
1111          * @default false
1112          * @see JXG.AbstractRenderer#drawNavigationBar
1113          * @see JXG.AbstractRenderer#drawNavigationBar
1114          */
1115         showFullscreen: false,
1116 
1117         /**
1118          * If true, the infobox is shown on mouse/pen over for all points
1119          * which have set their attribute showInfobox to 'inherit'.
1120          * If a point has set its attribute showInfobox to false or true,
1121          * that value will have priority over this value.
1122          *
1123          * @name JXG.Board#showInfobox
1124          * @see Point#showInfobox
1125          * @type Boolean
1126          * @default true
1127          */
1128         showInfobox: true,
1129 
1130         /**
1131          * Display of navigation arrows and zoom buttons in the navigation bar.
1132          *
1133          * @name JXG.Board#showNavigation
1134          * @type Boolean
1135          * @default true
1136          * @see JXG.AbstractRenderer#drawNavigationBar
1137          */
1138         showNavigation: true,
1139 
1140         /**
1141          * Show a button in the navigation bar to force reload of a construction.
1142          * Works only with the JessieCode tag.
1143          *
1144          * @name JXG.Board#showReload
1145          * @type Boolean
1146          * @default false
1147          * @see JXG.AbstractRenderer#drawNavigationBar
1148          */
1149         showReload: false,
1150 
1151         /**
1152          * Show a button in the navigation bar to enable screenshots.
1153          *
1154          * @name JXG.Board#showScreenshot
1155          * @type Boolean
1156          * @default false
1157          * @see JXG.AbstractRenderer#drawNavigationBar
1158          */
1159         showScreenshot: false,
1160 
1161         /**
1162          * Display of zoom buttons in the navigation bar. To show zoom buttons, additionally
1163          * showNavigation has to be set to true.
1164          *
1165          * @name JXG.Board#showZoom
1166          * @type Boolean
1167          * @default true
1168          * @see JXG.AbstractRenderer#drawNavigationBar
1169          */
1170         showZoom: true,
1171 
1172         /**
1173          * If true the first element of the set JXG.board.objects having hasPoint==true is taken as drag element.
1174          *
1175          * @name JXG.Board#takeFirst
1176          * @type Boolean
1177          * @default false
1178          */
1179         takeFirst: false,
1180 
1181         /**
1182         * If true, when read from a file or string - the size of the div can be changed by the construction text.
1183         *
1184         * @name JXG.Board#takeSizeFromFile
1185         * @type Boolean
1186         * @default false
1187         */
1188         takeSizeFromFile: false,
1189 
1190         /**
1191          * Title string for the board.
1192          * Primarily used in an invisible text element which is adressed by
1193          * the attribute 'aria-labelledby' from the JSXGraph container.
1194          * JSXGraph creates a new div-element with id "{containerid}_ARIAlabel"
1195          * containing this string.
1196          *
1197          * @name JXG.Board#title
1198          * @see JXG.Board#description
1199          * @type String
1200          * @default ''
1201          *
1202          */
1203         title: '',
1204 
1205         /**
1206          * Control the possibilities for zoom interaction.
1207          *
1208          * Possible sub-attributes with default values are:
1209          * <pre>
1210          * zoom: {
1211          *   factorX: 1.25,  // horizontal zoom factor (multiplied to {@link JXG.Board#zoomX})
1212          *   factorY: 1.25,  // vertical zoom factor (multiplied to {@link JXG.Board#zoomY})
1213          *   wheel: true,     // allow zooming by mouse wheel or
1214          *   				   // by pinch-to-toom gesture on touch devices
1215          *   needShift: true,   // mouse wheel zooming needs pressing of the shift key
1216          *   min: 0.001,        // minimal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomOut
1217          *   max: 1000.0,       // maximal values of {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}, limits zoomIn
1218          *
1219          *   pinchHorizontal: true, // Allow pinch-to-zoom to zoom only horizontal axis
1220          *   pinchVertical: true,   // Allow pinch-to-zoom to zoom only vertical axis
1221          *   pinchSensitivity: 7    // Sensitivity (in degrees) for recognizing horizontal or vertical pinch-to-zoom gestures.
1222          * }
1223          * </pre>
1224          *
1225          * Deprecated: zoom.eps which is superseded by zoom.min
1226          *
1227          * @name JXG.Board#zoom
1228          * @type Object
1229          * @default
1230          */
1231         zoom: {
1232             enabled: true,
1233             factorX: 1.25,
1234             factorY: 1.25,
1235             wheel: true,
1236             needShift: true,
1237             min: 0.0001,
1238             max: 10000.0,
1239             pinchHorizontal: true,
1240             pinchVertical: true,
1241             pinchSensitivity: 7
1242         },
1243 
1244         // /**
1245         //  * Additional zoom factor multiplied to {@link JXG.Board#zoomX} and {@link JXG.Board#zoomY}.
1246         //  *
1247         //  * @name JXG.Board#zoomFactor
1248         //  * @type Number
1249         //  * @default 1.0
1250         //  */
1251         // zoomFactor: 1,
1252 
1253         /**
1254          * Zoom factor in horizontal direction.
1255          *
1256          * @name JXG.Board#zoomX
1257          * @see JXG.Board#zoomY
1258          * @type Number
1259          * @default 1.0
1260          */
1261         zoomX: 1,
1262 
1263         /**
1264          * Zoom factor in vertical direction.
1265          *
1266          * @name JXG.Board#zoomY
1267          * @see JXG.Board#zoomX
1268          * @type Number
1269          * @default 1.0
1270          */
1271         zoomY: 1
1272 
1273         /**#@-*/
1274     },
1275 
1276     /**
1277      * Options that are used by the navigation bar.
1278      *
1279      * Default values are
1280      * <pre>
1281      * JXG.Option.navbar: {
1282      *   strokeColor: '#333333',
1283      *   fillColor: 'transparent',
1284      *   highlightFillColor: '#aaaaaa',
1285      *   padding: '2px',
1286      *   position: 'absolute',
1287      *   fontSize: '14px',
1288      *   cursor: 'pointer',
1289      *   zIndex: '100',
1290      *   right: '5px',
1291      *   bottom: '5px'
1292      * },
1293      * </pre>
1294      * These settings are overruled by the CSS class 'JXG_navigation'.
1295      * @deprecated
1296      * @type Object
1297      * @name JXG.Options#navbar
1298      *
1299      */
1300     navbar: {
1301         strokeColor: '#333333', //'#aaaaaa',
1302         fillColor: 'transparent', //#f5f5f5',
1303         highlightFillColor: '#aaaaaa',
1304         padding: '2px',
1305         position: 'absolute',
1306         fontSize: '14px',
1307         cursor: 'pointer',
1308         zIndex: '100',
1309         right: '5px',
1310         bottom: '5px'
1311         //border: 'none 1px black',
1312         //borderRadius: '4px'
1313     },
1314 
1315     /*
1316      *  Generic options used by {@link JXG.GeometryElement}
1317      */
1318     elements: {

1320 
1321         /**#@+
1322          * @visprop
1323          */
1324 
1325         /**
1326          * The stroke color of the given geometry element.
1327          * @type String
1328          * @name JXG.GeometryElement#strokeColor
1329          * @see JXG.GeometryElement#highlightStrokeColor
1330          * @see JXG.GeometryElement#strokeWidth
1331          * @see JXG.GeometryElement#strokeOpacity
1332          * @see JXG.GeometryElement#highlightStrokeOpacity
1333          * @default {@link JXG.Options.elements.color#strokeColor}
1334          */
1335         strokeColor: Color.palette.blue,
1336 
1337         /**
1338          * The stroke color of the given geometry element when the user moves the mouse over it.
1339          * @type String
1340          * @name JXG.GeometryElement#highlightStrokeColor
1341          * @see JXG.GeometryElement#strokeColor
1342          * @see JXG.GeometryElement#strokeWidth
1343          * @see JXG.GeometryElement#strokeOpacity
1344          * @see JXG.GeometryElement#highlightStrokeOpacity
1345          * @default {@link JXG.Options.elements.color#highlightStrokeColor}
1346          */
1347         highlightStrokeColor: '#c3d9ff',
1348 
1349         /**
1350          * The fill color of this geometry element.
1351          * @type String
1352          * @name JXG.GeometryElement#fillColor
1353          * @see JXG.GeometryElement#highlightFillColor
1354          * @see JXG.GeometryElement#fillOpacity
1355          * @see JXG.GeometryElement#highlightFillOpacity
1356          * @default {@link JXG.Options.elements.color#fillColor}
1357          */
1358         fillColor: Color.palette.red,
1359 
1360         /**
1361          * The fill color of the given geometry element when the mouse is pointed over it.
1362          * @type String
1363          * @name JXG.GeometryElement#highlightFillColor
1364          * @see JXG.GeometryElement#fillColor
1365          * @see JXG.GeometryElement#fillOpacity
1366          * @see JXG.GeometryElement#highlightFillOpacity
1367          * @default {@link JXG.Options.elements.color#highlightFillColor}
1368          */
1369         highlightFillColor: 'none',
1370 
1371         /**
1372          * Opacity for element's stroke color.
1373          * @type Number
1374          * @name JXG.GeometryElement#strokeOpacity
1375          * @see JXG.GeometryElement#strokeColor
1376          * @see JXG.GeometryElement#highlightStrokeColor
1377          * @see JXG.GeometryElement#strokeWidth
1378          * @see JXG.GeometryElement#highlightStrokeOpacity
1379          * @default {@link JXG.Options.elements#strokeOpacity}
1380          */
1381         strokeOpacity: 1,
1382 
1383         /**
1384          * Opacity for stroke color when the object is highlighted.
1385          * @type Number
1386          * @name JXG.GeometryElement#highlightStrokeOpacity
1387          * @see JXG.GeometryElement#strokeColor
1388          * @see JXG.GeometryElement#highlightStrokeColor
1389          * @see JXG.GeometryElement#strokeWidth
1390          * @see JXG.GeometryElement#strokeOpacity
1391          * @default {@link JXG.Options.elements#highlightStrokeOpacity}
1392          */
1393         highlightStrokeOpacity: 1,
1394 
1395         /**
1396          * Opacity for fill color.
1397          * @type Number
1398          * @name JXG.GeometryElement#fillOpacity
1399          * @see JXG.GeometryElement#fillColor
1400          * @see JXG.GeometryElement#highlightFillColor
1401          * @see JXG.GeometryElement#highlightFillOpacity
1402          * @default {@link JXG.Options.elements.color#fillOpacity}
1403          */
1404         fillOpacity: 1,
1405 
1406         /**
1407          * Opacity for fill color when the object is highlighted.
1408          * @type Number
1409          * @name JXG.GeometryElement#highlightFillOpacity
1410          * @see JXG.GeometryElement#fillColor
1411          * @see JXG.GeometryElement#highlightFillColor
1412          * @see JXG.GeometryElement#fillOpacity
1413          * @default {@link JXG.Options.elements.color#highlightFillOpacity}
1414          */
1415         highlightFillOpacity: 1,
1416 
1417         /**
1418          * Gradient type. Possible values are 'linear'. 'radial' or null.
1419          *
1420          * @example
1421          *     var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});
1422          *     var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});
1423          *     var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});
1424          *
1425          *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1426          *                 fillOpacity: 1,
1427          *                 fillColor: 'yellow',
1428          *                 gradient: 'linear',
1429          *                 gradientSecondColor: 'blue',
1430          *                 gradientAngle: function() { return a.Value(); },
1431          *                 gradientStartOffset: function() { return b.Value(); },
1432          *                 gradientEndOffset: function() { return c.Value(); },
1433          *                 hasInnerPoints: true
1434          *         });
1435          *
1436          * </pre><div id="JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0" class="jxgbox" style="width: 300px; height: 300px;"></div>
1437          * <script type="text/javascript">
1438          *     (function() {
1439          *         var board = JXG.JSXGraph.initBoard('JXG3d04b5fd-0cd4-4f49-8c05-4e9686cd7ff0',
1440          *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});
1441          *         var a = board.create('slider', [[0, -0.2], [3.5, -0.2], [0, 0, 2 * Math.PI]], {name: 'angle'});
1442          *         var b = board.create('slider', [[0, -0.4], [3.5, -0.4], [0, 0, 1]], {name: 'offset1'});
1443          *         var c = board.create('slider', [[0, -0.6], [3.5, -0.6], [0, 1, 1]], {name: 'offset2'});
1444          *
1445          *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1446          *                     fillOpacity: 1,
1447          *                     fillColor: 'yellow',
1448          *                     gradient: 'linear',
1449          *                     gradientSecondColor: 'blue',
1450          *                     gradientAngle: function() { return a.Value(); },
1451          *                     gradientStartOffset: function() { return b.Value(); },
1452          *                     gradientEndOffset: function() { return c.Value(); },
1453          *                     hasInnerPoints: true
1454          *             });
1455          *
1456          *     })();
1457          *
1458          * </script><pre>
1459          *
1460          * @example
1461          *     var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});
1462          *     var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});
1463          *     var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});
1464          *     var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});
1465          *     var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});
1466          *     var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});
1467          *
1468          *     var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1469          *                 fillOpacity: 1,
1470          *                 fillColor: 'yellow',
1471          *                 gradient: 'radial',
1472          *                 gradientSecondColor: 'blue',
1473          *                 gradientCX: function() { return cx.Value(); },
1474          *                 gradientCY: function() { return cx.Value(); },
1475          *                 gradientR: function() { return r.Value(); },
1476          *                 gradientFX: function() { return fx.Value(); },
1477          *                 gradientFY: function() { return fx.Value(); },
1478          *                 gradientFR: function() { return fr.Value(); },
1479          *                 gradientStartOffset: function() { return o1.Value(); },
1480          *                 gradientEndOffset: function() { return o2.Value(); },
1481          *                 hasInnerPoints: true
1482          *     });
1483          *
1484          * </pre><div id="JXG6081ca7f-0d09-4525-87ac-325a02fe2225" class="jxgbox" style="width: 300px; height: 300px;"></div>
1485          * <script type="text/javascript">
1486          *     (function() {
1487          *         var board = JXG.JSXGraph.initBoard('JXG6081ca7f-0d09-4525-87ac-325a02fe2225',
1488          *             {boundingbox: [-1.5, 4.5, 5, -1.5], axis: true, showcopyright: false, shownavigation: false});
1489          *         var cx = board.create('slider', [[0, -.2], [3.5, -.2], [0, 0.5, 1]], {name: 'cx, cy'});
1490          *         var fx = board.create('slider', [[0, -.4], [3.5, -.4], [0, 0.5, 1]], {name: 'fx, fy'});
1491          *         var o1 = board.create('slider', [[0, -.6], [3.5, -.6], [0, 0.0, 1]], {name: 'offset1'});
1492          *         var o2 = board.create('slider', [[0, -.8], [3.5, -.8], [0, 1, 1]], {name: 'offset2'});
1493          *         var r = board.create('slider', [[0, -1], [3.5, -1], [0, 0.5, 1]], {name: 'r'});
1494          *         var fr = board.create('slider', [[0, -1.2], [3.5, -1.2], [0, 0, 1]], {name: 'fr'});
1495          *
1496          *         var pol = board.create('polygon', [[0, 0], [4, 0], [4,4], [0,4]], {
1497          *                     fillOpacity: 1,
1498          *                     fillColor: 'yellow',
1499          *                     gradient: 'radial',
1500          *                     gradientSecondColor: 'blue',
1501          *                     gradientCX: function() { return cx.Value(); },
1502          *                     gradientCY: function() { return cx.Value(); },
1503          *                     gradientR: function() { return r.Value(); },
1504          *                     gradientFX: function() { return fx.Value(); },
1505          *                     gradientFY: function() { return fx.Value(); },
1506          *                     gradientFR: function() { return fr.Value(); },
1507          *                     gradientStartOffset: function() { return o1.Value(); },
1508          *                     gradientEndOffset: function() { return o2.Value(); },
1509          *                     hasInnerPoints: true
1510          *         });
1511          *
1512          *     })();
1513          *
1514          * </script><pre>
1515          *
1516          *
1517          * @type String
1518          * @name JXG.GeometryElement#gradient
1519          * @see JXG.GeometryElement#gradientSecondColor
1520          * @see JXG.GeometryElement#gradientSecondOpacity
1521          * @default null
1522          */
1523         gradient: null,
1524 
1525         /**
1526          * Second color for gradient.
1527          * @type String
1528          * @name JXG.GeometryElement#gradientSecondColor
1529          * @see JXG.GeometryElement#gradient
1530          * @see JXG.GeometryElement#gradientSecondOpacity
1531          * @default '#ffffff'
1532          */
1533         gradientSecondColor: '#ffffff',
1534 
1535         /**
1536          * Opacity of second gradient color. Takes a value between 0 and 1.
1537          * @type Number
1538          * @name JXG.GeometryElement#gradientSecondOpacity
1539          * @see JXG.GeometryElement#gradient
1540          * @see JXG.GeometryElement#gradientSecondColor
1541          * @default 1
1542          */
1543         gradientSecondOpacity: 1,
1544 
1545         /**
1546          * The gradientStartOffset attribute is a number (ranging from 0 to 1) which indicates where the first gradient stop is placed,
1547          * see the SVG specification for more information.
1548          * For linear gradients, this attribute represents a location along the gradient vector.
1549          * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.
1550          * @type Number
1551          * @name JXG.GeometryElement#gradientStartOffset
1552          * @see JXG.GeometryElement#gradient
1553          * @see JXG.GeometryElement#gradientEndOffset
1554          * @default 0.0
1555          */
1556         gradientStartOffset: 0.0,
1557 
1558         /**
1559          * The gradientEndOffset attribute is a number (ranging from 0 to 1) which indicates where the second gradient stop is placed,
1560          * see the SVG specification for more information.
1561          * For linear gradients, this attribute represents a location along the gradient vector.
1562          * For radial gradients, it represents a percentage distance from (fx,fy) to the edge of the outermost/largest circle.
1563          * @type Number
1564          * @name JXG.GeometryElement#gradientEndOffset
1565          * @see JXG.GeometryElement#gradient
1566          * @see JXG.GeometryElement#gradientStartOffset
1567          * @default 1.0
1568          */
1569         gradientEndOffset: 1.0,
1570 
1571         /**
1572          * Angle (in radians) of the gradiant in case the gradient is of type 'linear'.
1573          * If the angle is 0, the first color is on the left and the second color is on the right.
1574          * If the angle is π/2 the first color is on top and the second color at the
1575          * bottom.
1576          * @type Number
1577          * @name JXG.GeometryElement#gradientAngle
1578          * @see JXG.GeometryElement#gradient
1579          * @default 0
1580          */
1581         gradientAngle: 0,
1582 
1583         /**
1584          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1585          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1586          * For radial gradients in canvas this is the value 'x1'.
1587          * Takes a value between 0 and 1.
1588          * @type Number
1589          * @name JXG.GeometryElement#gradientCX
1590          * @see JXG.GeometryElement#gradient
1591          * @see JXG.GeometryElement#gradientCY
1592          * @see JXG.GeometryElement#gradientR
1593          * @default 0.5
1594          */
1595         gradientCX: 0.5,
1596 
1597         /**
1598          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1599          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1600          * For radial gradients in canvas this is the value 'y1'.
1601          * Takes a value between 0 and 1.
1602          * @type Number
1603          * @name JXG.GeometryElement#gradientCY
1604          * @see JXG.GeometryElement#gradient
1605          * @see JXG.GeometryElement#gradientCX
1606          * @see JXG.GeometryElement#gradientR
1607          * @default 0.5
1608          */
1609         gradientCY: 0.5,
1610 
1611         /**
1612          * From the SVG specification: ‘cx’, ‘cy’ and ‘r’ define the largest (i.e., outermost) circle for the radial gradient.
1613          * The gradient will be drawn such that the 100% gradient stop is mapped to the perimeter of this largest (i.e., outermost) circle.
1614          * For radial gradients in canvas this is the value 'r1'.
1615          * Takes a value between 0 and 1.
1616          * @type Number
1617          * @name JXG.GeometryElement#gradientR
1618          * @see JXG.GeometryElement#gradient
1619          * @see JXG.GeometryElement#gradientCX
1620          * @see JXG.GeometryElement#gradientCY
1621          * @default 0.5
1622          */
1623         gradientR: 0.5,
1624 
1625         /**
1626          * ‘fx’ and ‘fy’ define the focal point for the radial gradient.
1627          * The gradient will be drawn such that the 0% gradient stop is mapped to (fx, fy).
1628          * For radial gradients in canvas this is the value 'x0'.
1629          * Takes a value between 0 and 1.
1630          * @type Number
1631          * @name JXG.GeometryElement#gradientFX
1632          * @see JXG.GeometryElement#gradient
1633          * @see JXG.GeometryElement#gradientFY
1634          * @see JXG.GeometryElement#gradientFR
1635          * @default 0.5
1636          */
1637         gradientFX: 0.5,
1638 
1639         /**
1640          * y-coordinate of the circle center for the second color in case of gradient 'radial'. (The attribute fy in SVG)
1641          * For radial gradients in canvas this is the value 'y0'.
1642          * Takes a value between 0 and 1.
1643          * @type Number
1644          * @name JXG.GeometryElement#gradientFY
1645          * @see JXG.GeometryElement#gradient
1646          * @see JXG.GeometryElement#gradientFX
1647          * @see JXG.GeometryElement#gradientFR
1648          * @default 0.5
1649          */
1650         gradientFY: 0.5,
1651 
1652         /**
1653          * This attribute defines the radius of the start circle of the radial gradient.
1654          * The gradient will be drawn such that the 0% <stop> is mapped to the perimeter of the start circle.
1655          * For radial gradients in canvas this is the value 'r0'.
1656          * Takes a value between 0 and 1.
1657          * @type Number
1658          * @name JXG.GeometryElement#gradientFR
1659          * @see JXG.GeometryElement#gradient
1660          * @see JXG.GeometryElement#gradientFX
1661          * @see JXG.GeometryElement#gradientFY
1662          * @default 0.0
1663          */
1664         gradientFR: 0.0,
1665 
1666         /**
1667          * Transition duration (in milliseconds) for certain cahnges of properties like color and opacity.
1668          * The properties can be set in the attribute transitionProperties
1669          * Works in SVG renderer, only.
1670          * @type Number
1671          * @name JXG.GeometryElement#transitionDuration
1672          * @see JXG.GeometryElement#transitionProperties
1673          * @see JXG.GeometryElement#strokeColor
1674          * @see JXG.GeometryElement#highlightStrokeColor
1675          * @see JXG.GeometryElement#strokeOpacity
1676          * @see JXG.GeometryElement#highlightStrokeOpacity
1677          * @see JXG.GeometryElement#fillColor
1678          * @see JXG.GeometryElement#highlightFillColor
1679          * @see JXG.GeometryElement#fillOpacity
1680          * @see JXG.GeometryElement#highlightFillOpacity
1681          * @default 100 {@link JXG.Options.elements#transitionDuration}
1682          */
1683         transitionDuration: 100,
1684 
1685         /**
1686          * Properties which change smoothly in the time set in transitionDuration.
1687          * Possible values are
1688          * ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry']
1689          * (and maybe more) for geometry elements and
1690          * ['color', 'opacity', 'all'] for HTML texts.
1691          *
1692          * @type Array
1693          * @name JXG.GeometryElement#transitionProperties
1694          * @see JXG.GeometryElement#transitionDuration
1695          *
1696          *
1697          * @example
1698          * var p1 = board.create("point", [0, 2], {
1699          *     name: "A",
1700          *     highlightStrokeWidth: 10,
1701          *     transitionDuration: 1000,
1702          *     transitionProperties: ['width', 'height', 'stroke-width',
1703          *         'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });
1704          *
1705          * </pre><div id="JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b" class="jxgbox" style="width: 300px; height: 300px;"></div>
1706          * <script type="text/javascript">
1707          *     (function() {
1708          *         var board = JXG.JSXGraph.initBoard('JXGdf5230a1-5870-43db-b6ff-4d5b2f5b786b',
1709          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
1710          *     var p1 = board.create("point", [0, 2], {
1711          *         name: "A",
1712          *         highlightStrokeWidth: 20,
1713          *         transitionDuration: 1000,
1714          *         transitionProperties: ['width', 'height', 'stroke-width',
1715          *             'fill', 'fill-opacity', 'rx', 'ry', 'stroke', 'stroke-opacity'] });
1716          *
1717          *     })();
1718          *
1719          * </script><pre>
1720          *
1721          */
1722         transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width'],
1723 
1724         /**
1725          * Width of the element's stroke.
1726          * @type Number
1727          * @name JXG.GeometryElement#strokeWidth
1728          * @see JXG.GeometryElement#strokeColor
1729          * @see JXG.GeometryElement#highlightStrokeColor
1730          * @see JXG.GeometryElement#strokeOpacity
1731          * @see JXG.GeometryElement#highlightStrokeOpacity
1732          * @default {@link JXG.Options.elements#strokeWidth}
1733          */
1734         strokeWidth: 2,
1735 
1736         /**
1737          * Width of the element's stroke when the mouse is pointed over it.
1738          * @type Number
1739          * @name JXG.GeometryElement#highlightStrokeWidth
1740          * @see JXG.GeometryElement#strokeColor
1741          * @see JXG.GeometryElement#highlightStrokeColor
1742          * @see JXG.GeometryElement#strokeOpacity
1743          * @see JXG.GeometryElement#highlightStrokeOpacity
1744          * @see JXG.GeometryElement#highlightFillColor
1745          * @default {@link JXG.Options.elements#strokeWidth}
1746          */
1747         highlightStrokeWidth: 2,
1748 
1749         /**
1750          * If true the element is fixed and can not be dragged around. The element
1751          * will be repositioned on zoom and moveOrigin events.
1752          * @type Boolean
1753          * @default false
1754          * @name JXG.GeometryElement#fixed
1755          */
1756         fixed: false,
1757 
1758         /**
1759          * If true the element is fixed and can not be dragged around. The element
1760          * will even stay at its position on zoom and moveOrigin events.
1761          * Only free elements like points, texts, curves can be frozen.
1762          * @type Boolean
1763          * @default false
1764          * @name JXG.GeometryElement#frozen
1765          */
1766         frozen: false,
1767 
1768         /**
1769          * If true a label will display the element's name.
1770          * @type Boolean
1771          * @default false
1772          * @name JXG.GeometryElement#withLabel
1773          */
1774         withLabel: false,
1775 
1776         /**
1777          * If false the element won't be visible on the board, otherwise it is shown.
1778          * @type Boolean
1779          * @name JXG.GeometryElement#visible
1780          * @see JXG.GeometryElement#hideElement
1781          * @see JXG.GeometryElement#showElement
1782          * @default true
1783          */
1784         visible: true,
1785 
1786         /**
1787          * A private element will be inaccessible in certain environments, e.g. a graphical user interface.
1788          *
1789          * @name JXG.GeometryElement#priv
1790          * @type Boolean
1791          * @default false
1792          */
1793         priv: false,
1794 
1795         /**
1796          * Display layer which will contain the element.
1797          * @name JXG.GeometryElement#layer
1798          * @see JXG.Options#layer
1799          * @default See {@link JXG.Options#layer}
1800          */
1801         layer: 0,
1802 
1803         /**
1804          * Line endings (linecap) of a stroke element, i.e. line, circle, curve.
1805          * Possible values are:
1806          * <ul>
1807          * <li> 'butt',
1808          * <li> 'round',
1809          * <li> 'square'.
1810          * </ul>
1811          * Not available for VML renderer.
1812          *
1813          * @name JXG.GeometryElement#lineCap
1814          * @type String
1815          * @default 'butt'
1816          */
1817         lineCap: 'butt',
1818 
1819         /**
1820          * Determines the elements border-style.
1821          * Possible values are:
1822          * <ul><li>0 for a solid line</li>
1823          * <li>1 for a dotted line</li>
1824          * <li>2 for a line with small dashes</li>
1825          * <li>3 for a line with medium dashes</li>
1826          * <li>4 for a line with big dashes</li>
1827          * <li>5 for a line with alternating medium and big dashes and large gaps</li>
1828          * <li>6 for a line with alternating medium and big dashes and small gaps</li>
1829          * <li>7 for a dotted line. Needs {@link JXG.GeometryElement#linecap} set to "round" for round dots.</li>
1830          * </ul>
1831          * The dash patterns are defined in {@link JXG.AbstractRenderer#dashArray}.
1832          *
1833          * @type Number
1834          * @name JXG.GeometryElement#dash
1835          * @default 0
1836          *
1837          * @see JXG.GeometryElement#lineCap
1838          * @see JXG.AbstractRenderer#dashArray
1839          */
1840         dash: 0,
1841 
1842         /**
1843          * If enabled:true the (stroke) element will get a customized shadow.
1844          * <p>
1845          * Customize <i>color</i> and <i>opacity</i>:
1846          * If the object's RGB stroke color is <tt>[r,g,b]</tt> and its opacity is <tt>op</i>, and
1847          * the shadow parameters <i>color</i> is given as <tt>[r', g', b']</tt> and <i>opacity</i> as <tt>op'</tt>
1848          * the shadow will receive the RGB color
1849          * <center>
1850          * <tt>[blend*r + r', blend*g + g', blend*b + b'] </tt>
1851          * </center>
1852          * and its opacity will be equal to <tt>op * op'</tt>.
1853          * Further, the parameters <i>blur</i> and <i>offset</i> can be adjusted.
1854          * <p>
1855          * This attribute is only available with SVG, not with canvas.
1856          *
1857          * @type Object
1858          * @name JXG.GeometryElement#shadow
1859          * @default shadow: {
1860          *   enabled: false,
1861          *   color: [0, 0, 0],
1862          *   opacity: 1,
1863          *   blur: 3,
1864          *   blend: 0.1,
1865          *   offset: [5, 5]
1866          * }
1867          *
1868          * @example
1869          * board.options.line.strokeWidth = 2
1870          * // No shadow
1871          * var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});
1872          *
1873          * // Default shadow
1874          * var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});
1875          *
1876          * // No shadow
1877          * var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});
1878          *
1879          * // Shadow uses same color as line
1880          * var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',
1881          *             shadow: {enabled: true, color: '#000000', blend: 1}
1882          *         });
1883          *
1884          * // Shadow color as a mixture between black and the line color, additionally set opacity
1885          * var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',
1886          *             shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}
1887          *         });
1888          *
1889          * // Use different value for blur and offset [dx, dy]
1890          * var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',
1891          *             shadow: {enabled: true, offset:[0, 25], blur: 6}
1892          *         });
1893          *
1894          * </pre><div id="JXG1185a9fa-0fa5-425f-8c15-55b56e1be958" class="jxgbox" style="width: 300px; height: 300px;"></div>
1895          * <script type="text/javascript">
1896          *     (function() {
1897          *         var board = JXG.JSXGraph.initBoard('JXG1185a9fa-0fa5-425f-8c15-55b56e1be958',
1898          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
1899          *     board.options.line.strokeWidth = 2
1900          *     // No shadow
1901          *     var li1 = board.create('line', [[-2, 5], [2, 6]], {strokeColor: 'red', shadow: false});
1902          *
1903          *     // Default shadow
1904          *     var li2 = board.create('line', [[-2, 3], [2, 4]], {strokeColor: 'red', shadow: true});
1905          *
1906          *     // No shadow
1907          *     var li3 = board.create('line', [[-2, 1], [2, 2]], {strokeColor: 'blue', shadow: {enabled: false}});
1908          *
1909          *     // Shadow uses same color as line
1910          *     var li4 = board.create('line', [[-2, -1], [2, 0]], {strokeColor: 'blue',
1911          *                 shadow: {enabled: true, color: '#000000', blend: 1}
1912          *             });
1913          *
1914          *     // Shadow color as a mixture between black and the line color, additionally set opacity
1915          *     var li5 = board.create('line', [[-2, -3], [2, -2]], {strokeColor: 'blue',
1916          *                 shadow: {enabled: true, color: '#000000', blend: 0.5, opacity: 0.5}
1917          *             });
1918          *
1919          *     // Use different value for blur and offset [dx, dy]
1920          *     var li6 = board.create('line', [[-2, -5], [2, -4]], {strokeColor: 'blue',
1921          *                 shadow: {enabled: true, offset:[0, 25], blur: 6}
1922          *             });
1923          *
1924          *     })();
1925          *
1926          * </script><pre>
1927          *
1928          */
1929         shadow: {
1930             enabled: false,
1931             color: [0, 0, 0],
1932             opacity: 1,
1933             blur: 3,
1934             blend: 0.1,
1935             offset: [5, 5]
1936         },
1937 
1938         /**
1939          * If true the element will be traced, i.e. on every movement the element will be copied
1940          * to the background. Use {@link JXG.GeometryElement#clearTrace} to delete the trace elements.
1941          *
1942          * The calling of element.setAttribute({trace:false}) additionally
1943          * deletes all traces of this element. By calling
1944          * element.setAttribute({trace:'pause'})
1945          * the removal of already existing traces can be prevented.
1946          *
1947          * The visual appearance of the trace can be influenced by {@link JXG.GeometryElement#traceAttributes}.
1948          *
1949          * @see JXG.GeometryElement#clearTrace
1950          * @see JXG.GeometryElement#traces
1951          * @see JXG.GeometryElement#numTraces
1952          * @see JXG.GeometryElement#traceAttributes
1953          * @type Boolean|String
1954          * @default false
1955          * @name JXG.GeometryElement#trace
1956          */
1957         trace: false,
1958 
1959         /**
1960          * Extra visual properties for traces of an element
1961          * @type Object
1962          * @see JXG.GeometryElement#trace
1963          * @name JXG.GeometryElement#traceAttributes
1964          * @default {}
1965          *
1966          * @example
1967          * JXG.Options.elements.traceAttributes = {
1968          *     size: 2
1969          * };
1970          *
1971          * const board = JXG.JSXGraph.initBoard(BOARDID, {
1972          *     boundingbox: [-4, 4, 4, -4],
1973          *     keepaspectratio: true
1974          * });
1975          *
1976          * var p = board.create('point', [0.0, 2.0], {
1977          *     trace: true,
1978          *     size: 10,
1979          *     traceAttributes: {
1980          *         color: 'black',
1981          *         face: 'x'
1982          *     }
1983          * });
1984          *
1985          * </pre><div id="JXG504889cb-bb6f-4b65-85db-3ad555c08bcf" class="jxgbox" style="width: 300px; height: 300px;"></div>
1986          * <script type="text/javascript">
1987          *     (function() {
1988          *     JXG.Options.elements.traceAttributes = {
1989          *         size: 2
1990          *     };
1991          *         var board = JXG.JSXGraph.initBoard('JXG504889cb-bb6f-4b65-85db-3ad555c08bcf',
1992          *             {boundingbox: [-4, 4, 4, -4], axis: true, showcopyright: false, shownavigation: true, showClearTraces: true});
1993          *
1994          *     var p = board.create('point', [0.0, 2.0], {
1995          *         trace: true,
1996          *         size: 10,
1997          *         traceAttributes: {
1998          *             color: 'black',
1999          *             face: 'x'
2000          *         }
2001          *     });
2002          *
2003          *     })();
2004          *
2005          * </script><pre>
2006          *
2007          */
2008         traceAttributes: {},
2009 
2010         /**
2011          *
2012          * @type Boolean
2013          * @default true
2014          * @name JXG.GeometryElement#highlight
2015          */
2016         highlight: true,
2017 
2018         /**
2019          * If this is set to true, the element is updated in every update
2020          * call of the board. If set to false, the element is updated only after
2021          * zoom events or more generally, when the bounding box has been changed.
2022          * Examples for the latter behavior should be axes.
2023          * @type Boolean
2024          * @default true
2025          * @see JXG.GeometryElement#needsRegularUpdate
2026          * @name JXG.GeometryElement#needsRegularUpdate
2027          */
2028         needsRegularUpdate: true,
2029 
2030         /**
2031          * Snaps the element or its parents to the grid. Currently only relevant for points, circles,
2032          * and lines. Points are snapped to grid directly, on circles and lines it's only the parent
2033          * points that are snapped
2034          * @type Boolean
2035          * @default false
2036          * @name JXG.GeometryElement#snapToGrid
2037          */
2038         snapToGrid: false,
2039 
2040         /**
2041          * Determines whether two-finger manipulation of this object may change its size.
2042          * If set to false, the object is only rotated and translated.
2043          * <p>
2044          * In case the element is a horizontal or vertical line having ticks, "scalable:true"
2045          * enables zooming of the board by dragging ticks lines. This feature is enabled,
2046          * for the ticks element of the line element the attribute "fixed" has to be false
2047          * and the line element's scalable attribute has to be true.
2048          * <p>
2049          * In case the element is a polygon or line and it has the attribute "scalable:false",
2050          * moving the element with two fingers results in a rotation or translation.
2051          * <p>
2052          * If an element is set to be neither scalable nor rotatable, it can only be translated.
2053          * <p>
2054          * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints
2055          * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have
2056          * snapToGrid disabled.
2057          *
2058          * @type Boolean
2059          * @default true
2060          * @name JXG.GeometryElement#scalable
2061          * @see JXG.Ticks#fixed
2062          * @see JXG.GeometryElement#rotatable
2063          */
2064         scalable: true,
2065 
2066         /**
2067          * Determines whether two-finger manipulation may rotate this object.
2068          * If set to false, the object can only be scaled and translated.
2069          * <p>
2070          * In case the element is a polygon or line and it has the attribute "rotatable:false",
2071          * moving the element with two fingers results in a rotation or translation.
2072          * <p>
2073          * If an element is set to be neither scalable nor rotatable, it can only be translated.
2074          * <p>
2075          * In case of a polygon, scaling is only possible if <i>no</i> vertex has snapToGrid or snapToPoints
2076          * enabled and no vertex is fixed by some other constraint. Also, the polygon itself has to have
2077          * snapToGrid disabled.
2078          *
2079          * @type Boolean
2080          * @default true
2081          * @name JXG.GeometryElement#rotatable
2082          * @see JXG.GeometryElement#scalable
2083          */
2084         rotatable: true,
2085 
2086         /**
2087          * If the element is dragged it will be moved on mousedown or touchstart to the
2088          * top of its layer. Works only for SVG renderer and for simple elements
2089          * consisting of one SVG node.
2090          * @example
2091          * var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});
2092          * var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});
2093          *
2094          * </pre><div id="JXG38449fee-1ab4-44de-b7d1-43caa1f50f86" class="jxgbox" style="width: 300px; height: 300px;"></div>
2095          * <script type="text/javascript">
2096          *     (function() {
2097          *         var board = JXG.JSXGraph.initBoard('JXG38449fee-1ab4-44de-b7d1-43caa1f50f86',
2098          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2099          *     var li1 = board.create('line', [1, 1, 1], {strokeWidth: 20, dragToTopOfLayer: true});
2100          *     var li2 = board.create('line', [1, -1, 1], {strokeWidth: 20, strokeColor: 'red'});
2101          *
2102          *     })();
2103          *
2104          * </script><pre>
2105          *
2106          * @type Boolean
2107          * @default false
2108          * @name JXG.GeometryElement#dragToTopOfLayer
2109          */
2110         dragToTopOfLayer: false,
2111 
2112         /**
2113          * Precision options for JSXGraph elements.
2114          * This attributes takes either the value 'inherit' or an object of the form:
2115          * <pre>
2116          * precision: {
2117          *      touch: 30,
2118          *      mouse: 4,
2119          *      pen: 4
2120          * }
2121          * </pre>
2122          *
2123          * In the first case, the global, JSXGraph-wide values of JXGraph.Options.precision
2124          * are taken.
2125          *
2126          * @type {String|Object}
2127          * @name JXG.GeometryElement#precision
2128          * @see JXG.Options#precision
2129          * @default 'inherit'
2130          */
2131         precision: 'inherit',
2132 
2133         /**
2134          * If draft.draft: true the element will be drawn in grey scale colors (as default)
2135          * to visualize that it's only a draft.
2136          *
2137          * @name JXG.GeometryElement#draft
2138          * @type Object
2139          * @default {@link JXG.Options.elements.draft#draft}
2140          */
2141         draft: {
2142             draft: false,
2143             strokeColor: '#565656',
2144             fillColor: '#565656',
2145             strokeOpacity: 0.8,
2146             fillOpacity: 0.8,
2147             strokeWidth: 1
2148         },
2149 
2150         /**
2151          * @name JXG.GeometryElement#isLabel
2152          * @default false
2153          * @private
2154          * By default, an element is not a label. Do not change this.
2155          */
2156         isLabel: false,
2157 
2158         /**
2159          * Controls if an element can get the focus with the tab key.
2160          * tabindex corresponds to the HTML attribute of the same name.
2161          * See <a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex">descriptiona at MDN</a>.
2162          * The additional value "null" completely disables focus of an element.
2163          * The value will be ignored if keyboard control of the board is not enabled or
2164          * the element is fixed or not visible.
2165          *
2166          * @name JXG.GeometryElement#tabindex
2167          * @type Number
2168          * @default 0
2169          * @see JXG.Board#keyboard
2170          * @see JXG.GeometryElement#fixed
2171          * @see JXG.GeometryElement#visible
2172          */
2173         tabindex: 0,
2174 
2175         /**
2176          * If true, the dash pattern is multiplied by strokeWidth / 2.
2177          * @name JXG.GeometryElement#dashScale
2178          * @type Boolean
2179          * @default false
2180          *
2181          * @see JXG.GeometryElement#dash
2182          * @see JXG.AbstractRenderer#dashArray
2183          */
2184         dashScale: false
2185 
2186         // close the meta tag
2187         /**#@-*/
2188     },
2189 
2190     /*
2191      *  Generic options used by {@link JXG.Ticks}
2192      */
2193     ticks: {
2194         /**#@+
2195          * @visprop
2196          */
2197 
2198         /**
2199          * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
2200          * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
2201          * The third parameter is a null, number or a string. In the latter two cases, this value is taken.
2202          * Returns a string.
2203          *
2204          * @type function
2205          * @name Ticks#generateLabelText
2206          *
2207          * @example
2208          * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,
2209          *     defaultAxes: {
2210          *         x: {
2211          *                 margin: -4,
2212          *                 ticks: {
2213          *                     minTicksDistance: 0,
2214          *                     minorTicks:4,
2215          *                     ticksDistance: 3,
2216          *                     scale: Math.PI,
2217          *                     scaleSymbol: 'π',
2218          *                     insertTicks: true
2219          *                 }
2220          *              },
2221          *         y: {}
2222          *     }
2223          * });
2224          *
2225          * // Generate a logarithmic labelling of the vertical axis.
2226          * board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {
2227          *     var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2])),
2228          *         distance, labelText;
2229          *     return this.formatLabelText(value);
2230          * };
2231          *
2232          * </pre><div id="JXG3d2203ee-a797-416a-a33c-409581fafdd7" class="jxgbox" style="width: 300px; height: 300px;"></div>
2233          * <script type="text/javascript">
2234          *     (function() {
2235          *         var board = JXG.JSXGraph.initBoard('JXG3d2203ee-a797-416a-a33c-409581fafdd7',
2236          *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,
2237          *         defaultAxes: {
2238          *             x: {
2239          *                     margin: -4,
2240          *                     ticks: {
2241          *                         minTicksDistance: 0,
2242          *                         minorTicks:4,
2243          *                         ticksDistance: 3,
2244          *                         scale: Math.PI,
2245          *                         scaleSymbol: 'π',
2246          *                         insertTicks: true
2247          *                     }
2248          *                  },
2249          *             y: {}
2250          *         }
2251          *     });
2252          *
2253          *     // Generate a logarithmic labelling of the vertical axis.
2254          *     board.defaultAxes.y.ticks[0].generateLabelText = function (tick, zero) {
2255          *         var value = Math.pow(10, Math.round(tick.usrCoords[2] - zero.usrCoords[2])),
2256          *             distance, labelText;
2257          *         return this.formatLabelText(value);
2258          *     };
2259          *
2260          *     })();
2261          *
2262          * </script><pre>
2263          *
2264          */
2265         generateLabelText: null,
2266 
2267         /**
2268          * A function that expects two {@link JXG.Coords}, the first one representing the coordinates of the
2269          * tick that is to be labeled, the second one the coordinates of the center (the tick with position 0).
2270          *
2271          * @deprecated Use {@link JGX.Options@generateLabelText}
2272          * @type function
2273          * @name Ticks#generateLabelValue
2274          */
2275         generateLabelValue: null,
2276 
2277         /**
2278          * Draw labels yes/no
2279          *
2280          * @type Boolean
2281          * @name Ticks#drawLabels
2282          * @default false
2283          */
2284         drawLabels: false,
2285 
2286         /**
2287          * Attributes for the ticks labels
2288          *
2289          * @name Ticks#label
2290          * @type Object
2291          * @default {}
2292          *
2293          */
2294         label: {
2295         },
2296 
2297         /**
2298         * Format tick labels that were going to have scientific notation
2299         * like 5.00e+6 to look like 5•10⁶.
2300         *
2301         * @example
2302         * var board = JXG.JSXGraph.initBoard("jxgbox", {
2303         *     boundingbox: [-500000, 500000, 500000, -500000],
2304         *     axis: true,
2305         *     defaultAxes: {
2306         *         x: {
2307         *             scalable: true,
2308         *             ticks: {
2309         *                 beautifulScientificTickLabels: true
2310         *           },
2311         *         },
2312         *         y: {
2313         *             scalable: true,
2314         *             ticks: {
2315         *                 beautifulScientificTickLabels: true
2316         *           },
2317         *         }
2318         *     },
2319         * });
2320         *
2321         * </pre><div id="JXGc1e46cd1-e025-4002-80aa-b450869fdaa2" class="jxgbox" style="width: 300px; height: 300px;"></div>
2322         * <script type="text/javascript">
2323         *     (function() {
2324         *     var board = JXG.JSXGraph.initBoard('JXGc1e46cd1-e025-4002-80aa-b450869fdaa2', {
2325         *         boundingbox: [-500000, 500000, 500000, -500000],
2326         *         showcopyright: false, shownavigation: false,
2327         *         axis: true,
2328         *         defaultAxes: {
2329         *             x: {
2330         *                 scalable: true,
2331         *                 ticks: {
2332         *                     beautifulScientificTickLabels: true
2333         *               },
2334         *             },
2335         *             y: {
2336         *                 scalable: true,
2337         *                 ticks: {
2338         *                     beautifulScientificTickLabels: true
2339         *               },
2340         *             }
2341         *         },
2342         *     });
2343         *
2344         *     })();
2345         *
2346         * </script><pre>
2347         *
2348         * @name Ticks#beautifulScientificTickLabels
2349         * @type Boolean
2350         * @default false
2351         */
2352         beautifulScientificTickLabels: false,
2353 
2354         /**
2355          * Use the unicode character 0x2212, i.e. the HTML entity &minus; as minus sign.
2356          * That is −1 instead of -1.
2357          *
2358          * @type Boolean
2359          * @name Ticks#useUnicodeMinus
2360          * @default true
2361          */
2362         useUnicodeMinus: true,
2363 
2364         /**
2365          * Determine the position of the tick with value 0. 'left' means point1 of the line, 'right' means point2,
2366          * and 'middle' is equivalent to the midpoint of the defining points. This attribute is ignored if the parent
2367          * line is of type axis.
2368          *
2369          * @type String
2370          * @name Ticks#anchor
2371          * @default 'left'
2372          *
2373          * @example
2374          * var li = board.create('segment', [[-4, -3], [4, 2]]);
2375          * var t = board.create('ticks', [li], {
2376          *     // drawZero: true,
2377          *     anchor: 'left',
2378          *     drawLabels: true,
2379          *     minorTicks: 0,
2380          *     label: {
2381          *         anchorX: 'middle',
2382          *         anchorY: 'top',
2383          *         offset: [0, -5]
2384          *     }
2385          * });
2386          *
2387          *
2388          * </pre><div id="JXG3dd23f77-a31d-4649-b0f0-7472722158d8" class="jxgbox" style="width: 300px; height: 300px;"></div>
2389          * <script type="text/javascript">
2390          *     (function() {
2391          *         var board = JXG.JSXGraph.initBoard('JXG3dd23f77-a31d-4649-b0f0-7472722158d8',
2392          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2393          *     var li = board.create('segment', [[-4, -3], [4, 2]]);
2394          *     var t = board.create('ticks', [li], {
2395          *         // drawZero: true,
2396          *         anchor: 'left',
2397          *         drawLabels: true,
2398          *         minorTicks: 0,
2399          *         label: {
2400          *             anchorX: 'middle',
2401          *             anchorY: 'top',
2402          *             offset: [0, -5]
2403          *         }
2404          *     });
2405          *
2406          *
2407          *     })();
2408          *
2409          * </script><pre>
2410          *
2411          * @example
2412          * var li = board.create('segment', [[-4, -3], [4, 2]]);
2413          * var t = board.create('ticks', [li], {
2414          *     drawZero: true,
2415          *     anchor: 'middle',
2416          *     drawLabels: true,
2417          *     minorTicks: 0,
2418          *     label: {
2419          *         anchorX: 'middle',
2420          *         anchorY: 'top',
2421          *         offset: [0, -5]
2422          *     }
2423          * });
2424          *
2425          * </pre><div id="JXG430914fd-4e12-44de-b510-e3cc2fd473e0" class="jxgbox" style="width: 300px; height: 300px;"></div>
2426          * <script type="text/javascript">
2427          *     (function() {
2428          *         var board = JXG.JSXGraph.initBoard('JXG430914fd-4e12-44de-b510-e3cc2fd473e0',
2429          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2430          *     var li = board.create('segment', [[-4, -3], [4, 2]]);
2431          *     var t = board.create('ticks', [li], {
2432          *         drawZero: true,
2433          *         anchor: 'middle',
2434          *         drawLabels: true,
2435          *         minorTicks: 0,
2436          *         label: {
2437          *             anchorX: 'middle',
2438          *             anchorY: 'top',
2439          *             offset: [0, -5]
2440          *         }
2441          *     });
2442          *
2443          *     })();
2444          *
2445          * </script><pre>
2446          *
2447          */
2448         anchor: 'left',
2449 
2450         /**
2451          * Draw the zero tick, that lies at line.point1?
2452          *
2453          * @type Boolean
2454          * @name Ticks#drawZero
2455          * @default false
2456          *
2457          * @example
2458          * var li = board.create('segment', [[-4, 2], [4, 2]]);
2459          * var t = board.create('ticks', [li], {
2460          *     drawZero: false,
2461          *     anchor: 'middle',
2462          *     drawLabels: true,
2463          *     minorTicks: 0,
2464          *     label: {
2465          *         anchorX: 'middle',
2466          *         anchorY: 'top',
2467          *         offset: [0, -5]
2468          *     }
2469          * });
2470          *
2471          * var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2472          * var t2 = board.create('ticks', [li2], {
2473          *     drawZero: true,
2474          *     anchor: 'middle',
2475          *     drawLabels: true,
2476          *     minorTicks: 0,
2477          *     label: {
2478          *         anchorX: 'middle',
2479          *         anchorY: 'top',
2480          *         offset: [0, -5]
2481          *     }
2482          * });
2483          *
2484          * </pre><div id="JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1" class="jxgbox" style="width: 300px; height: 300px;"></div>
2485          * <script type="text/javascript">
2486          *     (function() {
2487          *         var board = JXG.JSXGraph.initBoard('JXG91584dc4-0ca8-4b3e-841c-c877f2ccdcf1',
2488          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
2489          *     var li = board.create('segment', [[-4, 2], [4, 2]]);
2490          *     var t = board.create('ticks', [li], {
2491          *         drawZero: false,
2492          *         anchor: 'middle',
2493          *         drawLabels: true,
2494          *         minorTicks: 0,
2495          *         label: {
2496          *             anchorX: 'middle',
2497          *             anchorY: 'top',
2498          *             offset: [0, -5]
2499          *         }
2500          *     });
2501          *
2502          *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2503          *     var t2 = board.create('ticks', [li2], {
2504          *         drawZero: true,
2505          *         anchor: 'middle',
2506          *         drawLabels: true,
2507          *         minorTicks: 0,
2508          *         label: {
2509          *             anchorX: 'middle',
2510          *             anchorY: 'top',
2511          *             offset: [0, -5]
2512          *         }
2513          *     });
2514          *
2515          *     })();
2516          *
2517          * </script><pre>
2518          *
2519          */
2520            drawZero: false,
2521 
2522         /**
2523          * Let JSXGraph determine the distance between ticks automatically.
2524          * If <tt>true</tt>, the attribute <tt>ticksDistance</tt> is ignored.
2525          * The distance between ticks is affected by the size of the board and
2526          * the attribute <tt>minTicksDistance</tt> (in pixel).
2527          *
2528          * @type Boolean
2529          * @name Ticks#insertTicks
2530          * @see Ticks#ticksDistance
2531          * @see Ticks#minTicksDistance
2532          * @default false
2533          * @example
2534          * // Create an axis providing two coord pairs.
2535          *   var p1 = board.create('point', [0, 0]);
2536          *   var p2 = board.create('point', [50, 25]);
2537          *   var l1 = board.create('line', [p1, p2]);
2538          *   var t = board.create('ticks', [l1], {
2539          *      insertTicks: true,
2540          *      majorHeight: -1,
2541          *      label: {
2542          *          offset: [4, -9]
2543          *      },
2544          *      drawLabels: true
2545          *  });
2546          * </pre><div class="jxgbox" id="JXG2f6fb842-40bd-4223-aa28-3e9369d2097f" style="width: 300px; height: 300px;"></div>
2547          * <script type="text/javascript">
2548          * (function () {
2549          *   var board = JXG.JSXGraph.initBoard('JXG2f6fb842-40bd-4223-aa28-3e9369d2097f', {
2550          *     boundingbox: [-100, 70, 70, -100], axis: true, showcopyright: false, shownavigation: true});
2551          *   var p1 = board.create('point', [0, 0]);
2552          *   var p2 = board.create('point', [50, 25]);
2553          *   var l1 = board.create('line', [p1, p2]);
2554          *   var t = board.create('ticks', [l1], {insertTicks: true, majorHeight: -1, label: {offset: [4, -9]}, drawLabels: true});
2555          * })();
2556          * </script><pre>
2557          */
2558         insertTicks: false,
2559 
2560         /**
2561          * Minimum distance in pixel of equidistant ticks in case insertTicks==true.
2562          * @name Ticks#minTicksDistance
2563          * @type Number
2564          * @default 10
2565          * @see Ticks#insertTicks
2566          */
2567         minTicksDistance: 10,
2568 
2569         /**
2570          * Total height of a minor tick. If negative the full height of the board is taken.
2571          *
2572          * @type Number
2573          * @name Ticks#minorHeight
2574          * @default 4
2575          */
2576         minorHeight: 4,
2577 
2578         /**
2579          * Total height of a major tick. If negative the full height of the board is taken.
2580          *
2581          * @type Number
2582          * @name Ticks#majorHeight
2583          * @default 10
2584          */
2585         majorHeight: 10,
2586 
2587         /**
2588          * Decides in which direction minor ticks are visible. Possible values are either the constants
2589          * 0=false or 1=true or a function returning 0 or 1.
2590          *
2591          * In case of [0,1] the tick is only visible to the right of the line. In case of
2592          * [1,0] the tick is only visible to the left of the line.
2593          *
2594          * @type Array
2595          * @name Ticks#tickEndings
2596          * @see Ticks#majorTickEndings
2597          * @default [1, 1]
2598          */
2599         tickEndings: [1, 1],
2600 
2601         /**
2602          * Decides in which direction major ticks are visible. Possible values are either the constants
2603          * 0=false or 1=true or a function returning 0 or 1.
2604          *
2605          * In case of [0,1] the tick is only visible to the right of the line. In case of
2606          * [1,0] the tick is only visible to the left of the line.
2607          *
2608         * @example
2609         *         var board = JXG.JSXGraph.initBoard("jxgbox", {
2610         *             boundingbox: [-5, 5, 5, -5],
2611         *             axis: true,
2612         *             defaultAxes: {
2613         *                 x: {
2614         *                     ticks: {
2615         *                         majorTickEndings: [1, 0],
2616         *                         ignoreInfiniteTickEndings: false
2617         *                     }
2618         *                 },
2619         *                 y: {
2620         *                     ticks: {
2621         *                         majorTickEndings: [0, 1],
2622         *                         ignoreInfiniteTickEndings: false
2623         *                     }
2624         *                 }
2625         *             }
2626         *         });
2627         *
2628         *         var p = board.create('point', [1, 1]);
2629         *         var l = board.create('line', [1, -1, 1]);
2630         *
2631         * </pre><div id="JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1" class="jxgbox" style="width: 300px; height: 300px;"></div>
2632         * <script type="text/javascript">
2633         *     (function() {
2634         *         var board = JXG.JSXGraph.initBoard('JXGf9ccb731-7a73-44d1-852e-f9c9c405a9d1',
2635         *             {   showcopyright: false, shownavigation: false,
2636         *                 boundingbox: [-5, 5, 5, -5],
2637         *                 axis: true,
2638         *                 defaultAxes: {
2639         *                     x: {
2640         *                         ticks: {
2641         *                             majorTickEndings: [1, 0],
2642         *                             ignoreInfiniteTickEndings: false
2643         *                         }
2644         *                     },
2645         *                     y: {
2646         *                         ticks: {
2647         *                             majorTickEndings: [0, 1],
2648         *                             ignoreInfiniteTickEndings: false
2649         *                         }
2650         *                     }
2651         *                 }
2652         *             });
2653         *
2654         *             var p = board.create('point', [1, 1]);
2655         *             var l = board.create('line', [1, -1, 1]);
2656         *
2657         *     })();
2658         *
2659         * </script><pre>
2660         *
2661         * @type Array
2662          * @name Ticks#majorTickEndings
2663          * @see Ticks#tickEndings
2664          * @see Ticks#ignoreInfiniteTickEndings
2665          * @default [1, 1]
2666          */
2667         majorTickEndings: [1, 1],
2668 
2669         /**
2670          * If true, ignore the tick endings attribute for infinite (full height) ticks.
2671          * This affects major and minor ticks.
2672          *
2673          * @type Boolean
2674          * @name Ticks#ignoreInfiniteTickEndings
2675          * @see Ticks#tickEndings
2676          * @see Ticks#majorTickEndings
2677          * @default true
2678          */
2679         ignoreInfiniteTickEndings: true,
2680 
2681         /**
2682          * The number of minor ticks between two major ticks.
2683          * @type Number
2684          * @name Ticks#minorTicks
2685          * @default 4
2686          */
2687         minorTicks: 4,
2688 
2689         /**
2690          * By default, i.e. if ticksPerLabel==false, labels are generated for major ticks, only.
2691          * If ticksPerLabel is set to a(n integer) number, this denotes the number of minor ticks
2692          * between two labels.
2693          *
2694          * @type {Number|Boolean}
2695          * @name Ticks#ticksPerLabel
2696          * @default false
2697          *
2698          * @example
2699          * const board = JXG.JSXGraph.initBoard('jxgbox', {
2700          *     boundingbox: [-4, 4, 4, -4],
2701          *     axis: true,
2702          *     defaultAxes: {
2703          *         x: {
2704          *             ticks: {
2705          *                 minorTicks: 7,
2706          *                 ticksPerLabel: 4,
2707          *                 minorHeight: 20,
2708          *             }
2709          *         },
2710          *         y: {
2711          *             ticks: {
2712          *                 minorTicks: 3,
2713          *                 ticksPerLabel: 2,
2714          *                 minorHeight: 20
2715          *             }
2716          *         }
2717          *     }
2718          * });
2719          *
2720          * </pre><div id="JXGbc45a421-c867-4b0a-9b8d-2b2576020690" class="jxgbox" style="width: 300px; height: 300px;"></div>
2721          * <script type="text/javascript">
2722          *     (function() {
2723          *         var board = JXG.JSXGraph.initBoard('JXGbc45a421-c867-4b0a-9b8d-2b2576020690',
2724          *             {showcopyright: false, shownavigation: false,
2725          *              boundingbox: [-4, 4, 4, -4],
2726          *         axis: true,
2727          *         defaultAxes: {
2728          *             x: {
2729          *                 ticks: {
2730          *                     minorTicks: 7,
2731          *                     ticksPerLabel: 4,
2732          *                     minorHeight: 20,
2733          *                 }
2734          *             },
2735          *             y: {
2736          *                 ticks: {
2737          *                     minorTicks: 3,
2738          *                     ticksPerLabel: 2,
2739          *                     minorHeight: 20
2740          *                 }
2741          *             }
2742          *         }
2743          *     });
2744          *     })();
2745          *
2746          * </script><pre>
2747          */
2748         ticksPerLabel: false,
2749 
2750         /**
2751          * Scale the ticks but not the tick labels.
2752          * @type Number
2753          * @default 1
2754          * @name Ticks#scale
2755          * @see Ticks#scaleSymbol
2756          *
2757          * @example
2758          * const board = JXG.JSXGraph.initBoard('jxgbox', { boundingBox: [-10, 10, 10, -10], axis: true,
2759          *     defaultAxes: {
2760          *         x : {
2761          *                 margin: -4,
2762          *                 ticks: {
2763          *                     minTicksDistance: 0,
2764          *                     minorTicks:4,
2765          *                     ticksDistance: 3,
2766          *                     scale: Math.PI,
2767          *                     scaleSymbol: 'π',
2768          *                     insertTicks: true
2769          *                 }
2770          *              },
2771          *         y : {}
2772          *     }
2773          * });
2774          *
2775          * </pre><div id="JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a" class="jxgbox" style="width: 300px; height: 300px;"></div>
2776          * <script type="text/javascript">
2777          *     (function() {
2778          *         var board = JXG.JSXGraph.initBoard('JXG23bfda5d-4a85-4469-a552-aa9b4cf62b4a',
2779          *             {boundingbox: [-10, 10, 10, -10], axis: true, showcopyright: false, shownavigation: false,
2780          *         defaultAxes: {
2781          *             x : {
2782          *                     margin: -4,
2783          *                     ticks: {
2784          *                         minTicksDistance: 0,
2785          *                         minorTicks:4,
2786          *                         ticksDistance: 3,
2787          *                         scale: Math.PI,
2788          *                         scaleSymbol: 'π',
2789          *                         insertTicks: true
2790          *                     }
2791          *                  },
2792          *             y : {
2793          *                  }
2794          *         }
2795          *     });
2796          *
2797          *     })();
2798          *
2799          * </script><pre>
2800          */
2801         scale: 1,
2802 
2803         /**
2804          * A string that is appended to every tick, used to represent the scale
2805          * factor given in {@link Ticks#scale}.
2806          *
2807          * @type String
2808          * @default ''
2809          * @name Ticks#scaleSymbol
2810          * @see Ticks#scale
2811          */
2812         scaleSymbol: '',
2813 
2814         /**
2815          * User defined labels for special ticks. Instead of the i-th tick's position, the i-th string stored in this array
2816          * is shown. If the number of strings in this array is less than the number of special ticks, the tick's position is
2817          * shown as a fallback.
2818          *
2819          * @type Array
2820          * @name Ticks#labels
2821          * @default []
2822          */
2823         labels: [],
2824 
2825         /**
2826          * The maximum number of characters a tick label can use.
2827          *
2828          * @type Number
2829          * @name Ticks#maxLabelLength
2830          * @see Ticks#digits
2831          * @default 5
2832          */
2833         maxLabelLength: 5,
2834 
2835         /**
2836          * If a label exceeds {@link Ticks#maxLabelLength} this determines the precision used to shorten the tick label.
2837          * Deprecated! Replaced by the attribute <tt>digits</tt>.
2838          *
2839          * @type Number
2840          * @name Ticks#precision
2841          * @see Ticks#maxLabelLength
2842          * @see Ticks#digits
2843          * @deprecated
2844          * @default 3
2845          */
2846         precision: 3,
2847 
2848         /**
2849          * If a label exceeds {@link Ticks#maxLabelLength} this determines the number of digits used to shorten the tick label.
2850          *
2851          * @type Number
2852          * @name Ticks#digits
2853          * @see Ticks#maxLabelLength
2854          * @deprecated
2855          * @default 3
2856          */
2857         digits: 3,
2858 
2859         /**
2860          * The default distance (in user coordinates, not  pixels) between two ticks. Please be aware that this value does not have
2861          * to be used if {@link Ticks#insertTicks} is set to true.
2862          *
2863          * @type Number
2864          * @name Ticks#ticksDistance
2865          * @see Ticks#insertTicks
2866          * @default 1
2867          */
2868         ticksDistance: 1,
2869 
2870         /**
2871          * Tick face for major ticks of finite length.  By default (face: '|') this is a straight line.
2872          * Possible other values are '<' and '>'. These faces are used in
2873          * {@link JXG.Hatch} for hatch marking parallel lines.
2874          * @type String
2875          * @name Ticks#face
2876          * @see hatch
2877          * @default '|'
2878          * @example
2879          *   var p1 = board.create('point', [0, 3]);
2880          *   var p2 = board.create('point', [1, 3]);
2881          *   var l1 = board.create('line', [p1, p2]);
2882          *   var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});
2883          *
2884          * </pre><div id="JXG950a568a-1264-4e3a-b61d-b6881feecf4b" class="jxgbox" style="width: 300px; height: 300px;"></div>
2885          * <script type="text/javascript">
2886          *     (function() {
2887          *         var board = JXG.JSXGraph.initBoard('JXG950a568a-1264-4e3a-b61d-b6881feecf4b',
2888          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
2889          *       var p1 = board.create('point', [0, 3]);
2890          *       var p2 = board.create('point', [1, 3]);
2891          *       var l1 = board.create('line', [p1, p2]);
2892          *       var t = board.create('ticks', [l1], {ticksDistance: 2, face: '>', minorTicks: 0});
2893          *
2894          *     })();
2895          *
2896          * </script><pre>
2897          *
2898          */
2899         face: '|',
2900 
2901         strokeOpacity: 1,
2902         strokeWidth: 1,
2903         strokeColor: '#000000',
2904         highlightStrokeColor: '#888888',
2905         fillColor: 'none',
2906         highlightFillColor: 'none',
2907         visible: 'inherit',
2908 
2909         /**
2910          * Whether line boundaries should be included or not in the lower and upper bounds when
2911          * creating ticks. In mathematical terms: if a segment considered as interval is open (includeBoundaries:false)
2912          * or closed (includeBoundaries:true). In case of open interval, the interval is shortened by a small
2913          * ε.
2914          *
2915          * @type Boolean
2916          * @name Ticks#includeBoundaries
2917          * @default false
2918          *
2919          * @example
2920          * var li = board.create('segment', [[-4, 2], [4, 2]]);
2921          * var t = board.create('ticks', [li], {
2922          *     includeBoundaries: true,
2923          *     drawZero: true,
2924          *     anchor: 'middle',
2925          *     drawLabels: true,
2926          *     minorTicks: 0,
2927          *     label: {
2928          *         anchorX: 'middle',
2929          *         anchorY: 'top',
2930          *         offset: [0, -5]
2931          *     }
2932          * });
2933          *
2934          * var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2935          * var t2 = board.create('ticks', [li2], {
2936          *     includeBoundaries: false,
2937          *     drawZero: true,
2938          *     anchor: 'middle',
2939          *     drawLabels: true,
2940          *     minorTicks: 0,
2941          *     label: {
2942          *         anchorX: 'middle',
2943          *         anchorY: 'top',
2944          *         offset: [0, -5]
2945          *     }
2946          * });
2947          *
2948          * </pre><div id="JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96" class="jxgbox" style="width: 300px; height: 300px;"></div>
2949          * <script type="text/javascript">
2950          *     (function() {
2951          *         var board = JXG.JSXGraph.initBoard('JXG08e79180-7c9a-4638-bb72-8aa7fd8a8b96',
2952          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
2953          *     var li = board.create('segment', [[-4, 2], [4, 2]]);
2954          *     var t = board.create('ticks', [li], {
2955          *         includeBoundaries: true,
2956          *         drawZero: true,
2957          *         anchor: 'middle',
2958          *         drawLabels: true,
2959          *         minorTicks: 0,
2960          *         label: {
2961          *             anchorX: 'middle',
2962          *             anchorY: 'top',
2963          *             offset: [0, -5]
2964          *         }
2965          *     });
2966          *
2967          *     var li2 = board.create('segment', [[-4, -2], [4, -2]]);
2968          *     var t2 = board.create('ticks', [li2], {
2969          *         includeBoundaries: false,
2970          *         drawZero: true,
2971          *         anchor: 'middle',
2972          *         drawLabels: true,
2973          *         minorTicks: 0,
2974          *         label: {
2975          *             anchorX: 'middle',
2976          *             anchorY: 'top',
2977          *             offset: [0, -5]
2978          *         }
2979          *     });
2980          *
2981          *     })();
2982          *
2983          * </script><pre>
2984          *
2985          */
2986         includeBoundaries: false,
2987 
2988         /**
2989          * Set the ticks type.
2990          * Possible values are 'linear' or 'polar'.
2991          *
2992          * @type String
2993          * @name Ticks#type
2994          * @default 'linear'
2995          *
2996          * @example
2997          * var ax = board.create('axis', [[0,0], [1,0]], {
2998          *              needsRegularUpdate: false,
2999          *              ticks: {
3000          *                      type: 'linear',
3001          *                      majorHeight: 0
3002          *                  }
3003          *              });
3004          * var ay = board.create('axis', [[0,0], [0,1]], {
3005          *              ticks: {
3006          *                      type: 'polar'
3007          *                  }
3008          *              });
3009          *
3010          * var p = board.create('point', [3, 2]);
3011          *
3012          * </pre><div id="JXG9ab0b50c-b486-4f95-9698-c0dd276155ff" class="jxgbox" style="width: 300px; height: 300px;"></div>
3013          * <script type="text/javascript">
3014          *     (function() {
3015          *         var board = JXG.JSXGraph.initBoard('JXG9ab0b50c-b486-4f95-9698-c0dd276155ff',
3016          *             {boundingbox: [-8, 8, 8,-8], axis: false, showcopyright: false, shownavigation: false});
3017          *     var ax = board.create('axis', [[0,0], [1,0]], { needsRegularUpdate: false, ticks: { type: 'linear', majorHeight: 0}});
3018          *     var ay = board.create('axis', [[0,0], [0,1]], { ticks: { type: 'polar'}});
3019          *
3020          *     var p = board.create('point', [3, 2]);
3021          *
3022          *     })();
3023          *
3024          * </script><pre>
3025          *
3026          */
3027         type: 'linear',
3028 
3029         /**
3030          * Internationalization support for ticks labels.
3031          * @name intl
3032          * @memberOf Ticks.prototype
3033          * @default {
3034          *    enabled: 'inherit',
3035          *    options: {}
3036          * }
3037          * @see JXG.Board#intl
3038          * @see Text#intl
3039          *
3040                   * @example
3041          * // Here, locale is disabled in general, but enabled for the horizontal
3042          * // axis and the infobox.
3043          * const board = JXG.JSXGraph.initBoard(BOARDID, {
3044          *     boundingbox: [-0.5, 0.5, 0.5, -0.5],
3045          *     intl: {
3046          *         enabled: false,
3047          *         locale: 'de-DE'
3048          *     },
3049          *     keepaspectratio: true,
3050          *     axis: true,
3051          *     defaultAxes: {
3052          *         x: {
3053          *             ticks: {
3054          *                 intl: {
3055          *                         enabled: true,
3056          *                         options: {
3057          *                             style: 'unit',
3058          *                             unit: 'kilometer-per-hour',
3059          *                             unitDisplay: 'narrow'
3060          *                         }
3061          *                 }
3062          *             }
3063          *         },
3064          *         y: {
3065          *             ticks: {
3066          *             }
3067          *         }
3068          *     },
3069          *     infobox: {
3070          *         fontSize: 12,
3071          *         intl: {
3072          *             enabled: true,
3073          *             options: {
3074          *                 minimumFractionDigits: 4,
3075          *                 maximumFractionDigits: 5
3076          *             }
3077          *         }
3078          *     }
3079          * });
3080          *
3081          * var p = board.create('point', [0.1, 0.1], {});
3082          *
3083          * </pre><div id="JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe" class="jxgbox" style="width: 600px; height: 300px;"></div>
3084          * <script type="text/javascript">
3085          *     (function() {
3086          *     var board = JXG.JSXGraph.initBoard('JXG820b60ff-b453-4be9-a9d5-06c0342a9dbe', {
3087          *         boundingbox: [-0.5, 0.5, 0.5, -0.5], showcopyright: false, shownavigation: false,
3088          *         intl: {
3089          *             enabled: false,
3090          *             locale: 'de-DE'
3091          *         },
3092          *         keepaspectratio: true,
3093          *         axis: true,
3094          *         defaultAxes: {
3095          *             x: {
3096          *                 ticks: {
3097          *                     intl: {
3098          *                             enabled: true,
3099          *                             options: {
3100          *                                 style: 'unit',
3101          *                                 unit: 'kilometer-per-hour',
3102          *                                 unitDisplay: 'narrow'
3103          *                             }
3104          *                     }
3105          *                 }
3106          *             },
3107          *             y: {
3108          *                 ticks: {
3109          *                 }
3110          *             }
3111          *         },
3112          *         infobox: {
3113          *             fontSize: 12,
3114          *             intl: {
3115          *                 enabled: true,
3116          *                 options: {
3117          *                     minimumFractionDigits: 4,
3118          *                     maximumFractionDigits: 5
3119          *                 }
3120          *             }
3121          *         }
3122          *     });
3123          *
3124          *     var p = board.create('point', [0.1, 0.1], {});
3125          *
3126          *     })();
3127          *
3128          * </script><pre>
3129          *
3130          */
3131         intl: {
3132             enabled: 'inherit',
3133             options: {}
3134         },
3135 
3136         // TODO implementation and documentation
3137         minorTicksInArrow: false,
3138         majorTicksInArrow: true,
3139         labelInArrow: true,
3140         minorTicksInMargin: false,
3141         majorTicksInMargin: true,
3142         labelInMargin: true
3143 
3144         // close the meta tag
3145         /**#@-*/
3146     },
3147 
3148     /*
3149      *  Generic options used by {@link JXG.Hatch}
3150      */
3151     hatch: {
3152         drawLabels: false,
3153         drawZero: true,
3154         majorHeight: 20,
3155         anchor: 'middle',
3156         face: '|',
3157         strokeWidth: 2,
3158         strokeColor: Color.palette.blue,
3159         /**
3160          * The default distance (in user coordinates, not  pixels) between two hatch symbols.
3161          *
3162          * @type Number
3163          * @name Hatch#ticksDistance
3164          * @default 0.2
3165          */
3166         ticksDistance: 0.2
3167     },
3168 
3169     /**
3170      * Precision options, defining how close a pointer device (mouse, finger, pen) has to be
3171      * to an object such that the object is highlighted or can be dragged.
3172      * These values are board-wide and can be overwritten for individual elements by
3173      * changing their precision attribute.
3174      *
3175      * The default values are
3176      * <pre>
3177      * JXG.Options.precision: {
3178      *   touch: 30,
3179      *   touchMax: 100,
3180      *   mouse: 4,
3181      *   pen: 4,
3182      *   epsilon: 0.0001,
3183      *   hasPoint: 4
3184      * }
3185      * </pre>
3186      *
3187      * @type Object
3188      * @name JXG.Options#precision
3189      * @see JXG.GeometryElement#precision
3190      */
3191     precision: {
3192         touch: 30,
3193         touchMax: 100,
3194         mouse: 4,
3195         pen: 4,
3196         epsilon: 0.0001, // Unused
3197         hasPoint: 4
3198     },
3199 
3200     /**
3201      * Default ordering of the layers.
3202      * The numbering starts from 0 and the highest layer number is numlayers-1.
3203      *
3204      * The default values are
3205      * <pre>
3206      * JXG.Options.layer: {
3207      *   numlayers: 20, // only important in SVG
3208      *   text: 9,
3209      *   point: 9,
3210      *   glider: 9,
3211      *   arc: 8,
3212      *   line: 7,
3213      *   circle: 6,
3214      *   curve: 5,
3215      *   turtle: 5,
3216      *   polygon: 3,
3217      *   sector: 3,
3218      *   angle: 3,
3219      *   integral: 3,
3220      *   axis: 2,
3221      *   ticks: 2,
3222      *   grid: 1,
3223      *   image: 0,
3224      *   trace: 0
3225      * }
3226      * </pre>
3227      * @type Object
3228      * @name JXG.Options#layer
3229      */
3230     layer: {
3231         numlayers: 20, // only important in SVG
3232         unused9: 19,
3233         unused8: 18,
3234         unused7: 17,
3235         unused6: 16,
3236         unused5: 15,
3237         unused4: 14,
3238         unused3: 13,
3239         unused2: 12,
3240         unused1: 11,
3241         unused0: 10,
3242         text: 9,
3243         point: 9,
3244         glider: 9,
3245         arc: 8,
3246         line: 7,
3247         circle: 6,
3248         curve: 5,
3249         turtle: 5,
3250         polygon: 3,
3251         sector: 3,
3252         angle: 3,
3253         integral: 3,
3254         axis: 2,
3255         ticks: 2,
3256         grid: 1,
3257         image: 0,
3258         trace: 0
3259     },
3260 
3261     /* special angle options */
3262     angle: {
3263         /**#@+
3264          * @visprop
3265          */
3266 
3267         withLabel: true,
3268 
3269         /**
3270          * Radius of the sector, displaying the angle.
3271          * The radius can be given as number (in user coordinates)
3272          * or as string 'auto'. In the latter case, the angle
3273          * is set to an value between 20 and 50 px.
3274          *
3275          * @type {Number|String}
3276          * @name Angle#radius
3277          * @default 'auto'
3278          * @visprop
3279          */
3280         radius: 'auto',
3281 
3282         /**
3283          * Display type of the angle field. Possible values are
3284          * 'sector' or 'sectordot' or 'square' or 'none'.
3285          *
3286          * @type String
3287          * @default 'sector'
3288          * @name Angle#type
3289          * @visprop
3290          */
3291         type: 'sector',
3292 
3293         /**
3294          * Display type of the angle field in case of a right angle. Possible values are
3295          * 'sector' or 'sectordot' or 'square' or 'none'.
3296          *
3297          * @type String
3298          * @default square
3299          * @name Angle#orthoType
3300          * @see Angle#orthoSensitivity
3301          * @visprop
3302          */
3303         orthoType: 'square',
3304 
3305         /**
3306          * Sensitivity (in degrees) to declare an angle as right angle.
3307          * If the angle measure is inside this distance from a rigth angle, the orthoType
3308          * of the angle is used for display.
3309          *
3310          * @type Number
3311          * @default 1.0
3312          * @name Angle#orthoSensitivity
3313          * @see Angle#orthoType
3314          * @visprop
3315          */
3316         orthoSensitivity: 1.0,
3317 
3318         fillColor: Color.palette.orange,
3319         highlightFillColor: Color.palette.orange,
3320         strokeColor: Color.palette.orange,
3321         // fillColor: '#ff7f00',
3322         // highlightFillColor: '#ff7f00',
3323         // strokeColor: '#ff7f00',
3324 
3325         fillOpacity: 0.3,
3326         highlightFillOpacity: 0.3,
3327 
3328         /**
3329          * @name Angle#radiuspoint
3330          * @type Object
3331          * @deprecated
3332          */
3333         radiuspoint: {
3334             withLabel: false,
3335             visible: false,
3336             name: ''
3337         },
3338 
3339         /**
3340          * @name Angle#pointsquare
3341          * @type Object
3342          * @deprecated
3343          */
3344         pointsquare: {
3345             withLabel: false,
3346             visible: false,
3347             name: ''
3348         },
3349 
3350         /**
3351          * Attributes of the dot point marking right angles.
3352          * @name Angle#dot
3353          * @type Object
3354          * @default {face: 'o', size: 2}
3355          */
3356         dot: {
3357             visible: false,
3358             strokeColor: 'none',
3359             fillColor: '#000000',
3360             size: 2,
3361             face: 'o',
3362             withLabel: false,
3363             name: ''
3364         },
3365 
3366         label: {
3367             position: 'top',
3368             offset: [0, 0],
3369             strokeColor: Color.palette.blue
3370         },
3371 
3372         /**
3373          * Attributes for sub-element arc. In general, the arc will run through the first point and
3374          * thus will not have the same radius as the angle sector.
3375          *
3376          * @type Arc
3377          * @name Angle#arc
3378          * @default '{visible:false}'
3379          */
3380         arc: {
3381             visible: false,
3382             fillColor: 'none'
3383         },
3384 
3385         /**#@-*/
3386     },
3387 
3388     /* special arc options */
3389     arc: {
3390         /**#@+
3391          * @visprop
3392          */
3393 
3394         /**
3395          * Type of arc. Possible values are 'minor', 'major', and 'auto'.
3396          *
3397          * @type String
3398          * @name Arc#selection
3399          * @default 'auto'
3400          */
3401         selection: 'auto',
3402 
3403         /**
3404          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
3405          *
3406          * @see JXG.GeometryElement#hasPoint
3407          * @name Arc#hasInnerPoints
3408          * @type Boolean
3409          * @default false
3410          */
3411         hasInnerPoints: false,
3412 
3413         label: {
3414             anchorX: 'auto',
3415             anchorY: 'auto'
3416         },
3417         firstArrow: false,
3418         lastArrow: false,
3419         fillColor: 'none',
3420         highlightFillColor: 'none',
3421         strokeColor: Color.palette.blue,
3422         highlightStrokeColor: '#c3d9ff',
3423         useDirection: false,
3424 
3425         /**
3426          * Attributes for center point.
3427          *
3428          * @type Point
3429          * @name Arc#center
3430          */
3431         center: {
3432         },
3433 
3434         /**
3435          * Attributes for radius point.
3436          *
3437          * @type Point
3438          * @name Arc#radiusPoint
3439          */
3440         radiusPoint: {
3441         },
3442 
3443         /**
3444          * Attributes for angle point.
3445          *
3446          * @type Point
3447          * @name Arc#anglePoint
3448          */
3449         anglePoint: {
3450         }
3451 
3452         /**#@-*/
3453     },
3454 
3455     /* special arrow options */
3456     arrow: {
3457         /**#@+
3458          * @visprop
3459          */
3460 
3461         firstArrow: false,
3462 
3463         lastArrow: {
3464             type: 1,
3465             highlightSize: 6,
3466             size: 6
3467         }
3468 
3469         /**#@-*/
3470     },
3471 
3472     /* special arrowparallel options */
3473     arrowparallel: {
3474     },
3475 
3476     /* special axis options */
3477     axis: {
3478         /**#@+
3479          * @visprop
3480          */
3481 
3482         name: '',                            // By default, do not generate names for axes.
3483         needsRegularUpdate: false,           // Axes only updated after zooming and moving of the origin.
3484         strokeWidth: 1,
3485         lastArrow: {
3486             type: 1,
3487             highlightSize: 8,
3488             size: 8
3489         },
3490         strokeColor: '#666666',
3491         highlightStrokeWidth: 1,
3492         highlightStrokeColor: '#888888',
3493 
3494         /**
3495          * Show / hide ticks.
3496          *
3497          * Deprecated. Suggested alternative is "ticks: {visible: false}"
3498          *
3499          * @type Boolean
3500          * @name Axis#withTicks
3501          * @default true
3502          * @deprecated
3503          */
3504         withTicks: true,
3505         straightFirst: true,
3506         straightLast: true,
3507         margin: -4,
3508         withLabel: false,
3509         scalable: false,
3510 
3511         /**
3512          * Attributes for ticks of the axis.
3513          *
3514          * @type Ticks
3515          * @name Axis#ticks
3516          */
3517         ticks: {
3518             label: {
3519                 offset: [4, -12 + 3],     // This seems to be a good offset for 12 point fonts
3520                 parse: false,
3521                 needsRegularUpdate: false,
3522                 display: 'internal',
3523                 visible: 'inherit',
3524                 layer: 9
3525             },
3526             visible: 'inherit',
3527             needsRegularUpdate: false,
3528             strokeWidth: 1,
3529             strokeColor: '#666666',
3530             highlightStrokeColor: '#888888',
3531             drawLabels: true,
3532             drawZero: false,
3533             insertTicks: true,
3534             minTicksDistance: 5,
3535             minorHeight: 10,          // if <0: full width and height
3536             majorHeight: -1,          // if <0: full width and height
3537             tickEndings: [0, 1],
3538             majorTickEndings: [1, 1],
3539             minorTicks: 4,
3540             ticksDistance: 1,         // TODO doc
3541             strokeOpacity: 0.25
3542         },
3543 
3544         /**
3545          * Attributes for first point the axis.
3546          *
3547          * @type Point
3548          * @name Axis#point1
3549          */
3550         point1: {                  // Default values for point1 if created by line
3551             needsRegularUpdate: false,
3552             visible: false
3553         },
3554 
3555         /**
3556          * Attributes for second point the axis.
3557          *
3558          * @type Point
3559          * @name Axis#point2
3560          */
3561         point2: {                  // Default values for point2 if created by line
3562             needsRegularUpdate: false,
3563             visible: false
3564         },
3565 
3566         tabindex: -1,
3567 
3568         /**
3569          * Attributes for the axis label.
3570          *
3571          * @type Label
3572          * @name Axis#label
3573          */
3574         label: {
3575             position: 'lft',
3576             offset: [10, 10]
3577         }
3578         /**#@-*/
3579     },
3580 
3581     /* special options for angle bisector of 3 points */
3582     bisector: {
3583         /**#@+
3584          * @visprop
3585          */
3586 
3587         strokeColor: '#000000', // Bisector line
3588 
3589         /**
3590          * Attributes for the helper point of the bisector.
3591          *
3592          * @type Point
3593          * @name Bisector#point
3594          */
3595         point: {               // Bisector point
3596             visible: false,
3597             fixed: false,
3598             withLabel: false,
3599             name: ''
3600         }
3601 
3602         /**#@-*/
3603     },
3604 
3605     /* special options for the 2 bisectors of 2 lines */
3606     bisectorlines: {
3607         /**#@+
3608          * @visprop
3609          */
3610 
3611         /**
3612          * Attributes for first line.
3613          *
3614          * @type Line
3615          * @name Bisectorlines#line1
3616          */
3617         line1: {               //
3618             strokeColor: '#000000'
3619         },
3620 
3621         /**
3622          * Attributes for second line.
3623          *
3624          * @type Line
3625          * @name Bisectorlines#line2
3626          */
3627         line2: {               //
3628             strokeColor: '#000000'
3629         }
3630 
3631         /**#@-*/
3632     },
3633 
3634     /* special options for boxplot curves */
3635     boxplot: {
3636         /**#@+
3637          * @visprop
3638          */
3639 
3640         /**
3641          *  Direction of the box plot: 'vertical' or 'horizontal'
3642          *
3643          * @type String
3644          * @name Boxplot#dir
3645          * @default 'vertical'
3646          */
3647         dir: 'vertical',
3648 
3649         /**
3650          * Relative width of the maximum and minimum quantile
3651          *
3652          * @type Number
3653          * @name Boxplot#smallWidth
3654          * @default 0.5
3655          */
3656         smallWidth: 0.5,
3657 
3658         strokeWidth: 2,
3659         strokeColor: Color.palette.blue,
3660         fillColor: Color.palette.blue,
3661         fillOpacity: 0.2,
3662         highlightStrokeWidth: 2,
3663         highlightStrokeColor: Color.palette.blue,
3664         highlightFillColor: Color.palette.blue,
3665         highlightFillOpacity: 0.1
3666 
3667         /**#@-*/
3668     },
3669 
3670     /* special button options */
3671     button: {
3672         /**#@+
3673          * @visprop
3674          */
3675 
3676         /**
3677          * Control the attribute "disabled" of the HTML button.
3678          *
3679          * @name disabled
3680          * @memberOf Button.prototype
3681          *
3682          * @type Boolean
3683          * @default false
3684          */
3685         disabled: false,
3686 
3687         display: 'html'
3688 
3689         /**#@-*/
3690     },
3691 
3692     /* special cardinal spline options */
3693     cardinalspline: {
3694         /**#@+
3695          * @visprop
3696          */
3697 
3698         /**
3699          * Controls if the data points of the cardinal spline when given as
3700          * arrays should be converted into {@link JXG.Points}.
3701          *
3702          * @name createPoints
3703          * @memberOf Cardinalspline.prototype
3704          *
3705          * @see Cardinalspline#points
3706          *
3707          * @type Boolean
3708          * @default true
3709          */
3710         createPoints: true,
3711 
3712         /**
3713          * If set to true, the supplied coordinates are interpreted as
3714          * [[x_0, y_0], [x_1, y_1], p, ...].
3715          * Otherwise, if the data consists of two arrays of equal length,
3716          * it is interpreted as
3717          * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]
3718          *
3719          * @name isArrayOfCoordinates
3720          * @memberOf Cardinalspline.prototype
3721          * @type Boolean
3722          * @default true
3723          */
3724         isArrayOfCoordinates: true,
3725 
3726         /**
3727          * Attributes for the points generated by Cardinalspline in cases
3728          * {@link createPoints} is set to true
3729          *
3730          * @name points
3731          * @memberOf Cardinalspline.prototype
3732          *
3733          * @see Cardinalspline#createPoints
3734          * @type Object
3735          */
3736         points: {
3737             strokeOpacity: 0.05,
3738             fillOpacity: 0.05,
3739             highlightStrokeOpacity: 1.0,
3740             highlightFillOpacity: 1.0,
3741             withLabel: false,
3742             name: '',
3743             fixed: false
3744         }
3745 
3746         /**#@-*/
3747     },
3748 
3749     /* special chart options */
3750     chart: {
3751         /**#@+
3752          * @visprop
3753          */
3754 
3755         chartStyle: 'line',
3756         colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],
3757         highlightcolors: null,
3758         fillcolor: null,
3759         highlightonsector: false,
3760         highlightbysize: false,
3761 
3762         fillOpacity: 0.6,
3763         withLines: false,
3764 
3765         label: {
3766         }
3767         /**#@-*/
3768     },
3769 
3770     /* special html slider options */
3771     checkbox: {
3772         /**#@+
3773          * @visprop
3774          */
3775 
3776         /**
3777          * Control the attribute "disabled" of the HTML checkbox.
3778          *
3779          * @name disabled
3780          * @memberOf Checkbox.prototype
3781          *
3782          * @type Boolean
3783          * @default false
3784          */
3785         disabled: false,
3786 
3787         /**
3788          * Control the attribute "checked" of the HTML checkbox.
3789          *
3790          * @name checked
3791          * @memberOf Checkbox.prototype
3792          *
3793          * @type Boolean
3794          * @default false
3795          */
3796         checked: false,
3797 
3798         display: 'html'
3799 
3800         /**#@-*/
3801     },
3802 
3803     /*special circle options */
3804     circle: {
3805         /**#@+
3806          * @visprop
3807          */
3808 
3809         /**
3810          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
3811          *
3812          * @see JXG.GeometryElement#hasPoint
3813          * @name Circle#hasInnerPoints
3814          * @type Boolean
3815          * @default false
3816          */
3817         hasInnerPoints: false,
3818 
3819         fillColor: 'none',
3820         highlightFillColor: 'none',
3821         strokeColor: Color.palette.blue,
3822         highlightStrokeColor: '#c3d9ff',
3823 
3824         /**
3825          * Attributes for center point.
3826          *
3827          * @type Point
3828          * @name Circle#center
3829          */
3830         center: {
3831             visible: false,
3832             withLabel: false,
3833             fixed: false,
3834 
3835             fillColor: Color.palette.red,
3836             strokeColor: Color.palette.red,
3837             highlightFillColor: '#c3d9ff',
3838             highlightStrokeColor: '#c3d9ff',
3839             layer: 9,
3840 
3841             name: ''
3842         },
3843 
3844         /**
3845          * Attributes for center point.
3846          *
3847          * @type Point
3848          * @name Circle#center
3849          */
3850         point2: {
3851             fillColor: Color.palette.red,
3852             strokeColor: Color.palette.red,
3853             highlightFillColor: '#c3d9ff',
3854             highlightStrokeColor: '#c3d9ff',
3855             layer: 9,
3856 
3857             visible: false,
3858             withLabel: false,
3859             fixed: false,
3860             name: ''
3861         },
3862 
3863         /**
3864          * Attributes for circle label.
3865          *
3866          * @type Label
3867          * @name Circle#label
3868          */
3869         label: {
3870             position: 'urt'
3871         }
3872         /**#@-*/
3873     },
3874 
3875     /* special options for circumcircle of 3 points */
3876     circumcircle: {
3877         /**#@+
3878          * @visprop
3879          */
3880 
3881         fillColor: 'none',
3882         highlightFillColor: 'none',
3883         strokeColor: Color.palette.blue,
3884         highlightStrokeColor: '#c3d9ff',
3885 
3886         /**
3887          * Attributes for center point.
3888          *
3889          * @type Point
3890          * @name Circumcircle#center
3891          */
3892         center: {               // center point
3893             visible: false,
3894             fixed: false,
3895             withLabel: false,
3896             fillColor: Color.palette.red,
3897             strokeColor: Color.palette.red,
3898             highlightFillColor: '#c3d9ff',
3899             highlightStrokeColor: '#c3d9ff',
3900             name: ''
3901         }
3902         /**#@-*/
3903     },
3904 
3905     circumcirclearc: {
3906         /**#@+
3907          * @visprop
3908          */
3909 
3910         fillColor: 'none',
3911         highlightFillColor: 'none',
3912         strokeColor: Color.palette.blue,
3913         highlightStrokeColor: '#c3d9ff',
3914 
3915         /**
3916          * Attributes for center point.
3917          *
3918          * @type Point
3919          * @name CircumcircleArc#center
3920          */
3921         center: {
3922             visible: false,
3923             withLabel: false,
3924             fixed: false,
3925             name: ''
3926         }
3927         /**#@-*/
3928     },
3929 
3930     /* special options for circumcircle sector of 3 points */
3931     circumcirclesector: {
3932         /**#@+
3933          * @visprop
3934          */
3935 
3936         useDirection: true,
3937         fillColor: Color.palette.yellow,
3938         highlightFillColor: Color.palette.yellow,
3939         fillOpacity: 0.3,
3940         highlightFillOpacity: 0.3,
3941         strokeColor: Color.palette.blue,
3942         highlightStrokeColor: '#c3d9ff',
3943 
3944         /**
3945          * Attributes for center point.
3946          *
3947          * @type Point
3948          * @name Circle#point
3949          */
3950         point: {
3951             visible: false,
3952             fixed: false,
3953             withLabel: false,
3954             name: ''
3955         }
3956         /**#@-*/
3957     },
3958 
3959     /* special options for comb */
3960     comb: {
3961         /**#@+
3962          * @visprop
3963          */
3964 
3965         /**
3966          * Frequency of comb elements.
3967          *
3968          * @type Number
3969          * @name Comb#frequency
3970          * @default 0.2
3971          */
3972         frequency: 0.2,
3973 
3974         /**
3975          * Width of the comb.
3976          *
3977          * @type Number
3978          * @name Comb#width
3979          * @default 0.4
3980          */
3981         width: 0.4,
3982 
3983         /**
3984          * Angle - given in radians - under which comb elements are positioned.
3985          *
3986          * @type Number
3987          * @name Comb#angle
3988          * @default Math.PI / 3 (i.e. π /3  or 60^° degrees)
3989          */
3990         angle: Math.PI / 3,
3991 
3992         /**
3993          * Should the comb go right to left instead of left to right.
3994          *
3995          * @type Boolean
3996          * @name Comb#reverse
3997          * @default false
3998          */
3999         reverse: false,
4000 
4001         /**
4002          * Attributes for first defining point of the comb.
4003          *
4004          * @type Point
4005          * @name Comb#point1
4006          */
4007         point1: {
4008             visible: false,
4009             withLabel: false,
4010             fixed: false,
4011             name: ''
4012         },
4013 
4014         /**
4015          * Attributes for second defining point of the comb.
4016          *
4017          * @type Point
4018          * @name Comb#point2
4019          */
4020         point2: {
4021             visible: false,
4022             withLabel: false,
4023             fixed: false,
4024             name: ''
4025         },
4026 
4027         // /**
4028         //  * Attributes for the curve displaying the comb.
4029         //  *
4030         //  * @type Curve
4031         //  * @name Comb#curve
4032         //  */
4033         // curve: {
4034         //     strokeWidth: 1,
4035         //     strokeColor: '#0000ff',
4036         //     fillColor: 'none'
4037         // },
4038         strokeWidth: 1,
4039         strokeColor: '#0000ff',
4040         fillColor: 'none'
4041 },
4042 
4043     /* special conic options */
4044     conic: {
4045         /**#@+
4046          * @visprop
4047          */
4048 
4049         fillColor: 'none',
4050         highlightFillColor: 'none',
4051         strokeColor: Color.palette.blue,
4052         highlightStrokeColor: '#c3d9ff',
4053 
4054         /**
4055          * Attributes for foci points.
4056          *
4057          * @type Point
4058          * @name Conic#foci
4059          */
4060         foci: {
4061             // points
4062             fixed: false,
4063             visible: false,
4064             withLabel: false,
4065             name: ''
4066         },
4067 
4068         /**
4069          * Attributes for center point.
4070          *
4071          * @type Point
4072          * @name Conic#center
4073          */
4074         center: {
4075             visible: false,
4076             withLabel: false,
4077             name: ''
4078         },
4079 
4080         /**
4081          * Attributes for five points defining the conic, if some of them are given as coordinates.
4082          *
4083          * @type Point
4084          * @name Conic#point
4085          */
4086         point: {
4087             withLabel: false,
4088             name: ''
4089         },
4090 
4091         /**
4092          * Attributes for parabola line in case the line is given by two
4093          * points or coordinate pairs.
4094          *
4095          * @type Line
4096          * @name Conic#line
4097          */
4098         line: {
4099             visible: false
4100         }
4101 
4102         /**#@-*/
4103     },
4104 
4105     /* special curve options */
4106     curve: {
4107         strokeWidth: 1,
4108         strokeColor: Color.palette.blue,
4109         fillColor: 'none',
4110         fixed: true,
4111 
4112         useQDT: false,
4113 
4114         /**#@+
4115          * @visprop
4116          */
4117 
4118         /**
4119          * The data points of the curve are not connected with straight lines but with bezier curves.
4120          * @name Curve#handDrawing
4121          * @type Boolean
4122          * @default false
4123          */
4124         handDrawing: false,
4125 
4126         /**
4127          * The curveType is set in {@link JXG.Curve#generateTerm} and used in {@link JXG.Curve#updateCurve}.
4128          * Possible values are <ul>
4129          * <li>'none'</li>
4130          * <li>'plot': Data plot</li>
4131          * <li>'parameter': we can not distinguish function graphs and parameter curves</li>
4132          * <li>'functiongraph': function graph</li>
4133          * <li>'polar'</li>
4134          * <li>'implicit' (not yet)</li></ul>
4135          * Only parameter and plot are set directly. Polar is set with {@link JXG.GeometryElement#setAttribute} only.
4136          * @name Curve#curveType
4137          * @type String
4138          * @default null
4139          */
4140         curveType: null,
4141 
4142         /**
4143          * Apply Ramer-Douglas-Peuker smoothing.
4144          *
4145          * @type Boolean
4146          * @name Curve#RDPsmoothing
4147          * @default false
4148          */
4149         RDPsmoothing: false,     // Apply the Ramer-Douglas-Peuker algorithm
4150 
4151         /**
4152          * Number of points used for plotting triggered by up events
4153          * (i.e. high quality plotting) in case
4154          * {@link Curve#doAdvancedPlot} is false.
4155          *
4156          * @name Curve#numberPointsHigh
4157          * @see Curve#doAdvancedPlot
4158          * @type Number
4159          * @default 1600
4160          */
4161         numberPointsHigh: 1600,  // Number of points on curves after mouseUp
4162 
4163         /**
4164          * Number of points used for plotting triggered by move events
4165          * (i.e. lower quality plotting but fast) in case
4166          * {@link Curve#doAdvancedPlot} is false.
4167          *
4168          * @name Curve#numberPointsLow
4169          * @see Curve#doAdvancedPlot
4170          * @type Number
4171          * @default 400
4172          */
4173         numberPointsLow: 400,    // Number of points on curves after mousemove
4174 
4175         /**
4176          * If true use a recursive bisection algorithm.
4177          * It is slower, but usually the result is better. It tries to detect jumps
4178          * and singularities.
4179          *
4180          * @name Curve#doAdvancedPlot
4181          * @type Boolean
4182          * @default true
4183          */
4184         doAdvancedPlot: true,
4185 
4186         /**
4187          *
4188          * Recursion depth used for plotting triggered by up events
4189          * (i.e. high quality plotting) in case
4190          * {@link Curve#doAdvancedPlot} is true.
4191          *
4192          * @name Curve#recursionDepthHigh
4193          * @see Curve#doAdvancedPlot
4194          * @type Number
4195          * @default 17
4196          */
4197         recursionDepthHigh: 17,
4198 
4199         /**
4200          * Number of points used for plotting triggered by move events in case
4201          * (i.e. lower quality plotting but fast)
4202          * {@link Curve#doAdvancedPlot} is true.
4203          *
4204          * @name Curve#recursionDepthLow
4205          * @see Curve#doAdvancedPlot
4206          * @type Number
4207          * @default 13
4208          */
4209         recursionDepthLow: 15,
4210 
4211         /**
4212          * If true use the algorithm by Gillam and Hohenwarter, which was default until version 0.98.
4213          *
4214          * @name Curve#doAdvancedPlotOld
4215          * @see Curve#doAdvancedPlot
4216          * @type Boolean
4217          * @default false
4218          * @deprecated
4219          */
4220         doAdvancedPlotOld: false,   // v1
4221 
4222         /**
4223          * Select the version of the plot algorithm.
4224          * <ul>
4225          * <li> Version 1 is very outdated
4226          * <li> Version 2 is the default version in JSXGraph v0.99.*, v1.0, and v1.1, v1.2.0
4227          * <li> Version 3 is an internal version that was never published in  a stable version.
4228          * <li> Version 4 is available since JSXGraph v1.2.0
4229          * </ul>
4230          * Version 4 plots correctly logarithms if the function term is supplied as string (i.e. as JessieCode)
4231          *
4232          * @example
4233          *   var c = board.create('functiongraph', ["log(x)"]);
4234          *
4235          * @name Curve#plotVersion
4236          * @type Number
4237          * @default 2
4238          */
4239         plotVersion: 2,
4240 
4241         /**
4242          * Attributes for circle label.
4243          *
4244          * @type Label
4245          * @name Circle#label
4246          */
4247         label: {
4248             position: 'lft'
4249         },
4250 
4251         /**
4252          * Configure arrow head at the start position for curve.
4253          * Recommended arrow head type is 7.
4254          *
4255          * @name Curve#firstArrow
4256          * @type Boolean / Object
4257          * @default false
4258          * @see Line#firstArrow for options
4259          */
4260         firstArrow: false,
4261 
4262         /**
4263          * Configure arrow head at the end position for curve.
4264          * Recommended arrow head type is 7.
4265          *
4266          * @name Curve#lastArrow
4267          * @see Line#lastArrow for options
4268          * @type Boolean / Object
4269          * @default false
4270          */
4271         lastArrow: false
4272 
4273         /**#@-*/
4274     },
4275 
4276     /* special foreignObject options */
4277     foreignobject: {
4278         /**#@+
4279          * @visprop
4280          */
4281 
4282         fixed: true,
4283         visible: true,
4284         needsRegularUpdate: false,
4285 
4286         /**
4287          * List of attractor elements. If the distance of the foreignobject is less than
4288          * attractorDistance the foreignobject is made to glider of this element.
4289          *
4290          * @name ForeignObject#attractors
4291          *
4292          * @type Array
4293          * @default empty
4294          */
4295         attractors: []
4296 
4297         /**#@-*/
4298     },
4299 
4300     glider: {
4301         /**#@+
4302          * @visprop
4303          */
4304 
4305         label: {}
4306         /**#@-*/
4307     },
4308 
4309     /* special grid options */
4310     grid: {
4311         /**#@+
4312          * @visprop
4313          */
4314 
4315         /* grid styles */
4316         needsRegularUpdate: false,
4317         hasGrid: false,
4318         gridX: 1,
4319         gridY: 1,
4320         //strokeColor: '#c0c0c0',
4321         strokeColor: '#c0c0c0',
4322         strokeOpacity: 0.5,
4323         strokeWidth: 1,
4324         dash: 0,    // dashed grids slow down the iPad considerably
4325         /* snap to grid options */
4326 
4327         /**
4328          * @name Grid#snapToGrid
4329          * @type Boolean
4330          * @deprecated
4331          */
4332         snapToGrid: false,
4333 
4334         /**
4335          * @name Grid#snapSizeX
4336          * @type Boolean
4337          * @deprecated
4338          */
4339         snapSizeX: 10,
4340 
4341         /**
4342          * @name Grid#snapSizeY
4343          * @type Boolean
4344          * @deprecated
4345          */
4346         snapSizeY: 10
4347 
4348         /**#@-*/
4349     },
4350 
4351     group: {
4352         needsRegularUpdate: true
4353     },
4354 
4355     /* special html slider options */
4356     htmlslider: {
4357         /**#@+
4358          * @visprop
4359          */
4360 
4361         // /**
4362         //  *
4363         //  * These affect the DOM element input type="range".
4364         //  * The other attributes affect the DOM element div containing the range element.
4365         //  */
4366         widthRange: 100,
4367         widthOut: 34,
4368         step: 0.01,
4369 
4370         frozen: true,
4371         isLabel: false,
4372         strokeColor: '#000000',
4373         display: 'html',
4374         anchorX: 'left',
4375         anchorY: 'middle',
4376         withLabel: false
4377 
4378         /**#@-*/
4379     },
4380 
4381     /* special image options */
4382     image: {
4383         /**#@+
4384          * @visprop
4385          */
4386 
4387         imageString: null,
4388         fillOpacity: 1.0,
4389         highlightFillOpacity: 0.6,
4390 
4391 
4392         /**
4393          * Defines the CSS class used by the image. CSS attributes defined in
4394          * this class will overwrite the corresponding JSXGraph attributes, e.g.
4395          * opacity.
4396          * The default CSS class is defined in jsxgraph.css.
4397          *
4398          * @name Image#cssClass
4399          *
4400          * @see Image#highlightCssClass
4401          * @type String
4402          * @default 'JXGimage'
4403          */
4404         cssClass: 'JXGimage',
4405 
4406         /**
4407          * Defines the CSS class used by the image when highlighted.
4408          * CSS attributes defined in this class will overwrite the
4409          * corresponding JSXGraph attributes, e.g. highlightFillOpacity.
4410          * The default CSS class is defined in jsxgraph.css.
4411          *
4412          * @name Image#highlightCssClass
4413          *
4414          * @see Image#cssClass
4415          * @type String
4416          * @default 'JXGimageHighlight'
4417          */
4418         highlightCssClass: 'JXGimageHighlight',
4419 
4420         /**
4421          * Image rotation in degrees.
4422          *
4423          * @name Image#rotate
4424          * @type Number
4425          * @default 0
4426          */
4427         rotate: 0,
4428 
4429         /**
4430          * Defines together with {@link Image#snapSizeY} the grid the image snaps on to.
4431          * The image will only snap on user coordinates which are
4432          * integer multiples to snapSizeX in x and snapSizeY in y direction.
4433          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
4434          * of the default ticks of the default x axes of the board.
4435          *
4436          * @name Image#snapSizeX
4437          *
4438          * @see Point#snapToGrid
4439          * @see Image#snapSizeY
4440          * @see JXG.Board#defaultAxes
4441          * @type Number
4442          * @default 1
4443          */
4444         snapSizeX: 1,
4445 
4446         /**
4447          * Defines together with {@link Image#snapSizeX} the grid the image snaps on to.
4448          * The image will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
4449          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
4450          * of the default ticks of the default y axes of the board.
4451          *
4452          * @name Image#snapSizeY
4453          *
4454          * @see Point#snapToGrid
4455          * @see Image#snapSizeX
4456          * @see JXG.Board#defaultAxes
4457          * @type Number
4458          * @default 1
4459          */
4460         snapSizeY: 1,
4461 
4462         /**
4463          * List of attractor elements. If the distance of the image is less than
4464          * attractorDistance the image is made to glider of this element.
4465          *
4466          * @name Image#attractors
4467          *
4468          * @type Array
4469          * @default empty
4470          */
4471         attractors: []
4472 
4473         /**#@-*/
4474     },
4475 
4476     /* special options for incircle of 3 points */
4477     incircle: {
4478         /**#@+
4479          * @visprop
4480          */
4481 
4482         fillColor: 'none',
4483         highlightFillColor: 'none',
4484         strokeColor: Color.palette.blue,
4485         highlightStrokeColor: '#c3d9ff',
4486 
4487         /**
4488          * Attributes of circle center.
4489          *
4490          * @type Point
4491          * @name Incircle#center
4492          */
4493         center: {               // center point
4494             visible: false,
4495             fixed: false,
4496             withLabel: false,
4497             fillColor: Color.palette.red,
4498             strokeColor: Color.palette.red,
4499             highlightFillColor: '#c3d9ff',
4500             highlightStrokeColor: '#c3d9ff',
4501             name: ''
4502         }
4503         /**#@-*/
4504     },
4505 
4506     inequality: {
4507         /**#@+
4508          * @visprop
4509          */
4510 
4511         fillColor: Color.palette.red,
4512         fillOpacity: 0.2,
4513         strokeColor: 'none',
4514 
4515         /**
4516          * By default an inequality is less (or equal) than. Set inverse to <tt>true</tt> will consider the inequality
4517          * greater (or equal) than.
4518          *
4519          * @type Boolean
4520          * @default false
4521          * @name Inequality#inverse
4522          * @visprop
4523          */
4524         inverse: false
4525         /**#@-*/
4526     },
4527 
4528     infobox: {
4529         /**#@+
4530          * @visprop
4531          */
4532 
4533         /**
4534          * Horizontal offset in pixel of the infobox text from its anchor point.
4535          *
4536          * @type Number
4537          * @default -20
4538          * @name JXG.Board.infobox#distanceX
4539          * @visprop
4540          */
4541         distanceX: -20,
4542 
4543         /**
4544          * Vertical offset in pixel of the infobox text from its anchor point.
4545          *
4546          * @type Number
4547          * @default 25
4548          * @name JXG.Board.infobox#distanceY
4549          * @visprop
4550          */
4551         distanceY: 25,
4552 
4553         /**
4554          * Internationalization support for infobox text.
4555          *
4556          * @name JXG.Board.infobox#intl
4557          * @type object
4558                   * @default {
4559          *    enabled: 'inherit',
4560          *    options: {}
4561          * }
4562          * @visprop
4563          * @see JXG.Board#intl
4564          * @see Text#intl
4565          */
4566         intl: {
4567             enabled: 'inherit',
4568             options: {}
4569         },
4570 
4571         fontSize: 12,
4572         isLabel: false,
4573         strokeColor: '#bbbbbb',
4574         display: 'html',             // 'html' or 'internal'
4575         anchorX: 'left',             //  'left', 'middle', or 'right': horizontal alignment
4576         //  of the text.
4577         anchorY: 'middle',           //  'top', 'middle', or 'bottom': vertical alignment
4578         //  of the text.
4579         cssClass: 'JXGinfobox',
4580         rotate: 0,                   // works for non-zero values only in combination
4581         // with display=='internal'
4582         visible: true,
4583         parse: false,
4584         transitionDuration: 0,
4585         needsRegularUpdate: false,
4586         tabindex: null
4587 
4588         /**#@-*/
4589     },
4590 
4591     /* special options for integral */
4592     integral: {
4593         /**#@+
4594          * @visprop
4595          */
4596 
4597         axis: 'x',        // 'x' or 'y'
4598         withLabel: true,    // Show integral value as text
4599         fixed: true,
4600         strokeWidth: 0,
4601         strokeOpacity: 0,
4602         fillColor: Color.palette.red,
4603         fillOpacity: 0.3,
4604         highlightFillColor: Color.palette.red,
4605         highlightFillOpacity: 0.2,
4606 
4607         /**
4608          * Attributes of the (left) starting point of the integral.
4609          *
4610          * @type Point
4611          * @name Integral#curveLeft
4612          * @see Integral#baseLeft
4613          */
4614         curveLeft: {    // Start point
4615             visible: true,
4616             withLabel: false,
4617             color: Color.palette.red,
4618             fillOpacity: 0.8,
4619             layer: 9
4620         },
4621 
4622         /**
4623          * Attributes of the (left) base point of the integral.
4624          *
4625          * @type Point
4626          * @name Integral#baseLeft
4627          * @see Integral#curveLeft
4628          */
4629         baseLeft: {    // Start point
4630             visible: false,
4631             fixed: false,
4632             withLabel: false,
4633             name: ''
4634         },
4635 
4636         /**
4637          * Attributes of the (right) end point of the integral.
4638          *
4639          * @type Point
4640          * @name Integral#curveRight
4641          * @see Integral#baseRight
4642          */
4643         curveRight: {      // End point
4644             visible: true,
4645             withLabel: false,
4646             color: Color.palette.red,
4647             fillOpacity: 0.8,
4648             layer: 9
4649         },
4650 
4651         /**
4652          * Attributes of the (right) base point of the integral.
4653          *
4654          * @type Point
4655          * @name Integral#baseRight
4656          * @see Integral#curveRight
4657          */
4658         baseRight: {      // End point
4659             visible: false,
4660             fixed: false,
4661             withLabel: false,
4662             name: ''
4663         },
4664 
4665         /**
4666          * Attributes for integral label.
4667          *
4668          * @type Label
4669          * @name Integral#label
4670          * @default {
4671          *      fontSize: 20,
4672          *      digits: 4,
4673          *      intl: {
4674          *          enabled: false,
4675          *          options: {}
4676          *      }
4677          *    }
4678          */
4679         label: {
4680             fontSize: 20,
4681             digits: 4,
4682             intl: {
4683                 enabled: false,
4684                 options: {}
4685             }
4686         }
4687         /**#@-*/
4688     },
4689 
4690     /* special input options */
4691     input: {
4692         /**#@+
4693          * @visprop
4694          */
4695 
4696         /**
4697          * Control the attribute "disabled" of the HTML input field.
4698          *
4699          * @name disabled
4700          * @memberOf Input.prototype
4701          *
4702          * @type Boolean
4703          * @default false
4704          */
4705         disabled: false,
4706 
4707         /**
4708          * Control the attribute "maxlength" of the HTML input field.
4709          *
4710          * @name maxlength
4711          * @memberOf Input.prototype
4712          *
4713          * @type Number
4714          * @default 524288 (as in HTML)
4715          */
4716         maxlength: 524288,
4717 
4718         display: 'html'
4719 
4720         /**#@-*/
4721     },
4722 
4723     /* special intersection point options */
4724     intersection: {
4725         /**#@+
4726          * @visprop
4727          */
4728 
4729         /**
4730          * Used in {@link JXG.Intersection}.
4731          * This flag sets the behaviour of intersection points of e.g.
4732          * two segments. If true, the intersection is treated as intersection of lines. If false
4733          * the intersection point exists if the segments intersect setwise.
4734          *
4735          * @name Intersection.alwaysIntersect
4736          * @type Boolean
4737          * @default true
4738          */
4739         alwaysIntersect: true
4740 
4741         /**#@-*/
4742     },
4743 
4744     /* special label options */
4745     label: {
4746         /**#@+
4747          * @visprop
4748          */
4749 
4750         visible: 'inherit',
4751         strokeColor: '#000000',
4752         strokeOpacity: 1,
4753         highlightStrokeOpacity: 0.666666,
4754         highlightStrokeColor: '#000000',
4755 
4756         fixed: true,
4757 
4758         /**
4759          * Possible string values for the position of a label for
4760          * label anchor points are:
4761          * <ul>
4762          * <li> 'first' (lines only)
4763          * <li> 'last' (lines only)
4764          * <li> 'lft'
4765          * <li> 'rt'
4766          * <li> 'top'
4767          * <li> 'bot'
4768          * <li> 'ulft'
4769          * <li> 'urt'
4770          * <li> 'llft'
4771          * <li> 'lrt'
4772          * </ul>
4773          * This is relevant for non-points: line, circle, curve.
4774          *
4775          * The names have been borrowed from <a href="https://www.tug.org/metapost.html">MetaPost</a>.
4776          *
4777          * @name Label#position
4778          * @see Label#offset
4779          * @type String
4780          * @default 'urt'
4781          */
4782         position: 'urt',
4783 
4784         /**
4785          *  Label offset from label anchor.
4786          *  The label anchor is determined by {@link Label#position}
4787          *
4788          * @name Label#offset
4789          * @see Label#position
4790          * @type Array
4791          * @default [10,10]
4792          */
4793         offset: [10, 10],
4794 
4795         /**
4796          * Automatic position of label text. When called first, the positioning algorithm
4797          * starts at the position defined by offset.
4798          * The algorithm tries to find a position with the least number of
4799          * overlappings with other elements, while retaining the distance
4800          * to the anchor element.
4801          *
4802          * @name Label#autoPosition
4803          * @see Label#offset
4804          * @type Boolean
4805          * @default false
4806          *
4807          * @example
4808          * 	var p1 = board.create('point', [-2, 1], {id: 'A'});
4809          * 	var p2 = board.create('point', [-0.85, 1], {
4810          *      name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}
4811          *  });
4812          * 	var p3 = board.create('point', [-1, 1.2], {
4813          *      name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}
4814          *  });
4815          *  var c = board.create('circle', [p1, p2]);
4816          * 	var l = board.create('line', [p1, p2]);
4817          *
4818          * </pre><div id="JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2" class="jxgbox" style="width: 300px; height: 300px;"></div>
4819          * <script type="text/javascript">
4820          *     (function() {
4821          *         var board = JXG.JSXGraph.initBoard('JXG7d4dafe7-1a07-4d3f-95cb-bfed9d96dea2',
4822          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
4823          *     	var p1 = board.create('point', [-2, 1], {id: 'A'});
4824          *     	var p2 = board.create('point', [-0.85, 1], {name: 'B', id: 'B', label:{autoPosition: true, offset:[10, 10]}});
4825          *     	var p3 = board.create('point', [-1, 1.2], {name: 'C', id: 'C', label:{autoPosition: true, offset:[10, 10]}});
4826          *      var c = board.create('circle', [p1, p2]);
4827          *     	var l = board.create('line', [p1, p2]);
4828          *
4829          *     })();
4830          *
4831          * </script><pre>
4832          *
4833          *
4834          */
4835         autoPosition: false,
4836 
4837         /**
4838          * The auto position algorithm tries to put a label to a conflict-free
4839          * position around it's anchor element. For this, the algorithm tests 12 positions
4840          * around the anchor element starting at a distance from the anchor
4841          * defined here (in pixel).
4842          *
4843          * @name Label#autoPositionMinDistance
4844          * @see Label#autoPosition
4845          * @see Label#autoPositionMaxDistance
4846          * @type Number
4847          * @default 12
4848          *
4849          */
4850         autoPositionMinDistance: 12,
4851 
4852         /**
4853          * The auto position algorithm tries to put a label to a conflict-free
4854          * position around it's anchor element. For this, the algorithm tests 12 positions
4855          * around the anchor element up to a distance from the anchor
4856          * defined here (in pixel).
4857          *
4858          * @name Label#autoPositionMaxDistance
4859          * @see Label#autoPosition
4860          * @see Label#autoPositionMinDistance
4861          * @type Number
4862          * @default 28
4863          *
4864          */
4865         autoPositionMaxDistance: 28
4866 
4867         /**#@-*/
4868     },
4869 
4870     /* special legend options */
4871     legend: {
4872         /**
4873          * @visprop
4874          */
4875 
4876         /**
4877          * Default style of a legend element. The only possible value is 'vertical'.
4878          * @name Legend#style
4879          * @type String
4880          * @default 'vertical'
4881          */
4882         style: 'vertical',
4883 
4884         /**
4885          * Label names of a legend element.
4886          * @name Legend#labels
4887          * @type Array
4888          * @default "['1', '2', '3', '4', '5', '6', '7', '8']"
4889          */
4890         labels: ['1', '2', '3', '4', '5', '6', '7', '8'],
4891 
4892         /**
4893          * (Circular) array of label colors.
4894          * @name Legend#colors
4895          * @type Array
4896          * @default "['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00']"
4897          */
4898         colors: ['#B02B2C', '#3F4C6B', '#C79810', '#D15600', '#FFFF88', '#c3d9ff', '#4096EE', '#008C00'],
4899 
4900         /**
4901          * Height (in px) of one legend entry
4902          * @name Legend#rowHeight
4903          * @type Number
4904          * @default 20
4905          *
4906          */
4907         rowHeight: 20,
4908 
4909         strokeWidth: 5
4910 
4911         /**#@-*/
4912     },
4913 
4914     /* special line options */
4915     line: {
4916         /**#@+
4917          * @visprop
4918          */
4919 
4920         /**
4921          * Configure the arrow head at the position of its first point or the corresponding
4922          * intersection with the canvas border
4923          *
4924          * In case firstArrow is an object it has the sub-attributes:
4925          * <pre>
4926          * {
4927          *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.
4928          *      size: 6, // size of the arrow head. Default value is 6.
4929          *               // This value is multiplied with the strokeWidth of the line
4930          *               // Exception: for type=7 size is ignored
4931          *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value
4932          * }
4933          * </pre>
4934          * type=7 is the default for curves if firstArrow: true
4935          *
4936          * @example
4937          *     board.options.line.lastArrow = false;
4938          *     board.options.line.firstArrow = {size: 10, highlightSize: 10};
4939          *     board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};
4940          *     board.options.line.strokeWidth = 4;
4941          *     board.options.line.highlightStrokeWidth = 4;
4942          *
4943          *     board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});
4944          *     board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});
4945          *     board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});
4946          *     board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});
4947          *     board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});
4948          *     board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});
4949          *     board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});
4950          *
4951          * </pre><div id="JXGc94a93da-c942-4204-8bb6-b39726cbb09b" class="jxgbox" style="width: 300px; height: 300px;"></div>
4952          * <script type="text/javascript">
4953          *     (function() {
4954          *         var board = JXG.JSXGraph.initBoard('JXGc94a93da-c942-4204-8bb6-b39726cbb09b',
4955          *             {boundingbox: [-6, 6, 4,-4], axis: false, showcopyright: false, shownavigation: false});
4956          *         board.options.line.lastArrow = false;
4957          *         board.options.line.firstArrow = {size: 10, highlightSize: 10};
4958          *         board.options.line.point1 = {visible: false, withLabel: true, label: {visible: true, anchorX: 'right'}};
4959          *         board.options.line.strokeWidth = 4;
4960          *         board.options.line.highlightStrokeWidth = 4;
4961          *
4962          *         board.create('segment', [[-5,4], [3,4]], {firstArrow: {type: 1}, point1: {name: 'type:1'}});
4963          *         board.create('segment', [[-5,3], [3,3]], {firstArrow: {type: 2}, point1: {name: 'type:2'}});
4964          *         board.create('segment', [[-5,2], [3,2]], {firstArrow: {type: 3}, point1: {name: 'type:3'}});
4965          *         board.create('segment', [[-5,1], [3,1]], {firstArrow: {type: 4}, point1: {name: 'type:4'}});
4966          *         board.create('segment', [[-5,0], [3,0]], {firstArrow: {type: 5}, point1: {name: 'type:5'}});
4967          *         board.create('segment', [[-5,-1], [3,-1]], {firstArrow: {type: 6}, point1: {name: 'type:6'}});
4968          *         board.create('segment', [[-5,-2], [3,-2]], {firstArrow: {type: 7}, point1: {name: 'type:7'}});
4969          *
4970          *     })();
4971          *
4972          * </script><pre>
4973          *
4974          * @name Line#firstArrow
4975          * @see Line#lastArrow
4976          * @see Line#touchFirstPoint
4977          * @type Boolean / Object
4978          * @default false
4979          */
4980         firstArrow: false,
4981 
4982         /**
4983          * Configure the arrow head at the position of its second point or the corresponding
4984          * intersection with the canvas border.
4985          *
4986          * In case lastArrow is an object it has the sub-attributes:
4987          * <pre>
4988          * {
4989          *      type: 1, // possible values are 1, 2, ..., 7. Default value is 1.
4990          *      size: 6, // size of the arrow head. Default value is 6.
4991          *               // This value is multiplied with the strokeWidth of the line.
4992          *               // Exception: for type=7 size is ignored
4993          *      highlightSize: 6, // size of the arrow head in case the element is highlighted. Default value is 6.
4994          * }
4995          * </pre>
4996          * type=7 is the default for curves if lastArrow: true
4997          *
4998          * @example
4999          *     var p1 = board.create('point', [-5, 2], {size:1});
5000          *     var p2 = board.create('point', [5, 2], {size:10});
5001          *     var li = board.create('segment', ['A','B'],
5002          *         {name:'seg',
5003          *          strokeColor:'#000000',
5004          *          strokeWidth:1,
5005          *          highlightStrokeWidth: 5,
5006          *          lastArrow: {type: 2, size: 8, highlightSize: 6},
5007          *          touchLastPoint: true,
5008          *          firstArrow: {type: 3, size: 8}
5009          *         });
5010          *
5011          * </pre><div id="JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3" class="jxgbox" style="width: 300px; height: 300px;"></div>
5012          * <script type="text/javascript">
5013          *     (function() {
5014          *         var board = JXG.JSXGraph.initBoard('JXG184e915c-c2ef-11e8-bece-04d3b0c2aad3',
5015          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
5016          *         var p1 = board.create('point', [-5, 2], {size:1});
5017          *         var p2 = board.create('point', [5, 2], {size:10});
5018          *         var li = board.create('segment', ['A','B'],
5019          *             {name:'seg',
5020          *              strokeColor:'#000000',
5021          *              strokeWidth:1,
5022          *              highlightStrokeWidth: 5,
5023          *              lastArrow: {type: 2, size: 8, highlightSize: 6},
5024          *              touchLastPoint: true,
5025          *              firstArrow: {type: 3, size: 8}
5026          *             });
5027          *     })();
5028          *
5029          * </script>
5030          *
5031          * @example
5032          *     board.options.line.strokeWidth = 4;
5033          *     board.options.line.highlightStrokeWidth = 4;
5034          *     board.options.line.firstArrow = false;
5035          *     board.options.line.lastArrow = {size: 10, highlightSize: 10};
5036          *     board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};
5037          *
5038          *     board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});
5039          *     board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});
5040          *     board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});
5041          *     board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});
5042          *     board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});
5043          *     board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});
5044          *     board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});
5045          *
5046          * </pre><div id="JXGca206b1c-e319-4899-8b90-778f53fd926d" class="jxgbox" style="width: 300px; height: 300px;"></div>
5047          * <script type="text/javascript">
5048          *     (function() {
5049          *         var board = JXG.JSXGraph.initBoard('JXGca206b1c-e319-4899-8b90-778f53fd926d',
5050          *             {boundingbox: [-6, 6, 6,-4], axis: false, showcopyright: false, shownavigation: false});
5051          *         board.options.line.strokeWidth = 4;
5052          *         board.options.line.highlightStrokeWidth = 4;
5053          *         board.options.line.firstArrow = false;
5054          *         board.options.line.lastArrow = {size: 10, highlightSize: 10};
5055          *         board.options.line.point2 = {visible: false, withLabel: true, label: {visible: true}};
5056          *
5057          *         board.create('segment', [[-5,4], [3,4]], {lastArrow: {type: 1}, point2: {name: 'type:1'}});
5058          *         board.create('segment', [[-5,3], [3,3]], {lastArrow: {type: 2}, point2: {name: 'type:2'}});
5059          *         board.create('segment', [[-5,2], [3,2]], {lastArrow: {type: 3}, point2: {name: 'type:3'}});
5060          *         board.create('segment', [[-5,1], [3,1]], {lastArrow: {type: 4}, point2: {name: 'type:4'}});
5061          *         board.create('segment', [[-5,0], [3,0]], {lastArrow: {type: 5}, point2: {name: 'type:5'}});
5062          *         board.create('segment', [[-5,-1], [3,-1]], {lastArrow: {type: 6}, point2: {name: 'type:6'}});
5063          *         board.create('segment', [[-5,-2], [3,-2]], {lastArrow: {type: 7}, point2: {name: 'type:7'}});
5064          *     })();
5065          *
5066          * </script><pre>
5067          *
5068          * @name Line#lastArrow
5069          * @see Line#firstArrow
5070          * @see Line#touchLastPoint
5071          * @type Boolean / Object
5072          * @default false
5073          */
5074         lastArrow: false,
5075 
5076         /**
5077          * This number (pixel value) controls where infinite lines end at the canvas border. If zero, the line
5078          * ends exactly at the border, if negative there is a margin to the inside, if positive the line
5079          * ends outside of the canvas (which is invisible).
5080          *
5081          * @name Line#margin
5082          * @type Number
5083          * @default 0
5084          */
5085         margin: 0,
5086 
5087         /**
5088          * If true, line stretches infinitely in direction of its first point.
5089          * Otherwise it ends at point1.
5090          *
5091          * @name Line#straightFirst
5092          * @see Line#straightLast
5093          * @type Boolean
5094          * @default true
5095          */
5096         straightFirst: true,
5097 
5098         /**
5099          * If true, line stretches infinitely in direction of its second point.
5100          * Otherwise it ends at point2.
5101          *
5102          * @name Line#straightLast
5103          * @see Line#straightFirst
5104          * @type Boolean
5105          * @default true
5106          */
5107         straightLast: true,
5108 
5109         fillColor: 'none',           // Important for VML on IE
5110         highlightFillColor: 'none',  // Important for VML on IE
5111         strokeColor: Color.palette.blue,
5112         highlightStrokeColor: '#c3d9ff',
5113         withTicks: false,
5114 
5115         /**
5116          * Attributes for first defining point of the line.
5117          *
5118          * @type Point
5119          * @name Line#point1
5120          */
5121         point1: {                  // Default values for point1 if created by line
5122             fillColor: Color.palette.red,
5123             strokeColor: Color.palette.red,
5124             highlightFillColor: '#c3d9ff',
5125             highlightStrokeColor: '#c3d9ff',
5126             layer: 9,
5127 
5128             visible: false,
5129             withLabel: false,
5130             fixed: false,
5131             name: ''
5132         },
5133 
5134         /**
5135          * Attributes for second defining point of the line.
5136          *
5137          * @type Point
5138          * @name Line#point2
5139          */
5140         point2: {                  // Default values for point2 if created by line
5141             fillColor: Color.palette.red,
5142             strokeColor: Color.palette.red,
5143             highlightFillColor: '#c3d9ff',
5144             highlightStrokeColor: '#c3d9ff',
5145             layer: 9,
5146 
5147             visible: false,
5148             withLabel: false,
5149             fixed: false,
5150             name: ''
5151         },
5152 
5153         /**
5154          * Attributes for ticks of the line.
5155          *
5156          * @name Line#ticks
5157          * @type Object
5158          * @see Ticks
5159          */
5160         ticks: {
5161             drawLabels: true,
5162             label: {
5163                 offset: [4, -12 + 3] // This seems to be a good offset for 12 point fonts
5164             },
5165             drawZero: false,
5166             insertTicks: false,
5167             ticksDistance: 1,
5168             minTicksDistance: 50,
5169             minorHeight: 4,          // if <0: full width and height
5170             majorHeight: -1,         // if <0: full width and height
5171             minorTicks: 4,
5172             strokeOpacity: 0.3,
5173             visible: 'inherit'
5174         },
5175 
5176         /**
5177          * Attributes for the line label.
5178          *
5179          * @type Object
5180          * @name Line#label
5181          * @see Label
5182          */
5183         label: {
5184             position: 'llft'
5185         },
5186 
5187         /**
5188          * If set to true, the point will snap to a grid defined by
5189          * {@link Point#snapSizeX} and {@link Point#snapSizeY}.
5190          *
5191          * @see Point#snapSizeX
5192          * @see Point#snapSizeY
5193          * @type Boolean
5194          * @name Line#snapToGrid
5195          * @default false
5196          */
5197         snapToGrid: false,
5198 
5199         /**
5200          * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.
5201          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
5202          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5203          * of the default ticks of the default x axes of the board.
5204          *
5205          * @see Point#snapToGrid
5206          * @see Point#snapSizeY
5207          * @see JXG.Board#defaultAxes
5208          * @type Number
5209          * @name Line#snapSizeX
5210          * @default 1
5211          */
5212         snapSizeX: 1,
5213 
5214         /**
5215          * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.
5216          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
5217          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5218          * of the default ticks of the default y axes of the board.
5219          *
5220          * @see Point#snapToGrid
5221          * @see Point#snapSizeX
5222          * @see JXG.Board#defaultAxes
5223          * @type Number
5224          * @name Line#snapSizeY
5225          * @default 1
5226          */
5227         snapSizeY: 1,
5228 
5229         /**
5230          * If set to true, {@link Line#firstArrow} is set to true and the point is visible,
5231          * the arrow head will just touch the circle line of the start point of the line.
5232          *
5233          * @see Line#firstArrow
5234          * @type Boolean
5235          * @name Line#touchFirstPoint
5236          * @default false
5237          */
5238         touchFirstPoint: false,
5239 
5240         /**
5241          * If set to true, {@link Line#lastArrow} is set to true and the point is visible,
5242          * the arrow head will just touch the circle line of the start point of the line.
5243          * @see Line#firstArrow
5244          * @type Boolean
5245          * @name Line#touchLastPoint
5246          * @default false
5247          */
5248         touchLastPoint: false,
5249 
5250         /**#@-*/
5251     },
5252 
5253     /* special options for locus curves */
5254     locus: {
5255         /**#@+
5256          * @visprop
5257          */
5258 
5259         translateToOrigin: false,
5260         translateTo10: false,
5261         stretch: false,
5262         toOrigin: null,
5263         to10: null
5264         /**#@-*/
5265     },
5266 
5267     /* special cardinal spline options */
5268     metapostspline: {
5269         /**#@+
5270          * @visprop
5271          */
5272 
5273         /**
5274           * Controls if the data points of the cardinal spline when given as
5275           * arrays should be converted into {@link JXG.Points}.
5276           *
5277           * @name createPoints
5278           * @memberOf Metapostspline.prototype
5279           *
5280           * @see Metapostspline#points
5281           *
5282           * @type Boolean
5283           * @default true
5284           */
5285         createPoints: true,
5286 
5287         /**
5288          * If set to true, the supplied coordinates are interpreted as
5289          * [[x_0, y_0], [x_1, y_1], p, ...].
5290          * Otherwise, if the data consists of two arrays of equal length,
5291          * it is interpreted as
5292          * [[x_o x_1, ..., x_n], [y_0, y_1, ..., y_n]]
5293          *
5294          * @name isArrayOfCoordinates
5295          * @memberOf Metapostspline.prototype
5296          * @type Boolean
5297          * @default true
5298          */
5299         isArrayOfCoordinates: true,
5300 
5301         /**
5302          * Attributes for the points generated by Metapost spline in cases
5303          * {@link createPoints} is set to true
5304          *
5305          * @name points
5306          * @memberOf Metapostspline.prototype
5307          *
5308          * @see Metapostspline#createPoints
5309          * @type Object
5310          */
5311         points: {
5312             strokeOpacity: 0.5,
5313             fillOpacity: 0.5,
5314             highlightStrokeOpacity: 1.0,
5315             highlightFillOpacity: 1.0,
5316             withLabel: false,
5317             name: '',
5318             fixed: false
5319         }
5320 
5321         /**#@-*/
5322     },
5323 
5324     /* special mirrorelement options */
5325     mirrorelement: {
5326         /**#@+
5327          * @visprop
5328          */
5329 
5330         fixed: true,
5331 
5332         /**
5333          * Attributes of mirror point, i.e. the point along which the element is mirrored.
5334          *
5335          * @type Point
5336          * @name mirrorelement#point
5337          */
5338         point: {},
5339 
5340         /**
5341          * Attributes of circle center, i.e. the center of the circle,
5342          * if a circle is the mirror element and the transformation type is 'Euclidean'
5343          *
5344          * @type Point
5345          * @name mirrorelement#center
5346          */
5347         center: {},
5348 
5349         /**
5350          * Type of transformation. Possible values are 'Euclidean', 'projective'.
5351          *
5352          * If the value is 'Euclidean', the mirror element of a circle is again a circle,
5353          * otherwise it is a conic section.
5354          *
5355          * @type String
5356          * @name mirrorelement#type
5357          * @default 'Euclidean'
5358          */
5359         type: 'Euclidean'
5360 
5361         /**#@-*/
5362     },
5363 
5364     /* special nonreflexangle options */
5365     nonreflexangle: {
5366         /**#@+
5367          * @visprop
5368          */
5369 
5370         /**#@-*/
5371     },
5372 
5373     // /* special options for Msector of 3 points */
5374     // msector: {
5375     //     strokeColor: '#000000', // Msector line
5376     //     point: {               // Msector point
5377     //         visible: false,
5378     //         fixed: false,
5379     //         withLabel: false,
5380     //         name: ''
5381     //     }
5382     // },
5383 
5384     /* special options for normal lines */
5385     normal: {
5386         /**#@+
5387          * @visprop
5388          */
5389 
5390         strokeColor: '#000000', //  normal line
5391 
5392         /**
5393          * Attributes of helper point of normal.
5394          *
5395          * @type Point
5396          * @name Normal#point
5397          */
5398         point: {
5399             visible: false,
5400             fixed: false,
5401             withLabel: false,
5402             name: ''
5403         }
5404         /**#@-*/
5405     },
5406 
5407     /* special options for orthogonal projection points */
5408     orthogonalprojection: {
5409         /**#@+
5410          * @visprop
5411          */
5412 
5413 
5414         /**#@-*/
5415     },
5416 
5417     /* special options for parallel lines */
5418     parallel: {
5419         /**#@+
5420          * @visprop
5421          */
5422 
5423         strokeColor: '#000000', // Parallel line
5424 
5425         /**
5426          * Attributes of helper point of normal.
5427          *
5428          * @type Point
5429          * @name Parallel#point
5430          */
5431         point: {
5432             visible: false,
5433             fixed: false,
5434             withLabel: false,
5435             name: ''
5436         },
5437 
5438         label: {
5439             position: 'llft'
5440         }
5441         /**#@-*/
5442     },
5443 
5444     /* special parallelpoint options */
5445     parallelpoint: {
5446     },
5447 
5448     /* special perpendicular options */
5449     perpendicular: {
5450         /**#@+
5451          * @visprop
5452          */
5453 
5454         strokeColor: '#000000', // Perpendicular line
5455         straightFirst: true,
5456         straightLast: true
5457         /**#@-*/
5458     },
5459 
5460     /* special perpendicular options */
5461     perpendicularsegment: {
5462         /**#@+
5463          * @visprop
5464          */
5465 
5466         strokeColor: '#000000', // Perpendicular segment
5467         straightFirst: false,
5468         straightLast: false,
5469         point: {               // Perpendicular point
5470             visible: false,
5471             fixed: true,
5472             withLabel: false,
5473             name: ''
5474         }
5475         /**#@-*/
5476     },
5477 
5478     /* special point options */
5479     point: {
5480         /**#@+
5481          * @visprop
5482          */
5483 
5484         withLabel: true,
5485         label: {},
5486 
5487         /**
5488          * This attribute was used to determined the point layout. It was derived from GEONExT and was
5489          * replaced by {@link Point#face} and {@link Point#size}.
5490          *
5491          * @name Point#style
5492          *
5493          * @see Point#face
5494          * @see Point#size
5495          * @type Number
5496          * @default 5
5497          * @deprecated
5498          */
5499         style: 5,
5500 
5501         /**
5502          * There are different point styles which differ in appearance.
5503          * Posssible values are
5504          * <table><tr><th>Value</th></tr>
5505          * <tr><th>Input</th><th>Output</th></tr>
5506          * <tr><td>cross</td><td>x</td></tr>
5507          * <tr><td>circle</td><td>o</td></tr>
5508          * <tr><td>square, []</td><td>[]</td></tr>
5509          * <tr><td>plus</td><td>+</td></tr>
5510          * <tr><td>minus</td><td>-</td></tr>
5511          * <tr><td>divide</td><td>|</td></tr>
5512          * <tr><td>diamond</td><td><></td></tr>
5513          * <tr><td>triangleup</td><td>^, a, A</td></tr>
5514          * <tr><td>triangledown</td><td>v</td></tr>
5515          * <tr><td>triangleleft</td><td><</td></tr>
5516          * <tr><td>triangleright</td><td>></td></tr>
5517          * </table>
5518          *
5519          * @name Point#face
5520          *
5521          * @type String
5522          * @see JXG.Point#setStyle
5523          * @default circle
5524          */
5525         face: 'o',
5526 
5527         /**
5528          * Size of a point, either in pixel or user coordinates.
5529          * Means radius resp. half the width of a point (depending on the face).
5530          *
5531          * @name Point#size
5532          *
5533          * @see Point#face
5534          * @see JXG.Point#setStyle
5535          * @see Point#sizeUnit
5536          * @type Number
5537          * @default 3
5538          */
5539         size: 3,
5540 
5541         /**
5542          * Unit for size.
5543          * Possible values are 'screen' and 'user.
5544          *
5545          * @name Point#sizeUnit
5546          *
5547          * @see Point#size
5548          * @type String
5549          * @default 'screen'
5550          */
5551         sizeUnit: 'screen',
5552 
5553         strokeWidth: 2,
5554 
5555         transitionProperties: ['fill', 'fill-opacity', 'stroke', 'stroke-opacity', 'stroke-width', 'width', 'height', 'rx', 'ry'],
5556         fillColor: Color.palette.red,
5557         strokeColor: Color.palette.red,
5558         highlightFillColor: '#c3d9ff',
5559         highlightStrokeColor: '#c3d9ff',
5560         // strokeOpacity: 1.0,
5561         // fillOpacity: 1.0,
5562         // highlightFillOpacity: 0.5,
5563         // highlightStrokeOpacity: 0.5,
5564 
5565         // fillColor: '#ff0000',
5566         // highlightFillColor: '#eeeeee',
5567         // strokeWidth: 2,
5568         // strokeColor: '#ff0000',
5569         // highlightStrokeColor: '#c3d9ff',
5570 
5571         /**
5572          * If true, the point size changes on zoom events.
5573          *
5574          * @type Boolean
5575          * @name Point#zoom
5576          * @default false
5577          *
5578          */
5579         zoom: false,             // Change the point size on zoom
5580 
5581         /**
5582          * If true, the infobox is shown on mouse/pen over, if false not.
5583          * If the value is 'inherit', the value of
5584          * {@link JXG.Board#showInfobox} is taken.
5585          *
5586          * @name Point#showInfobox
5587          * @see JXG.Board#showInfobox
5588          * @type {Boolean|String} true | false | 'inherit'
5589          * @default true
5590          */
5591         showInfobox: 'inherit',
5592 
5593         /**
5594          * Truncating rule for the digits in the infobox.
5595          * <ul>
5596          * <li>'auto': done automatically by JXG.autoDigits()
5597          * <li>'none': no truncation
5598          * <li>number: truncate after "number digits" with JXG.toFixed()
5599          * </ul>
5600          *
5601          * @name Point#infoboxDigits
5602          *
5603          * @type String, Number
5604          * @default 'auto'
5605          * @see JXG#autoDigits
5606          * @see JXG#toFixed
5607          */
5608         infoboxDigits: 'auto',
5609 
5610         draft: false,
5611 
5612         /**
5613          * List of attractor elements. If the distance of the point is less than
5614          * attractorDistance the point is made to glider of this element.
5615          *
5616          * @name Point#attractors
5617          *
5618          * @type Array
5619          * @default empty
5620          */
5621         attractors: [],
5622 
5623         /**
5624          * Unit for attractorDistance and snatchDistance, used for magnetized points and for snapToPoints.
5625          * Possible values are 'screen' and 'user'.
5626          *
5627          * @name Point#attractorUnit
5628          *
5629          * @see Point#attractorDistance
5630          * @see Point#snatchDistance
5631          * @see Point#snapToPoints
5632          * @see Point#attractors
5633          * @type String
5634          * @default 'user'
5635          */
5636         attractorUnit: 'user',    // 'screen', 'user'
5637 
5638         /**
5639          * If the distance of the point to one of its attractors is less
5640          * than this number the point will be a glider on this
5641          * attracting element.
5642          * If set to zero nothing happens.
5643          *
5644          * @name Point#attractorDistance
5645          *
5646          * @type Number
5647          * @default 0.0
5648          */
5649         attractorDistance: 0.0,
5650 
5651         /**
5652          * If the distance of the point to one of its attractors is at least
5653          * this number the point will be released from being a glider on the
5654          * attracting element.
5655          * If set to zero nothing happens.
5656          *
5657          * @name Point#snatchDistance
5658          *
5659          * @type Number
5660          * @default 0.0
5661          */
5662         snatchDistance: 0.0,
5663 
5664         /**
5665          * If set to true, the point will snap to a grid of integer multiples of
5666          * {@link Point#snapSizeX} and {@link Point#snapSizeY} (in user coordinates).
5667          * <p>
5668          * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY
5669          * (given in user coordinates, not pixels) or are the intersection points
5670          * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.
5671          *
5672          * @name Point#snapToGrid
5673          *
5674          * @see Point#snapSizeX
5675          * @see Point#snapSizeY
5676          * @type Boolean
5677          * @default false
5678          */
5679         snapToGrid: false,
5680 
5681         /**
5682          * If set to true, the point will only snap to (possibly invisibly) grid points
5683          * when within {@link Point#attractorDistance} of such a grid point.
5684          * <p>
5685          * The coordinates of the grid points are either integer multiples of snapSizeX and snapSizeY
5686          * (given in user coordinates, not pixels) or are the intersection points
5687          * of the major ticks of the boards default axes in case that snapSizeX, snapSizeY are negative.
5688          *
5689          * @name Point#attractToGrid
5690          *
5691          * @see Point#attractorDistance
5692          * @see Point#attractorUnit
5693          * @see Point#snapToGrid
5694          * @see Point#snapSizeX
5695          * @see Point#snapSizeY
5696          * @type Boolean
5697          * @default false
5698          *
5699          * @example
5700          * board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });
5701          *
5702          * </pre><div id="JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6" class="jxgbox" style="width: 300px; height: 300px;"></div>
5703          * <script type="text/javascript">
5704          *     (function() {
5705          *         var board = JXG.JSXGraph.initBoard('JXG397ab787-cd40-449c-a7e7-a3f7bab1d4f6',
5706          *             {boundingbox: [-1, 4, 7,-4], axis: true, showcopyright: false, shownavigation: false});
5707          *     board.create('point', [3, 3], { attractToGrid: true, attractorDistance: 10, attractorunit: 'screen' });
5708          *
5709          *     })();
5710          *
5711          * </script><pre>
5712          *
5713          */
5714         attractToGrid: false,
5715 
5716         /**
5717          * Defines together with {@link Point#snapSizeY} the grid the point snaps on to.
5718          * It is given in user coordinates, not in pixels.
5719          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
5720          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5721          * of the default ticks of the default x axes of the board.
5722          *
5723          * @name Point#snapSizeX
5724          *
5725          * @see Point#snapToGrid
5726          * @see Point#snapSizeY
5727          * @see JXG.Board#defaultAxes
5728          * @type Number
5729          * @default 1
5730          */
5731         snapSizeX: 1,
5732 
5733         /**
5734          * Defines together with {@link Point#snapSizeX} the grid the point snaps on to.
5735          * It is given in user coordinates, not in pixels.
5736          * The point will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
5737          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
5738          * of the default ticks of the default y axes of the board.
5739          *
5740          * @name Point#snapSizeY
5741          *
5742          * @see Point#snapToGrid
5743          * @see Point#snapSizeX
5744          * @see JXG.Board#defaultAxes
5745          * @type Number
5746          * @default 1
5747          */
5748         snapSizeY: 1,
5749 
5750         /**
5751          * If set to true, the point will snap to the nearest point in distance of
5752          * {@link Point#attractorDistance}.
5753          *
5754          * @name Point#snapToPoints
5755          *
5756          * @see Point#attractorDistance
5757          * @type Boolean
5758          * @default false
5759          */
5760         snapToPoints: false,
5761 
5762         /**
5763          * List of elements which are ignored by snapToPoints.
5764          * @name Point#ignoredSnapToPoints
5765          *
5766          * @type Array
5767          * @default empty
5768          */
5769         ignoredSnapToPoints: []
5770 
5771         /**#@-*/
5772     },
5773 
5774     /* special polygon options */
5775     polygon: {
5776         /**#@+
5777          * @visprop
5778          */
5779 
5780         /**
5781          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
5782          *
5783          * @see JXG.GeometryElement#hasPoint
5784          * @name Polygon#hasInnerPoints
5785          * @type Boolean
5786          * @default false
5787          */
5788         hasInnerPoints: false,
5789 
5790         fillColor: Color.palette.yellow,
5791         highlightFillColor: Color.palette.yellow,
5792         // fillColor: '#00ff00',
5793         // highlightFillColor: '#00ff00',
5794         fillOpacity: 0.3,
5795         highlightFillOpacity: 0.2,
5796 
5797         /**
5798          * Is the polygon bordered by lines?
5799          *
5800          * @type Boolean
5801          * @name Polygon#withLines
5802          * @default true
5803          */
5804         withLines: true,
5805 
5806         /**
5807          * Attributes for the polygon border lines.
5808          *
5809          * @type Line
5810          * @name Polygon#borders
5811          */
5812         borders: {
5813             withLabel: false,
5814             strokeWidth: 1,
5815             highlightStrokeWidth: 1,
5816             // Polygon layer + 1
5817             layer: 5,
5818             label: {
5819                 position: 'top'
5820             },
5821             visible: 'inherit'
5822         },
5823 
5824         /**
5825          * By default, the strokewidths of the borders of a polygon are not changed during highlighting (only strokeColor and strokeOpacity are changed
5826          * to highlightStrokeColor, and highlightStrokeOpacity).
5827          * However, strokewidth is changed to highlightStrokewidth if an individual border gets the focus.
5828          * <p>
5829          * With this attribute set to true, also the borders change strokeWidth if the polygon itself gets the focus.
5830          *
5831          * @type Boolean
5832          * @name Polygon#highlightByStrokeWidth
5833          * @default false
5834          */
5835         highlightByStrokeWidth: false,
5836 
5837         /**
5838          * Attributes for the polygon vertices.
5839          *
5840          * @type Point
5841          * @name Polygon#vertices
5842          */
5843         vertices: {
5844             layer: 9,
5845             withLabel: false,
5846             name: '',
5847             strokeColor: Color.palette.red,
5848             fillColor: Color.palette.red,
5849             fixed: false,
5850             visible: 'inherit'
5851         },
5852 
5853         /**
5854          * Attributes for the polygon label.
5855          *
5856          * @type Label
5857          * @name Polygon#label
5858          */
5859         label: {
5860             offset: [0, 0]
5861         }
5862 
5863         /**#@-*/
5864     },
5865 
5866     /* special polygonal chain options
5867     */
5868     polygonalchain: {
5869         /**#@+
5870          * @visprop
5871          */
5872 
5873         fillColor: 'none',
5874         highlightFillColor: 'none'
5875 
5876         /**#@-*/
5877     },
5878 
5879     /* special prescribed angle options
5880     * Not yet implemented. But angle.setAngle(val) is implemented.
5881     */
5882     prescribedangle: {
5883         /**#@+
5884          * @visprop
5885          */
5886 
5887         /**
5888          * Attributes for the helper point of the prescribed angle.
5889          *
5890          * @type Point
5891          * @name PrescribedAngle#anglePoint
5892          */
5893         anglePoint: {
5894             size: 2,
5895             visible: false,
5896             withLabel: false
5897         }
5898 
5899         /**#@-*/
5900     },
5901 
5902     /* special reflection options */
5903     reflection: {
5904         /**#@+
5905          * @visprop
5906          */
5907 
5908         fixed: true,
5909 
5910         /**
5911          * Attributes of circle center, i.e. the center of the circle,
5912          * if a circle is the mirror element and the transformation type is 'Euclidean'
5913          *
5914          * @type Point
5915          * @name Mirrorelement#center
5916          */
5917         center: {},
5918 
5919         /**
5920          * Type of transformation. Possible values are 'Euclidean', 'projective'.
5921          *
5922          * If the value is 'Euclidean', the reflected element of a circle is again a circle,
5923          * otherwise it is a conic section.
5924          *
5925          * @type String
5926          * @name Reflection#type
5927          * @default 'Euclidean'
5928          */
5929         type: 'Euclidean'
5930 
5931         /**#@-*/
5932     },
5933 
5934     /* special reflexangle options */
5935     reflexangle: {
5936         /**#@+
5937          * @visprop
5938          */
5939 
5940         /**#@-*/
5941     },
5942 
5943     /* special regular polygon options */
5944     regularpolygon: {
5945         /**#@+
5946          * @visprop
5947          */
5948 
5949         /**
5950          * If <tt>true</tt>, moving the mouse over inner points triggers hasPoint.
5951          * @see JXG.GeometryElement#hasPoint
5952          *
5953          * @name RegularPolygon#hasInnerPoints
5954          * @type Boolean
5955          * @default false
5956          */
5957         hasInnerPoints: false,
5958         fillColor: Color.palette.yellow,
5959         highlightFillColor: Color.palette.yellow,
5960         fillOpacity: 0.3,
5961         highlightFillOpacity: 0.2,
5962 
5963         /**
5964          * Is the polygon bordered by lines?
5965          *
5966          * @type Boolean
5967          * @name RegularPolygon#withLines
5968          * @default true
5969          */
5970         withLines: true,
5971 
5972         /**
5973          * Attributes for the polygon border lines.
5974          *
5975          * @type Line
5976          * @name RegularPolygon#borders
5977          */
5978         borders: {
5979             withLabel: false,
5980             strokeWidth: 1,
5981             highlightStrokeWidth: 1,
5982             // Polygon layer + 1
5983             layer: 5,
5984             label: {
5985                 position: 'top'
5986             }
5987         },
5988 
5989         /**
5990          * Attributes for the polygon vertices.
5991          *
5992          * @type Point
5993          * @name RegularPolygon#vertices
5994          */
5995         vertices: {
5996             layer: 9,
5997             withLabel: true,
5998             strokeColor: Color.palette.red,
5999             fillColor: Color.palette.red,
6000             fixed: false
6001         },
6002 
6003         /**
6004          * Attributes for the polygon label.
6005          *
6006          * @type Label
6007          * @name Polygon#label
6008          */
6009         label: {
6010             offset: [0, 0]
6011         }
6012 
6013         /**#@-*/
6014     },
6015 
6016     /* special options for riemann sums */
6017     riemannsum: {
6018         /**#@+
6019          * @visprop
6020          */
6021 
6022         withLabel: false,
6023         fillOpacity: 0.3,
6024         fillColor: Color.palette.yellow
6025 
6026         /**#@-*/
6027     },
6028 
6029     /* special sector options */
6030     sector: {
6031         /**#@+
6032          * @visprop
6033          */
6034 
6035         fillColor: Color.palette.yellow,
6036         highlightFillColor: Color.palette.yellow,
6037         // fillColor: '#00ff00',
6038         // highlightFillColor: '#00ff00',
6039 
6040         fillOpacity: 0.3,
6041         highlightFillOpacity: 0.3,
6042         highlightOnSector: false,
6043         highlightStrokeWidth: 0,
6044 
6045         /**
6046          * Type of sector. Possible values are 'minor', 'major', and 'auto'.
6047          *
6048          * @type String
6049          * @name Sector#selection
6050          * @default 'auto'
6051          */
6052         selection: 'auto',
6053 
6054         /**
6055          * Attributes for sub-element arc. It is only available, if the sector is defined by three points.
6056          *
6057          * @type Arc
6058          * @name Sector#arc
6059          * @default '{visible:false}'
6060          */
6061         arc: {
6062             visible: false,
6063             fillColor: 'none'
6064         },
6065 
6066         /**
6067          * Attributes for helper point radiuspoint in case it is provided by coordinates.
6068          *
6069          * @type Point
6070          * @name Sector#radiusPoint
6071          */
6072         radiusPoint: {
6073             visible: false,
6074             withLabel: false
6075         },
6076 
6077         /**
6078          * Attributes for helper point center in case it is provided by coordinates.
6079          *
6080          * @type Point
6081          * @name Sector#center
6082          */
6083         center: {
6084             visible: false,
6085             withLabel: false
6086         },
6087 
6088         /**
6089          * Attributes for helper point anglepoint in case it is provided by coordinates.
6090          *
6091          * @type Point
6092          * @name Sector#anglePoint
6093          */
6094         anglePoint: {
6095             visible: false,
6096             withLabel: false
6097         },
6098 
6099         /**
6100          * Attributes for the sector label.
6101          *
6102          * @type Label
6103          * @name Sector#label
6104          */
6105         label: {
6106             offset: [0, 0],
6107             anchorX: 'auto',
6108             anchorY: 'auto'
6109         }
6110 
6111         /**#@-*/
6112     },
6113 
6114     /* special segment options */
6115     segment: {
6116         /**#@+
6117          * @visprop
6118          */
6119 
6120         label: {
6121             position: 'top'
6122         }
6123         /**#@-*/
6124     },
6125 
6126     semicircle: {
6127         /**#@+
6128          * @visprop
6129          */
6130 
6131         /**
6132          * Attributes for center point of the semicircle.
6133          *
6134          * @type Point
6135          * @name Semicircle#center
6136          */
6137         center: {
6138             visible: false,
6139             withLabel: false,
6140             fixed: false,
6141             fillColor: Color.palette.red,
6142             strokeColor: Color.palette.red,
6143             highlightFillColor: '#eeeeee',
6144             highlightStrokeColor: Color.palette.red,
6145             name: ''
6146         }
6147 
6148         /**#@-*/
6149     },
6150 
6151     /* special slider options */
6152     slider: {
6153         /**#@+
6154          * @visprop
6155          */
6156 
6157         /**
6158          * The slider only returns integer multiples of this value, e.g. for discrete values set this property to <tt>1</tt>. For
6159          * continuous results set this to <tt>-1</tt>.
6160          *
6161          * @memberOf Slider.prototype
6162          * @name snapWidth
6163          * @type Number
6164          */
6165         snapWidth: -1,      // -1 = deactivated
6166 
6167         /**
6168          * List of values to snap to. If the glider is within snapValueDistance
6169          * (in user coordinate units) of one of these points,
6170          * then the glider snaps to that point.
6171          *
6172          * @memberOf Slider.prototype
6173          * @name snapValues
6174          * @type Array
6175          * @see Slider#snapValueDistance
6176          * @default empty
6177          *
6178          * @example
6179          *         var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {
6180          *             name: 'n',
6181          *             snapWidth: 1,
6182          *             snapValues: [1, 22, 77, 100],
6183          *             snapValueDistance: 5
6184          *         });
6185          *
6186          *         var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {
6187          *             name: 'k',
6188          *             snapWidth: 0.1,
6189          *             snapValues: [-3, -1, 1, 3],
6190          *             snapValueDistance: 0.4
6191          *         });
6192          *
6193          * </pre><div id="JXG9be68014-4e14-479a-82b4-e92d9b8f6eef" class="jxgbox" style="width: 300px; height: 300px;"></div>
6194          * <script type="text/javascript">
6195          *     (function() {
6196          *         var board = JXG.JSXGraph.initBoard('JXG9be68014-4e14-479a-82b4-e92d9b8f6eef',
6197          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
6198          *             var n = board.create('slider', [[-2, 3], [4, 3], [1, 5, 100]], {
6199          *                 name: 'n',
6200          *                 snapWidth: 1,
6201          *                 snapValues: [1, 22, 77, 100],
6202          *                 snapValueDistance: 5
6203          *             });
6204          *
6205          *             var k = board.create('slider', [[-2, -1], [4, -1], [-4, 0, 4]], {
6206          *                 name: 'k',
6207          *                 snapWidth: 0.1,
6208          *                 snapValues: [-3, -1, 1, 3],
6209          *                 snapValueDistance: 0.4
6210          *             });
6211          *
6212          *     })();
6213          *
6214          * </script><pre>
6215          *
6216          */
6217         snapValues: [],
6218 
6219         /**
6220          * If the difference between the slider value and one of the elements of snapValues is less
6221          * than this number (in user coordinate units), the slider will snap to that value.
6222          *
6223          * @memberOf Slider.prototype
6224          * @name snapValueDistance
6225          * @type Number
6226          * @see Slider#snapValues
6227          * @default 0.0
6228          */
6229         snapValueDistance: 0.0,
6230 
6231         /**
6232          * The precision of the slider value displayed in the optional text.
6233          * Replaced by the attribute "digits".
6234          *
6235          * @memberOf Slider.prototype
6236          * @name precision
6237          * @type Number
6238          * @deprecated
6239          * @see Slider#digits
6240          * @default 2
6241          */
6242         precision: 2,
6243 
6244         /**
6245          * The number of digits of the slider value displayed in the optional text.
6246          *
6247          * @memberOf Slider.prototype
6248          * @name digits
6249          * @type Number
6250          * @default 2
6251          */
6252         digits: 2,
6253 
6254         /**
6255          * Internationalization support for slider labels.
6256          *
6257          * @name intl
6258          * @memberOf Slider.prototype
6259          * @type object
6260          * @default {
6261          *    enabled: 'inherit',
6262          *    options: {}
6263          * }
6264          * @see JXG.Board#intl
6265          * @see Text#intl
6266          *
6267          * @example
6268          * var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {
6269          *     name: 'α',
6270          *     snapWidth: 1,
6271          *     intl: {
6272          *         enabled: true,
6273          *         options: {
6274          *             style: 'unit',
6275          *             unit: 'degree',
6276          *         }
6277          *     }
6278          * });
6279          *
6280          * </pre><div id="JXGb49a9779-c0c8-419d-9173-c67232cfd65c" class="jxgbox" style="width: 300px; height: 300px;"></div>
6281          * <script type="text/javascript">
6282          *     (function() {
6283          *         var board = JXG.JSXGraph.initBoard('JXGb49a9779-c0c8-419d-9173-c67232cfd65c',
6284          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
6285          *     var s = board.create('slider', [[-2, 3], [2, 3], [0, 1, 360]], {
6286          *         name: 'α',
6287          *         snapWidth: 1,
6288          *         intl: {
6289          *             enabled: true,
6290          *             options: {
6291          *                 style: 'unit',
6292          *                 unit: 'degree',
6293          *             }
6294          *         }
6295          *     });
6296          *
6297          *     })();
6298          *
6299          * </script><pre>
6300          *
6301          */
6302         intl: {
6303             enabled: 'inherit',
6304             options: {}
6305         },
6306 
6307         firstArrow: false,
6308         lastArrow: false,
6309 
6310         /**
6311          * Show slider ticks.
6312          *
6313          * @type Boolean
6314          * @name Slider#withTicks
6315          * @default true
6316          */
6317         withTicks: true,
6318 
6319         /**
6320          * Show slider label.
6321          *
6322          * @type Boolean
6323          * @name Slider#withLabel
6324          * @default true
6325          */
6326         withLabel: true,
6327 
6328         /**
6329          * If not null, this replaces the part "name = " in the slider label.
6330          * Possible types: string, number or function.
6331          * @type String
6332          * @name suffixLabel
6333          * @memberOf Slider.prototype
6334          * @default null
6335          * @see JXG.Slider#unitLabel
6336          * @see JXG.Slider#postLabel
6337          */
6338         suffixLabel: null,
6339 
6340         /**
6341          * If not null, this is appended to the value in the slider label.
6342          * Possible types: string, number or function.
6343          * @type String
6344          * @name unitLabel
6345          * @memberOf Slider.prototype
6346          * @default null
6347          * @see JXG.Slider#suffixLabel
6348          * @see JXG.Slider#postLabel
6349          */
6350         unitLabel: null,
6351 
6352         /**
6353          * If not null, this is appended to the value and to unitLabel in the slider label.
6354          * Possible types: string, number or function.
6355          * @type String
6356          * @name postLabel
6357          * @memberOf Slider.prototype
6358          * @default null
6359          * @see JXG.Slider#suffixLabel
6360          * @see JXG.Slider#unitLabel
6361          */
6362         postLabel: null,
6363 
6364         layer: 9,
6365         showInfobox: false,
6366         name: '',
6367         visible: true,
6368         strokeColor: '#000000',
6369         highlightStrokeColor: '#888888',
6370         fillColor: '#ffffff',
6371         highlightFillColor: 'none',
6372 
6373         /**
6374          * Size of slider point.
6375          *
6376          * @type Number
6377          * @name Slider#size
6378          * @default 6
6379          * @see Point#size
6380          */
6381         size: 6,
6382 
6383         /**
6384          * Attributes for first (left) helper point defining the slider position.
6385          *
6386          * @type Point
6387          * @name Slider#point1
6388          */
6389         point1: {
6390             needsRegularUpdate: false,
6391             showInfobox: false,
6392             withLabel: false,
6393             visible: false,
6394             fixed: true,
6395             name: ''
6396         },
6397 
6398         /**
6399          * Attributes for second (right) helper point defining the slider position.
6400          *
6401          * @type Point
6402          * @name Slider#point2
6403          */
6404         point2: {
6405             needsRegularUpdate: false,
6406             showInfobox: false,
6407             withLabel: false,
6408             visible: false,
6409             fixed: true,
6410             name: ''
6411         },
6412 
6413         /**
6414          * Attributes for the base line of the slider.
6415          *
6416          * @type Line
6417          * @name Slider#baseline
6418          */
6419         baseline: {
6420             needsRegularUpdate: false,
6421             visible: 'inherit',
6422             fixed: true,
6423             scalable: false,
6424             tabindex: null,
6425             name: '',
6426             strokeWidth: 1,
6427             strokeColor: '#000000',
6428             highlightStrokeColor: '#888888'
6429         },
6430 
6431         /**
6432          * Attributes for the ticks of the base line of the slider.
6433          *
6434          * @type Ticks
6435          * @name Slider#ticks
6436          */
6437         ticks: {
6438             needsRegularUpdate: false,
6439             fixed: true,
6440 
6441             // Label drawing
6442             drawLabels: false,
6443             digits: 2,
6444             includeBoundaries: true,
6445             drawZero: true,
6446             label: {
6447                 offset: [-4, -14],
6448                 display: 'internal'
6449             },
6450 
6451             minTicksDistance: 30,
6452             insertTicks: true,
6453             ticksDistance: 1,      // Not necessary, since insertTicks = true
6454             minorHeight: 4,        // if <0: full width and height
6455             majorHeight: 5,        // if <0: full width and height
6456             minorTicks: 0,
6457             strokeOpacity: 1,
6458             strokeWidth: 1,
6459             tickEndings: [0, 1],
6460             majortickEndings: [0, 1],
6461             strokeColor: '#000000',
6462             visible: 'inherit'
6463         },
6464 
6465         /**
6466          * Attributes for the highlighting line of the slider.
6467          *
6468          * @type Line
6469          * @name Slider#highline
6470          */
6471         highline: {
6472             strokeWidth: 3,
6473             visible: 'inherit',
6474             fixed: true,
6475             tabindex: null,
6476             name: '',
6477             strokeColor: '#000000',
6478             highlightStrokeColor: '#888888'
6479         },
6480 
6481         /**
6482          * Attributes for the slider label.
6483          *
6484          * @type Label
6485          * @name Slider#label
6486          */
6487         label: {
6488             visible: 'inherit',
6489             strokeColor: '#000000'
6490         },
6491 
6492         /**
6493          * If true, 'up' events on the baseline will trigger slider moves.
6494          *
6495          * @type Boolean
6496          * @name Slider#moveOnUp
6497          * @default true
6498          */
6499         moveOnUp: true
6500 
6501         /**#@-*/
6502     },
6503 
6504     /* special vector field options */
6505     slopefield: {
6506         /**#@+
6507          * @visprop
6508          */
6509 
6510         strokeWidth: 0.5,
6511         highlightStrokeWidth: 0.5,
6512         highlightStrokeColor: Color.palette.blue,
6513         highlightStrokeOpacity: 0.8,
6514 
6515         /**
6516          * Set length of the vectors in user coordinates. This in contrast to vector fields, where this attribute just scales the vector.
6517          * @name scale
6518          * @memberOf Slopefield.prototype
6519          * @type {Number|Function}
6520          * @see Vectorfield.scale
6521          * @default 1
6522          */
6523         scale: 1,
6524 
6525         /**
6526          * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.
6527          * Fields are:
6528          * <ul>
6529          *  <li> enabled: Boolean
6530          *  <li> size: length of the arrow head legs (in pixel)
6531          *  <li> angle: angle of the arrow head legs In radians.
6532          * </ul>
6533          * @name arrowhead
6534          * @memberOf Slopefield.prototype
6535          * @type {Object}
6536          * @default <tt>{enabled: false, size: 5, angle: Math.PI * 0.125}</tt>
6537          */
6538         arrowhead: {
6539             enabled: false,
6540             size: 5,
6541             angle: Math.PI * 0.125
6542         }
6543 
6544         /**#@-*/
6545     },
6546 
6547     /* special options for slope triangle */
6548     slopetriangle: {
6549         /**#@+
6550          * @visprop
6551          */
6552 
6553         fillColor: Color.palette.red,
6554         fillOpacity: 0.4,
6555         highlightFillColor: Color.palette.red,
6556         highlightFillOpacity: 0.3,
6557 
6558         borders: {
6559             lastArrow: {
6560                 type: 1,
6561                 size: 6
6562             }
6563         },
6564 
6565         /**
6566          * Attributes for the gliding helper point.
6567          *
6568          * @type Point
6569          * @name Slopetriangle#glider
6570          */
6571         glider: {
6572             fixed: true,
6573             visible: false,
6574             withLabel: false
6575         },
6576 
6577         /**
6578          * Attributes for the base line.
6579          *
6580          * @type Line
6581          * @name Slopetriangle#baseline
6582          */
6583         baseline: {
6584             visible: false,
6585             withLabel: false,
6586             name: ''
6587         },
6588 
6589         /**
6590          * Attributes for the base point.
6591          *
6592          * @type Point
6593          * @name Slopetriangle#basepoint
6594          */
6595         basepoint: {
6596             visible: false,
6597             withLabel: false,
6598             name: ''
6599         },
6600 
6601         /**
6602          * Attributes for the tangent.
6603          * The tangent is constructed by slop triangle if the construction
6604          * is based on a glider, solely.
6605          *
6606          * @type Line
6607          * @name Slopetriangle#tangent
6608          */
6609         tangent: {
6610             visible: false,
6611             withLabel: false,
6612             name: ''
6613         },
6614 
6615         /**
6616          * Attributes for the top point.
6617          *
6618          * @type Point
6619          * @name Slopetriangle#toppoint
6620          */
6621         toppoint: {
6622             visible: false,
6623             withLabel: false,
6624             name: ''
6625         },
6626 
6627         /**
6628          * Attributes for the slope triangle label.
6629          *
6630          * @type Label
6631          * @name Slopetriangle#label
6632          */
6633         label: {
6634             visible: true
6635         }
6636         /**#@-*/
6637     },
6638 
6639     /* special options for smartlabel of angle */
6640     smartlabelangle: {
6641         cssClass: 'smart-label-solid smart-label-angle',
6642         highlightCssClass:'smart-label-solid smart-label-angle',
6643         anchorX: 'left',
6644         anchorY: 'middle',
6645 
6646         unit: '',
6647         prefix: '',
6648         suffix: '',
6649 
6650         measure: 'deg',
6651         useMathJax: true
6652     },
6653 
6654     /* special options for smartlabel of circle */
6655     smartlabelcircle: {
6656         /**#@+
6657          * @visprop
6658          */
6659 
6660         /**
6661          * CSS classes for the smart label. Available classes are:
6662          * <ul>
6663          * <li> 'smart-label-solid'
6664          * <li> 'smart-label-outline'
6665          * <li> 'smart-label-pure'
6666          * </ul>
6667          *
6668          * By default, an additional class is given specific for the element type.
6669          * Available classes are 'smart-label-angle', 'smart-label-circle',
6670          * 'smart-label-line', 'smart-label-point', 'smart-label-polygon'.
6671          *
6672          * @example
6673          *  cssClass: 'smart-label-solid smart-label-point'
6674          *
6675          * @type String
6676          * @name Smartlabel#cssClass
6677          * @see Smartlabel#highlightCssClass
6678          * @default <ul>
6679          *  <li> 'smart-label-solid smart-label-circle' for circles</li>
6680          *  <li> 'smart-label-solid smart-label-point' for points</li>
6681          *  <li> ...</li>
6682          * </ul>
6683          */
6684         cssClass: 'smart-label-solid smart-label-circle',
6685 
6686         /**
6687          * CSS classes for the smart label when highlighted.
6688          *
6689          * @type String
6690          * @name Smartlabel#highlightCssClass
6691          * @see Smartlabel#cssClass
6692          * @default <ul>
6693          *  <li> 'smart-label-solid smart-label-circle' for circles</li>
6694          *  <li> 'smart-label-solid smart-label-point' for points</li>
6695          *  <li> ...</li>
6696          * </ul>
6697          */
6698         highlightCssClass:'smart-label-solid smart-label-circle',
6699         anchorX: 'middle',
6700         useMathJax: true,
6701 
6702         /**
6703          * Measurement unit appended to the output text. For areas, the unit is squared automatically.
6704          * Comes directly after the measurement value.
6705          *
6706          * @type {String|Function}
6707          * @name Smartlabel#unit
6708          * @default ''
6709          */
6710         unit: '',
6711 
6712         /**
6713          * Prefix text for the smartlabel. Comes before the measurement value.
6714          *
6715          * @type {String|Function}
6716          * @name Smartlabel#prefix
6717          * @default ''
6718          */
6719         prefix: '',
6720 
6721         /**
6722          * Suffix text for the smartlabel. Comes after unit.
6723          *
6724          * @type {String|Function}
6725          * @name Smartlabel#suffix
6726          * @default ''
6727          */
6728         suffix: '',
6729 
6730         /**
6731          * Type of measurement.
6732          * Available values are:
6733          *  <ul>
6734          *  <li> 'deg', 'rad' for angles</li>
6735          *  <li> 'area', 'perimeter', 'radius' for circles</li>
6736          *  <li> 'length', 'slope' for lines</li>
6737          *  <li> 'area', 'perimeter' for polygons</li>
6738          * </ul>
6739          * Dependent on this value, i.e. the type of measurement, the label is
6740          * positioned differently on the object.
6741          *
6742          * @type String
6743          * @name Smartlabel#measure
6744          * @default <ul>
6745          *   <li> 'radius' for circles</li>
6746          *   <li> 'length' for lines</li>
6747          *   <li> 'area' for polygons</li>
6748          *   <li> 'deg' for angles</li>
6749          * </ul>
6750          */
6751         measure: 'radius',
6752 
6753         /**#@-*/
6754     },
6755 
6756     /* special options for smartlabel of line */
6757     smartlabelline: {
6758         cssClass: 'smart-label-solid smart-label-line',
6759         highlightCssClass:'smart-label-solid smart-label-line',
6760         anchorX: 'middle',
6761 
6762         useMathJax: true,
6763 
6764         unit: '',
6765         measure: 'length'
6766     },
6767 
6768     /* special options for smartlabel of point */
6769     smartlabelpoint: {
6770         /**#@+
6771          * @visprop
6772          */
6773 
6774         cssClass: 'smart-label-solid smart-label-point',
6775         highlightCssClass:'smart-label-solid smart-label-point',
6776         anchorX: 'middle',
6777         anchorY: 'top',
6778 
6779         useMathJax: true,
6780 
6781         /**
6782          * Display of point coordinates either as row vector or column vector.
6783          * Available values are 'row' or 'column'.
6784          * @type String
6785          * @name Smartlabel#dir
6786          * @default 'row'
6787          */
6788         dir: 'row',
6789 
6790         unit: ''
6791         /**#@-*/
6792     },
6793 
6794     /* special options for smartlabel of polygon */
6795     smartlabelpolygon: {
6796         cssClass: 'smart-label-solid smart-label-polygon',
6797         highlightCssClass:'smart-label-solid smart-label-polygon',
6798         anchorX: 'middle',
6799 
6800         useMathJax: true,
6801 
6802         unit: '',
6803         measure: 'area'
6804     },
6805 
6806     /* special options for step functions */
6807     stepfunction: {
6808         /**#@+
6809          * @visprop
6810          */
6811 
6812         /**#@-*/
6813     },
6814 
6815     /* special tangent options */
6816     tangent: {
6817     },
6818 
6819     /* special tape measure options */
6820     tapemeasure: {
6821         /**#@+
6822          * @visprop
6823          */
6824 
6825         strokeColor: '#000000',
6826         strokeWidth: 2,
6827         highlightStrokeColor: '#000000',
6828 
6829         /**
6830          * Show tape measure ticks.
6831          *
6832          * @type Boolean
6833          * @name Tapemeasure#withTicks
6834          * @default true
6835          */
6836         withTicks: true,
6837 
6838         /**
6839          * Show tape measure label.
6840          *
6841          * @type Boolean
6842          * @name Tapemeasure#withLabel
6843          * @default true
6844          */
6845         withLabel: true,
6846 
6847         /**
6848          * Text rotation in degrees.
6849          *
6850          * @name Tapemeasure#rotate
6851          * @type Number
6852          * @default 0
6853          */
6854         rotate: 0,
6855 
6856         /**
6857          * The precision of the tape measure value displayed in the optional text.
6858          * Replaced by the attribute digits
6859          *
6860          * @memberOf Tapemeasure.prototype
6861          * @name precision
6862          * @type Number
6863          * @deprecated
6864          * @see Tapemeasure#digits
6865          * @default 2
6866          */
6867         precision: 2,
6868 
6869         /**
6870          * The precision of the tape measure value displayed in the optional text.
6871          * @memberOf Tapemeasure.prototype
6872          * @name precision
6873          * @type Number
6874          * @default 2
6875          */
6876         digits: 2,
6877 
6878         /**
6879          * Attributes for first helper point defining the tape measure position.
6880          *
6881          * @type Point
6882          * @name Tapemeasure#point1
6883          */
6884         point1: {
6885             visible: 'inherit',
6886             strokeColor: '#000000',
6887             fillColor: '#ffffff',
6888             fillOpacity: 0.0,
6889             highlightFillOpacity: 0.1,
6890             size: 6,
6891             snapToPoints: true,
6892             attractorUnit: 'screen',
6893             attractorDistance: 20,
6894             showInfobox: false,
6895             withLabel: false,
6896             name: ''
6897         },
6898 
6899         /**
6900          * Attributes for second helper point defining the tape measure position.
6901          *
6902          * @type Point
6903          * @name Tapemeasure#point2
6904          */
6905         point2: {
6906             visible: 'inherit',
6907             strokeColor: '#000000',
6908             fillColor: '#ffffff',
6909             fillOpacity: 0.0,
6910             highlightFillOpacity: 0.1,
6911             size: 6,
6912             snapToPoints: true,
6913             attractorUnit: 'screen',
6914             attractorDistance: 20,
6915             showInfobox: false,
6916             withLabel: false,
6917             name: ''
6918         },
6919 
6920         /**
6921          * Attributes for the ticks of the tape measure.
6922          *
6923          * @type Ticks
6924          * @name Tapemeasure#ticks
6925          */
6926         ticks: {
6927             drawLabels: false,
6928             drawZero: true,
6929             insertTicks: true,
6930             ticksDistance: 0.1, // Ignored, since insertTicks=true
6931             minorHeight: 8,
6932             majorHeight: 16,
6933             minorTicks: 4,
6934             tickEndings: [0, 1],
6935             majorTickEndings: [0, 1],
6936             strokeOpacity: 1,
6937             strokeWidth: 1,
6938             strokeColor: '#000000',
6939             visible: 'inherit'
6940         },
6941 
6942         /**
6943          * Attributes for the tape measure label.
6944          *
6945          * @type Label
6946          * @name Tapemeasure#label
6947          */
6948         label: {
6949             position: 'top'
6950         }
6951         /**#@-*/
6952     },
6953 
6954     /* special text options */
6955     text: {
6956         /**#@+
6957          * @visprop
6958          */
6959 
6960         /**
6961          * The font size in pixels.
6962          *
6963          * @name fontSize
6964          * @memberOf Text.prototype
6965          * @default 12
6966          * @type Number
6967          * @see Text#fontUnit
6968          */
6969         fontSize: 12,
6970 
6971         /**
6972          * CSS unit for the font size of a text element. Usually, this will be the default value 'px' but
6973          * for responsive application, also 'vw', 'vh', vmax', 'vmin' or 'rem' might be useful.
6974          *
6975          * @name fontUnit
6976          * @memberOf Text.prototype
6977          * @default 'px'
6978          * @type String
6979          * @see Text#fontSize
6980          *
6981          * @example
6982          * var txt = board.create('text', [2, 2, "hello"], {fontSize: 8, fontUnit: 'vmin'});
6983          *
6984          * </pre><div id="JXG2da7e972-ac62-416b-a94b-32559c9ec9f9" class="jxgbox" style="width: 300px; height: 300px;"></div>
6985          * <script type="text/javascript">
6986          *     (function() {
6987          *         var board = JXG.JSXGraph.initBoard('JXG2da7e972-ac62-416b-a94b-32559c9ec9f9',
6988          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
6989          *     var txt = board.create('text', [2, 2, "hello"], {fontSize: 8, fontUnit: 'vmin'});
6990          *
6991          *     })();
6992          *
6993          * </script><pre>
6994          *
6995          */
6996         fontUnit: 'px',
6997 
6998         /**
6999          * Used to round texts given by a number.
7000          *
7001          * @name digits
7002          * @memberOf Text.prototype
7003          * @default 2
7004          * @type Number
7005          */
7006         digits: 2,
7007 
7008         /**
7009          * Internationalization support for texts consisting of a number only.
7010          * <p>
7011          * Setting the local overwrites the board-wide locale set in the board attributes.
7012          * The JSXGraph attribute digits is overruled by the
7013          * Intl attributes "minimumFractionDigits" and "maximumFractionDigits".
7014          * 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>
7015          * for more information about possible options.
7016          * <p>
7017          * See below for an example where the text is composed from a string and a locale formatted number.
7018          *
7019          * @name intl
7020          * @memberOf Text.prototype
7021          * @type object
7022          * @default {
7023          *    enabled: 'inherit',
7024          *    options: {}
7025          * }
7026          * @see JXG.Board#intl
7027          *
7028          * @example
7029          * var t = board.create('text', [1, 2, -Math.PI*100], {
7030          *         digits: 2,
7031          *         intl: {
7032          *                 enabled: true,
7033          *                 options: {
7034          *                     style: 'unit',
7035          *                     unit: 'celsius'
7036          *                 }
7037          *             }
7038          *     });
7039          *
7040          * </pre><div id="JXGb7162923-1beb-4e56-8817-19aa66e226d1" class="jxgbox" style="width: 300px; height: 300px;"></div>
7041          * <script type="text/javascript">
7042          *     (function() {
7043          *         var board = JXG.JSXGraph.initBoard('JXGb7162923-1beb-4e56-8817-19aa66e226d1',
7044          *             {boundingbox: [-8, 8, 8,-8], axis: true, showcopyright: false, shownavigation: false});
7045          *     var t = board.create('text', [1, 2, -Math.PI*100], {
7046          *             digits: 2,
7047          *             intl: {
7048          *                     enabled: true,
7049          *                     options: {
7050          *                         style: 'unit',
7051          *                         unit: 'celsius'
7052          *                     }
7053          *                 }
7054          *         });
7055          *
7056          *     })();
7057          *
7058          * </script><pre>
7059          *
7060          *
7061          * @example
7062          * var t = board.create('text', [0.05, -0.2, ''], {
7063          *     intl: {
7064          *         enabled: true,
7065          *         locale: 'it-IT',
7066          *         options: {
7067          *             style: 'unit',
7068          *             unit: 'kilometer-per-hour',
7069          *             unitDisplay: 'narrow',
7070          *             maximumFractionDigits: 2
7071          *         }
7072          *     }
7073          * });
7074          *
7075          * // Set dynamic text consisting of text and number.
7076          * t.setText(function() {
7077          *     var txt = 'Speed: ',
7078          *         number = t.X();
7079          *
7080          *     // Add formatted number to variable txt
7081          *     // with fallback if locale is not supported.
7082          *     if (t.useLocale()) {
7083          *         txt += t.formatNumberLocale(number);
7084          *     } else {
7085          *         txt += JXG.toFixed(number, 2);
7086          *     }
7087          *     return txt;
7088          * });
7089          *
7090          * </pre><div id="JXG560aeb1c-55fb-45da-8ad5-d3ad26216056" class="jxgbox" style="width: 300px; height: 300px;"></div>
7091          * <script type="text/javascript">
7092          *     (function() {
7093          *         var board = JXG.JSXGraph.initBoard('JXG560aeb1c-55fb-45da-8ad5-d3ad26216056',
7094          *             {boundingbox: [-0.5, 0.5, 0.5, -0.5], axis: true, showcopyright: false, shownavigation: false});
7095          *     var t = board.create('text', [0.3, -0.3, ''], {
7096          *         intl: {
7097          *             enabled: true,
7098          *             locale: 'it-IT',
7099          *             options: {
7100          *                 style: 'unit',
7101          *                 unit: 'kilometer-per-hour',
7102          *                 unitDisplay: 'narrow',
7103          *                 maximumFractionDigits: 2
7104          *             }
7105          *         }
7106          *     });
7107          *
7108          *     // Set dynamic text consisting of text and number.
7109          *     t.setText(function() {
7110          *         var txt = 'Speed: ',
7111          *             number = t.X();
7112          *
7113          *         // Add formatted number to variable txt
7114          *         if (t.useLocale()) {
7115          *             txt += t.formatNumberLocale(number);
7116          *         } else {
7117          *             txt += JXG.toFixed(number, 2);
7118          *         }
7119          *         return txt;
7120          *     });
7121          *
7122          *     })();
7123          *
7124          * </script><pre>
7125          *
7126          */
7127         intl: {
7128             enabled: 'inherit',
7129             options: {}
7130         },
7131 
7132         /**
7133          * If set to true, the text is parsed and evaluated.
7134          * For labels parse==true results in converting names of the form k_a to subscripts.
7135          * If the text is given by string and parse==true, the string is parsed as
7136          * JessieCode expression.
7137          *
7138          * @name parse
7139          * @memberOf Text.prototype
7140          * @default true
7141          * @type Boolean
7142          */
7143         parse: true,
7144 
7145         /**
7146          * If set to true and caja's sanitizeHTML function can be found it
7147          * will be used to sanitize text output.
7148          *
7149          * @name useCaja
7150          * @memberOf Text.prototype
7151          * @default false
7152          * @type Boolean
7153          */
7154         useCaja: false,
7155 
7156         /**
7157          * If enabled, the text will be handled as label. Intended for internal use.
7158          *
7159          * @name isLabel
7160          * @memberOf Text.prototype
7161          * @default false
7162          * @type Boolean
7163          */
7164         isLabel: false,
7165 
7166         strokeColor: '#000000',
7167         highlightStrokeColor: '#000000',
7168         highlightStrokeOpacity: 0.666666,
7169 
7170         /**
7171          * Default CSS properties of the HTML text element.
7172          * <p>
7173          * The CSS properties which are set here, are handed over to the style property
7174          * of the HTML text element. That means, they have higher property than any
7175          * CSS class.
7176          * <p>
7177          * If a property which is set here should be overruled by a CSS class
7178          * then this property should be removed here.
7179          * <p>
7180          * The reason, why this attribute should be kept to its default value at all,
7181          * is that screen dumps of SVG boards with <tt>board.renderer.dumpToCanvas()</tt>
7182          * will ignore the font-family if it is set in a CSS class.
7183          * It has to be set explicitly as style attribute.
7184          * <p>
7185          * In summary, the order of priorities from high to low is
7186          * <ol>
7187          *  <li> JXG.Options.text.cssStyle
7188          *  <li> JXG.Options.text.cssDefaultStyle
7189          *  <li> JXG.Options.text.cssClass
7190          * </ol>
7191          * @example
7192          * If all texts should get its font-family from the default CSS class
7193          * before initializing the board
7194          * <pre>
7195          *   JXG.Options.text.cssDefaultStyle = '';
7196          *   JXG.Options.text.highlightCssDefaultStyle = '';
7197          * </pre>
7198          * should be called.
7199          *
7200          * @name cssDefaultStyle
7201          * @memberOf Text.prototype
7202          * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'
7203          * @type String
7204          * @see Text#highlightCssDefaultStyle
7205          * @see Text#cssStyle
7206          * @see Text#highlightCssStyle
7207          */
7208         cssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',
7209 
7210         /**
7211          * Default CSS properties of the HTML text element in case of highlighting.
7212          * <p>
7213          * The CSS properties which are set here, are handed over to the style property
7214          * of the HTML text element. That means, they have higher property than any
7215          * CSS class.
7216          * @example
7217          * If all texts should get its font-family from the default CSS class
7218          * before initializing the board
7219          * <pre>
7220          *   JXG.Options.text.cssDefaultStyle = '';
7221          *   JXG.Options.text.highlightCssDefaultStyle = '';
7222          * </pre>
7223          * should be called.
7224          *
7225          * @name highlightCssDefaultStyle
7226          * @memberOf Text.prototype
7227          * @default  'font-family: Arial, Helvetica, Geneva, sans-serif;'
7228          * @type String
7229          * @see Text#cssDefaultStyle
7230          * @see Text#cssStyle
7231          * @see Text#highlightCssStyle
7232         */
7233         highlightCssDefaultStyle: 'font-family: Arial, Helvetica, Geneva, sans-serif;',
7234 
7235         /**
7236          * CSS properties of the HTML text element.
7237          * <p>
7238          * The CSS properties which are set here, are handed over to the style property
7239          * of the HTML text element. That means, they have higher property than any
7240          * CSS class.
7241          *
7242          * @name cssStyle
7243          * @memberOf Text.prototype
7244          * @default  ''
7245          * @type String
7246          * @see Text#cssDefaultStyle
7247          * @see Text#highlightCssDefaultStyle
7248          * @see Text#highlightCssStyle
7249         */
7250         cssStyle: '',
7251 
7252         /**
7253          * CSS properties of the HTML text element in case of highlighting.
7254          * <p>
7255          * The CSS properties which are set here, are handed over to the style property
7256          * of the HTML text element. That means, they have higher property than any
7257          * CSS class.
7258          *
7259          * @name highlightCssStyle
7260          * @memberOf Text.prototype
7261          * @default  ''
7262          * @type String
7263          * @see Text#cssDefaultStyle
7264          * @see Text#highlightCssDefaultStyle
7265          * @see Text#cssStyle
7266         */
7267         highlightCssStyle: '',
7268 
7269         transitionProperties: ['color', 'opacity'],
7270 
7271         /**
7272          * If true, the input will be given to ASCIIMathML before rendering.
7273          *
7274          * @name useASCIIMathML
7275          * @memberOf Text.prototype
7276          * @default false
7277          * @type Boolean
7278          */
7279         useASCIIMathML: false,
7280 
7281         /**
7282          * If true, MathJax will be used to render the input string.
7283          * Supports MathJax 2 as well as Mathjax 3.
7284          * It is recommended to use this option together with the option
7285          * "parse: false". Otherwise, 4 backslashes (e.g. \\\\alpha) are needed
7286          * instead of two (e.g. \\alpha).
7287          *
7288          * @name useMathJax
7289          * @memberOf Text.prototype
7290          * @default false
7291          * @type Boolean
7292          * @see Text#parse
7293          *
7294          * @example
7295          *  // Before loading MathJax, it has to be configured something like this:
7296          * window.MathJax = {
7297          *   tex: {
7298          *     inlineMath: [ ['$','$'], ["\\(","\\)"] ],
7299          *     displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
7300          *     packages: ['base', 'ams']
7301          *   },
7302          *   options: {
7303          *     ignoreHtmlClass: 'tex2jax_ignore',
7304          *     processHtmlClass: 'tex2jax_process'
7305          *   }
7306          * };
7307          *
7308          * // Display style
7309          * board.create('text',[ 2,2,  function(){return '$$X=\\frac{2}{x}$$'}], {
7310          *     fontSize: 15, color:'green', useMathJax: true});
7311          *
7312          * // Inline style
7313          * board.create('text',[-2,2,  function(){return '$X_A=\\frac{2}{x}$'}], {
7314          *     fontSize: 15, color:'green', useMathJax: true});
7315          *
7316          * var A = board.create('point', [-2, 0]);
7317          * var B = board.create('point', [1, 0]);
7318          * var C = board.create('point', [0, 1]);
7319          *
7320          * var graph = board.create('ellipse', [A, B, C], {
7321          *         fixed: true,
7322          *         withLabel: true,
7323          *         strokeColor: 'black',
7324          *         strokeWidth: 2,
7325          *         fillColor: '#cccccc',
7326          *         fillOpacity: 0.3,
7327          *         highlightStrokeColor: 'red',
7328          *         highlightStrokeWidth: 3,
7329          *         name: '$1=\\frac{(x-h)^2}{a^2}+\\frac{(y-k)^2}{b^2}$',
7330          *         label: {useMathJax: true}
7331          *     });
7332          *
7333          * var nvect1 = board.create('text', [-4, -3, '\\[\\overrightarrow{V}\\]'],
7334          * {
7335          *   fontSize: 24, parse: false
7336          * });
7337          * var nvect1 = board.create('text', [-2, -4, function() {return '$\\overrightarrow{G}$';}],
7338          * {
7339          *   fontSize: 24, useMathJax: true
7340          * });
7341          *
7342          * </pre>
7343          * <script>
7344          * window.MathJax = {
7345          *   tex: {
7346          *     inlineMath: [ ['$','$'], ["\\(","\\)"] ],
7347          *     displayMath: [ ['$$','$$'], ["\\[","\\]"] ],
7348          *     packages: ['base', 'ams']
7349          *   },
7350          *   options: {
7351          *     ignoreHtmlClass: 'tex2jax_ignore',
7352          *     processHtmlClass: 'tex2jax_process'
7353          *   }
7354          * };
7355          * </script>
7356          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
7357          * <div id="JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9" class="jxgbox" style="width: 400px; height: 400px;"></div>
7358          * <script type="text/javascript">
7359          *     (function() {
7360          *         var board = JXG.JSXGraph.initBoard('JXGe2a04876-5813-4db0-b7e8-e48bf4e220b9',
7361          *             {boundingbox: [-5, 5, 5, -5], axis: true, showcopyright: false, shownavigation: false});
7362          *     // Display style
7363          *     board.create('text',[ 2,2,  function(){return '$$X=\\frac{2}{x}$$'}], {
7364          *         fontSize: 15, color:'green', useMathJax: true});
7365          *
7366          *     // Inline style
7367          *     board.create('text',[-2,2,  function(){return '$X_A=\\frac{2}{x}$'}], {
7368          *         fontSize: 15, color:'green', useMathJax: true});
7369          *
7370          *     var A = board.create('point', [-2, 0]);
7371          *     var B = board.create('point', [1, 0]);
7372          *     var C = board.create('point', [0, 1]);
7373          *
7374          *     var graph = board.create('ellipse', [A, B, C], {
7375          *             fixed: true,
7376          *             withLabel: true,
7377          *             strokeColor: 'black',
7378          *             strokeWidth: 2,
7379          *             fillColor: '#cccccc',
7380          *             fillOpacity: 0.3,
7381          *             highlightStrokeColor: 'red',
7382          *             highlightStrokeWidth: 3,
7383          *             name: '$1=\\frac{(x-h)^2}{a^2}+\\frac{(y-k)^2}{b^2}$',
7384          *             label: {useMathJax: true}
7385          *         });
7386          *
7387          *     var nvect1 = board.create('text', [-4, -3, '\\[\\overrightarrow{V}\\]'],
7388          *     {
7389          *       fontSize: 24, parse: false
7390          *     });
7391          *     var nvect1 = board.create('text', [-2, -4, function() {return '$\\overrightarrow{G}$';}],
7392          *     {
7393          *       fontSize: 24, useMathJax: true
7394          *     });
7395          *     })();
7396          *
7397          * </script><pre>
7398          *
7399          *
7400          * @example
7401          * // Load MathJax:
7402          * // <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"<</script>
7403          *
7404          * // function and its derivative
7405          * var f1 = function(x) { return x * x * x; },
7406          * graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),
7407          *
7408          * A = board.create('glider', [0.5, f1(0.5), graph1], {
7409          *             name: 'f(x)',
7410          *             color: 'black',
7411          *             face:'x',
7412          *             fixed: true,
7413          *             size: 3,
7414          *             label: {offset: [-30, 10], fontSize: 15}
7415          *         }),
7416          * B = board.create('glider', [0.7, f1(0.7), graph1], {
7417          *             name: 'f(x+Δx)',
7418          *             size: 3,
7419          *             label: {offset: [-60, 10], fontSize: 15}
7420          *         }),
7421          *
7422          * secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),
7423          * a_h_segment = board.create('segment', [A, [
7424          *                     function(){ return B.X() > A.X() ? B.X() : A.X()},
7425          *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}
7426          *                 ]],{ name: 'Δx', dash: 1, color: 'black'});
7427          *
7428          * b_v_segment = board.create('segment', [B, [
7429          *                     function(){ return B.X() > A.X() ? B.X() : A.X()},
7430          *                     function(){ return B.X() > A.X() ? A.Y() : B.Y()}
7431          *                 ]],{ name: 'Δy', dash: 1, color: 'black'}),
7432          *
7433          * ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2
7434          *     ], {visible: false});
7435          *
7436          * board.create('text', [0, 0, function() {return '\\[\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\]'}], {
7437          *     anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'
7438          * });
7439          *
7440          * mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});
7441          * board.create('text', [0, 0, function() {return '\\[\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\]'}], {
7442          *     anchor: mb, useMathJax: true, fixed: true, color: 'green'
7443          * });
7444          *
7445          * dval = board.create('text',[0.1, 0.8,
7446          *     function(){
7447          *         return '\\[\\frac{\\Delta_y}{\\Delta_x}=\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +
7448          *             '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\]';
7449          *     }],{fontSize: 15, useMathJax: true});
7450          *
7451          * </pre>
7452          * <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js" id="MathJax-script"></script>
7453          * <div id="JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621" class="jxgbox" style="width: 400px; height: 400px;"></div>
7454          * <script type="text/javascript">
7455          *     (function() {
7456          *         var board = JXG.JSXGraph.initBoard('JXG8c2b65e7-4fc4-43f7-b23c-5076a7fa9621',
7457          *             {boundingbox: [-0.1, 1.1, 1.1, -0.1], axis: true, showcopyright: false, shownavigation: false});
7458          *     // function and its derivative
7459          *     var f1 = function(x) { return x * x * x; },
7460          *     graph1 = board.create('functiongraph', [f1, -0.1, 1.1]),
7461          *
7462          *     A = board.create('glider', [0.5, f1(0.5), graph1], {
7463          *                 name: 'f(x)',
7464          *                 color: 'black',
7465          *                 face:'x',
7466          *                 fixed: true,
7467          *                 size: 3,
7468          *                 label: {offset: [-30, 10], fontSize: 15}
7469          *             }),
7470          *     B = board.create('glider', [0.7, f1(0.7), graph1], {
7471          *                 name: 'f(x+Δx)',
7472          *                 size: 3,
7473          *                 label: {offset: [-60, 10], fontSize: 15}
7474          *             }),
7475          *
7476          *     secant_line = board.create('line', [A,B],{dash: 1, color: 'green'}),
7477          *     a_h_segment = board.create('segment', [A, [
7478          *                         function(){ return B.X() > A.X() ? B.X() : A.X()},
7479          *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}
7480          *                     ]],{ name: 'Δx', dash: 1, color: 'black'});
7481          *
7482          *     b_v_segment = board.create('segment', [B, [
7483          *                         function(){ return B.X() > A.X() ? B.X() : A.X()},
7484          *                         function(){ return B.X() > A.X() ? A.Y() : B.Y()}
7485          *                     ]],{ name: 'Δy', dash: 1, color: 'black'}),
7486          *
7487          *     ma = board.create('midpoint', [a_h_segment.point1, a_h_segment.point2
7488          *         ], {visible: false});
7489          *
7490          *     board.create('text', [0, 0, function() {return '\\[\\Delta_x='+(B.X()-A.X()).toFixed(4)+'\\]'}], {
7491          *         anchor: ma, useMathJax: true, fixed: true, color: 'green', anchorY: 'top'
7492          *     });
7493          *
7494          *     mb = board.create('midpoint', [b_v_segment.point1, b_v_segment.point2], {visible: false});
7495          *     board.create('text', [0, 0, function() {return '\\[\\Delta_y='+(B.Y()-A.Y()).toFixed(4)+'\\]'}], {
7496          *         anchor: mb, useMathJax: true, fixed: true, color: 'green'
7497          *     });
7498          *
7499          *     dval = board.create('text',[0.1, 0.8,
7500          *         function(){
7501          *             return '\\[\\frac{\\Delta_y}{\\Delta_x}=\\frac{' + ((B.Y()-A.Y()).toFixed(4)) + '}{' + ((B.X()-A.X()).toFixed(4)) +
7502          *                 '}=' + (((B.Y()-A.Y()).toFixed(4))/((B.X()-A.X()).toFixed(4))).toFixed(4) + '\\]';
7503          *         }],{fontSize: 15, useMathJax: true});
7504          *
7505          *     })();
7506          *
7507          * </script><pre>
7508          *
7509          * @example
7510          * var board = JXG.JSXGraph.initBoard('jxgbox', {boundingbox: [-1, 10, 11, -2], axis: true});
7511          * board.options.text.useMathjax = true;
7512          *
7513          * a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
7514          *     suffixlabel:'\\(t_1=\\)',
7515          *     unitLabel: ' \\(\\text{ ms}\\)',
7516          *     snapWidth:0.01}),
7517          *
7518          * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
7519          * text1 = board.create('text', [5, 1, function(){
7520          *             return '\\(a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}\\)';
7521          *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});
7522          *
7523          * </pre><div id="JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6" class="jxgbox" style="width: 300px; height: 300px;"></div>
7524          * <script type="text/javascript">
7525          *     (function() {
7526          *         var board = JXG.JSXGraph.initBoard('JXGf8bd01db-fb6a-4a5c-9e7f-8823f7aa5ac6',
7527          *             {boundingbox: [-1, 10, 11, -2], axis: true, showcopyright: false, shownavigation: false});
7528          *     board.options.text.useMathjax = true;
7529          *
7530          *     a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
7531          *         suffixlabel:'\\(t_1=\\)',
7532          *         unitLabel: ' \\(\\text{ ms}\\)',
7533          *         snapWidth:0.01}),
7534          *
7535          *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
7536          *     text1 = board.create('text', [5, 1, function(){
7537          *                 return '\\(a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}\\)';
7538          *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top', parse: false});
7539          *
7540          *     })();
7541          *
7542          * </script><pre>
7543          *
7544          */
7545         useMathJax: false,
7546 
7547         /**
7548          *
7549          * If true, KaTeX will be used to render the input string.
7550          * For this feature, katex.min.js and katex.min.css have to be included.
7551          * <p>
7552          * The example below does not work, because there is a conflict with
7553          * the MathJax library which is used below.
7554          * </p>
7555          *
7556          * @name useKatex
7557          * @memberOf Text.prototype
7558          * @default false
7559          * @type Boolean
7560          *
7561          *
7562          * @example
7563          * JXG.Options.text.useKatex = true;
7564          *
7565          * const board = JXG.JSXGraph.initBoard('jxgbox', {
7566          *     boundingbox: [-2, 5, 8, -5], axis:true
7567          * });
7568          *
7569          * var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
7570          *     suffixlabel:'t_1=',
7571          *     unitLabel: ' \\text{ ms}',
7572          *     snapWidth:0.01});
7573          *
7574          * func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
7575          * text1 = board.create('text', [5, 1, function(){
7576          *             return 'a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}';
7577          *         }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});
7578          *
7579          * </pre>
7580          * <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">
7581          * <script src="https://cdn.jsdelivr.net/npm/katex@0.13.10/dist/katex.min.js" integrity="sha384-dtFDxK2tSkECx/6302Z4VN2ZRqt6Gis+b1IwCjJPrn0kMYFQT9rbtyQWg5NFWAF7" crossorigin="anonymous"></script>
7582          * <div id="JXG497f065c-cfc1-44c3-ba21-5fa581668869" class="jxgbox" style="width: 300px; height: 300px;"></div>
7583          * <script type="text/javascript">
7584          *     (function() {
7585          *         var board = JXG.JSXGraph.initBoard('JXG497f065c-cfc1-44c3-ba21-5fa581668869',
7586          *             {boundingbox: [-2, 5, 8, -5], axis: true, showcopyright: false, shownavigation: false});
7587          *     board.options.useKatex = true;
7588          *     var a = board.create('slider',[[-0.7,1.5],[5,1.5],[0,0.5,1]], {
7589          *         suffixlabel:'t_1=',
7590          *         unitLabel: ' \\text{ ms}',
7591          *         snapWidth:0.01});
7592          *
7593          *     func = board.create('functiongraph',[function(x){return (a.Value()*x*x)}], {strokeColor: "red"});
7594          *     text1 = board.create('text', [5, 1, function(){
7595          *                 return 'a(t)= { 1 \\over ' + a.Value().toFixed(3) + '}';
7596          *             }], {fontSize: 15, fixed:true, strokeColor:'red', anchorY: 'top'});
7597          *
7598          *     })();
7599          *
7600          * </script><pre>
7601          */
7602         useKatex: false,
7603 
7604         /**
7605          * Object or function returning an object that contains macros for KaTeX.
7606          *
7607          * @name katexMacros
7608          * @memberOf Text.prototype
7609          * @default {}
7610          * @type Object
7611          *
7612          * @example
7613          * // to globally apply macros to all text elements use:
7614          * JXG.Options.text.katexMacros = {'\\jxg': 'JSXGraph is awesome'};
7615          *
7616          * const board = JXG.JSXGraph.initBoard('jxgbox', {
7617          *     boundingbox: [-2, 5, 8, -5], axis:true
7618          * });
7619          *
7620          * // This macro only get applied to the p ('text') element
7621          * var p = board.create('text', [1, 0, '\\jsg \\sR '], { katexMacros: {'\\sR':'\\mathbb{R}'} });
7622          */
7623         katexMacros: {},
7624 
7625         /**
7626          * Determines the rendering method of the text. Possible values
7627          * include <tt>'html'</tt> and <tt>'internal</tt>.
7628          *
7629          * @name display
7630          * @memberOf Text.prototype
7631          * @default 'html'
7632          * @type String
7633          */
7634         display: 'html',
7635 
7636         /**
7637          * Anchor element {@link Point}, {@link Text} or {@link Image} of the text.
7638          * If it exists, the coordinates of the text are relative
7639          * to this anchor element. In this case, only numbers are possible coordinates,
7640          * functions are not supported.
7641          *
7642          * @name anchor
7643          * @memberOf Text.prototype
7644          * @default null
7645          * @type Object
7646          */
7647         anchor: null,
7648 
7649         /**
7650          * The horizontal alignment of the text. Possible values include <tt>'auto</tt>, <tt>'left'</tt>,
7651          * <tt>'middle'</tt>, and <tt>'right'</tt>.
7652          *
7653          * @name anchorX
7654          * @memberOf Text.prototype
7655          * @default 'left'
7656          * @type String
7657          */
7658         anchorX: 'left',
7659 
7660         /**
7661          * The vertical alignment of the text. Possible values include <tt>'auto</tt>, <tt>'top'</tt>, <tt>'middle'</tt>, and
7662          * <tt>'bottom'</tt>.
7663          * For MathJax or KaTeX, 'top' is recommended.
7664          *
7665          * @name anchorY
7666          * @memberOf Text.prototype
7667          * @default 'middle'
7668          * @type String
7669          */
7670         anchorY: 'middle',
7671 
7672         /**
7673          * CSS class of the text in non-highlighted view.
7674          *
7675          * @name cssClass
7676          * @memberOf Text.prototype
7677          * @type String
7678          * @default 'JXGtext'
7679          */
7680         cssClass: 'JXGtext',
7681 
7682         /**
7683          * CSS class of the text in highlighted view.
7684          *
7685          * @name highlightCssClass
7686          * @memberOf Text.prototype
7687          * @type String
7688          * @default 'JXGtext'
7689          */
7690         highlightCssClass: 'JXGtext',
7691 
7692         /**
7693          * Sensitive area for dragging the text.
7694          * Possible values are 'all', or something else.
7695          * If set to 'small', a sensitivity margin at the right and left border is taken.
7696          * This may be extended to left, right, ... in the future.
7697          *
7698          * @name Text#dragArea
7699          * @type String
7700          * @default 'all'
7701          */
7702         dragArea: 'all',
7703 
7704         withLabel: false,
7705 
7706         /**
7707          * Text rotation in degrees.
7708          * Works for non-zero values only in combination with display=='internal'.
7709          *
7710          * @name Text#rotate
7711          * @type Number
7712          * @default 0
7713          */
7714         rotate: 0,
7715 
7716         visible: true,
7717 
7718         /**
7719          * Defines together with {@link Text#snapSizeY} the grid the text snaps on to.
7720          * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
7721          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
7722          * of the default ticks of the default x axes of the board.
7723          *
7724          * @name snapSizeX
7725          * @memberOf Text.prototype
7726          *
7727          * @see Point#snapToGrid
7728          * @see Text#snapSizeY
7729          * @see JXG.Board#defaultAxes
7730          * @type Number
7731          * @default 1
7732          */
7733         snapSizeX: 1,
7734 
7735         /**
7736          * Defines together with {@link Text#snapSizeX} the grid the text snaps on to.
7737          * The text will only snap on integer multiples to snapSizeX in x and snapSizeY in y direction.
7738          * If this value is equal to or less than <tt>0</tt>, it will use the grid displayed by the major ticks
7739          * of the default ticks of the default y axes of the board.
7740          *
7741          * @name snapSizeY
7742          * @memberOf Text.prototype
7743          *
7744          * @see Point#snapToGrid
7745          * @see Text#snapSizeX
7746          * @see JXG.Board#defaultAxes
7747          * @type Number
7748          * @default 1
7749          */
7750         snapSizeY: 1,
7751 
7752         /**
7753          * List of attractor elements. If the distance of the text is less than
7754          * attractorDistance the text is made to glider of this element.
7755          *
7756          * @name attractors
7757          * @memberOf Text.prototype
7758          * @type Array
7759          * @default empty
7760          */
7761         attractors: [],
7762 
7763         /**#@-*/
7764     },
7765 
7766     /* special options for trace curves */
7767     tracecurve: {
7768         /**#@+
7769          * @visprop
7770          */
7771         strokeColor: '#000000',
7772         fillColor: 'none',
7773 
7774         /**
7775          * The number of evaluated data points.
7776          * @memberOf Tracecurve.prototype
7777          * @default 100
7778          * @name numberPoints
7779          * @type Number
7780          */
7781         numberPoints: 100
7782 
7783         /**#@-*/
7784     },
7785 
7786     /* special turtle options */
7787     turtle: {
7788         /**#@+
7789          * @visprop
7790          */
7791 
7792         strokeWidth: 1,
7793         fillColor: 'none',
7794         strokeColor: '#000000',
7795 
7796         /**
7797          * Attributes for the turtle arrow.
7798          *
7799          * @type Curve
7800          * @name Turtle#arrow
7801          */
7802         arrow: {
7803             strokeWidth: 2,
7804             withLabel: false,
7805             strokeColor: Color.palette.red,
7806             lastArrow: true
7807         }
7808         /**#@-*/
7809     },
7810 
7811     /* special vector field options */
7812     vectorfield: {
7813         /**#@+
7814          * @visprop
7815          */
7816 
7817         strokeWidth: 0.5,
7818         highlightStrokeWidth: 0.5,
7819         highlightStrokeColor: Color.palette.blue,
7820         highlightStrokeOpacity: 0.8,
7821 
7822         /**
7823          * Scaling factor of the vectors. This in contrast to slope fields, where this attribute sets the vector to the given length.
7824          * @name scale
7825          * @memberOf Vectorfield.prototype
7826          * @type {Number|Function}
7827          * @see Slopefield.scale
7828          * @default 1
7829          */
7830         scale: 1,
7831 
7832         /**
7833          * Customize arrow heads of vectors. Be careful! If enabled this will slow down the performance.
7834          * Fields are:
7835          * <ul>
7836          *  <li> enabled: Boolean
7837          *  <li> size: length of the arrow head legs (in pixel)
7838          *  <li> angle: angle of the arrow head legs In radians.
7839          * </ul>
7840          * @name arrowhead
7841          * @memberOf Vectorfield.prototype
7842          * @type {Object}
7843          * @default <tt>{enabled: true, size: 5, angle: Math.PI * 0.125}</tt>
7844          */
7845         arrowhead: {
7846             enabled: true,
7847             size: 5,
7848             angle: Math.PI * 0.125
7849         }
7850 
7851         /**#@-*/
7852     },
7853 
7854     /**
7855      * Abbreviations of attributes. Setting the shortcut means setting abbreviated properties
7856      * to the same value.
7857      * It is used in {@link JXG.GeometryElement#setAttribute} and in
7858      * the constructor {@link JXG.GeometryElement}.
7859      * Attention: In Options.js abbreviations are not allowed.
7860      * @type Object
7861      * @name JXG.Options#shortcuts
7862      *
7863      */
7864     shortcuts: {
7865         color: ['strokeColor', 'fillColor'],
7866         opacity: ['strokeOpacity', 'fillOpacity'],
7867         highlightColor: ['highlightStrokeColor', 'highlightFillColor'],
7868         highlightOpacity: ['highlightStrokeOpacity', 'highlightFillOpacity'],
7869         strokeWidth: ['strokeWidth', 'highlightStrokeWidth']
7870     }
7871 };
7872 
7873     /**
7874      * Holds all possible properties and the according validators for geometry elements.
7875      * A validator is either a function
7876      * which takes one parameter and returns true, if the value is valid for the property,
7877      * or it is false if no validator is required.
7878      */
7879     JXG.Validator = (function () {
7880         var i,
7881             validatePixel = function (v) {
7882                 return (/^[0-9]+px$/).test(v);
7883             },
7884             validateDisplay = function (v) {
7885                 return (v  === 'html' || v === 'internal');
7886             },
7887             validateColor = function (v) {
7888                 // for now this should do it...
7889                 return Type.isString(v);
7890             },
7891             validatePointFace = function (v) {
7892                 return Type.exists(JXG.normalizePointFace(v));
7893             },
7894             validateInteger = function (v) {
7895                 return (Math.abs(v - Math.round(v)) < Mat.eps);
7896             },
7897             validateNotNegativeInteger = function (v) {
7898                 return validateInteger(v) && v >= 0;
7899             },
7900             validatePositiveInteger = function (v) {
7901                 return validateInteger(v) && v > 0;
7902             },
7903             validateScreenCoords = function (v) {
7904                 return v.length >= 2 && validateInteger(v[0]) && validateInteger(v[1]);
7905             },
7906             validateRenderer = function (v) {
7907                 return (v === 'vml' || v === 'svg' || v === 'canvas' || v === 'no');
7908             },
7909             validatePositive = function (v) {
7910                 return v > 0;
7911             },
7912             validateNotNegative = function (v) {
7913                 return v >= 0;
7914             },
7915             v = {},
7916             validators = {
7917                 attractorDistance: validateNotNegative,
7918                 color: validateColor,
7919                 // defaultDistance: Type.isNumber,
7920                 display: validateDisplay,
7921                 doAdvancedPlot: false,
7922                 draft: false,
7923                 drawLabels: false,
7924                 drawZero: false,
7925                 face: validatePointFace,
7926                 factor: Type.isNumber,
7927                 fillColor: validateColor,
7928                 fillOpacity: Type.isNumber,
7929                 firstArrow: false,
7930                 fontSize: validateInteger,
7931                 dash: validateInteger,
7932                 gridX: Type.isNumber,
7933                 gridY: Type.isNumber,
7934                 hasGrid: false,
7935                 highlightFillColor: validateColor,
7936                 highlightFillOpacity: Type.isNumber,
7937                 highlightStrokeColor: validateColor,
7938                 highlightStrokeOpacity: Type.isNumber,
7939                 insertTicks: false,
7940                 //: validateScreenCoords,
7941                 lastArrow: false,
7942                 layer: validateNotNegativeInteger,
7943                 majorHeight: validateInteger,
7944                 minorHeight: validateInteger,
7945                 minorTicks: validateNotNegative,
7946                 minTicksDistance: validatePositiveInteger,
7947                 numberPointsHigh: validatePositiveInteger,
7948                 numberPointsLow: validatePositiveInteger,
7949                 opacity: Type.isNumber,
7950                 radius: Type.isNumber,
7951                 RDPsmoothing: false,
7952                 renderer: validateRenderer,
7953                 right: validatePixel,
7954                 showCopyright: false,
7955                 showInfobox: false,
7956                 showNavigation: false,
7957                 size: validateNotNegative, //validateInteger,
7958                 snapSizeX: validatePositive,
7959                 snapSizeY: validatePositive,
7960                 snapWidth: Type.isNumber,
7961                 snapToGrid: false,
7962                 snatchDistance: validateNotNegative,
7963                 straightFirst: false,
7964                 straightLast: false,
7965                 stretch: false,
7966                 strokeColor: validateColor,
7967                 strokeOpacity: Type.isNumber,
7968                 strokeWidth: validateNotNegative, //validateInteger,
7969                 takeFirst: false,
7970                 takeSizeFromFile: false,
7971                 to10: false,
7972                 toOrigin: false,
7973                 translateTo10: false,
7974                 translateToOrigin: false,
7975                 useASCIIMathML: false,
7976                 useDirection: false,
7977                 useMathJax: false,
7978                 withLabel: false,
7979                 withTicks: false,
7980                 zoom: false
7981             };
7982 
7983         // this seems like a redundant step but it makes sure that
7984         // all properties in the validator object have lower case names
7985         // and the validator object is easier to read.
7986         for (i in validators) {
7987             if (validators.hasOwnProperty(i)) {
7988                 v[i.toLowerCase()] = validators[i];
7989             }
7990         }
7991 
7992         return v;
7993     }());
7994 
7995     /**
7996      * All point faces can be defined with more than one name, e.g. a cross faced point can be given
7997      * by face equal to 'cross' or equal to 'x'. This method maps all possible values to fixed ones to
7998      * simplify if- and switch-clauses regarding point faces. The translation table is as follows:
7999      * <table>
8000      * <tr><th>Input</th><th>Output</th></tr>
8001      * <tr><td>cross</td><td>x</td></tr>
8002      * <tr><td>circle</td><td>o</td></tr>
8003      * <tr><td>square, []</td><td>[]</td></tr>
8004      * <tr><td>plus</td><td>+</td></tr>
8005      * <tr><td>minus</td><td>-</td></tr>
8006      * <tr><td>divide</td><td>|</td></tr>
8007      * <tr><td>diamond</td><td><></td></tr>
8008      * <tr><td>triangleup</td><td>^, a, A</td></tr>
8009      * <tr><td>triangledown</td><td>v</td></tr>
8010      * <tr><td>triangleleft</td><td><</td></tr>
8011      * <tr><td>triangleright</td><td>></td></tr>
8012      * </table>
8013      * @param {String} s A string which should determine a valid point face.
8014      * @returns {String} Returns a normalized string or undefined if the given string is not a valid
8015      * point face.
8016      */
8017     JXG.normalizePointFace = function (s) {
8018         var map = {
8019             cross: 'x',
8020             x: 'x',
8021             circle: 'o',
8022             o: 'o',
8023             square: '[]',
8024             '[]': '[]',
8025             plus: '+',
8026             '+': '+',
8027             divide: '|',
8028             '|': '|',
8029             minus: '-',
8030             '-': '-',
8031             diamond: '<>',
8032             '<>': '<>',
8033             triangleup: '^',
8034             A: '^',
8035             a: '^',
8036             '^': '^',
8037             triangledown: 'v',
8038             v: 'v',
8039             triangleleft: '<',
8040             '<': '<',
8041             triangleright: '>',
8042             '>': '>'
8043         };
8044 
8045         return map[s];
8046     };
8047 
8048 
8049     /**
8050      * Apply the options stored in this object to all objects on the given board.
8051      * @param {JXG.Board} board The board to which objects the options will be applied.
8052      */
8053     JXG.useStandardOptions = function (board) {
8054         var el, t, p, copyProps,
8055             o = JXG.Options,
8056             boardHadGrid = board.hasGrid;
8057 
8058         board.options.grid.hasGrid = o.grid.hasGrid;
8059         board.options.grid.gridX = o.grid.gridX;
8060         board.options.grid.gridY = o.grid.gridY;
8061         board.options.grid.gridColor = o.grid.gridColor;
8062         board.options.grid.gridOpacity = o.grid.gridOpacity;
8063         board.options.grid.gridDash = o.grid.gridDash;
8064         board.options.grid.snapToGrid = o.grid.snapToGrid;
8065         board.options.grid.snapSizeX = o.grid.SnapSizeX;
8066         board.options.grid.snapSizeY = o.grid.SnapSizeY;
8067         board.takeSizeFromFile = o.takeSizeFromFile;
8068 
8069         copyProps = function (p, o) {
8070             p.visProp.fillcolor = o.fillColor;
8071             p.visProp.highlightfillcolor = o.highlightFillColor;
8072             p.visProp.strokecolor = o.strokeColor;
8073             p.visProp.highlightstrokecolor = o.highlightStrokeColor;
8074         };
8075 
8076         for (el in board.objects) {
8077             if (board.objects.hasOwnProperty(el)) {
8078                 p = board.objects[el];
8079                 if (p.elementClass === Const.OBJECT_CLASS_POINT) {
8080                     copyProps(p, o.point);
8081                 } else if (p.elementClass === Const.OBJECT_CLASS_LINE) {
8082                     copyProps(p, o.line);
8083 
8084                     for (t = 0; t < p.ticks.length; t++) {
8085                         p.ticks[t].majorTicks = o.line.ticks.majorTicks;
8086                         p.ticks[t].minTicksDistance = o.line.ticks.minTicksDistance;
8087                         p.ticks[t].visProp.minorheight = o.line.ticks.minorHeight;
8088                         p.ticks[t].visProp.majorheight = o.line.ticks.majorHeight;
8089                     }
8090                 } else if (p.elementClass === Const.OBJECT_CLASS_CIRCLE) {
8091                     copyProps(p, o.circle);
8092                 } else if (p.type === Const.OBJECT_TYPE_ANGLE) {
8093                     copyProps(p, o.angle);
8094                 } else if (p.type === Const.OBJECT_TYPE_ARC) {
8095                     copyProps(p, o.arc);
8096                 } else if (p.type === Const.OBJECT_TYPE_POLYGON) {
8097                     copyProps(p, o.polygon);
8098                 } else if (p.type === Const.OBJECT_TYPE_CONIC) {
8099                     copyProps(p, o.conic);
8100                 } else if (p.type === Const.OBJECT_TYPE_CURVE) {
8101                     copyProps(p, o.curve);
8102                 } else if (p.type === Const.OBJECT_TYPE_SECTOR) {
8103                     p.arc.visProp.fillcolor = o.sector.fillColor;
8104                     p.arc.visProp.highlightfillcolor = o.sector.highlightFillColor;
8105                     p.arc.visProp.fillopacity = o.sector.fillOpacity;
8106                     p.arc.visProp.highlightfillopacity = o.sector.highlightFillOpacity;
8107                 }
8108             }
8109         }
8110 
8111         board.fullUpdate();
8112         if (boardHadGrid && !board.hasGrid) {
8113             board.removeGrids(board);
8114         } else if (!boardHadGrid && board.hasGrid) {
8115             board.create('grid', []);
8116         }
8117     };
8118 
8119     /**
8120      * Converts all color values to greyscale and calls useStandardOption to put them onto the board.
8121      * @param {JXG.Board} board The board to which objects the options will be applied.
8122      * @see #useStandardOptions
8123      */
8124     JXG.useBlackWhiteOptions = function (board) {
8125         var o = JXG.Options;
8126         o.point.fillColor = Color.rgb2bw(o.point.fillColor);
8127         o.point.highlightFillColor = Color.rgb2bw(o.point.highlightFillColor);
8128         o.point.strokeColor = Color.rgb2bw(o.point.strokeColor);
8129         o.point.highlightStrokeColor = Color.rgb2bw(o.point.highlightStrokeColor);
8130 
8131         o.line.fillColor = Color.rgb2bw(o.line.fillColor);
8132         o.line.highlightFillColor = Color.rgb2bw(o.line.highlightFillColor);
8133         o.line.strokeColor = Color.rgb2bw(o.line.strokeColor);
8134         o.line.highlightStrokeColor = Color.rgb2bw(o.line.highlightStrokeColor);
8135 
8136         o.circle.fillColor = Color.rgb2bw(o.circle.fillColor);
8137         o.circle.highlightFillColor = Color.rgb2bw(o.circle.highlightFillColor);
8138         o.circle.strokeColor = Color.rgb2bw(o.circle.strokeColor);
8139         o.circle.highlightStrokeColor = Color.rgb2bw(o.circle.highlightStrokeColor);
8140 
8141         o.arc.fillColor = Color.rgb2bw(o.arc.fillColor);
8142         o.arc.highlightFillColor = Color.rgb2bw(o.arc.highlightFillColor);
8143         o.arc.strokeColor = Color.rgb2bw(o.arc.strokeColor);
8144         o.arc.highlightStrokeColor = Color.rgb2bw(o.arc.highlightStrokeColor);
8145 
8146         o.polygon.fillColor = Color.rgb2bw(o.polygon.fillColor);
8147         o.polygon.highlightFillColor  = Color.rgb2bw(o.polygon.highlightFillColor);
8148 
8149         o.sector.fillColor = Color.rgb2bw(o.sector.fillColor);
8150         o.sector.highlightFillColor  = Color.rgb2bw(o.sector.highlightFillColor);
8151 
8152         o.curve.strokeColor = Color.rgb2bw(o.curve.strokeColor);
8153         o.grid.gridColor = Color.rgb2bw(o.grid.gridColor);
8154 
8155         JXG.useStandardOptions(board);
8156     };
8157 
8158 // needs to be exported
8159 JXG.Options.normalizePointFace = JXG.normalizePointFace;
8160 
8161 export default JXG.Options;
8162