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