PageSourceSearch

https://www.aspenpharma.com/wp-content/themes/aspen-pharmacare/js/wheelnav.js?ver=1.7.1

js aspenpharma.com collected 2026-10-03 21:37:23 UTC 151,797 bytes, 3,956 lines download raw bytes

1///#source 1 1 /js/source/wheelnav.core.js
2/* ======================================================================================= */
3/*                                   wheelnav.js - v1.7.1                                  */
4/* ======================================================================================= */
5/* This is a small JavaScript library for animated SVG based wheel navigation.             */
6/* Requires Raphaël JavaScript Vector Library (http://dmitrybaranovskiy.github.io/raphael/)*/
7/* ======================================================================================= */
8/* Check http://wheelnavjs.softwaretailoring.net for samples.                              */
9/* Fork https://github.com/softwaretailoring/wheelnav for contribution.                    */
10/* ======================================================================================= */
11/* Copyright © 2014-2017 Gábor Berkesi (http://softwaretailoring.net)                      */
12/* Licensed under MIT (https://github.com/softwaretailoring/wheelnav/blob/master/LICENSE)  */
13/* ======================================================================================= */
14
15/* ======================================================================================= */
16/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/core.html          */
17/* ======================================================================================= */
18
19wheelnav = function (divId, raphael, divWidth, divHeight) {
20
21    this.holderId = "wheel";
22
23    if (divId !== undefined &&
24        divId !== null) {
25        this.holderId = divId;
26    }
27
28    var holderDiv = document.getElementById(divId);
29
30    if ((holderDiv === null ||
31        holderDiv === undefined) &&
32        (raphael === undefined ||
33        raphael === null)) {
34        return this;
35    }
36    
37    //Prepare raphael object and set the width
38    var canvasWidth;
39    var clearContent = true;
40
41    if (raphael === undefined ||
42        raphael === null) {
43
44        var removeChildrens = [];
45        for (var i = 0; i < holderDiv.children.length; i++) {
46            if (holderDiv.children[i].localName === "svg") {
47                removeChildrens.push(holderDiv.children[i]);
48            }
49        }
50
51        for (var i = 0; i < removeChildrens.length; i++) {
52            holderDiv.removeChild(removeChildrens[i]);
53        }
54
55        if (divWidth !== undefined &&
56            divWidth !== null) {
57            if (divHeight === undefined ||
58                divHeight === null) {
59                divHeight = divWidth;
60            }
61            this.raphael = new Raphael(divId, divWidth, divHeight);
62            canvasWidth = divWidth;
63        }
64        else {
65            this.raphael = new Raphael(divId);
66            canvasWidth = holderDiv.clientWidth;
67        }
68
69        this.raphael.setViewBox(0, 0, this.raphael.width, this.raphael.height, true);
70    }
71    else {
72        //The divId parameter has to be the identifier of the wheelnav in this case.
73        this.raphael = raphael;
74        canvasWidth = this.raphael.width;
75        clearContent = false;
76    }
77
78    //Public properties
79    this.centerX = canvasWidth / 2;
80    this.centerY = canvasWidth / 2;
81    this.wheelRadius = canvasWidth / 2;
82    this.navAngle = 0;
83    this.sliceAngle = null;
84    this.titleRotateAngle = null;
85    this.initTitleRotate = false;
86    this.clickModeRotate = true;
87    this.rotateRound = false;
88    this.rotateRoundCount = 0;
89    this.clickModeSpreadOff = false;
90    this.animatetimeCalculated = false; // In clickModeRotate, when animatetimeCalculated is true, the navItem.animatetime calculated by wheelnav.animatetime and current rotationAngle. In this case, the wheelnav.animatetime belongs to the full rotation.
91    this.animateRepeatCount = 0;
92    this.clockwise = true;
93    this.multiSelect = false;
94    this.hoverPercent = 1;
95    this.selectedPercent = 1;
96    this.clickablePercentMin = 0;
97    this.clickablePercentMax = 1;
98    this.currentPercent = null;
99    this.cssMode = false;
100    this.selectedToFront = true;
101    this.selectedNavItemIndex = 0;
102
103    this.navItemCount = 0;
104    this.navItemCountLabeled = false;
105    this.navItemCountLabelOffset = 0;
106    this.navItems = [];
107    this.navItemsEnabled = true;
108    this.animateFinishFunction = null;
109
110    // These settings are useful when navItem.sliceAngle < 360 / this.navItemCount
111    this.navItemsContinuous = false; 
112    this.navItemsCentered = true; // This is reasoned when this.navItemsContinuous = false;
113
114    this.colors = colorpalette.defaultpalette;
115    this.titleSpreadScale = null;
116
117    //Spreader settings
118    this.spreaderEnable = false;
119    this.spreaderRadius = 20;
120    this.spreaderStartAngle = 0;
121    this.spreaderSliceAngle = 360;
122    this.spreaderPathFunction = spreaderPath().PieSpreader;
123    this.spreaderPathCustom = null;
124    this.spreaderInPercent = 1;
125    this.spreaderOutPercent = 1;
126    this.spreaderInTitle = "+";
127    this.spreaderOutTitle = "-";
128    this.spreaderTitleFont = null;
129    this.spreaderPathInAttr = null;
130    this.spreaderPathOutAttr = null;
131    this.spreaderTitleInAttr = null;
132    this.spreaderTitleOutAttr = null;
133    this.spreaderInTitleWidth = null;
134    this.spreaderInTitleHeight = null;
135    this.spreaderOutTitleWidth = null;
136    this.spreaderOutTitleHeight = null;
137
138    //Percents
139    this.minPercent = 0.01;
140    this.maxPercent = 1;
141    this.initPercent = 1;
142
143    //Marker settings
144    this.markerEnable = false;
145    this.markerPathFunction = markerPath().TriangleMarker;
146    this.markerPathCustom = null;
147
148    //Private properties
149    this.currentClick = 0;
150    this.animateLocked = false;
151
152    //NavItem default settings. These are configurable between initWheel() and createWheel().
153    this.slicePathAttr = null;
154    this.sliceHoverAttr = null;
155    this.sliceSelectedAttr = null;
156    
157    this.titleFont = '100 24px Impact, Charcoal, sans-serif';
158    this.titleAttr = null;
159    this.titleHoverAttr = null;
160    this.titleSelectedAttr = null;
161    //When navTitle start with 'imgsrc:' it can parse as URL of image or data URI. These properties are available for images and paths.
162    this.titleWidth = null;
163    this.titleHeight = null;
164    this.titleHoverWidth = null;
165    this.titleHoverHeight = null;
166    this.titleSelectedWidth = null;
167    this.titleSelectedHeight = null;
168
169    this.linePathAttr = null;
170    this.lineHoverAttr = null;
171    this.lineSelectedAttr = null;
172
173    this.slicePathCustom = null;
174    this.sliceClickablePathCustom = null;
175    this.sliceSelectedPathCustom = null;
176    this.sliceHoverPathCustom = null;
177    this.sliceInitPathCustom = null;
178
179    this.sliceTransformCustom = null;
180    this.sliceSelectedTransformCustom = null;
181    this.sliceHoverTransformCustom = null;
182    this.sliceInitTransformCustom = null;
183
184    this.animateeffect = null;
185    this.animatetime = null;
186    if (slicePath()["PieSlice"] !== undefined) {
187        this.slicePathFunction = slicePath().PieSlice;
188    }
189    else {
190        this.slicePathFunction = slicePath().NullSlice;
191    }
192    this.sliceClickablePathFunction = null;
193    this.sliceTransformFunction = null;
194    this.sliceSelectedPathFunction = null;
195    this.sliceSelectedTransformFunction = null;
196    this.sliceHoverPathFunction = null;
197    this.sliceHoverTransformFunction = null;
198    this.sliceInitPathFunction = null;
199    this.sliceInitTransformFunction = null;
200
201    this.keynavigateEnabled = false;
202    this.keynavigateOnlyFocus = false;
203    this.keynavigateDownCode = 37; // left arrow
204    this.keynavigateDownCodeAlt = 40; // down arrow
205    this.keynavigateUpCode = 39; // right arrow
206    this.keynavigateUpCodeAlt = 38; // up arrow
207
208    this.parseWheel(holderDiv);
209
210    return this;
211};
212
213wheelnav.prototype.initWheel = function (titles) {
214
215    //Init slices and titles
216    this.styleWheel();
217
218    var navItem;
219    if (this.navItemCount === 0) {
220
221        if (titles === undefined ||
222            titles === null ||
223            !Array.isArray(titles)) {
224            titles = ["title-0", "title-1", "title-2", "title-3"];
225        }
226
227        this.navItemCount = titles.length;
228    }
229    else {
230        titles = null;
231    }
232
233    for (i = 0; i < this.navItemCount; i++) {
234
235        var itemTitle = "";
236
237        if (this.navItemCountLabeled) {
238            itemTitle = (i + this.navItemCountLabelOffset).toString();
239        }
240        else {
241            if (titles !== null)
242                { itemTitle = titles[i]; }
243            else
244                { itemTitle = ""; }
245        }
246
247        navItem = new wheelnavItem(this, itemTitle, i);
248        this.navItems.push(navItem);
249    }
250
251    //Init colors
252    var colorIndex = 0;
253    for (i = 0; i < this.navItems.length; i++) {
254        this.navItems[i].fillAttr = this.colors[colorIndex];
255        colorIndex++;
256        if (colorIndex === this.colors.length) { colorIndex = 0;}
257    }
258};
259
260wheelnav.prototype.createWheel = function (titles, withSpread) {
261
262    if (this.currentPercent === null) {
263        if (withSpread) {
264            this.currentPercent = this.minPercent;
265        }
266        else {
267            this.currentPercent = this.maxPercent;
268        }
269    }
270
271    if (this.navItems.length === 0) {
272        this.initWheel(titles);
273    }
274
275    if (this.selectedNavItemIndex !== null) {
276        this.navItems[this.selectedNavItemIndex].selected = true;
277    }
278
279    for (i = 0; i < this.navItemCount; i++) {
280        this.navItems[i].createNavItem();
281    }
282
283    if (this.keynavigateEnabled) {
284        var thiswheelnav = this;
285        var keyelement = window;
286
287        if (this.keynavigateOnlyFocus) {
288            keyelement = document.getElementById(this.holderId);
289            if (!keyelement.hasAttribute("tabindex")) {
290                keyelement.setAttribute("tabindex", 0);
291            }
292        }
293
294        keyelement.addEventListener("keydown", this.keyNavigateFunction =  function (e) {
295            e = e || window.e;
296            var keyCodeEvent = e.which || e.keyCode;
297            if ([thiswheelnav.keynavigateDownCode, thiswheelnav.keynavigateDownCodeAlt, thiswheelnav.keynavigateUpCode, thiswheelnav.keynavigateUpCodeAlt].indexOf(e.keyCode) > -1) {
298                e.preventDefault();
299            }
300
301            var keynavigate = null;
302
303            if (keyCodeEvent === thiswheelnav.keynavigateUpCode || keyCodeEvent === thiswheelnav.keynavigateUpCodeAlt) {
304                if (thiswheelnav.currentClick === thiswheelnav.navItemCount - 1) {
305                    keynavigate = 0;
306                }
307                else {
308                    keynavigate = thiswheelnav.currentClick + 1;
309                }
310            }
311            if (keyCodeEvent === thiswheelnav.keynavigateDownCode || keyCodeEvent === thiswheelnav.keynavigateDownCodeAlt) {
312                if (thiswheelnav.currentClick === 0) {
313                    keynavigate = thiswheelnav.navItemCount - 1;
314                }
315                else {
316                    keynavigate = thiswheelnav.currentClick - 1;
317                }
318            }
319
320            if (keynavigate !== null) {
321                thiswheelnav.navigateWheel(keynavigate);
322            }
323        });
324    }
325
326    this.spreader = new spreader(this);
327
328    this.marker = new marker(this);
329
330    this.refreshWheel();
331
332    if (withSpread !== undefined) {
333        this.spreadWheel();
334    }
335
336    return this;
337};
338
339wheelnav.prototype.removeWheel = function () {
340    this.raphael.remove();
341
342    if (this.keynavigateEnabled) {
343        var keyelement = window;
344
345        if (this.keynavigateOnlyFocus) {
346            keyelement = document.getElementById(this.holderId);
347            if (keyelement.hasAttribute("tabindex")) {
348                keyelement.removeAttribute("tabindex");
349            }
350        }
351
352        keyelement.removeEventListener("keydown", this.keyNavigateFunction);
353    }
354};
355
356wheelnav.prototype.refreshWheel = function (withPathAndTransform) {
357
358    for (i = 0; i < this.navItemCount; i++) {
359        var navItem = this.navItems[i];
360        navItem.setWheelSettings(withPathAndTransform);
361        navItem.refreshNavItem(withPathAndTransform);
362    }
363
364    this.marker.setCurrentTransform();
365    this.spreader.setCurrentTransform();
366};
367
368wheelnav.prototype.navigateWheel = function (clicked) {
369
370    this.animateUnlock(true);
371
372    if (this.clickModeRotate) {
373        this.animateLocked = true;
374    }
375
376    var navItem;
377
378    for (i = 0; i < this.navItemCount; i++) {
379        navItem = this.navItems[i];
380
381        navItem.hovered = false;
382
383        if (i === clicked) {
384            if (this.multiSelect) {
385                navItem.selected = !navItem.selected;
386            } else {
387                navItem.selected = true;
388                this.selectedNavItemIndex = i;
389            }
390        }
391        else {
392            if (!this.multiSelect) {
393                navItem.selected = false;
394            }
395        }
396
397        if (this.clickModeRotate) {
398            var rotationAngle = this.navItems[clicked].navAngle - this.navItems[this.currentClick].navAngle;
399
400            if (this.rotateRound) {
401                if (this.clockwise && rotationAngle < 0) {
402                    rotationAngle = 360 + rotationAngle;
403                }
404                if (!this.clockwise && rotationAngle > 0) {
405                    rotationAngle = rotationAngle - 360;
406                }
407            }
408
409            navItem.currentRotateAngle -= rotationAngle;
410            var currentAnimateTime;
411            if (this.animatetime != null) {
412                currentAnimateTime = this.animatetime;
413            }
414            else {
415                currentAnimateTime = 1500;
416            }
417
418            if (this.animatetimeCalculated &&
419                clicked !== this.currentClick) {
420                navItem.animatetime = currentAnimateTime * (Math.abs(rotationAngle) / 360);
421            }
422
423            if (this.rotateRoundCount > 0) {
424                if (this.clockwise) { navItem.currentRotateAngle -= this.rotateRoundCount * 360; }
425                else { navItem.currentRotateAngle += this.rotateRoundCount * 360; }
426
427                navItem.animatetime = currentAnimateTime * (this.rotateRoundCount + 1);
428            }
429        }
430    }
431
432    for (i = 0; i < this.navItemCount; i++) {
433        navItem = this.navItems[i];
434        navItem.setCurrentTransform(true, true);
435        navItem.refreshNavItem();
436    }
437
438    this.currentClick = clicked;
439
440    if (this.clickModeSpreadOff) {
441        this.currentPercent = this.maxPercent;
442        this.spreadWheel();
443    }
444    else {
445        if (clicked !== null &&
446            !this.clickModeRotate) {
447            this.marker.setCurrentTransform(this.navItems[this.currentClick].navAngle);
448        }
449        else {
450            this.marker.setCurrentTransform();
451        }
452        this.spreader.setCurrentTransform(true);
453    }
454
455    if (clicked !== null &&
456        this.navItems[clicked].navigateFunction !== null) {
457        this.navItems[clicked].navigateFunction();
458    }
459};
460
461wheelnav.prototype.spreadWheel = function () {
462
463    this.animateUnlock(true);
464    this.animateLocked = true;
465
466    if (this.currentPercent === this.maxPercent ||
467        this.currentPercent === null) {
468        this.currentPercent = this.minPercent;
469    }
470    else {
471        this.currentPercent = this.maxPercent;
472    }
473
474    for (i = 0; i < this.navItemCount; i++) {
475        var navItem = this.navItems[i];
476        navItem.hovered = false;
477        navItem.setCurrentTransform(true, false);
478    }
479
480    this.marker.setCurrentTransform();
481    this.spreader.setCurrentTransform();
482
483    return this;
484};
485
486wheelnav.prototype.animateUnlock = function (force, withFinishFunction) {
487
488    if (force !== undefined && 
489        force === true) {
490        for (var f = 0; f < this.navItemCount; f++) {
491            this.navItems[f].navSliceUnderAnimation = false;
492            this.navItems[f].navTitleUnderAnimation = false;
493            this.navItems[f].navLineUnderAnimation = false;
494            this.navItems[f].navSlice.stop();
495            this.navItems[f].navLine.stop();
496            this.navItems[f].navTitle.stop();
497        }
498    }
499    else {
500        for (var i = 0; i < this.navItemCount; i++) {
501            if (this.navItems[i].navSliceUnderAnimation === true ||
502                this.navItems[i].navTitleUnderAnimation === true ||
503                this.navItems[i].navLineUnderAnimation === true) {
504                return;
505            }
506        }
507
508        this.animateLocked = false;
509        if (this.animateFinishFunction !== null &&
510            withFinishFunction !== undefined &&
511            withFinishFunction === true) {
512            this.animateFinishFunction();
513        }
514    }
515};
516
517wheelnav.prototype.setTooltips = function (tooltips) {
518    if (tooltips !== undefined &&
519        tooltips !== null &&
520        Array.isArray(tooltips) &&
521        tooltips.length <= this.navItems.length) {
522        for (var i = 0; i < tooltips.length; i++) {
523            this.navItems[i].setTooltip(tooltips[i]);
524        }
525    }
526};
527
528wheelnav.prototype.getItemId = function (index) {
529    return "wheelnav-" + this.holderId + "-item-" + index;
530};
531wheelnav.prototype.getSliceId = function (index) {
532    return "wheelnav-" + this.holderId + "-slice-" + index;
533};
534wheelnav.prototype.getClickableSliceId = function (index) {
535    return "wheelnav-" + this.holderId + "-clickableslice-" + index;
536};
537wheelnav.prototype.getTitleId = function (index) {
538    return "wheelnav-" + this.holderId + "-title-" + index;
539};
540wheelnav.prototype.getLineId = function (index) {
541    return "wheelnav-" + this.holderId + "-line-" + index;
542};
543wheelnav.prototype.getSpreaderId = function () {
544    return "wheelnav-" + this.holderId + "-spreader";
545};
546wheelnav.prototype.getSpreaderTitleId = function () {
547    return "wheelnav-" + this.holderId + "-spreadertitle";
548};
549wheelnav.prototype.getMarkerId = function () {
550    return "wheelnav-" + this.holderId + "-marker";
551};
552
553///#source 1 1 /js/source/wheelnav.parse.js
554/* ======================================================================================= */
555/* Parse html5 data- attributes, the onmouseup events and anchor links                     */
556/* ======================================================================================= */
557/* ======================================================================================= */
558/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/html5.html         */
559/* ======================================================================================= */
560
561wheelnav.prototype.parseWheel = function (holderDiv) {
562    if (holderDiv !== undefined &&
563        holderDiv !== null) {
564        //data-wheelnav attribute is required
565        var wheelnavData = holderDiv.hasAttribute("data-wheelnav");
566        if (wheelnavData) {
567            var parsedNavItems = [];
568            var parsedNavItemsHref = [];
569            var parsedNavItemsOnmouseup = [];
570            var onlyInit = false;
571
572            //data-wheelnav-slicepath
573            var wheelnavSlicepath = holderDiv.getAttribute("data-wheelnav-slicepath");
574            if (wheelnavSlicepath !== null) {
575                if (slicePath()[wheelnavSlicepath] !== undefined) {
576                    this.slicePathFunction = slicePath()[wheelnavSlicepath];
577                }
578            }
579            //data-wheelnav-colors
580            var wheelnavColors = holderDiv.getAttribute("data-wheelnav-colors");
581            if (wheelnavColors !== null) {
582                this.colors = wheelnavColors.split(',');
583            }
584            //data-wheelnav-wheelradius
585            var wheelnavWheelradius = holderDiv.getAttribute("data-wheelnav-wheelradius");
586            if (wheelnavWheelradius !== null) {
587                this.wheelRadius = Number(wheelnavWheelradius);
588            }
589            //data-wheelnav-navangle
590            var wheelnavNavangle = holderDiv.getAttribute("data-wheelnav-navangle");
591            if (wheelnavNavangle !== null) {
592                this.navAngle = Number(wheelnavNavangle);
593            }
594            //data-wheelnav-rotateoff
595            var wheelnavRotateOff = holderDiv.getAttribute("data-wheelnav-rotateoff");
596            if (wheelnavRotateOff !== null) {
597                this.clickModeRotate = false;
598            }
599            //data-wheelnav-cssmode
600            var wheelnavCssmode = holderDiv.getAttribute("data-wheelnav-cssmode");
601            if (wheelnavCssmode !== null) {
602                this.cssMode = true;
603            }
604            //data-wheelnav-spreader
605            var wheelnavSpreader = holderDiv.getAttribute("data-wheelnav-spreader");
606            if (wheelnavSpreader !== null) {
607                this.spreaderEnable = true;
608            }
609            //data-wheelnav-spreaderradius
610            var wheelnavSpreaderRadius = holderDiv.getAttribute("data-wheelnav-spreaderradius");
611            if (wheelnavSpreaderRadius !== null) {
612                this.spreaderRadius = Number(wheelnavSpreaderRadius);
613            }
614            //data-wheelnav-spreaderpath
615            var wheelnavSpreaderPath = holderDiv.getAttribute("data-wheelnav-spreaderpath");
616            if (wheelnavSpreaderPath !== null) {
617                if (markerPath()[wheelnavSpreaderPath] !== undefined) {
618                    this.spreaderPathFunction = spreaderPath()[wheelnavSpreaderPath];
619                }
620            }
621            //data-wheelnav-marker
622            var wheelnavMarker = holderDiv.getAttribute("data-wheelnav-marker");
623            if (wheelnavMarker !== null) {
624                this.markerEnable = true;
625            }
626            //data-wheelnav-markerpath
627            var wheelnavMarkerPath = holderDiv.getAttribute("data-wheelnav-markerpath");
628            if (wheelnavMarkerPath !== null) {
629                if (markerPath()[wheelnavMarkerPath] !== undefined) {
630                    this.markerPathFunction = markerPath()[wheelnavMarkerPath];
631                }
632            }
633            //data-wheelnav-titlewidth
634            var wheelnavTitleWidth = holderDiv.getAttribute("data-wheelnav-titlewidth");
635            if (wheelnavTitleWidth !== null) {
636                this.titleWidth = Number(wheelnavTitleWidth);
637            }
638            //data-wheelnav-titleheight
639            var wheelnavTitleHeight = holderDiv.getAttribute("data-wheelnav-titleheight");
640            if (wheelnavTitleHeight !== null) {
641                this.titleHeight = Number(wheelnavTitleHeight);
642            }
643
644            //data-wheelnav-keynav
645            var wheelnavKeynav = holderDiv.getAttribute("data-wheelnav-keynav");
646            if (wheelnavKeynav !== null) {
647                this.keynavigateEnabled = true;
648            }
649            //data-wheelnav-keynavonlyfocus
650            var wheelnavKeynavOnlyfocus = holderDiv.getAttribute("data-wheelnav-keynavonlyfocus");
651            if (wheelnavKeynavOnlyfocus !== null) {
652                this.keynavigateOnlyFocus = true;
653            }
654            //data-wheelnav-keynavdowncode
655            var wheelnavKeynavDowncode = holderDiv.getAttribute("data-wheelnav-keynavdowncode");
656            if (wheelnavKeynavDowncode !== null) {
657                this.keynavigateDownCode = Number(wheelnavKeynavDowncode);
658            }
659            //data-wheelnav-keynavdowncodealt
660            var wheelnavKeynavDowncodeAlt = holderDiv.getAttribute("data-wheelnav-keynavdowncodealt");
661            if (wheelnavKeynavDowncodeAlt !== null) {
662                this.keynavigateDownCodeAlt = Number(wheelnavKeynavDowncodeAlt);
663            }
664            //data-wheelnav-keynavupcode
665            var wheelnavKeynavUpcode = holderDiv.getAttribute("data-wheelnav-keynavupcode");
666            if (wheelnavKeynavUpcode !== null) {
667                this.keynavigateUpCode = Number(wheelnavKeynavUpcode);
668            }
669            //data-wheelnav-keynavupcodealt
670            var wheelnavKeynavUpcodeAlt = holderDiv.getAttribute("data-wheelnav-keynavupcodealt");
671            if (wheelnavKeynavUpcodeAlt !== null) {
672                this.keynavigateUpCodeAlt = Number(wheelnavKeynavUpcodeAlt);
673            }
674
675            //data-wheelnav-init
676            var wheelnavOnlyinit = holderDiv.getAttribute("data-wheelnav-init");
677            if (wheelnavOnlyinit !== null) {
678                onlyInit = true;
679            }
680
681            for (var i = 0; i < holderDiv.children.length; i++) {
682
683                var wheelnavNavitemtext = holderDiv.children[i].getAttribute("data-wheelnav-navitemtext");
684                var wheelnavNavitemicon = holderDiv.children[i].getAttribute("data-wheelnav-navitemicon");
685                var wheelnavNavitemimg = holderDiv.children[i].getAttribute("data-wheelnav-navitemimg");
686                if (wheelnavNavitemtext !== null ||
687                    wheelnavNavitemicon !== null ||
688                    wheelnavNavitemimg !== null) {
689                    //data-wheelnav-navitemtext
690                    if (wheelnavNavitemtext !== null) {
691                        parsedNavItems.push(wheelnavNavitemtext);
692                    }
693                    //data-wheelnav-navitemicon
694                    else if (wheelnavNavitemicon !== null) {
695                        if (icon[wheelnavNavitemicon] !== undefined) {
696                            parsedNavItems.push(icon[wheelnavNavitemicon]);
697                        }
698                        else {
699                            parsedNavItems.push(wheelnavNavitemicon);
700                        }
701                    }
702                    else if (wheelnavNavitemimg !== null) {
703                        parsedNavItems.push("imgsrc:" + wheelnavNavitemimg);
704                    }
705                    else {
706                        //data-wheelnav-navitemtext or data-wheelnav-navitemicon or data-wheelnav-navitemimg is required
707                        continue;
708                    }
709
710                    //onmouseup event of navitem element for call it in the navigateFunction
711                    if (holderDiv.children[i].onmouseup !== undefined) {
712                        parsedNavItemsOnmouseup.push(holderDiv.children[i].onmouseup);
713                    }
714                    else {
715                        parsedNavItemsOnmouseup.push(null);
716                    }
717
718                    //parse inner <a> tag in navitem element for use href in navigateFunction
719                    var foundHref = false;
720                    for (var j = 0; j < holderDiv.children[i].children.length; j++) {
721                        if (holderDiv.children[i].children[j].getAttribute('href') !== undefined) {
722                            parsedNavItemsHref.push(holderDiv.children[i].children[j].getAttribute('href'));
723                        }
724                    }
725                    if (!foundHref) {
726                        parsedNavItemsHref.push(null);
727                    }
728                }
729            }
730
731            if (parsedNavItems.length > 0) {
732                this.initWheel(parsedNavItems);
733
734                for (var i = 0; i < parsedNavItemsOnmouseup.length; i++) {
735                    this.navItems[i].navigateFunction = parsedNavItemsOnmouseup[i];
736                    this.navItems[i].navigateHref = parsedNavItemsHref[i];
737                }
738
739                if (!onlyInit) {
740                    this.createWheel();
741                }
742            }
743        }
744
745        var removeChildrens = [];
746        for (var i = 0; i < holderDiv.children.length; i++) {
747            if (holderDiv.children[i].localName !== "svg") {
748                removeChildrens.push(holderDiv.children[i]);
749            }
750        }
751
752        for (var i = 0; i < removeChildrens.length; i++) {
753            holderDiv.removeChild(removeChildrens[i]);
754        }
755    }
756};
757
758
759///#source 1 1 /js/source/wheelnav.navItem.js
760/* ======================================================================================= */
761/* Navigation item                                                                         */
762/* ======================================================================================= */
763/* ======================================================================================= */
764/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/navItem.html       */
765/* ======================================================================================= */
766
767wheelnavItem = function (wheelnav, title, itemIndex) {
768
769    this.wheelnav = wheelnav;
770    this.wheelItemIndex = itemIndex;
771    if (wheelnav.clockwise) {
772        this.itemIndex = itemIndex;
773    }
774    else {
775        this.itemIndex = -itemIndex;
776    }
777
778    this.enabled = wheelnav.navItemsEnabled;
779    this.selected = false;
780    this.hovered = false;
781
782    //Private properties
783    this.navItem = null;
784    this.navSlice = null;
785    this.navTitle = null;
786    this.navLine = null;
787    this.navClickableSlice = null;
788
789    this.navSliceCurrentTransformString = null;
790    this.navTitleCurrentTransformString = null;
791    this.navLineCurrentTransformString = null;
792
793    this.navSliceUnderAnimation = false;
794    this.navTitleUnderAnimation = false;
795    this.navLineUnderAnimation = false;
796
797    this.currentRotateAngle = 0;
798
799    this.setTitle(title);
800    this.tooltip = null;
801    
802    //Default settings
803    this.fillAttr = "#CCC";
804    this.titleFont = this.wheelnav.titleFont;
805    this.navigateHref = null;
806    this.navigateFunction = null;
807    //When navTitle start with 'imgsrc:' it can parse as URL of image or data URI. These properties are available for images and paths. Use after initWheel(), before createWheel()
808    this.titleWidth = null;
809    this.titleHeight = null;
810    this.titleHoverWidth = null;
811    this.titleHoverHeight = null;
812    this.titleSelectedWidth = null;
813    this.titleSelectedHeight = null;
814
815    //Wheelnav properties
816    this.animateeffect = null;
817    this.animatetime = null;
818
819    this.sliceInitPathFunction = null;
820    this.sliceClickablePathFunction = null;
821    this.slicePathFunction = null;
822    this.sliceSelectedPathFunction = null;
823    this.sliceHoverPathFunction = null;
824
825    this.sliceTransformFunction = null;
826    this.sliceSelectedTransformFunction = null;
827    this.sliceHoverTransformFunction = null;
828    this.sliceInitTransformFunction = null;
829
830    this.slicePathCustom = null;
831    this.sliceClickablePathCustom = null;
832    this.sliceSelectedPathCustom = null;
833    this.sliceHoverPathCustom = null;
834    this.sliceInitPathCustom = null;
835
836    this.sliceTransformCustom = null;
837    this.sliceSelectedTransformCustom = null;
838    this.sliceHoverTransformCustom = null;
839    this.sliceInitTransformCustom = null;
840
841    this.initPercent = null;
842    this.minPercent = null;
843    this.maxPercent = null;
844    this.hoverPercent = null;
845    this.selectedPercent = null;
846    this.clickablePercentMin = null;
847    this.clickablePercentMax = null;
848
849    this.titleSpreadScale = null;
850    this.sliceAngle = null;
851    this.titleRotateAngle = null;
852
853    //Default navitem styles
854    this.styleNavItem();
855
856    return this;
857};
858
859wheelnavItem.prototype.createNavItem = function () {
860
861    //Wheel settings
862    this.setWheelSettings(false);
863
864    //Set href navigation
865    if (this.navigateHref !== null) {
866        this.navigateFunction = function () {
867            window.location.href = this.navigateHref;
868        };
869    }
870
871    //Set colors
872    if (!this.wheelnav.cssMode) {
873        this.slicePathAttr.fill = this.fillAttr;
874        this.sliceHoverAttr.fill = this.fillAttr;
875        this.sliceSelectedAttr.fill = this.fillAttr;
876    }
877
878    //Set attrs
879    if (!this.enabled) {
880        if (!this.wheelnav.cssMode) {
881            this.slicePathAttr.cursor = "default";
882            this.sliceHoverAttr.cursor = "default";
883            this.titleAttr.cursor = "default";
884            this.titleHoverAttr.cursor = "default";
885            this.linePathAttr.cursor = "default";
886            this.lineHoverAttr.cursor = "default";
887        }
888
889        this.sliceClickablePathAttr.cursor = "default";
890        this.sliceClickableHoverAttr.cursor = "default";
891    }
892
893    //Set angles
894    var prevItemIndex = this.wheelItemIndex - 1;
895    var wheelSliceAngle = 360 / this.wheelnav.navItemCount;
896    if (this.sliceAngle === null) {
897        this.sliceAngle = 360 / this.wheelnav.navItemCount;
898    }
899    if (this.wheelnav.clockwise) {
900        if (this.wheelnav.navItemsContinuous) {
901            if (this.itemIndex === 0) {
902                this.baseAngle = (this.itemIndex * this.sliceAngle) + ((-this.sliceAngle / 2) + this.wheelnav.navAngle);
903            }
904            else {
905                this.baseAngle = this.wheelnav.navItems[prevItemIndex].baseAngle + this.wheelnav.navItems[prevItemIndex].sliceAngle;
906            }
907        }
908        else {
909            if (this.wheelnav.navItemsCentered) {
910                this.baseAngle = (this.itemIndex * wheelSliceAngle) + ((-this.sliceAngle / 2) + this.wheelnav.navAngle);
911            }
912            else {
913                this.baseAngle = (this.itemIndex * wheelSliceAngle) + ((-wheelSliceAngle / 2) + this.wheelnav.navAngle);
914                this.currentRotateAngle += ((wheelSliceAngle / 2) - (this.wheelnav.navItems[0].sliceAngle / 2));
915            }
916        }
917    }
918    else {
919        if (this.wheelnav.navItemsContinuous) {
920            if (this.itemIndex === 0) {
921                this.baseAngle = (this.itemIndex * this.sliceAngle) + ((-this.sliceAngle / 2) + this.wheelnav.navAngle);
922            }
923            else {
924                this.baseAngle = this.wheelnav.navItems[prevItemIndex].baseAngle - this.wheelnav.navItems[this.wheelItemIndex].sliceAngle;
925            }
926        }
927        else {
928            if (this.wheelnav.navItemsCentered) {
929                this.baseAngle = (this.itemIndex * wheelSliceAngle) + ((-this.sliceAngle / 2) + this.wheelnav.navAngle);
930            }
931            else {
932                this.baseAngle = (this.itemIndex * wheelSliceAngle) + ((-wheelSliceAngle / 2) + this.wheelnav.navAngle) + (wheelSliceAngle - this.sliceAngle);
933                this.currentRotateAngle -= ((wheelSliceAngle / 2) - (this.wheelnav.navItems[0].sliceAngle / 2));
934            }
935        }
936    }
937
938    this.navAngle = this.baseAngle + (this.sliceAngle / 2);
939
940    if (this.wheelnav.animatetimeCalculated) {
941        this.animatetime = this.wheelnav.animatetime / this.wheelnav.navItemCount;
942    }
943
944    this.initPathsAndTransforms();
945
946    var sliceInitPath = this.sliceInitPath;
947
948    //Create slice
949    this.navSlice = this.wheelnav.raphael.path(sliceInitPath.slicePathString);
950    this.navSlice.attr(this.slicePathAttr);
951    this.navSlice.id = this.wheelnav.getSliceId(this.wheelItemIndex);
952    this.navSlice.node.id = this.navSlice.id;
953
954    //Create linepath
955    this.navLine = this.wheelnav.raphael.path(sliceInitPath.linePathString);
956    this.navLine.attr(this.linePathAttr);
957    this.navLine.id = this.wheelnav.getLineId(this.wheelItemIndex);
958    this.navLine.node.id = this.navLine.id;
959
960    //Create title
961    var currentTitle = this.initNavTitle;
962
963    //Title defined by path
964    if (wheelnavTitle().isPathTitle(this.title)) {
965        this.navTitle = this.wheelnav.raphael.path(currentTitle.path);
966    }
967    //Title defined by image
968    else if (wheelnavTitle().isImageTitle(this.title)) {
969        this.navTitle = this.wheelnav.raphael.image(currentTitle.src, sliceInitPath.titlePosX - (this.titleWidth / 2), sliceInitPath.titlePosY - (this.titleHeight / 2), this.titleWidth, this.titleHeight);
970    }
971    //Title defined by text
972    else {
973        this.navTitle = this.wheelnav.raphael.text(sliceInitPath.titlePosX, sliceInitPath.titlePosY, currentTitle.title);
974    }
975
976    this.navTitle.attr(this.titleAttr);
977    this.navTitle.id = this.wheelnav.getTitleId(this.wheelItemIndex);
978    this.navTitle.node.id = this.navTitle.id;
979
980    //Set transforms
981    this.navSliceCurrentTransformString = "";
982    if (this.initTransform.sliceTransformString !== "") { this.navSliceCurrentTransformString += this.initTransform.sliceTransformString; }
983
984    this.navLineCurrentTransformString = "";
985    if (this.initTransform.lineTransformString !== "") { this.navLineCurrentTransformString += this.initTransform.lineTransformString; }
986
987    this.navTitleCurrentTransformString = "";
988    this.navTitleCurrentTransformString += this.getTitleRotateString(this.wheelnav.initTitleRotate);
989    if (this.initTransform.titleTransformString !== "") { this.navTitleCurrentTransformString += this.initTransform.titleTransformString; }
990    if (this.wheelnav.currentPercent < 0.05) {
991        this.navTitleCurrentTransformString += ",s0.05";
992    }
993    if (this.navTitleSizeTransform !== undefined) {
994        this.navTitleCurrentTransformString += this.navTitleSizeTransform;
995    }
996
997    this.navSlice.attr({ transform: this.navSliceCurrentTransformString });
998    this.navLine.attr({ transform: this.navLineCurrentTransformString });
999    this.navTitle.attr({ transform: this.navTitleCurrentTransformString });
1000    
1001    //Create item set
1002    this.navItem = this.wheelnav.raphael.set();
1003
1004    if (this.sliceClickablePathFunction !== null) {
1005        //Create clickable slice
1006        var sliceClickablePath = this.getCurrentClickablePath();
1007        this.navClickableSlice = this.wheelnav.raphael.path(sliceClickablePath.slicePathString).attr(this.sliceClickablePathAttr).toBack();
1008        this.navClickableSlice.id = this.wheelnav.getClickableSliceId(this.wheelItemIndex);
1009        this.navClickableSlice.node.id = this.navClickableSlice.id;
1010        
1011        this.navItem.push(
1012            this.navSlice,
1013            this.navLine,
1014            this.navTitle,
1015            this.navClickableSlice
1016        );
1017    }
1018    else {
1019        this.navItem.push(
1020            this.navSlice,
1021            this.navLine,
1022            this.navTitle
1023        );
1024    }
1025
1026    this.setTooltip(this.tooltip);
1027    this.navItem.id = this.wheelnav.getItemId(this.wheelItemIndex);
1028
1029    var thisWheelNav = this.wheelnav;
1030    var thisNavItem = this;
1031    var thisItemIndex = this.wheelItemIndex;
1032
1033    if (this.enabled) {
1034        this.navItem.mouseup(function () {
1035            thisWheelNav.navigateWheel(thisItemIndex);
1036        });
1037        this.navItem.mouseover(function () {
1038            if (thisNavItem.hovered !== true) {
1039                thisNavItem.hoverEffect(thisItemIndex, true);
1040            }
1041        });
1042        this.navItem.mouseout(function () {
1043            thisNavItem.hovered = false;
1044            thisNavItem.hoverEffect(thisItemIndex, false);
1045        });
1046    }
1047
1048    this.setCurrentTransform(true, false);
1049};
1050
1051wheelnavItem.prototype.hoverEffect = function (hovered, isEnter) {
1052
1053    if (this.wheelnav.animateLocked === false) {
1054        if (isEnter) {
1055            if (!this.selected) {
1056                this.hovered = true;
1057            }
1058        }
1059
1060        this.refreshNavItem();
1061
1062        if (this.hoverPercent !== 1 ||
1063            this.sliceHoverPathFunction !== null ||
1064            this.sliceHoverTransformFunction !== null ||
1065            this.titleHover !== this.title ||
1066            this.titleHoverWidth !== this.titleWidth ||
1067            this.titleHoverHeight !== this.titleHeight) {
1068            this.setCurrentTransform(false, false);
1069        }
1070
1071        this.wheelnav.marker.setCurrentTransform();
1072        this.wheelnav.spreader.setCurrentTransform(true);
1073    }
1074};
1075
1076wheelnavItem.prototype.setCurrentTransform = function (locked, withFinishFunction) {
1077
1078    if (!this.wheelnav.clickModeRotate ||
1079        (!this.navSliceUnderAnimation &&
1080        !this.navTitleUnderAnimation &&
1081        !this.navLineUnderAnimation)) {
1082
1083        if (locked !== undefined &&
1084            locked === true) {
1085            this.navSliceUnderAnimation = true;
1086            this.navTitleUnderAnimation = true;
1087            this.navLineUnderAnimation = true;
1088        }
1089
1090        //Set transforms
1091        //  Slice
1092        this.navSliceCurrentTransformString = "";
1093        if (this.wheelnav.clickModeRotate) { this.navSliceCurrentTransformString += this.getItemRotateString(); }
1094        if (this.selected) {
1095            if (this.selectTransform.sliceTransformString !== undefined) { this.navSliceCurrentTransformString += this.selectTransform.sliceTransformString; }
1096        }
1097        else if (this.hovered) {
1098            if (this.hoverTransform.sliceTransformString !== undefined) { this.navSliceCurrentTransformString += this.hoverTransform.sliceTransformString; }
1099        }
1100        if (this.sliceTransform.sliceTransformString !== undefined) { this.navSliceCurrentTransformString += this.sliceTransform.sliceTransformString; }
1101
1102        //  Line
1103        this.navLineCurrentTransformString = "";
1104        if (this.wheelnav.clickModeRotate) { this.navLineCurrentTransformString += this.getItemRotateString(); }
1105        if (this.selected) {
1106            if (this.selectTransform.lineTransformString !== undefined) { this.navLineCurrentTransformString += this.selectTransform.lineTransformString; }
1107        }
1108        else if (this.hovered) {
1109            if (this.hoverTransform.lineTransformString !== undefined) { this.navLineCurrentTransformString += this.hoverTransform.lineTransformString; }
1110        }
1111        if (this.sliceTransform.lineTransformString !== undefined) { this.navLineCurrentTransformString += this.sliceTransform.lineTransformString; }
1112
1113        //  Title
1114        this.navTitleCurrentTransformString = "";
1115        this.navTitleCurrentTransformString += this.getTitleRotateString(true);
1116
1117        if (this.selected) {
1118            if (this.navTitleSizeSelectedTransform !== undefined) {
1119                this.navTitleCurrentTransformString += this.navTitleSizeSelectedTransform;
1120            }
1121            if (this.selectTransform.titleTransformString === "" ||
1122                this.selectTransform.titleTransformString === undefined) {
1123                this.navTitleCurrentTransformString += ",s1";
1124            }
1125            else {
1126                this.navTitleCurrentTransformString += "," + this.selectTransform.titleTransformString;
1127            }
1128            if (this.wheelnav.currentPercent < 0.05) {
1129                this.navTitleCurrentTransformString += ",s0.05";
1130            }
1131        }
1132        else if (this.hovered) {
1133            if (this.navTitleSizeHoverTransform !== undefined) {
1134                this.navTitleCurrentTransformString += this.navTitleSizeHoverTransform;
1135            }
1136            if (this.hoverTransform.titleTransformString === "" ||
1137                this.hoverTransform.titleTransformString === undefined) {
1138                this.navTitleCurrentTransformString += ",s1";
1139            }
1140            else {
1141                this.navTitleCurrentTransformString += "," + this.hoverTransform.titleTransformString;
1142            }
1143        }
1144        else if (this.wheelnav.currentPercent < 0.05) {
1145            this.navTitleCurrentTransformString += ",s0.05";
1146        }
1147        else if (this.titleSpreadScale) {
1148            this.navTitleCurrentTransformString += ",s" + this.wheelnav.currentPercent;
1149        }
1150        else {
1151            if (this.navTitleSizeTransform !== undefined) {
1152                this.navTitleCurrentTransformString += this.navTitleSizeTransform;
1153            }
1154            if (this.sliceTransform.titleTransformString === "" ||
1155                this.sliceTransform.titleTransformString === undefined) {
1156                this.navTitleCurrentTransformString += ",s1";
1157            }
1158            else {
1159                this.navTitleCurrentTransformString += "," + this.sliceTransform.titleTransformString;
1160            }
1161        }
1162
1163        //Set path
1164        var slicePath = this.getCurrentPath();
1165
1166        var sliceTransformAttr = {};
1167
1168        sliceTransformAttr = {
1169            path: slicePath.slicePathString,
1170            transform: this.navSliceCurrentTransformString
1171        };
1172
1173        var sliceClickableTransformAttr = {};
1174
1175        if (this.sliceClickablePathFunction !== null) {
1176            var sliceClickablePath = this.getCurrentClickablePath();
1177
1178            sliceClickableTransformAttr = {
1179                path: sliceClickablePath.slicePathString,
1180                transform: this.navSliceCurrentTransformString
1181            };
1182        }
1183
1184        var lineTransformAttr = {};
1185
1186        lineTransformAttr = {
1187            path: slicePath.linePathString,
1188            transform: this.navLineCurrentTransformString
1189        };
1190
1191        //Set title
1192        var currentTitle = this.getCurrentTitle();
1193        var titleTransformAttr = {};
1194
1195        if (wheelnavTitle().isPathTitle(currentTitle.title)) {
1196            titleTransformAttr = {
1197                path: currentTitle.path,
1198                transform: this.navTitleCurrentTransformString
1199            };
1200        }
1201        else if (wheelnavTitle().isImageTitle(currentTitle.title)) {
1202            titleTransformAttr = {
1203                x: currentTitle.x,
1204                y: currentTitle.y,
1205                width: currentTitle.width,
1206                height: currentTitle.height,
1207                transform: this.navTitleCurrentTransformString
1208            };
1209
1210            this.navTitle.attr({ src: currentTitle.src });
1211        }
1212        else {
1213            titleTransformAttr = {
1214                x: currentTitle.x,
1215                y: currentTitle.y,
1216                transform: this.navTitleCurrentTransformString
1217            };
1218
1219            if (currentTitle.title !== null) {
1220                this.navTitle.attr({ text: currentTitle.title });
1221            }
1222        }
1223
1224        var thisNavItem = this;
1225        var thisWheelnav = this.wheelnav;
1226
1227        //Animate navitem
1228        this.animSlice = Raphael.animation(sliceTransformAttr, this.animatetime, this.animateeffect, function () {
1229            thisNavItem.navSliceUnderAnimation = false;
1230            thisWheelnav.animateUnlock(false, withFinishFunction);
1231        });
1232        this.animLine = Raphael.animation(lineTransformAttr, this.animatetime, this.animateeffect, function () {
1233            thisNavItem.navLineUnderAnimation = false;
1234            thisWheelnav.animateUnlock(false, withFinishFunction);
1235        });
1236        this.animTitle = Raphael.animation(titleTransformAttr, this.animatetime, this.animateeffect, function () {
1237            thisNavItem.navTitleUnderAnimation = false;
1238            thisWheelnav.animateUnlock(false, withFinishFunction);
1239        });
1240
1241        if (this.navClickableSlice !== null) {
1242            this.animClickableSlice = Raphael.animation(sliceClickableTransformAttr, this.animatetime, this.animateeffect);
1243        }
1244
1245        var animateRepeatCount = this.wheelnav.animateRepeatCount;
1246
1247        if (locked !== undefined &&
1248            locked === true) {
1249            if (this.wheelItemIndex === this.wheelnav.navItemCount - 1) {
1250
1251                for (i = 0; i < this.wheelnav.navItemCount; i++) {
1252                    var navItemSlice = this.wheelnav.navItems[i];
1253                    navItemSlice.navSlice.animate(navItemSlice.animSlice.repeat(animateRepeatCount));
1254                }
1255                for (i = 0; i < this.wheelnav.navItemCount; i++) {
1256                    var navItemLine = this.wheelnav.navItems[i];
1257                    navItemLine.navLine.animate(navItemLine.animLine.repeat(animateRepeatCount));
1258                }
1259                for (i = 0; i < this.wheelnav.navItemCount; i++) {
1260                    var navItemTitle = this.wheelnav.navItems[i];
1261                    navItemTitle.navTitle.animate(navItemTitle.animTitle.repeat(animateRepeatCount));
1262                }
1263
1264                if (this.wheelnav.sliceClickablePathFunction !== null) {
1265                    for (i = 0; i < this.wheelnav.navItemCount; i++) {
1266                        var navItemClickableSlice = this.wheelnav.navItems[i];
1267                        if (navItemClickableSlice.navClickableSlice !== null) {
1268                            navItemClickableSlice.navClickableSlice.animate(navItemClickableSlice.animClickableSlice.repeat(animateRepeatCount));
1269                        }
1270                    }
1271                }
1272            }
1273        }
1274        else {
1275            this.navSlice.animate(this.animSlice.repeat(animateRepeatCount));
1276            this.navLine.animate(this.animLine.repeat(animateRepeatCount));
1277            this.navTitle.animate(this.animTitle.repeat(animateRepeatCount));
1278
1279            if (this.navClickableSlice !== null) {
1280                this.navClickableSlice.animate(this.animClickableSlice.repeat(animateRepeatCount));
1281            }
1282        }
1283    }
1284};
1285
1286wheelnavItem.prototype.setTitle = function (title) {
1287    if (title === undefined) {
1288        this.title = null;
1289    }
1290    else {
1291        this.title = title;
1292    }
1293    this.titleHover = this.title;
1294    this.titleSelected = this.title;
1295};
1296
1297wheelnavItem.prototype.setTooltip = function (tooltip) {
1298    if (tooltip !== null) {
1299        this.navItem.attr({ title: tooltip });
1300    }
1301};
1302
1303wheelnavItem.prototype.refreshNavItem = function (withPathAndTransform) {
1304
1305    if (this.selected) {
1306        this.navSlice.attr(this.sliceSelectedAttr);
1307        this.navLine.attr(this.lineSelectedAttr);
1308        this.navTitle.attr(this.titleSelectedAttr);
1309        if (this.navClickableSlice !== null) { this.navClickableSlice.attr(this.sliceClickableSelectedAttr); }
1310
1311        if (this.wheelnav.selectedToFront) {
1312            this.navSlice.toFront();
1313            this.navLine.toFront();
1314            this.navTitle.toFront();
1315            if (this.navClickableSlice !== null) { this.navClickableSlice.toFront(); }
1316        }
1317        else {
1318            if (this.navClickableSlice !== null) { this.navClickableSlice.toBack(); }
1319            this.navTitle.toBack();
1320            this.navLine.toBack();
1321            this.navSlice.toBack();
1322        }
1323    }
1324    else if (this.hovered) {
1325        this.navSlice.attr(this.sliceHoverAttr).toFront();
1326        this.navLine.attr(this.lineHoverAttr).toFront();
1327        this.navTitle.attr(this.titleHoverAttr).toFront();
1328        if (this.navClickableSlice !== null) { this.navClickableSlice.attr(this.sliceClickableHoverAttr).toFront(); }
1329    }
1330    else {
1331        this.navSlice.attr(this.slicePathAttr);
1332        this.navLine.attr(this.linePathAttr);
1333        this.navTitle.attr(this.titleAttr);
1334        if (this.navClickableSlice !== null) { this.navClickableSlice.attr(this.sliceClickablePathAttr); }
1335
1336        if (this.navClickableSlice !== null) { this.navClickableSlice.toBack(); };
1337        this.navTitle.toBack();
1338        this.navLine.toBack();
1339        this.navSlice.toBack();
1340    }
1341    
1342    if (withPathAndTransform !== undefined &&
1343        withPathAndTransform === true) {
1344        this.initPathsAndTransforms();
1345        this.setCurrentTransform(false, false);
1346    }
1347};
1348
1349wheelnavItem.prototype.setWheelSettings = function (force) {
1350
1351    //Set slice from wheelnav
1352    if (this.wheelnav.slicePathAttr !== null) { this.slicePathAttr = JSON.parse(JSON.stringify(this.wheelnav.slicePathAttr)); }
1353    if (this.wheelnav.sliceHoverAttr !== null) { this.sliceHoverAttr = JSON.parse(JSON.stringify(this.wheelnav.sliceHoverAttr)); }
1354    if (this.wheelnav.sliceSelectedAttr !== null) { this.sliceSelectedAttr = JSON.parse(JSON.stringify(this.wheelnav.sliceSelectedAttr)); }
1355    
1356    //Set title from wheelnav
1357    if (this.wheelnav.titleAttr !== null) { this.titleAttr = JSON.parse(JSON.stringify(this.wheelnav.titleAttr)); }
1358    if (this.wheelnav.titleHoverAttr !== null) { this.titleHoverAttr = JSON.parse(JSON.stringify(this.wheelnav.titleHoverAttr)); }
1359    if (this.wheelnav.titleSelectedAttr !== null) { this.titleSelectedAttr = JSON.parse(JSON.stringify(this.wheelnav.titleSelectedAttr)); }
1360    if (this.wheelnav.titleRotateAngle !== null && this.titleRotateAngle === null) { this.titleRotateAngle = this.wheelnav.titleRotateAngle; }
1361
1362    // Size
1363    if (this.wheelnav.titleWidth !== null && this.titleWidth === null) { this.titleWidth = this.wheelnav.titleWidth; }
1364    if (this.wheelnav.titleHeight !== null && this.titleHeight === null) { this.titleHeight = this.wheelnav.titleHeight; }
1365    if (this.titleWidth !== null && this.titleHeight === null) { this.titleHeight = this.titleWidth; }
1366    if (this.titleWidth === null && this.titleHeight !== null) { this.titleWidth = this.titleHeight; }
1367    if (wheelnavTitle().isImageTitle(this.title)) {
1368        // Image default value
1369        if (this.titleWidth === null) { this.titleWidth = 32; }
1370        if (this.titleHeight === null) { this.titleHeight = 32; }
1371    }
1372
1373    if (this.wheelnav.titleHoverWidth !== null && this.titleHoverWidth === null) { this.titleHoverWidth = this.wheelnav.titleHoverWidth; }
1374    if (this.wheelnav.titleHoverHeight !== null && this.titleHoverHeight === null) { this.titleHoverHeight = this.wheelnav.titleHoverHeight; }
1375    if (this.titleHoverWidth !== null && this.titleHoverHeight === null) { this.titleHoverHeight = this.titleHoverWidth; }
1376    if (this.titleHoverWidth === null && this.titleHoverHeight !== null) { this.titleHoverWidth = this.titleHoverHeight; }
1377
1378    if (this.wheelnav.titleSelectedWidth !== null && this.titleSelectedWidth === null) { this.titleSelectedWidth = this.wheelnav.titleSelectedWidth; }
1379    if (this.wheelnav.titleSelectedHeight !== null && this.titleSelectedHeight === null) { this.titleSelectedHeight = this.wheelnav.titleSelectedHeight; }
1380    if (this.titleSelectedWidth !== null && this.titleSelectedHeight === null) { this.titleSelectedHeight = this.titleSelectedWidth; }
1381    if (this.titleSelectedWidth === null && this.titleSelectedHeight !== null) { this.titleSelectedWidth = this.titleSelectedHeight; }
1382
1383    if (this.titleHoverHeight === null) { this.titleHoverHeight = this.titleHeight; }
1384    if (this.titleHoverWidth === null) { this.titleHoverWidth = this.titleWidth; }
1385    if (this.titleSelectedHeight === null) { this.titleSelectedHeight = this.titleHeight; }
1386    if (this.titleSelectedWidth === null) { this.titleSelectedWidth = this.titleWidth; }
1387
1388    //Set line from wheelnav
1389    if (this.wheelnav.linePathAttr !== null) { this.linePathAttr = JSON.parse(JSON.stringify(this.wheelnav.linePathAttr)); }
1390    if (this.wheelnav.lineHoverAttr !== null) { this.lineHoverAttr = JSON.parse(JSON.stringify(this.wheelnav.lineHoverAttr)); }
1391    if (this.wheelnav.lineSelectedAttr !== null) { this.lineSelectedAttr = JSON.parse(JSON.stringify(this.wheelnav.lineSelectedAttr)); }
1392
1393    //Set animation from wheelnav
1394    if (this.animateeffect === null || force) {
1395        if (this.wheelnav.animateeffect !== null) { this.animateeffect = this.wheelnav.animateeffect; }
1396        else { this.animateeffect = "bounce"; }
1397    }
1398    if (this.animatetime === null || force) {
1399        if (this.wheelnav.animatetime !== null) { this.animatetime = this.wheelnav.animatetime; }
1400        else { this.animatetime = 1500; }
1401    }
1402
1403    if (this.title !== null)
1403 {
1404        if (this.sliceInitPathFunction === null || force) { this.sliceInitPathFunction = this.wheelnav.sliceInitPathFunction; }
1405        if (this.sliceClickablePathFunction === null || force) { this.sliceClickablePathFunction = this.wheelnav.sliceClickablePathFunction; }
1406        if (this.slicePathFunction === null || force) { this.slicePathFunction = this.wheelnav.slicePathFunction; }
1407        if (this.sliceSelectedPathFunction === null || force) { this.sliceSelectedPathFunction = this.wheelnav.sliceSelectedPathFunction; }
1408        if (this.sliceHoverPathFunction === null || force) { this.sliceHoverPathFunction = this.wheelnav.sliceHoverPathFunction; }
1409            
1410        if (this.sliceTransformFunction === null || force) { this.sliceTransformFunction = this.wheelnav.sliceTransformFunction; }
1411        if (this.sliceSelectedTransformFunction === null || force) { this.sliceSelectedTransformFunction = this.wheelnav.sliceSelectedTransformFunction; }
1412        if (this.sliceHoverTransformFunction === null || force) { this.sliceHoverTransformFunction = this.wheelnav.sliceHoverTransformFunction; }
1413        if (this.sliceInitTransformFunction === null || force) { this.sliceInitTransformFunction = this.wheelnav.sliceInitTransformFunction; }
1414    }
1415    else {
1416        this.sliceInitPathFunction = slicePath().NullInitSlice;
1417        this.sliceClickablePathFunction = slicePath().NullSlice;
1418        this.slicePathFunction = slicePath().NullSlice;
1419        this.sliceSelectedPathFunction = null;
1420        this.sliceHoverPathFunction = null;
1421        this.sliceTransformFunction = null;
1422        this.sliceSelectedTransformFunction = null;
1423        this.sliceHoverTransformFunction = null;
1424        this.sliceInitTransformFunction = null;
1425    }
1426
1427    if (this.slicePathCustom === null || force) { this.slicePathCustom = this.wheelnav.slicePathCustom; }
1428    if (this.sliceClickablePathCustom === null || force) { this.sliceClickablePathCustom = this.wheelnav.sliceClickablePathCustom; }
1429    if (this.sliceSelectedPathCustom === null || force) { this.sliceSelectedPathCustom = this.wheelnav.sliceSelectedPathCustom; }
1430    if (this.sliceHoverPathCustom === null || force) { this.sliceHoverPathCustom = this.wheelnav.sliceHoverPathCustom; }
1431    if (this.sliceInitPathCustom === null || force) { this.sliceInitPathCustom = this.wheelnav.sliceInitPathCustom; }
1432
1433    if (this.sliceTransformCustom === null || force) { this.sliceTransformCustom = this.wheelnav.sliceTransformCustom; }
1434    if (this.sliceSelectedTransformCustom === null || force) { this.sliceSelectedTransformCustom = this.wheelnav.sliceSelectedTransformCustom; }
1435    if (this.sliceHoverTransformCustom === null || force) { this.sliceHoverTransformCustom = this.wheelnav.sliceHoverTransformCustom; }
1436    if (this.sliceInitTransformCustom === null || force) { this.sliceInitTransformCustom = this.wheelnav.sliceInitTransformCustom; }
1437
1438    if (this.initPercent === null || force) { this.initPercent = this.wheelnav.initPercent; }
1439    if (this.minPercent === null || force) { this.minPercent = this.wheelnav.minPercent; }
1440    if (this.maxPercent === null || force) { this.maxPercent = this.wheelnav.maxPercent; }
1441    if (this.hoverPercent === null || force) { this.hoverPercent = this.wheelnav.hoverPercent; }
1442    if (this.selectedPercent === null || force) { this.selectedPercent = this.wheelnav.selectedPercent; }
1443    if (this.clickablePercentMin === null || force) { this.clickablePercentMin = this.wheelnav.clickablePercentMin; }
1444    if (this.clickablePercentMax === null || force) { this.clickablePercentMax = this.wheelnav.clickablePercentMax; }
1445
1446    if (this.titleSpreadScale === null || force) {
1447        if (this.wheelnav.titleSpreadScale !== null) { this.titleSpreadScale = this.wheelnav.titleSpreadScale; }
1448        else { this.titleSpreadScale = false; }
1449    }
1450    if (this.sliceAngle === null || force) {
1451        if (this.wheelnav.sliceAngle !== null) { this.sliceAngle = this.wheelnav.sliceAngle; }
1452    }
1453};
1454
1455wheelnavItem.prototype.initPathsAndTransforms = function () {
1456
1457    this.sliceHelper = new pathHelper();
1458    this.sliceHelper.centerX = this.wheelnav.centerX;
1459    this.sliceHelper.centerY = this.wheelnav.centerY;
1460    this.sliceHelper.wheelRadius = this.wheelnav.wheelRadius;
1461    this.sliceHelper.startAngle = this.baseAngle;
1462    this.sliceHelper.sliceAngle = this.sliceAngle;
1463    this.sliceHelper.itemIndex = this.itemIndex;
1464
1465    //Set min/max sliecePaths
1466    //Default - min
1467    this.slicePathMin = this.slicePathFunction(this.sliceHelper, this.minPercent, this.slicePathCustom);
1468
1469    //Default - max
1470    this.slicePathMax = this.slicePathFunction(this.sliceHelper, this.maxPercent, this.slicePathCustom);
1471
1472    //Selected - min
1473    if (this.sliceSelectedPathFunction !== null) {
1474        this.selectedSlicePathMin = this.sliceSelectedPathFunction(this.sliceHelper, this.selectedPercent * this.minPercent, this.sliceSelectedPathCustom);
1475    }
1476    else {
1477        this.selectedSlicePathMin = this.slicePathFunction(this.sliceHelper, this.selectedPercent * this.minPercent, this.sliceSelectedPathCustom);
1478    }
1479
1480    //Selected - max
1481    if (this.sliceSelectedPathFunction !== null) {
1482        this.selectedSlicePathMax = this.sliceSelectedPathFunction(this.sliceHelper, this.selectedPercent * this.maxPercent, this.sliceSelectedPathCustom);
1483    }
1484    else {
1485        this.selectedSlicePathMax = this.slicePathFunction(this.sliceHelper, this.selectedPercent * this.maxPercent, this.sliceSelectedPathCustom);
1486    }
1487
1488    //Hovered - min
1489    if (this.sliceHoverPathFunction !== null) {
1490        this.hoverSlicePathMin = this.sliceHoverPathFunction(this.sliceHelper, this.hoverPercent * this.minPercent, this.sliceHoverPathCustom);
1491    }
1492    else {
1493        this.hoverSlicePathMin = this.slicePathFunction(this.sliceHelper, this.hoverPercent * this.minPercent, this.sliceHoverPathCustom);
1494    }
1495
1496    //Hovered - max
1497    if (this.sliceHoverPathFunction !== null) {
1498        this.hoverSlicePathMax = this.sliceHoverPathFunction(this.sliceHelper, this.hoverPercent * this.maxPercent, this.sliceHoverPathCustom);
1499    }
1500    else {
1501        this.hoverSlicePathMax = this.slicePathFunction(this.sliceHelper, this.hoverPercent * this.maxPercent, this.sliceHoverPathCustom);
1502    }
1503
1504    //Set min/max sliececlickablePaths
1505    
1506    if (this.sliceClickablePathFunction !== null) {
1507        //Default - min
1508        this.clickableSlicePathMin = this.sliceClickablePathFunction(this.sliceHelper, this.clickablePercentMin, this.sliceClickablePathCustom);
1509        //Default - max
1510        this.clickableSlicePathMax = this.sliceClickablePathFunction(this.sliceHelper, this.clickablePercentMax, this.sliceClickablePathCustom);
1511    }
1512
1513    //Initial path
1514    if (this.sliceInitPathFunction !== null) {
1515        this.sliceInitPath = this.sliceInitPathFunction(this.sliceHelper, this.initPercent, this.sliceInitPathCustom);
1516    }
1517    else {
1518        if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
1519            this.sliceInitPath = this.slicePathFunction(this.sliceHelper, this.maxPercent, this.sliceInitPathCustom);
1520        }
1521        else {
1522            this.sliceInitPath = this.slicePathFunction(this.sliceHelper, this.minPercent, this.sliceInitPathCustom);
1523        }
1524    }
1525
1526    //Set sliceTransforms
1527    //Default
1528    if (this.sliceTransformFunction !== null) {
1529        this.sliceTransform = this.sliceTransformFunction(this.wheelnav.centerX, this.wheelnav.centerY, this.wheelnav.wheelRadius, this.baseAngle, this.sliceAngle, this.titleRotateAngle, this.itemIndex, this.sliceTransformCustom);
1530    }
1531    else {
1532        this.sliceTransform = sliceTransform().NullTransform;
1533    }
1534
1535    //Selected
1536    if (this.sliceSelectedTransformFunction !== null) {
1537        this.selectTransform = this.sliceSelectedTransformFunction(this.wheelnav.centerX, this.wheelnav.centerY, this.wheelnav.wheelRadius, this.baseAngle, this.sliceAngle, this.titleRotateAngle, this.itemIndex, this.sliceSelectedTransformCustom);
1538    }
1539    else {
1540        this.selectTransform = sliceTransform().NullTransform;
1541    }
1542
1543    //Hovered
1544    if (this.sliceHoverTransformFunction !== null) {
1545        this.hoverTransform = this.sliceHoverTransformFunction(this.wheelnav.centerX, this.wheelnav.centerY, this.wheelnav.wheelRadius, this.baseAngle, this.sliceAngle, this.titleRotateAngle, this.itemIndex, this.sliceHoverTransformCustom);
1546    }
1547    else {
1548        this.hoverTransform = sliceTransform().NullTransform;
1549    }
1550
1551    //Initial transform
1552    if (this.sliceInitTransformFunction !== null) {
1553        this.initTransform = this.sliceInitTransformFunction(this.wheelnav.centerX, this.wheelnav.centerY, this.wheelnav.wheelRadius, this.baseAngle, this.sliceAngle, this.titleRotateAngle, this.itemIndex, this.sliceInitTransformCustom);
1554    }
1555    else {
1556        this.initTransform = sliceTransform().NullTransform;
1557    }
1558
1559    //Set titles
1560    if (wheelnavTitle().isPathTitle(this.title)) {
1561        initNavTitle = new wheelnavTitle(this.title, this.wheelnav.raphael.raphael);
1562        basicNavTitleMin = new wheelnavTitle(this.title, this.wheelnav.raphael.raphael);
1563        basicNavTitleMax = new wheelnavTitle(this.title, this.wheelnav.raphael.raphael);
1564        hoverNavTitleMin = new wheelnavTitle(this.titleHover, this.wheelnav.raphael.raphael);
1565        hoverNavTitleMax = new wheelnavTitle(this.titleHover, this.wheelnav.raphael.raphael);
1566        selectedNavTitleMin = new wheelnavTitle(this.titleSelected, this.wheelnav.raphael.raphael);
1567        selectedNavTitleMax = new wheelnavTitle(this.titleSelected, this.wheelnav.raphael.raphael);
1568        this.navTitleSizeTransform = basicNavTitleMax.getTitleSizeTransform(this.titleWidth, this.titleHeight);
1569        this.navTitleSizeHoverTransform = hoverNavTitleMax.getTitleSizeTransform(this.titleHoverWidth, this.titleHoverHeight);
1570        this.navTitleSizeSelectedTransform = selectedNavTitleMax.getTitleSizeTransform(this.titleSelectedWidth, this.titleSelectedHeight);
1571    }
1572    else {
1573        initNavTitle = new wheelnavTitle(this.title);
1574        basicNavTitleMin = new wheelnavTitle(this.title);
1575        basicNavTitleMax = new wheelnavTitle(this.title);
1576        hoverNavTitleMin = new wheelnavTitle(this.titleHover);
1577        hoverNavTitleMax = new wheelnavTitle(this.titleHover);
1578        selectedNavTitleMin = new wheelnavTitle(this.titleSelected);
1579        selectedNavTitleMax = new wheelnavTitle(this.titleSelected);
1580    }
1581
1582    this.initNavTitle = initNavTitle.getTitlePercentAttr(this.sliceInitPath.titlePosX, this.sliceInitPath.titlePosY, this.titleWidth, this.titleHeight);
1583    this.basicNavTitleMin = basicNavTitleMin.getTitlePercentAttr(this.slicePathMin.titlePosX, this.slicePathMin.titlePosY, this.titleWidth, this.titleHeight);
1584    this.basicNavTitleMax = basicNavTitleMax.getTitlePercentAttr(this.slicePathMax.titlePosX, this.slicePathMax.titlePosY, this.titleWidth, this.titleHeight);
1585    this.hoverNavTitleMin = hoverNavTitleMin.getTitlePercentAttr(this.hoverSlicePathMin.titlePosX, this.hoverSlicePathMin.titlePosY, this.titleHoverWidth, this.titleHoverHeight);
1586    this.hoverNavTitleMax = hoverNavTitleMax.getTitlePercentAttr(this.hoverSlicePathMax.titlePosX, this.hoverSlicePathMax.titlePosY, this.titleHoverWidth, this.titleHoverHeight);
1587    this.selectedNavTitleMin = selectedNavTitleMin.getTitlePercentAttr(this.selectedSlicePathMin.titlePosX, this.selectedSlicePathMin.titlePosY, this.titleSelectedWidth, this.titleSelectedHeight);
1588    this.selectedNavTitleMax = selectedNavTitleMax.getTitlePercentAttr(this.selectedSlicePathMax.titlePosX, this.selectedSlicePathMax.titlePosY, this.titleSelectedWidth, this.titleSelectedHeight);
1589};
1590
1591wheelnavItem.prototype.getCurrentPath = function () {
1592    var slicePath;
1593
1594    if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
1595        if (this.selected) {
1596            slicePath = this.selectedSlicePathMax;
1597        }
1598        else {
1599            if (this.hovered) {
1600                slicePath = this.hoverSlicePathMax;
1601            }
1602            else {
1603                slicePath = this.slicePathMax;
1604            }
1605        }
1606    }
1607    else {
1608        if (this.selected) {
1609            slicePath = this.selectedSlicePathMin;
1610        }
1611        else {
1612            if (this.hovered) {
1613                slicePath = this.hoverSlicePathMin;
1614            }
1615            else {
1616                slicePath = this.slicePathMin;
1617            }
1618        }
1619    }
1620
1621    return slicePath;
1622};
1623
1624wheelnavItem.prototype.getCurrentClickablePath = function () {
1625    var sliceClickablePath;
1626
1627    if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
1628        sliceClickablePath = this.clickableSlicePathMax;
1629    }
1630    else {
1631        sliceClickablePath = this.clickableSlicePathMin;
1632    }
1633
1634    return sliceClickablePath;
1635};
1636
1637wheelnavItem.prototype.getCurrentTitle = function () {
1638    var currentTitle;
1639
1640    if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
1641        if (this.selected) {
1642            currentTitle = this.selectedNavTitleMax;
1643        }
1644        else {
1645            if (this.hovered) {
1646                currentTitle = this.hoverNavTitleMax;
1647            }
1648            else {
1649                currentTitle = this.basicNavTitleMax;
1650            }
1651        }
1652    }
1653    else {
1654        if (this.selected) {
1655            currentTitle = this.selectedNavTitleMin;
1656        }
1657        else {
1658            if (this.hovered) {
1659                currentTitle = this.hoverNavTitleMin;
1660            }
1661            else {
1662                currentTitle = this.basicNavTitleMin;
1663            }
1664        }
1665    }
1666
1667    return currentTitle;
1668};
1669
1670wheelnavItem.prototype.getItemRotateString = function () {
1671    return "r," + (this.currentRotateAngle).toString() + "," + this.wheelnav.centerX + "," + this.wheelnav.centerY;
1672};
1673
1674wheelnavItem.prototype.getTitleRotateString = function (withTitleRotateAngle) {
1675
1676    var titleRotate = "";
1677    titleRotate += this.getItemRotateString();
1678
1679    if (this.titleRotateAngle !== null && withTitleRotateAngle) {
1680        titleRotate += ",r," + (this.navAngle + this.titleRotateAngle).toString();
1681    }
1682    else {
1683        titleRotate += ",r," + (-this.currentRotateAngle).toString();
1684    }
1685
1686    return titleRotate;
1687};
1688
1689wheelnavTitle = function (title, raphael) {
1690    this.title = title;
1691    //Calculate relative path
1692    if (title !== null) {
1693        if (raphael !== undefined) {
1694            this.relativePath = raphael.pathToRelative(title);
1695            var bbox = raphael.pathBBox(this.relativePath);
1696            this.centerX = bbox.cx;
1697            this.centerY = bbox.cy;
1698            this.width = bbox.width;
1699            this.height = bbox.height;
1700            this.startX = this.relativePath[0][1];
1701            this.startY = this.relativePath[0][2];
1702        }
1703        this.title = title;
1704    }
1705    else {
1706        this.title = "";
1707    }
1708
1709    this.isPathTitle = function (title) {
1710        if (title !== null &&
1711            (title.substr(0, 1) === "m" ||
1712            title.substr(0, 1) === "M") &&
1713            (title.substr(title.length - 1, 1) === "z" ||
1714            title.substr(title.length - 1, 1) === "Z") &&
1715            (title.indexOf(",") > -1 ||
1716            title.indexOf(" ") > -1)){
1717            return true;
1718        }
1719        else {
1720            return false;
1721        }
1722    };
1723
1724    this.isImageTitle = function (title) {
1725        if (title === undefined) { title = this.title;}
1726        if (title !== null &&
1727            title.substr(0, 7) === "imgsrc:") {
1728            return true;
1729        }
1730        else {
1731            return false;
1732        }
1733    };
1734
1735    return this;
1736};
1737
1738wheelnavTitle.prototype.getTitlePercentAttr = function (currentX, currentY, titlewidth, titleheight) {
1739
1740    var transformAttr = {};
1741
1742    if (this.relativePath !== undefined) {
1743        var pathCx = currentX + (this.startX - this.centerX);
1744        var pathCy = currentY + (this.startY - this.centerY);
1745
1746        this.relativePath[0][1] = pathCx;
1747        this.relativePath[0][2] = pathCy;
1748
1749        transformAttr = {
1750            path: this.relativePath,
1751            title: this.title
1752        };
1753    }
1754    else {
1755        if (this.isImageTitle()) {
1756            transformAttr = {
1757                x: currentX - (titlewidth / 2),
1758                y: currentY - (titleheight / 2),
1759                width: titlewidth,
1760                height: titleheight,
1761                title: this.title,
1762                src: this.title.substr(7, this.title.length)
1763            };
1764        }
1765        else {
1766            transformAttr = {
1767                x: currentX,
1768                y: currentY,
1769                title: this.title
1770            };
1771        }
1772    }
1773
1774    return transformAttr;
1775};
1776
1777wheelnavTitle.prototype.getTitleSizeTransform = function (titlewidth, titleheight) {
1778
1779    var transformAttr = "";
1780
1781    //Calculate path width & height
1782    if (titlewidth !== null && titleheight !== null) {
1783        transformAttr = "s";
1784        if (this.height > this.width) {
1785            transformAttr += (titlewidth / this.height).toString() + ",";
1786            transformAttr += (titleheight / this.height).toString();
1787        }
1788        else {
1789            transformAttr += (titlewidth / this.width).toString() + ",";
1790            transformAttr += (titleheight / this.width).toString();
1791        }
1792    }
1793
1794    return transformAttr;
1795};
1796
1797///#source 1 1 /js/source/wheelnav.style.js
1798/* ======================================================================================= */
1799/* Default styles and available css classes                                                */
1800/* ======================================================================================= */
1801/* ======================================================================================= */
1802/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/css3.html          */
1803/* ======================================================================================= */
1804
1805wheelnav.prototype.styleWheel = function () {
1806    if (!this.cssMode) {
1807        if (this.spreaderPathInAttr === undefined || this.spreaderPathInAttr === null) {
1808            this.spreaderPathInAttr = { fill: "#444", stroke: "#444", "stroke-width": 2, cursor: 'pointer' };
1809        }
1810        if (this.spreaderPathOutAttr === undefined || this.spreaderPathOutAttr === null) {
1811            this.spreaderPathOutAttr = { fill: "#444", stroke: "#444", "stroke-width": 2, cursor: 'pointer' };
1812        }
1813        if (this.spreaderTitleInAttr === undefined || this.spreaderTitleInAttr === null) {
1814            this.spreaderTitleInAttr = { fill: "#eee", stroke: "#444", cursor: 'pointer' };
1815        }
1816        if (this.spreaderTitleOutAttr === undefined || this.spreaderTitleOutAttr === null) {
1817            this.spreaderTitleOutAttr = { fill: "#eee", stroke: "#444", cursor: 'pointer' };
1818        }
1819        if (this.markerAttr === undefined || this.markerAttr === null) {
1820            this.markerAttr = { stroke: "#444", "stroke-width": 2 };
1821        }
1822    }
1823    else {
1824        this.spreaderPathInAttr = { "class": this.getSpreaderCssClass("in") };
1825        this.spreaderPathOutAttr = { "class": this.getSpreaderCssClass("out") };
1826        this.spreaderTitleInAttr = { "class": this.getSpreaderTitleCssClass("in") };
1827        this.spreaderTitleOutAttr = { "class": this.getSpreaderTitleCssClass("out") };
1828        this.markerAttr = { "class": this.getMarkerCssClass() };
1829    }
1830};
1831
1832wheelnavItem.prototype.styleNavItem = function () {
1833    if (!this.wheelnav.cssMode) {
1834        this.slicePathAttr = { stroke: "#333", "stroke-width": 0, cursor: 'pointer', "fill-opacity": 1 };
1835        this.sliceHoverAttr = { stroke: "#222", "stroke-width": 0, cursor: 'pointer', "fill-opacity": 0.77 };
1836        this.sliceSelectedAttr = { stroke: "#111", "stroke-width": 0, cursor: 'default', "fill-opacity": 1 };
1837
1838        this.titleAttr = { font: this.titleFont, fill: "#333", stroke: "none", cursor: 'pointer' };
1839        this.titleHoverAttr = { font: this.titleFont, fill: "#222", cursor: 'pointer', stroke: "none" };
1840        this.titleSelectedAttr = { font: this.titleFont, fill: "#fff", cursor: 'default' };
1841
1842        this.linePathAttr = { stroke: "#444", "stroke-width": 1, cursor: 'pointer' };
1843        this.lineHoverAttr = { stroke: "#222", "stroke-width": 2, cursor: 'pointer' };
1844        this.lineSelectedAttr = { stroke: "#444", "stroke-width": 1, cursor: 'default' };
1845    }
1846    else {
1847        this.slicePathAttr = { "class": this.wheelnav.getSliceCssClass(this.wheelItemIndex, "basic") };
1848        this.sliceHoverAttr = { "class": this.wheelnav.getSliceCssClass(this.wheelItemIndex, "hover") };
1849        this.sliceSelectedAttr = { "class": this.wheelnav.getSliceCssClass(this.wheelItemIndex, "selected") };
1850
1851        this.titleAttr = { "class": this.wheelnav.getTitleCssClass(this.wheelItemIndex, "basic") };
1852        this.titleHoverAttr = { "class": this.wheelnav.getTitleCssClass(this.wheelItemIndex, "hover") };
1853        this.titleSelectedAttr = { "class": this.wheelnav.getTitleCssClass(this.wheelItemIndex, "selected") };
1854
1855        this.linePathAttr = { "class": this.wheelnav.getLineCssClass(this.wheelItemIndex, "basic") };
1856        this.lineHoverAttr = { "class": this.wheelnav.getLineCssClass(this.wheelItemIndex, "hover") };
1857        this.lineSelectedAttr = { "class": this.wheelnav.getLineCssClass(this.wheelItemIndex, "selected") };
1858    }
1859
1860    this.sliceClickablePathAttr = { fill: "#FFF", stroke: "#FFF", "stroke-width": 0, cursor: 'pointer', "fill-opacity": 0.01 };
1861    this.sliceClickableHoverAttr = { stroke: "#FFF", "stroke-width": 0, cursor: 'pointer' };
1862    this.sliceClickableSelectedAttr = { stroke: "#FFF", "stroke-width": 0, cursor: 'default' };
1863}
1864
1865wheelnav.prototype.getSliceCssClass = function (index, subclass) {
1866    return "wheelnav-" + this.holderId + "-slice-" + subclass + "-" + index;
1867};
1868wheelnav.prototype.getTitleCssClass = function (index, subclass) {
1869    return "wheelnav-" + this.holderId + "-title-" + subclass + "-" + index;
1870};
1871wheelnav.prototype.getLineCssClass = function (index, subclass) {
1872    return "wheelnav-" + this.holderId + "-line-" + subclass + "-" + index;
1873};
1874wheelnav.prototype.getSpreaderCssClass = function (state) {
1875    return "wheelnav-" + this.holderId + "-spreader-" + state;
1876};
1877wheelnav.prototype.getSpreaderTitleCssClass = function (state) {
1878    return "wheelnav-" + this.holderId + "-spreadertitle-" + state;
1879};
1880wheelnav.prototype.getMarkerCssClass = function () {
1881    return "wheelnav-" + this.holderId + "-marker";
1882};
1883
1884///#source 1 1 /js/source/wheelnav.pathHelper.js
1885/* ======================================================================================= */
1886/* Slice path helper functions                                                                  */
1887/* ======================================================================================= */
1888/* ======================================================================================= */
1889/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/slicePath.html     */
1890/* ======================================================================================= */
1891
1892var pathHelper = function () {
1893
1894    this.sliceRadius = 0;
1895    this.startAngle = 0;
1896    this.middleAngle = 0;
1897    this.endAngle = 0;
1898    this.sliceAngle = 0;
1899    this.startTheta = 0;
1900    this.middleTheta = 0;
1901    this.endTheta = 0;
1902    this.titlePosX = 0;
1903    this.titlePosY = 0;
1904    this.titleRadius = 0;
1905    this.titleTheta = 0;
1906    this.custom = null;
1907    this.centerX = 0;
1908    this.centerY = 0;
1909    this.wheelRadius = 0;
1910    this.itemIndex = 0;
1911    this.navItemCount = 0;
1912    this.navAngle = 0;
1913
1914    this.setBaseValue = function (percent, custom) {
1915
1916        if (custom === null) {
1917            custom = new slicePathCustomization();
1918        }
1919        else {
1920            this.custom = custom;
1921        }
1922
1923        this.sliceRadius = this.wheelRadius * percent * 0.9;
1924
1925        this.middleAngle = this.startAngle + this.sliceAngle / 2;
1926        this.endAngle = this.startAngle + this.sliceAngle;
1927
1928        this.startTheta = this.getTheta(this.startAngle);
1929        this.middleTheta = this.getTheta(this.middleAngle);
1930        this.endTheta = this.getTheta(this.endAngle);
1931
1932        if (custom !== null) {
1933            if (custom.titleRadiusPercent !== null) {
1934                this.titleRadius = this.sliceRadius * custom.titleRadiusPercent;
1935            }
1936            if (custom.titleSliceAnglePercent !== null) {
1937                this.titleTheta = this.getTheta(this.startAngle + this.sliceAngle * custom.titleSliceAnglePercent);
1938            }
1939        }
1940        else {
1941            this.titleRadius = this.sliceRadius * 0.5;
1942            this.titleTheta = this.middleTheta;
1943        }
1944
1945        this.setTitlePos();
1946    };
1947
1948    this.setTitlePos = function () {
1949        this.titlePosX = this.titleRadius * Math.cos(this.titleTheta) + this.centerX;
1950        this.titlePosY = this.titleRadius * Math.sin(this.titleTheta) + this.centerY;
1951    };
1952
1953    this.getX = function (angle, length) {
1954        return length * Math.cos(this.getTheta(angle)) + this.centerX;
1955    };
1956
1957    this.getY = function (angle, length) {
1958        return length * Math.sin(this.getTheta(angle)) + this.centerY;
1959    };
1960
1961    this.MoveTo = function (angle, length) {
1962        return ["M", this.getX(angle, length), this.getY(angle, length)];
1963    };
1964
1965    this.MoveToCenter = function () {
1966        return ["M", this.centerX, this.centerY];
1967    };
1968
1969    this.LineTo = function (angle, length, angleY, lengthY) {
1970        if (angleY === undefined) {
1971            angleY = angle;
1972        }
1973        if (lengthY === undefined) {
1974            lengthY = length;
1975        }
1976        return ["L", this.getX(angle, length), this.getY(angleY, lengthY)];
1977    };
1978
1979    this.ArcTo = function (arcRadius, angle, length) {
1980        return ["A", arcRadius, arcRadius, 0, 0, 1, this.getX(angle, length), this.getY(angle, length)]
1981    };
1982
1983    this.ArcBackTo = function (arcRadius, angle, length) {
1984        return ["A", arcRadius, arcRadius, 0, 0, 0, this.getX(angle, length), this.getY(angle, length)]
1985    };
1986
1987    this.StartSpreader = function (spreaderPathString, angle, length) {
1988        if (this.endAngle - this.startAngle === 360) {
1989            spreaderPathString.push(this.MoveTo(angle, length));
1990        }
1991        else {
1992            spreaderPathString.push(this.MoveToCenter());
1993            spreaderPathString.push(this.LineTo(angle, length));
1994        }
1995    };
1996
1997    this.Close = function () {
1998        return ["z"];
1999    };
2000
2001    this.getTheta = function (angle) {
2002        return (angle % 360) * Math.PI / 180;
2003    };
2004
2005    // Converts from degrees to radians.
2006    this.radians = function (degrees) {
2007        return degrees * Math.PI / 180;
2008    };
2009
2010    // Converts from radians to degrees.
2011    this.degrees = function (radians) {
2012        return radians * 180 / Math.PI;
2013    };
2014
2015    return this;
2016};
2017
2018/* Custom properties
2019    - titleRadiusPercent
2020    - titleSliceAnglePercent
2021*/
2022var slicePathCustomization = function () {
2023
2024    this.titleRadiusPercent = 0.5;
2025    this.titleSliceAnglePercent = 0.5;
2026
2027    return this;
2028};
2029
2030/* Custom properties
2031    - titleRadiusPercent
2032    - titleSliceAnglePercent
2033    - spreaderPercent
2034*/
2035var spreaderPathCustomization = function () {
2036
2037    this.titleRadiusPercent = 0;
2038    this.titleSliceAnglePercent = 0.5;
2039    this.spreaderPercent = 1;
2040
2041    return this;
2042};
2043
2044/* Custom properties
2045    - titleRadiusPercent
2046    - titleSliceAnglePercent
2047    - markerPercent
2048*/
2049var markerPathCustomization = function () {
2050
2051    this.titleRadiusPercent = 1;
2052    this.titleSliceAnglePercent = 0.5;
2053    this.markerPercent = 1.05;
2054
2055    return this;
2056};
2057
2058
2059///#source 1 1 /js/source/slicePath/wheelnav.slicePath.js
2060///#source 1 1 /js/source/slicePath/wheelnav.slicePathStart.js
2061/* ======================================================================================= */
2062/* Slice path definitions.                                                                 */
2063/* ======================================================================================= */
2064/* ======================================================================================= */
2065/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/slicePath.html     */
2066/* ======================================================================================= */
2067
2068slicePath = function () {
2069
2070    this.NullSlice = function (helper, percent, custom) {
2071
2072        helper.setBaseValue(percent, custom);
2073
2074        return {
2075            slicePathString: "",
2076            linePathString: "",
2077            titlePosX: helper.titlePosX,
2078            titlePosY: helper.titlePosY
2079        };
2080    };
2081
2082    this.NullInitSlice = function (helper, percent, custom) {
2083
2084        helper.setBaseValue(percent, custom);
2085
2086        slicePathString = [helper.MoveToCenter(),
2087                 helper.Close()];
2088
2089        return {
2090            slicePathString: slicePathString,
2091            linePathString: slicePathString,
2092            titlePosX: helper.centerX,
2093            titlePosY: helper.centerY
2094        };
2095    };
2096
2097///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Pie.js
2098
2099this.PieSliceCustomization = function () {
2100
2101    var custom = new slicePathCustomization();
2102    custom.titleRadiusPercent = 0.6;
2103    custom.arcBaseRadiusPercent = 1;
2104    custom.arcRadiusPercent = 1;
2105    custom.startRadiusPercent = 0;
2106    return custom;
2107};
2108
2109this.PieSlice = function (helper, percent, custom) {
2110
2111    if (custom === null) {
2112        custom = PieSliceCustomization();
2113    }
2114
2115    helper.setBaseValue(percent, custom);
2116
2117    var arcBaseRadius = helper.sliceRadius * custom.arcBaseRadiusPercent;
2118    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
2119
2120    slicePathString = [helper.MoveTo(helper.middleAngle, custom.startRadiusPercent * helper.sliceRadius),
2121                 helper.LineTo(helper.startAngle, arcBaseRadius),
2122                 helper.ArcTo(arcRadius, helper.middleAngle, arcBaseRadius),
2123                 helper.ArcTo(arcRadius, helper.endAngle, arcBaseRadius),
2124                 helper.Close()];
2125    
2126    return {
2127        slicePathString: slicePathString,
2128        linePathString: "",
2129        titlePosX: helper.titlePosX,
2130        titlePosY: helper.titlePosY
2131    };
2132};
2133
2134this.FlowerSlice = function (helper, percent, custom) {
2135
2136    if (custom === null) {
2137        custom = PieSliceCustomization();
2138        custom.titleRadiusPercent = 0.5;
2139        custom.arcBaseRadiusPercent = 0.65;
2140        custom.arcRadiusPercent = 0.14;
2141    }
2142
2143    var slicePath = PieSlice(helper, percent, custom);
2144
2145    return {
2146        slicePathString: slicePath.slicePathString,
2147        linePathString: "",
2148        titlePosX: slicePath.titlePosX,
2149        titlePosY: slicePath.titlePosY
2150    };
2151};
2152
2153///#source 1 1 /js/source/slicePath/wheelnav.slicePath.PieArrow.js
2154
2155this.PieArrowSliceCustomization = function () {
2156
2157    var custom = new slicePathCustomization();
2158    custom.titleRadiusPercent = 0.6;
2159    custom.arrowRadiusPercent = 1.1;
2160
2161    return custom;
2162};
2163
2164this.PieArrowSlice = function (helper, percent, custom) {
2165
2166    if (custom === null) {
2167        custom = PieArrowSliceCustomization();
2168    }
2169
2170    helper.setBaseValue(percent, custom);
2171
2172    r = helper.sliceRadius;
2173    
2174    arrowAngleStart = helper.startAngle + helper.sliceAngle * 0.45;
2175    arrowAngleEnd = helper.startAngle + helper.sliceAngle * 0.55;
2176
2177    var arrowRadius = r * custom.arrowRadiusPercent;
2178
2179    slicePathString = [helper.MoveToCenter(),
2180                 helper.LineTo(helper.startAngle, r),
2181                 helper.ArcTo(r, arrowAngleStart, r),
2182                 helper.LineTo(helper.middleAngle, arrowRadius),
2183                 helper.LineTo(arrowAngleEnd, r),
2184                 helper.ArcTo(r, helper.endAngle, r),
2185                 helper.Close()];
2186
2187    return {
2188        slicePathString: slicePathString,
2189        linePathString: "",
2190        titlePosX: helper.titlePosX,
2191        titlePosY: helper.titlePosY
2192    };
2193};
2194
2195this.PieArrowBasePieSlice = function (helper, percent, custom) {
2196
2197    if (custom === null) {
2198        custom = PieArrowSliceCustomization();
2199    }
2200
2201    custom.arrowRadiusPercent = 1;
2202    var slicePath = PieArrowSlice(helper, percent, custom);
2203
2204    return {
2205        slicePathString: slicePath.slicePathString,
2206        linePathString: "",
2207        titlePosX: slicePath.titlePosX,
2208        titlePosY: slicePath.titlePosY
2209    };
2210};
2211
2212///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Donut.js
2213
2214this.DonutSliceCustomization = function () {
2215
2216    var custom = new slicePathCustomization();
2217    custom.minRadiusPercent = 0.37;
2218    custom.maxRadiusPercent = 0.9;
2219
2220    return custom;
2221};
2222
2223this.DonutSlice = function (helper, percent, custom) {
2224
2225    if (custom === null) {
2226        custom = DonutSliceCustomization();
2227    }
2228
2229    maxRadius = helper.wheelRadius * percent * custom.maxRadiusPercent;
2230    minRadius = helper.wheelRadius * percent * custom.minRadiusPercent;
2231
2232    helper.setBaseValue(percent, custom);
2233
2234    helper.titleRadius = (maxRadius + minRadius) / 2;
2235    helper.setTitlePos();
2236
2237    slicePathString = [helper.MoveTo(helper.startAngle, minRadius),
2238                 helper.LineTo(helper.startAngle, maxRadius),
2239                 helper.ArcTo(maxRadius, helper.middleAngle, maxRadius),
2240                 helper.ArcTo(maxRadius, helper.endAngle, maxRadius),
2241                 helper.LineTo(helper.endAngle, minRadius),
2242                 helper.ArcBackTo(minRadius, helper.middleAngle, minRadius),
2243                 helper.ArcBackTo(minRadius, helper.startAngle, minRadius),
2244                 helper.Close()];
2245
2246    return {
2247        slicePathString: slicePathString,
2248        linePathString: "",
2249        titlePosX: helper.titlePosX,
2250        titlePosY: helper.titlePosY
2251    };
2252};
2253
2254///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Cog.js
2255
2256this.CogSliceCustomization = function () {
2257
2258    var custom = new slicePathCustomization();
2259    custom.titleRadiusPercent = 0.55;
2260    custom.isBasePieSlice = false;
2261
2262    return custom;
2263};
2264
2265this.CogSlice = function (helper, percent, custom) {
2266
2267    if (custom === null) {
2268        custom = CogSliceCustomization();
2269    }
2270
2271    helper.setBaseValue(percent, custom);
2272
2273    r = helper.sliceRadius;
2274    rbase = helper.wheelRadius * percent * 0.83;
2275
2276    percentAngle0625 = helper.startAngle + helper.sliceAngle * 0.0625;
2277    percentAngle1250 = helper.startAngle + helper.sliceAngle * 0.125;
2278    percentAngle1875 = helper.startAngle + helper.sliceAngle * 0.1875;
2279    percentAngle2500 = helper.startAngle + helper.sliceAngle * 0.25;
2280    percentAngle3125 = helper.startAngle + helper.sliceAngle * 0.3125;
2281    percentAngle3750 = helper.startAngle + helper.sliceAngle * 0.375;
2282    percentAngle4375 = helper.startAngle + helper.sliceAngle * 0.4375;
2283    percentAngle5000 = helper.startAngle + helper.sliceAngle * 0.5;
2284    percentAngle5625 = helper.startAngle + helper.sliceAngle * 0.5625;
2285    percentAngle6250 = helper.startAngle + helper.sliceAngle * 0.625;
2286    percentAngle6875 = helper.startAngle + helper.sliceAngle * 0.6875;
2287    percentAngle7500 = helper.startAngle + helper.sliceAngle * 0.75;
2288    percentAngle8125 = helper.startAngle + helper.sliceAngle * 0.8125;
2289    percentAngle8750 = helper.startAngle + helper.sliceAngle * 0.875;
2290    percentAngle9375 = helper.startAngle + helper.sliceAngle * 0.9375;
2291    percentAngle9687 = helper.startAngle + helper.sliceAngle * 0.96875;
2292
2293    if (custom.isBasePieSlice) {
2294        r = rbase;
2295        slicePathString = [helper.MoveToCenter(),
2296            helper.LineTo(helper.startAngle, r),
2297            helper.ArcTo(r, percentAngle0625, r),
2298            helper.ArcTo(r, percentAngle1250, r),
2299            helper.ArcTo(r, percentAngle1875, r),
2300            helper.ArcTo(r, percentAngle2500, r),
2301            helper.ArcTo(r, percentAngle3125, r),
2302            helper.ArcTo(r, percentAngle3750, r),
2303            helper.ArcTo(r, percentAngle4375, r),
2304            helper.ArcTo(r, percentAngle5000, r),
2305            helper.ArcTo(r, percentAngle5625, r),
2306            helper.ArcTo(r, percentAngle6250, r),
2307            helper.ArcTo(r, percentAngle6875, r),
2308            helper.ArcTo(r, percentAngle7500, r),
2309            helper.ArcTo(r, percentAngle8125, r),
2310            helper.ArcTo(r, percentAngle8750, r),
2311            helper.ArcTo(r, percentAngle9375, r),
2312            helper.ArcTo(r, percentAngle9687, r),
2313            helper.ArcTo(r, helper.endAngle, r),
2314            helper.Close()];
2315    }
2316    else {
2317        slicePathString = [helper.MoveToCenter(),
2318            helper.LineTo(helper.startAngle, r),
2319            helper.ArcTo(r, percentAngle0625, r),
2320            helper.LineTo(percentAngle0625, rbase),
2321            helper.ArcTo(rbase, percentAngle1875, rbase),
2322            helper.LineTo(percentAngle1875, r),
2323            helper.ArcTo(r, percentAngle3125, r),
2324            helper.LineTo(percentAngle3125, rbase),
2325            helper.ArcTo(rbase, percentAngle4375, rbase),
2326            helper.LineTo(percentAngle4375, r),
2327            helper.ArcTo(r, percentAngle5625, r),
2328            helper.LineTo(percentAngle5625, rbase),
2329            helper.ArcTo(rbase, percentAngle6875, rbase),
2330            helper.LineTo(percentAngle6875, r),
2331            helper.ArcTo(r, percentAngle8125, r),
2332            helper.LineTo(percentAngle8125, rbase),
2333            helper.ArcTo(rbase, percentAngle9375, rbase),
2334            helper.LineTo(percentAngle9375, r),
2335            helper.ArcTo(r, helper.endAngle, r),
2336            helper.Close()];
2337    }
2338
2339    return {
2340        slicePathString: slicePathString,
2341        linePathString: "",
2342        titlePosX: helper.titlePosX,
2343        titlePosY: helper.titlePosY
2344    };
2345};
2346
2347this.CogBasePieSlice = function (helper, percent, custom) {
2348
2349    if (custom === null) {
2350        custom = CogSliceCustomization();
2351    }
2352
2353    custom.isBasePieSlice = true;
2354
2355    var slicePath = CogSlice(helper, percent, custom);
2356
2357    return {
2358        slicePathString: slicePath.slicePathString,
2359        linePathString: "",
2360        titlePosX: slicePath.titlePosX,
2361        titlePosY: slicePath.titlePosY
2362    };
2363};
2364
2365///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Star.js
2366
2367this.StarSliceCustomization = function () {
2368
2369    var custom = new slicePathCustomization();
2370    custom.titleRadiusPercent = 0.44;
2371    custom.minRadiusPercent = 0.5;
2372    custom.isBasePieSlice = false;
2373
2374    return custom;
2375};
2376
2377this.StarSlice = function (helper, percent, custom) {
2378
2379    if (custom === null) {
2380        custom = StarSliceCustomization();
2381    }
2382
2383    helper.setBaseValue(percent, custom);
2384
2385    r = helper.wheelRadius * percent;
2386    rbase = r * custom.minRadiusPercent;
2387
2388    if (custom.isBasePieSlice) {
2389        r = helper.sliceRadius;
2390        slicePathString = [helper.MoveToCenter(),
2391                 helper.LineTo(helper.startAngle, r),
2392                 helper.ArcTo(r, helper.middleAngle, r),
2393                 helper.ArcTo(r, helper.endAngle, r),
2394                 helper.Close()];
2395    }
2396    else {
2397        slicePathString = [helper.MoveToCenter(),
2398                     helper.LineTo(helper.startAngle, rbase),
2399                     helper.LineTo(helper.middleAngle, r),
2400                     helper.LineTo(helper.endAngle, rbase),
2401                     helper.Close()];
2402    }
2403
2404    return {
2405        slicePathString: slicePathString,
2406        linePathString: "",
2407        titlePosX: helper.titlePosX,
2408        titlePosY: helper.titlePosY
2409    };
2410};
2411
2412this.StarBasePieSlice = function (helper, percent, custom) {
2413
2414    if (custom === null) {
2415        custom = StarSliceCustomization();
2416    }
2417
2418    custom.titleRadiusPercent = 0.6;
2419    custom.isBasePieSlice = true;
2420
2421    var slicePath = StarSlice(helper, percent, custom);
2422
2423    return {
2424        slicePathString: slicePath.slicePathString,
2425        linePathString: "",
2426        titlePosX: slicePath.titlePosX,
2427        titlePosY: slicePath.titlePosY
2428    };
2429};
2430
2431///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Menu.js
2432
2433this.MenuSliceCustomization = function () {
2434
2435    var custom = new slicePathCustomization();
2436    custom.menuRadius = 35;
2437    custom.titleRadiusPercent = 0.63;
2438    custom.isSelectedLine = false;
2439    custom.lineBaseRadiusPercent = 0;
2440
2441    return custom;
2442};
2443
2444this.MenuSlice = function (helper, percent, custom) {
2445
2446    if (custom === null) {
2447        custom = MenuSliceCustomization();
2448    }
2449
2450    helper.setBaseValue(percent, custom);
2451    x = helper.centerX;
2452    y = helper.centerY;
2453
2454    var r = helper.wheelRadius * percent;
2455    helper.titleRadius = r * custom.titleRadiusPercent;
2456    helper.setTitlePos();
2457
2458    var menuRadius = percent * custom.menuRadius;
2459
2460    if (percent <= 0.05) { menuRadius = 10; }
2461
2462    middleTheta = helper.middleTheta;
2463
2464    slicePathString = [["M", helper.titlePosX - (menuRadius * Math.cos(middleTheta)), helper.titlePosY - (menuRadius * Math.sin(middleTheta))],
2465                ["A", menuRadius, menuRadius, 0, 0, 1, helper.titlePosX + (menuRadius * Math.cos(middleTheta)), helper.titlePosY + (menuRadius * Math.sin(middleTheta))],
2466                ["A", menuRadius, menuRadius, 0, 0, 1, helper.titlePosX - (menuRadius * Math.cos(middleTheta)), helper.titlePosY - (menuRadius * Math.sin(middleTheta))],
2467                ["z"]];
2468
2469    if (percent <= 0.05) {
2470        linePathString = [["M", x, y],
2471                ["A", 1, 1, 0, 0, 1, x + 1, y + 1]];
2472    }
2473    else {
2474        if (!custom.isSelectedLine) {
2475            linePathString = [helper.MoveTo(helper.middleAngle, custom.lineBaseRadiusPercent * r),
2476                              helper.ArcTo(r / 2, helper.middleAngle, helper.titleRadius - menuRadius)];
2477        }
2478        else {
2479            linePathString = [helper.MoveTo(helper.middleAngle, custom.lineBaseRadiusPercent * r),
2480                              helper.ArcTo(r / 3, helper.middleAngle, helper.titleRadius - menuRadius)];
2481        }
2482    }
2483
2484    return {
2485        slicePathString: slicePathString,
2486        linePathString: linePathString,
2487        titlePosX: helper.titlePosX,
2488        titlePosY: helper.titlePosY
2489    };
2490};
2491
2492this.MenuSliceSelectedLine = function (helper, percent, custom) {
2493
2494    if (custom === null) {
2495        custom = MenuSliceCustomization();
2496    }
2497
2498    custom.isSelectedLine = true;
2499
2500    var slicePath = MenuSlice(helper, percent, custom);
2501
2502    return {
2503        slicePathString: slicePath.slicePathString,
2504        linePathString: slicePath.linePathString,
2505        titlePosX: slicePath.titlePosX,
2506        titlePosY: slicePath.titlePosY
2507    };
2508};
2509
2510this.MenuSliceWithoutLine = function (helper, percent, custom) {
2511
2512    var slicePath = MenuSlice(helper, percent, custom);
2513
2514    return {
2515        slicePathString: slicePath.slicePathString,
2516        linePathString: "",
2517        titlePosX: slicePath.titlePosX,
2518        titlePosY: slicePath.titlePosY
2519    };
2520};
2521
2522///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Line.js
2523
2524this.LineSlice = function (helper, percent, custom) {
2525
2526    helper.setBaseValue(percent, custom);
2527
2528    r = helper.sliceRadius;
2529
2530    if (helper.sliceAngle > 60 &&
2531        helper.sliceAngle < 180) {
2532        helper.titleRadius = r * ((180 / helper.sliceAngle) / 5);
2533        helper.setTitlePos();
2534    }
2535    else {
2536        helper.titleRadius = r * 0.55;
2537        helper.setTitlePos();
2538    }
2539
2540    if (helper.sliceAngle < 180) {
2541        slicePathString = [helper.MoveToCenter(),
2542                 helper.LineTo(helper.startAngle, r),
2543                 helper.LineTo(helper.endAngle, r),
2544                 helper.Close()];
2545    }
2546    else {
2547        if (helper.startAngle === 180 ||
2548            helper.startAngle === 0 ||
2549            helper.startAngle === -180 ||
2550            helper.startAngle === 360) {
2551            slicePathString = [helper.MoveToCenter(),
2552                 helper.LineTo(helper.startAngle, r),
2553                 helper.LineTo(helper.startAngle, r, helper.middleAngle, r),
2554                 helper.LineTo(helper.endAngle, r, helper.middleAngle, r),
2555                 helper.LineTo(helper.endAngle, r),
2556                 helper.Close()];
2557        }
2558        else {
2559            slicePathString = [helper.MoveToCenter(),
2560             helper.LineTo(helper.startAngle, r),
2561             helper.LineTo(helper.middleAngle, r, helper.startAngle, r),
2562             helper.LineTo(helper.middleAngle, r, helper.endAngle, r),
2563             helper.LineTo(helper.endAngle, r),
2564             helper.Close()];
2565        }
2566    }
2567
2568    return {
2569        slicePathString: slicePathString,
2570        linePathString: "",
2571        titlePosX: helper.titlePosX,
2572        titlePosY: helper.titlePosY
2573    };
2574};
2575
2576///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Eye.js
2577
2578this.EyeSliceCustomization = function () {
2579
2580    var custom = new slicePathCustomization();
2581    custom.titleRadiusPercent = 0.68;
2582
2583    return custom;
2584};
2585
2586this.EyeSlice = function (helper, percent, custom) {
2587
2588    if (custom === null) {
2589        custom = EyeSliceCustomization();
2590    }
2591
2592    helper.setBaseValue(percent, custom);
2593
2594    r = helper.wheelRadius * percent * 0.7;
2595
2596    if (percent === 0) {
2597        r = 0.01;
2598    }
2599
2600    startAngle = helper.startAngle;
2601    endAngle = helper.endAngle;
2602
2603    if (helper.sliceAngle === 180) {
2604        startAngle = helper.startAngle + helper.sliceAngle / 4;
2605        endAngle = helper.startAngle + helper.sliceAngle - helper.sliceAngle / 4;
2606    }
2607
2608    slicePathString = [helper.MoveTo(endAngle, r),
2609                 helper.ArcTo(r, startAngle, r),
2610                 helper.ArcTo(r, endAngle, r),
2611                 helper.Close()];
2612
2613    return {
2614        slicePathString: slicePathString,
2615        linePathString: "",
2616        titlePosX: helper.titlePosX,
2617        titlePosY: helper.titlePosY
2618    };
2619};
2620
2621///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Wheel.js
2622
2623this.WheelSlice = function (helper, percent, custom) {
2624
2625    helper.setBaseValue(percent, custom);
2626    x = helper.centerX;
2627    y = helper.centerY;
2628
2629    r = helper.sliceRadius;
2630
2631    startTheta = helper.startTheta;
2632    middleTheta = helper.middleTheta;
2633    endTheta = helper.endTheta;
2634
2635    var innerRadiusPercent;
2636    var startendRadiusPercent;
2637
2638    if (helper.sliceAngle < 120) {
2639        helper.titleRadius = r * 0.57;
2640        innerRadiusPercent = 0.9;
2641        middleRadiusPercent = 0.87;
2642        startendRadiusPercent = 0.87;
2643    }
2644    else if (helper.sliceAngle < 180) {
2645        helper.titleRadius = r * 0.52;
2646        innerRadiusPercent = 0.91;
2647        middleRadiusPercent = 0.87;
2648        startendRadiusPercent = 0.87;
2649    }
2650    else {
2651        helper.titleRadius = r * 0.45;
2652        innerRadiusPercent = 0.873;
2653        middleRadiusPercent = 0.87;
2654        startendRadiusPercent = 0.94;
2655    }
2656
2657    slicePathString = [helper.MoveTo(helper.middleAngle, r * 0.07),
2658                 ["L", (r * 0.07) * Math.cos(middleTheta) + (r * startendRadiusPercent) * Math.cos(startTheta) + x, (r * 0.07) * Math.sin(middleTheta) + (r * startendRadiusPercent) * Math.sin(startTheta) + y],
2659                 ["A", (r * innerRadiusPercent), (r * innerRadiusPercent), 0, 0, 1, (r * 0.07) * Math.cos(middleTheta) + (r * middleRadiusPercent) * Math.cos(middleTheta) + x, (r * 0.07) * Math.sin(middleTheta) + (r * middleRadiusPercent) * Math.sin(middleTheta) + y],
2660                 ["A", (r * innerRadiusPercent), (r * innerRadiusPercent), 0, 0, 1, (r * 0.07) * Math.cos(middleTheta) + (r * startendRadiusPercent) * Math.cos(endTheta) + x, (r * 0.07) * Math.sin(middleTheta) + (r * startendRadiusPercent) * Math.sin(endTheta) + y],
2661                 helper.Close()];
2662
2663    linePathString = [helper.MoveTo(helper.startAngle, r),
2664                 helper.ArcTo(r, helper.middleAngle, r),
2665                 helper.ArcTo(r, helper.endAngle, r),
2666                 helper.ArcBackTo(r, helper.middleAngle, r),
2667                 helper.ArcBackTo(r, helper.startAngle, r)];
2668
2669    helper.setTitlePos();
2670
2671    return {
2672        slicePathString: slicePathString,
2673        linePathString: linePathString,
2674        titlePosX: helper.titlePosX,
2675        titlePosY: helper.titlePosY
2676    };
2677};
2678
2679///#source 1 1 /js/source/slicePath/wheelnav.slicePath.OuterStroke.js
2680
2681this.OuterStrokeSlice = function (helper, percent, custom) {
2682
2683    helper.setBaseValue(percent, custom);
2684    x = helper.centerX;
2685    y = helper.centerY;
2686
2687    r = helper.sliceRadius;
2688    innerRadius = r / 4;
2689
2690    if (helper.sliceAngle < 120) { helper.titleRadius = r * 0.57; }
2691    else if (helper.sliceAngle < 180) { helper.titleRadius = r * 0.52; }
2692    else { helper.titleRadius = r * 0.45; }
2693
2694    linePathString = [helper.MoveTo(helper.startAngle, innerRadius),
2695                 helper.LineTo(helper.startAngle, r),
2696                 helper.MoveTo(helper.endAngle, innerRadius),
2697                 helper.LineTo(helper.endAngle, r)];
2698
2699    slicePathString = [helper.MoveTo(helper.startAngle, r),
2700                 helper.ArcTo(r, helper.middleAngle, r),
2701                 helper.ArcTo(r, helper.endAngle, r),
2702                 helper.ArcBackTo(r, helper.middleAngle, r),
2703                 helper.ArcBackTo(r, helper.startAngle, r),
2704                 helper.MoveTo(helper.startAngle, innerRadius),
2705                 helper.ArcTo(innerRadius, helper.middleAngle, innerRadius),
2706                 helper.ArcTo(innerRadius, helper.endAngle, innerRadius),
2707                 helper.ArcBackTo(innerRadius, helper.middleAngle, innerRadius),
2708                 helper.ArcBackTo(innerRadius, helper.startAngle, innerRadius)];
2709
2710    helper.setTitlePos();
2711
2712    return {
2713        slicePathString: slicePathString,
2714        linePathString: linePathString,
2715        titlePosX: helper.titlePosX,
2716        titlePosY: helper.titlePosY
2717    };
2718};
2719
2720///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Tab.js
2721
2722this.TabSlice = function (helper, percent, custom) {
2723
2724    var rOriginal = helper.wheelRadius * 0.9;
2725    var navItemCount = 360 / helper.sliceAngle;
2726    var itemSize = 2 * rOriginal / navItemCount;
2727
2728    x = helper.centerX;
2729    y = helper.centerY;
2730    itemIndex = helper.itemIndex;
2731
2732    titlePosX = x;
2733    titlePosY = itemIndex * itemSize + y + (itemSize / 2) - rOriginal;
2734
2735    slicePathString = [["M", x - (itemSize / 2), itemIndex * itemSize + y - rOriginal],
2736                 ["L", (itemSize / 2) + x, itemIndex * itemSize + y - rOriginal],
2737                 ["L", (itemSize / 2) + x, (itemIndex + 1) * itemSize + y - rOriginal],
2738                 ["L", x - (itemSize / 2), (itemIndex + 1) * itemSize + y - rOriginal],
2739                 ["z"]];
2740
2741    return {
2742        slicePathString: slicePathString,
2743        linePathString: "",
2744        titlePosX: titlePosX,
2745        titlePosY: titlePosY
2746    };
2747};
2748
2749///#source 1 1 /js/source/slicePath/wheelnav.slicePath.YinYang.js
2750
2751this.YinYangSlice = function (helper, percent, custom) {
2752
2753    helper.setBaseValue(percent, custom);
2754
2755    r = helper.sliceRadius;
2756
2757    slicePathString = [helper.MoveToCenter(),
2758                 helper.ArcTo(r / 2, helper.startAngle, r),
2759                 helper.ArcTo(r, helper.middleAngle, r),
2760                 helper.ArcTo(r, helper.endAngle, r),
2761                 helper.ArcBackTo(r / 2, 0, 0),
2762                 helper.Close()];
2763
2764    titlePosX = helper.getX(helper.startAngle, r / 2);
2765    titlePosY = helper.getY(helper.startAngle, r / 2);
2766
2767    return {
2768        slicePathString: slicePathString,
2769        linePathString: slicePathString,
2770        titlePosX: titlePosX,
2771        titlePosY: titlePosY
2772    };
2773};
2774
2775///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Web.js
2776
2777this.WebSlice = function (helper, percent, custom) {
2778
2779    helper.setBaseValue(percent, custom);
2780
2781    r = helper.sliceRadius;
2782
2783    helper.titleRadius = r * 0.55;
2784    helper.setTitlePos();
2785
2786    linePathString = [helper.MoveToCenter(),
2787                 helper.LineTo(helper.startAngle, r * 1.1),
2788                 helper.MoveToCenter(),
2789                 helper.LineTo(helper.endAngle, r * 1.1),
2790                 helper.MoveTo(helper.startAngle, r * 0.15),
2791                 helper.LineTo(helper.endAngle, r * 0.15),
2792                 helper.MoveTo(helper.startAngle, r * 0.35),
2793                 helper.LineTo(helper.endAngle, r * 0.35),
2794                 helper.MoveTo(helper.startAngle, r * 0.55),
2795                 helper.LineTo(helper.endAngle, r * 0.55),
2796                 helper.MoveTo(helper.startAngle, r * 0.75),
2797                 helper.LineTo(helper.endAngle, r * 0.75),
2798                 helper.MoveTo(helper.startAngle, r * 0.95),
2799                 helper.LineTo(helper.endAngle, r * 0.95),
2800                 helper.Close()];
2801
2802    return {
2803        slicePathString: "",
2804        linePathString: linePathString,
2805        titlePosX: helper.titlePosX,
2806        titlePosY: helper.titlePosY
2807    };
2808};
2809
2810///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Winter.js
2811
2812this.WinterSliceCustomization = function () {
2813
2814    var custom = new slicePathCustomization();
2815    custom.titleRadiusPercent = 0.85;
2816    custom.arcRadiusPercent = 1;
2817    return custom;
2818};
2819
2820this.WinterSlice = function (helper, percent, custom) {
2821
2822    if (custom === null) {
2823        custom = WinterSliceCustomization();
2824    }
2825
2826    helper.setBaseValue(percent, custom);
2827
2828    sliceAngle = helper.sliceAngle;
2829
2830    parallelAngle = helper.startAngle + sliceAngle / 4;
2831    parallelAngle2 = helper.startAngle + ((sliceAngle / 4) * 3);
2832    borderAngle1 = helper.startAngle + (sliceAngle / 200);
2833    borderAngle2 = helper.startAngle + (sliceAngle / 2) - (sliceAngle / 200);
2834    borderAngle3 = helper.startAngle + (sliceAngle / 2) + (sliceAngle / 200);
2835    borderAngle4 = helper.startAngle + sliceAngle - (sliceAngle / 200);
2836
2837    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
2838
2839    slicePathString = [helper.MoveToCenter(),
2840                 helper.MoveTo(parallelAngle, arcRadius / 100),
2841                 helper.LineTo(borderAngle1, arcRadius / 2),
2842                 helper.LineTo(parallelAngle, arcRadius - (arcRadius / 100)),
2843                 helper.LineTo(borderAngle2, arcRadius / 2),
2844                 helper.LineTo(parallelAngle, arcRadius / 100),
2845                 helper.MoveTo(parallelAngle2, arcRadius / 100),
2846                 helper.LineTo(borderAngle4, arcRadius / 2),
2847                 helper.LineTo(parallelAngle2, arcRadius - (arcRadius / 100)),
2848                 helper.LineTo(borderAngle3, arcRadius / 2),
2849                 helper.LineTo(parallelAngle2, arcRadius / 100),
2850                 helper.Close()];
2851
2852    linePathString = [helper.MoveTo(parallelAngle, arcRadius),
2853                 helper.LineTo(borderAngle2, arcRadius / 2),
2854                 helper.MoveTo(borderAngle3, arcRadius / 2),
2855                 helper.LineTo(parallelAngle2, arcRadius)];
2856
2857    return {
2858        slicePathString: slicePathString,
2859        linePathString: linePathString,
2860        titlePosX: helper.titlePosX,
2861        titlePosY: helper.titlePosY
2862    };
2863};
2864
2865///#source 1 1 /js/source/slicePath/wheelnav.slicePath.Tutorial.js
2866
2867this.TutorialSliceCustomization = function () {
2868
2869    var custom = new slicePathCustomization();
2870    custom.titleRadiusPercent = 0.6;
2871    custom.isMoveTo = false;
2872    custom.isLineTo = false;
2873    custom.isArcTo = false;
2874    custom.isArcBackTo = false;
2875    return custom;
2876};
2877
2878this.TutorialSlice = function (helper, percent, custom) {
2879
2880    if (custom === null) {
2881        custom = TutorialSliceCustomization();
2882    }
2883
2884    helper.setBaseValue(percent, custom);
2885
2886    slicePathString = [];
2887
2888    slicePathString.push(helper.MoveToCenter());
2889    if (custom.isMoveTo === true) {
2890        slicePathString.push(helper.MoveTo(helper.middleAngle, helper.sliceRadius / 4));
2891    }
2892    if (custom.isLineTo) {
2893        slicePathString.push(helper.LineTo(helper.startAngle, helper.sliceRadius));
2894    }
2895    if (custom.isArcTo) {
2896        slicePathString.push(helper.ArcTo(helper.sliceRadius, helper.middleAngle, helper.sliceRadius));
2897    }
2898    if (custom.isArcBackTo) {
2899        slicePathString.push(helper.ArcBackTo(helper.sliceRadius, helper.endAngle, helper.sliceRadius));
2900    }
2901    slicePathString.push(helper.Close());
2902
2903    linePathString = [helper.MoveToCenter(),
2904                 helper.LineTo(helper.startAngle, helper.sliceRadius),
2905                 helper.ArcTo(helper.sliceRadius, helper.middleAngle, helper.sliceRadius),
2906                 helper.ArcTo(helper.sliceRadius, helper.endAngle, helper.sliceRadius),
2907                 helper.Close()];
2908
2909    return {
2910        slicePathString: slicePathString,
2911        linePathString: linePathString,
2912        titlePosX: helper.titlePosX,
2913        titlePosY: helper.titlePosY
2914    };
2915};
2916
2917///#source 1 1 /js/source/slicePath/wheelnav.slicePathEnd.js
2918
2919    return this;
2920};
2921
2922
2923
2924
2925///#source 1 1 /js/source/wheelnav.sliceTransform.js
2926/* ======================================================================================== */
2927/* Slice transform definitions                                                              */
2928/* ======================================================================================== */
2929/* ======================================================================================== */
2930/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/sliceTransform.html */
2931/* ======================================================================================== */
2932
2933
2934var sliceTransform = function () {
2935
2936    this.startAngle = 0;
2937    this.startTheta = 0;
2938    this.middleTheta = 0;
2939    this.endTheta = 0;
2940
2941    var setBaseValue = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
2942        this.startAngle = baseAngle;
2943        this.startTheta = getTheta(startAngle);
2944        this.middleTheta = getTheta(startAngle + sliceAngle / 2);
2945        this.endTheta = getTheta(startAngle + sliceAngle);
2946    };
2947
2948    var getTheta = function (angle) {
2949        return (angle % 360) * Math.PI / 180;
2950    };
2951
2952    this.NullTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
2953        return {
2954            sliceTransformString: "",
2955            lineTransformString: "",
2956            titleTransformString: ""
2957        };
2958    };
2959
2960    this.MoveMiddleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
2961
2962        setBaseValue(x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex);
2963        var sliceTransformString = "t" + (rOriginal / 10 * Math.cos(middleTheta)).toString() + "," + (rOriginal / 10 * Math.sin(middleTheta)).toString();
2964
2965        var baseTheta;
2966        if (titleRotateAngle !== null) {
2967            baseTheta = getTheta(-titleRotateAngle);
2968        }
2969        else {
2970            var wheelBaseAngle = baseAngle - (itemIndex * sliceAngle);
2971            baseTheta = getTheta(wheelBaseAngle + sliceAngle / 2);
2972        }
2973
2974        var titleTransformString = "s1,r0,t" + (rOriginal / 10 * Math.cos(baseTheta)).toString() + "," + (rOriginal / 10 * Math.sin(baseTheta)).toString();
2975
2976        return {
2977            sliceTransformString: sliceTransformString,
2978            lineTransformString: sliceTransformString,
2979            titleTransformString: titleTransformString
2980        };
2981    };
2982
2983    this.RotateTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
2984
2985        var sliceTransformString = "s1,r360";
2986
2987        return {
2988            sliceTransformString: sliceTransformString,
2989            lineTransformString: sliceTransformString,
2990            titleTransformString: sliceTransformString
2991        };
2992    };
2993
2994    this.RotateHalfTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
2995
2996        var sliceTransformString = "s1,r90";
2997
2998        return {
2999            sliceTransformString: sliceTransformString,
3000            lineTransformString: sliceTransformString,
3001            titleTransformString: sliceTransformString
3002        };
3003    };
3004
3005    this.RotateTitleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3006
3007        var titleTransformString = "s1,r360";
3008
3009        return {
3010            sliceTransformString: "",
3011            lineTransformString: "",
3012            titleTransformString: titleTransformString
3013        };
3014    };
3015
3016    this.ScaleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3017
3018        var sliceTransformString = "s1.2";
3019
3020        return {
3021            sliceTransformString: sliceTransformString,
3022            lineTransformString: "",
3023            titleTransformString: sliceTransformString
3024        };
3025    };
3026
3027    this.ScaleTitleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3028
3029        return {
3030            sliceTransformString: "",
3031            lineTransformString: "",
3032            titleTransformString: "s1.3"
3033        };
3034    };
3035
3036    this.RotateScaleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3037
3038        var sliceTransformString = "r360,s1.3";
3039
3040        return {
3041            sliceTransformString: sliceTransformString,
3042            lineTransformString: "",
3043            titleTransformString: sliceTransformString
3044        };
3045    };
3046
3047    this.CustomTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3048
3049        var sliceTransformString = custom.scaleString + "," + custom.rotateString;
3050
3051        return {
3052            sliceTransformString: sliceTransformString,
3053            lineTransformString: sliceTransformString,
3054            titleTransformString: sliceTransformString
3055        };
3056    };
3057
3058    this.CustomTitleTransform = function (x, y, rOriginal, baseAngle, sliceAngle, titleRotateAngle, itemIndex, custom) {
3059
3060        var titleTransformString = custom.scaleString + "," + custom.rotateString;
3061
3062        return {
3063            sliceTransformString: "",
3064            lineTransformString: "",
3065            titleTransformString: titleTransformString
3066        };
3067    };
3068
3069    return this;
3070};
3071
3072/* Custom properties
3073    - scaleString
3074    - rotateString
3075*/
3076var sliceTransformCustomization = function () {
3077
3078    this.scaleString = "s1";
3079    this.rotateString = "r0";
3080
3081    return this;
3082};
3083
3084
3085
3086
3087///#source 1 1 /js/source/spreader/wheelnav.spreader.js
3088///#source 1 1 /js/source/spreader/wheelnav.spreader.core.js
3089/* ======================================================================================= */
3090/* Spreader of wheel                                                                       */
3091/* ======================================================================================= */
3092/* ======================================================================================= */
3093/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/spreader.html      */
3094/* ======================================================================================= */
3095
3096spreader = function (wheelnav) {
3097
3098    this.wheelnav = wheelnav;
3099    if (this.wheelnav.spreaderEnable) {
3100
3101        this.spreaderHelper = new pathHelper();
3102        this.spreaderHelper.centerX = this.wheelnav.centerX;
3103        this.spreaderHelper.centerY = this.wheelnav.centerY;
3104        this.spreaderHelper.navItemCount = this.wheelnav.navItemCount;
3105        this.spreaderHelper.navAngle = this.wheelnav.navAngle;
3106        this.spreaderHelper.wheelRadius = this.wheelnav.spreaderRadius;
3107        this.spreaderHelper.startAngle = this.wheelnav.spreaderStartAngle;
3108        this.spreaderHelper.sliceAngle = this.wheelnav.spreaderSliceAngle;
3109
3110        var thisWheelNav = this.wheelnav;
3111        this.animateeffect = "bounce";
3112        this.animatetime = 1500;
3113        //Set animation from wheelnav
3114        if (this.wheelnav.animateeffect !== null) { this.animateeffect = this.wheelnav.animateeffect; }
3115        if (this.wheelnav.animatetime !== null) { this.animatetime = this.wheelnav.animatetime; }
3116
3117        if (this.wheelnav.spreaderTitleFont !== null) { this.fontAttr = { font: this.wheelnav.spreaderTitleFont }; }
3118        else { this.fontAttr = { font: '100 32px Impact, Charcoal, sans-serif' }; }
3119
3120        this.spreaderPathIn = this.wheelnav.spreaderPathFunction(this.spreaderHelper, this.wheelnav.spreaderInPercent, this.wheelnav.spreaderPathCustom);
3121        this.spreaderPathOut = this.wheelnav.spreaderPathFunction(this.spreaderHelper, this.wheelnav.spreaderOutPercent, this.wheelnav.spreaderPathCustom);
3122
3123        var currentPath = this.spreaderPathOut;
3124        if (thisWheelNav.initPercent < thisWheelNav.maxPercent) {
3125            currentPath = this.spreaderPathIn;
3126        }
3127
3128        this.spreaderPath = this.wheelnav.raphael.path(currentPath.spreaderPathString);
3129        this.spreaderPath.attr(thisWheelNav.spreaderPathAttr);
3130        this.spreaderPath.id = thisWheelNav.getSpreaderId();
3131        this.spreaderPath.node.id = this.spreaderPath.id;
3132        this.spreaderPath.click(function () {
3133            thisWheelNav.spreadWheel();
3134        });
3135
3136        //Set titles
3137        this.inTitleWidth = this.wheelnav.spreaderInTitleWidth;
3138        this.inTitleHeight = this.wheelnav.spreaderInTitleHeight;
3139        this.outTitleWidth = this.wheelnav.spreaderOutTitleWidth;
3140        this.outTitleHeight = this.wheelnav.spreaderOutTitleHeight;
3141
3142        if (this.inTitleWidth !== null && this.inTitleHeight === null) { this.inTitleHeight = this.inTitleWidth; }
3143        if (this.inTitleWidth === null && this.inTitleHeight !== null) { this.inTitleWidth = this.inTitleHeight; }
3144        if (this.outTitleWidth !== null && this.outTitleHeight === null) { this.outTitleHeight = this.outTitleWidth; }
3145        if (this.outTitleWidth === null && this.outTitleHeight !== null) { this.outTitleWidth = this.outTitleHeight; }
3146
3147        if (wheelnavTitle().isImageTitle(this.wheelnav.spreaderOutTitle)) {
3148            // Image default value
3149            if (this.inTitleWidth === null) { this.inTitleWidth = 32; }
3150            if (this.inTitleHeight === null) { this.inTitleHeight = 32; }
3151            if (this.outTitleWidth === null) { this.outTitleWidth = 32; }
3152            if (this.outTitleHeight === null) { this.outTitleHeight = 32; }
3153        }
3154
3155        if (wheelnavTitle().isPathTitle(this.wheelnav.spreaderInTitle)) {
3156            inTitle = new wheelnavTitle(this.wheelnav.spreaderInTitle, this.wheelnav.raphael.raphael);
3157        }
3158        else {
3159            inTitle = new wheelnavTitle(this.wheelnav.spreaderInTitle);
3160        }
3161        this.inTitleSizeTransform = inTitle.getTitleSizeTransform(this.inTitleWidth, this.inTitleHeight);
3162        this.inTitle = inTitle.getTitlePercentAttr(this.spreaderPathIn.titlePosX, this.spreaderPathIn.titlePosY, this.inTitleWidth, this.inTitleHeight);
3163
3164        if (wheelnavTitle().isPathTitle(this.wheelnav.spreaderOutTitle)) {
3165            outTitle = new wheelnavTitle(this.wheelnav.spreaderOutTitle, this.wheelnav.raphael.raphael);
3166        }
3167        else {
3168            outTitle = new wheelnavTitle(this.wheelnav.spreaderOutTitle);
3169        }
3170        this.outTitleSizeTransform = outTitle.getTitleSizeTransform(this.outTitleWidth, this.outTitleHeight);
3171        this.outTitle = outTitle.getTitlePercentAttr(this.spreaderPathOut.titlePosX, this.spreaderPathOut.titlePosY, this.outTitleWidth, this.outTitleHeight);
3172
3173        var currentTitle = this.outTitle;
3174        var currentTitleAttr = this.wheelnav.spreaderTitleOutAttr;
3175        var currentTitleWidth = this.outTitleWidth;
3176        var currentTitleHeight = this.outTitleHeight;
3177        var currentTitleSizeTransform = this.outTitleSizeTransform;
3178        if (thisWheelNav.initPercent < thisWheelNav.maxPercent) {
3179            currentTitle = this.inTitle;
3180            currentTitleAttr = this.wheelnav.spreaderTitleInAttr;
3181            currentTitleWidth = this.inTitleWidth;
3182            currentTitleHeight = this.inTitleHeight;
3183            currentTitleSizeTransform = this.inTitleSizeTransform;
3184        }
3185
3186        if (wheelnavTitle().isPathTitle(this.wheelnav.spreaderOutTitle)) {
3187            this.spreaderTitle = thisWheelNav.raphael.path(currentTitle.path);
3188        }
3189        else if (wheelnavTitle().isImageTitle(this.wheelnav.spreaderOutTitle)) {
3190            this.spreaderTitle = this.wheelnav.raphael.image(currentTitle.src, currentPath.titlePosX - (currentTitleWidth / 2), currentPath.titlePosY - (currentTitleHeight / 2), currentTitleWidth, currentTitleHeight);
3191        }
3192        else {
3193            this.spreaderTitle = thisWheelNav.raphael.text(currentPath.titlePosX, currentPath.titlePosY, currentTitle.title);
3194        }
3195        
3196        this.spreaderTitle.attr(this.fontAttr);
3197        this.spreaderTitle.attr(currentTitleAttr);
3198        this.spreaderTitle.attr({ transform: currentTitleSizeTransform });
3199        this.spreaderTitle.id = thisWheelNav.getSpreaderTitleId();
3200        this.spreaderTitle.node.id = this.spreaderTitle.id;
3201        this.spreaderTitle.click(function () {
3202            thisWheelNav.spreadWheel();
3203        });
3204
3205        this.setCurrentTransform();
3206    }
3207
3208    return this;
3209};
3210
3211spreader.prototype.setCurrentTransform = function (withoutAnimate) {
3212    if (this.wheelnav.spreaderEnable) {
3213
3214        if (withoutAnimate === undefined ||
3215            withoutAnimate === false) {
3216            
3217            if (this.wheelnav.currentPercent > this.wheelnav.minPercent) {
3218                currentPath = this.spreaderPathOut.spreaderPathString;
3219            }
3220            else {
3221                currentPath = this.spreaderPathIn.spreaderPathString;
3222            }
3223
3224            spreaderTransformAttr = {
3225                path: currentPath
3226            };
3227
3228            //Animate spreader
3229            this.spreaderPath.animate(spreaderTransformAttr, this.animatetime, this.animateeffect);
3230
3231            //titles
3232            var currentTitle;
3233            var titleTransformAttr;
3234            var titleSizeTransform;
3235
3236            if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
3237                currentTitle = this.outTitle;
3238                titleTransformAttr = this.wheelnav.spreaderTitleOutAttr;
3239                this.spreaderPath.attr(this.wheelnav.spreaderPathOutAttr);
3240                titleSizeTransform = this.outTitleSizeTransform;
3241            }
3242            else {
3243                currentTitle = this.inTitle;
3244                titleTransformAttr = this.wheelnav.spreaderTitleInAttr;
3245                this.spreaderPath.attr(this.wheelnav.spreaderPathInAttr);
3246                titleSizeTransform = this.inTitleSizeTransform;
3247            }
3248
3249            if (wheelnavTitle().isPathTitle(currentTitle.title)) {
3250                titleTransformAttr.path = currentTitle.path;
3251                titleTransformAttr.transform = titleSizeTransform;
3252            }
3253            else if (wheelnavTitle().isImageTitle(currentTitle.title)) {
3254                titleTransformAttr.x = currentTitle.x;
3255                titleTransformAttr.y = currentTitle.y;
3256                titleTransformAttr.width = currentTitle.width;
3257                titleTransformAttr.height = currentTitle.height;
3258                this.spreaderTitle.attr({ src: currentTitle.src });
3259            }
3260            else {
3261                //Little hack for proper appearance of "-" sign
3262                offYOffset = 0;
3263                if (currentTitle.title === "-") { offYOffset = 3; };
3264
3265                titleTransformAttr.x = currentTitle.x;
3266                titleTransformAttr.y = currentTitle.y - offYOffset;
3267
3268                if (currentTitle.title !== null) {
3269                    this.spreaderTitle.attr({ text: currentTitle.title });
3270                }
3271            }
3272
3273            //Animate title
3274            this.spreaderTitle.animate(titleTransformAttr, this.animatetime, this.animateeffect);
3275        }
3276
3277        this.spreaderPath.toFront();
3278        this.spreaderTitle.toFront();
3279    }
3280};
3281
3282///#source 1 1 /js/source/spreader/wheelnav.spreaderPathStart.js
3283/* ======================================================================================= */
3284/* Spreader path definitions.                                                              */
3285/* ======================================================================================= */
3286
3287spreaderPath = function () {
3288
3289    this.NullSpreader = function (helper, custom) {
3290
3291        if (custom === null) {
3292            custom = new spreaderPathCustomization();
3293        }
3294
3295        helper.setBaseValue(custom.spreaderPercent, custom);
3296
3297        return {
3298            spreaderPathString: "",
3299            titlePosX: helper.titlePosX,
3300            titlePosY: helper.titlePosY
3301        };
3302    };
3303
3304
3305
3306///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.Pie.js
3307
3308this.PieSpreaderCustomization = function () {
3309
3310    var custom = new spreaderPathCustomization();
3311    custom.spreaderRadius = 25;
3312    custom.arcBaseRadiusPercent = 1;
3313    custom.arcRadiusPercent = 1;
3314    custom.startRadiusPercent = 0;
3315    return custom;
3316};
3317
3318this.PieSpreader = function (helper, percent, custom) {
3319
3320    if (custom === null) {
3321        custom = PieSpreaderCustomization();
3322    }
3323
3324    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3325
3326    var arcBaseRadius = helper.sliceRadius * custom.arcBaseRadiusPercent;
3327    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
3328
3329    spreaderPathString = [];
3330    helper.StartSpreader(spreaderPathString, helper.startAngle, arcBaseRadius);
3331    spreaderPathString.push(helper.ArcTo(arcRadius, helper.middleAngle, arcBaseRadius));
3332    spreaderPathString.push(helper.ArcTo(arcRadius, helper.endAngle, arcBaseRadius));
3333    spreaderPathString.push(helper.Close());
3334
3335    return {
3336        spreaderPathString: spreaderPathString,
3337        titlePosX: helper.titlePosX,
3338        titlePosY: helper.titlePosY
3339    };
3340};
3341
3342///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.Star.js
3343
3344this.StarSpreaderCustomization = function () {
3345
3346    var custom = new spreaderPathCustomization();
3347    custom.minRadiusPercent = 0.5;
3348
3349    return custom;
3350};
3351
3352this.StarSpreader = function (helper, percent, custom) {
3353
3354    if (custom === null) {
3355        custom = StarSpreaderCustomization();
3356    }
3357
3358    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3359    rbase = helper.wheelRadius * custom.spreaderPercent * custom.minRadiusPercent * percent;
3360    r = helper.sliceRadius;
3361
3362    spreaderPathString = [];
3363
3364    sliceAngle = helper.sliceAngle / helper.navItemCount;
3365    baseAngle = helper.navAngle;
3366    if (helper.endAngle - helper.startAngle < 360) { baseAngle = helper.startAngle; }
3367
3368    helper.StartSpreader(spreaderPathString, baseAngle, r);
3369
3370    for (var i = 0; i < helper.navItemCount; i++) {
3371        startAngle = i * sliceAngle + (baseAngle + sliceAngle / 2);
3372        middleAngle = startAngle + (sliceAngle / 2);
3373        endAngle = startAngle + sliceAngle;
3374        if (helper.endAngle - helper.startAngle < 360) {
3375            if (i === helper.navItemCount - 1) { endAngle = middleAngle; }
3376        }
3377        spreaderPathString.push(helper.LineTo(startAngle, rbase));
3378        spreaderPathString.push(helper.LineTo(middleAngle, r));
3379        spreaderPathString.push(helper.LineTo(endAngle, rbase));
3380    }
3381
3382    spreaderPathString.push(helper.Close());
3383
3384    return {
3385        spreaderPathString: spreaderPathString,
3386        titlePosX: helper.titlePosX,
3387        titlePosY: helper.titlePosY
3388    };
3389};
3390
3391
3392///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.AntiStar.js
3393
3394this.AntiStarSpreaderCustomization = function () {
3395
3396    var custom = new spreaderPathCustomization();
3397    custom.minRadiusPercent = 0.21;
3398
3399    return custom;
3400};
3401
3402this.AntiStarSpreader = function (helper, percent, custom) {
3403
3404    if (custom === null) {
3405        custom = AntiStarSpreaderCustomization();
3406    }
3407
3408    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3409    rbase = helper.wheelRadius * custom.spreaderPercent * custom.minRadiusPercent * percent;
3410    r = helper.sliceRadius;
3411
3412    spreaderPathString = [];
3413
3414    sliceAngle = helper.sliceAngle / helper.navItemCount;
3415    baseAngle = helper.navAngle;
3416    if (helper.endAngle - helper.startAngle < 360) {
3417        baseAngle = helper.startAngle;
3418        helper.StartSpreader(spreaderPathString, baseAngle, rbase);
3419    }
3420    else {
3421        spreaderPathString.push(helper.MoveTo(helper.startAngle + (helper.navAngle + sliceAngle / 2), rbase));
3422    }
3423
3424    for (var i = 0; i < helper.navItemCount; i++) {
3425        startAngle = i * sliceAngle + (baseAngle + sliceAngle / 2);
3426        middleAngle = startAngle + (sliceAngle / 2);
3427        endAngle = startAngle + sliceAngle;
3428
3429        if (helper.endAngle - helper.startAngle < 360) {
3430            if (i === helper.navItemCount - 1) { endAngle = middleAngle; }
3431        }
3432
3433        spreaderPathString.push(helper.LineTo(startAngle, r));
3434        spreaderPathString.push(helper.LineTo(middleAngle, rbase));
3435        spreaderPathString.push(helper.LineTo(endAngle, r));
3436    }
3437
3438    spreaderPathString.push(helper.Close());
3439
3440    return {
3441        spreaderPathString: spreaderPathString,
3442        titlePosX: helper.titlePosX,
3443        titlePosY: helper.titlePosY
3444    };
3445};
3446
3447
3448///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.Flower.js
3449
3450this.FlowerSpreaderCustomization = function () {
3451
3452    var custom = new spreaderPathCustomization();
3453    custom.minRadiusPercent = 0.63
3454    custom.menuRadius = 7;;
3455
3456    return custom;
3457};
3458
3459this.FlowerSpreader = function (helper, percent, custom) {
3460
3461    if (custom === null) {
3462        custom = FlowerSpreaderCustomization();
3463    }
3464
3465    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3466    rbase = helper.wheelRadius * custom.spreaderPercent * custom.minRadiusPercent * percent;
3467    r = helper.sliceRadius;
3468
3469    spreaderPathString = [];
3470
3471    sliceAngle = helper.sliceAngle / helper.navItemCount;
3472    baseAngle = helper.navAngle;
3473    if (helper.endAngle - helper.startAngle < 360) {
3474        baseAngle = helper.startAngle;
3475        helper.StartSpreader(spreaderPathString, baseAngle, rbase);
3476    }
3477    else {
3478        spreaderPathString.push(helper.MoveTo(helper.startAngle + (helper.navAngle + sliceAngle / 2), rbase));
3479    }
3480    
3481    for (var i = 0; i < helper.navItemCount; i++) {
3482        startAngle = i * sliceAngle + (baseAngle + sliceAngle / 2);
3483        middleAngle = startAngle + (sliceAngle / 2);
3484        endAngle = startAngle + sliceAngle;
3485
3486        if (helper.endAngle - helper.startAngle < 360) {
3487            if (i === 0) { spreaderPathString.push(helper.ArcTo(custom.menuRadius, startAngle, rbase)); }
3488            if (i === helper.navItemCount - 1) { endAngle = middleAngle; }
3489        }
3490        else {
3491            spreaderPathString.push(helper.LineTo(startAngle, rbase));
3492        }
3493
3494        spreaderPathString.push(helper.ArcTo(custom.menuRadius, endAngle, rbase));
3495    }
3496
3497    spreaderPathString.push(helper.Close());
3498
3499    return {
3500        spreaderPathString: spreaderPathString,
3501        titlePosX: helper.titlePosX,
3502        titlePosY: helper.titlePosY
3503    };
3504};
3505
3506
3507///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.Holder.js
3508
3509this.HolderSpreaderCustomization = function () {
3510
3511    var custom = new spreaderPathCustomization();
3512    custom.minRadiusPercent = 0.5;
3513    custom.menuRadius = 37;
3514
3515    return custom;
3516};
3517
3518this.HolderSpreader = function (helper, percent, custom) {
3519
3520    if (custom === null) {
3521        custom = HolderSpreaderCustomization();
3522    }
3523
3524    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3525    rbase = helper.wheelRadius * custom.spreaderPercent * custom.minRadiusPercent * percent;
3526    r = helper.sliceRadius;
3527
3528    spreaderPathString = [];
3529
3530    sliceAngle = helper.sliceAngle / helper.navItemCount;
3531    baseAngle = helper.navAngle;
3532    if (helper.endAngle - helper.startAngle < 360) {
3533        baseAngle = helper.startAngle;
3534        helper.StartSpreader(spreaderPathString, baseAngle, rbase);
3535    }
3536    else {
3537        spreaderPathString.push(helper.MoveTo(helper.startAngle + (helper.navAngle + sliceAngle / 2), rbase));
3538    }
3539
3540    for (var i = 0; i < helper.navItemCount; i++) {
3541        startAngle = i * sliceAngle + (baseAngle + sliceAngle / 2);
3542        middleAngle = startAngle + (sliceAngle / 4);
3543        endAngle = startAngle + sliceAngle;
3544
3545        if (helper.endAngle - helper.startAngle < 360) {
3546            if (i === helper.navItemCount - 1) { endAngle = middleAngle; }
3547        }
3548        else {
3549            spreaderPathString.push(helper.LineTo(startAngle, rbase));
3550        }
3551
3552        spreaderPathString.push(helper.LineTo(startAngle, r));
3553        spreaderPathString.push(helper.ArcBackTo(custom.menuRadius, middleAngle, rbase));
3554        spreaderPathString.push(helper.ArcTo(custom.menuRadius, endAngle, r));
3555    }
3556
3557    spreaderPathString.push(helper.Close());
3558
3559    return {
3560        spreaderPathString: spreaderPathString,
3561        titlePosX: helper.titlePosX,
3562        titlePosY: helper.titlePosY
3563    };
3564};
3565
3566
3567///#source 1 1 /js/source/spreader/wheelnav.spreaderPath.Line.js
3568
3569this.LineSpreaderCustomization = function () {
3570
3571    var custom = new spreaderPathCustomization();
3572    custom.minRadiusPercent = 0.5;
3573
3574    return custom;
3575};
3576
3577this.LineSpreader = function (helper, percent, custom) {
3578
3579    if (custom === null) {
3580        custom = LineSpreaderCustomization();
3581    }
3582
3583    helper.setBaseValue(custom.spreaderPercent * percent, custom);
3584    rbase = helper.wheelRadius * custom.spreaderPercent * custom.minRadiusPercent * percent;
3585    r = helper.sliceRadius;
3586
3587    spreaderPathString = [];
3588
3589    sliceAngle = helper.sliceAngle / helper.navItemCount;
3590    baseAngle = helper.navAngle;
3591    if (helper.endAngle - helper.startAngle < 360) { baseAngle = helper.startAngle; }
3592
3593    spreaderPathString.push(helper.MoveTo(baseAngle + sliceAngle / 2, r));
3594
3595    for (var i = 0; i < helper.navItemCount; i++) {
3596        startAngle = i * sliceAngle + (baseAngle + sliceAngle / 2);
3597        endAngle = startAngle + sliceAngle;
3598        if (helper.navItemCount === 2) {
3599            endAngle -= 90;
3600        }
3601
3602        spreaderPathString.push(helper.LineTo(startAngle, r));
3603        spreaderPathString.push(helper.LineTo(endAngle, r));
3604    }
3605
3606    spreaderPathString.push(helper.Close());
3607
3608    return {
3609        spreaderPathString: spreaderPathString,
3610        titlePosX: helper.titlePosX,
3611        titlePosY: helper.titlePosY
3612    };
3613};
3614
3615
3616///#source 1 1 /js/source/spreader/wheelnav.spreaderPathEnd.js
3617
3618    return this;
3619};
3620
3621
3622
3623
3624///#source 1 1 /js/source/marker/wheelnav.marker.js
3625///#source 1 1 /js/source/marker/wheelnav.marker.core.js
3626/* ======================================================================================= */
3627/* Marker of wheel                                                                         */
3628/* ======================================================================================= */
3629/* ======================================================================================= */
3630/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/marker.html        */
3631/* ======================================================================================= */
3632
3633marker = function (wheelnav) {
3634
3635    this.wheelnav = wheelnav;
3636    if (this.wheelnav.markerEnable) {
3637
3638        this.markerHelper = new pathHelper();
3639        this.markerHelper.centerX = this.wheelnav.centerX;
3640        this.markerHelper.centerY = this.wheelnav.centerY;
3641        this.markerHelper.navItemCount = this.wheelnav.navItemCount;
3642        this.markerHelper.navAngle = this.wheelnav.navAngle;
3643        this.markerHelper.wheelRadius = this.wheelnav.wheelRadius * this.wheelnav.maxPercent;
3644        this.markerHelper.sliceAngle = this.wheelnav.navItems[0].sliceAngle;
3645        this.markerHelper.startAngle = this.markerHelper.navAngle - (this.markerHelper.sliceAngle / 2);
3646
3647        this.animateeffect = "bounce";
3648        this.animatetime = 1500;
3649        //Set animation from wheelnav
3650        if (this.wheelnav.animateeffect !== null) { this.animateeffect = this.wheelnav.animateeffect; }
3651        if (this.wheelnav.animatetime !== null) { this.animatetime = this.wheelnav.animatetime; }
3652
3653        this.markerPathMin = this.wheelnav.markerPathFunction(this.markerHelper, this.wheelnav.minPercent, this.wheelnav.markerPathCustom);
3654        this.markerPathMax = this.wheelnav.markerPathFunction(this.markerHelper, this.wheelnav.maxPercent, this.wheelnav.markerPathCustom);
3655        this.marker = this.wheelnav.raphael.path(this.markerPathMax.markerPathString);
3656        this.marker.attr(this.wheelnav.markerAttr);
3657        this.marker.id = this.wheelnav.getMarkerId();
3658        this.marker.node.id = this.marker.id;
3659    }
3660
3661    return this;
3662};
3663
3664marker.prototype.setCurrentTransform = function (navAngle) {
3665
3666    if (this.wheelnav.markerEnable) {
3667        var currentPath = "";
3668
3669        if (this.wheelnav.currentPercent === this.wheelnav.maxPercent) {
3670            currentPath = this.markerPathMax.markerPathString;
3671        }
3672        else {
3673            currentPath = this.markerPathMin.markerPathString;
3674        }
3675
3676        if (navAngle !== undefined) {
3677            var rotationAngle = navAngle - this.markerHelper.navAngle;
3678
3679            markerTransformAttr = {
3680                transform: "r," + (rotationAngle).toString() + "," + this.wheelnav.centerX + "," + this.wheelnav.centerY,
3681                path: currentPath
3682            };
3683        }
3684        else {
3685            markerTransformAttr = {
3686                path: currentPath
3687            };
3688        }
3689
3690        //Animate marker
3691        this.marker.animate(markerTransformAttr, this.animatetime, this.animateeffect);
3692        this.marker.toFront();
3693    }
3694};
3695
3696
3697
3698///#source 1 1 /js/source/marker/wheelnav.markerPathStart.js
3699/* ======================================================================================= */
3700/* Marker path definitions.                                                                */
3701/* ======================================================================================= */
3702
3703markerPath = function () {
3704
3705    this.NullMarker = function (helper, custom) {
3706
3707        if (custom === null) {
3708            custom = new markerPathCustomization();
3709        }
3710
3711        helper.setBaseValue(custom);
3712
3713        return {
3714            markerPathString: "",
3715            titlePosX: helper.titlePosX,
3716            titlePosY: helper.titlePosY
3717        };
3718    };
3719
3720
3721
3722///#source 1 1 /js/source/marker/wheelnav.markerPath.Triangle.js
3723
3724this.TriangleMarkerCustomization = function () {
3725
3726    var custom = new markerPathCustomization();
3727    custom.arcBaseRadiusPercent = 1.09;
3728    custom.arcRadiusPercent = 1.2;
3729    custom.startRadiusPercent = 0;
3730    return custom;
3731};
3732
3733this.TriangleMarker = function (helper, percent, custom) {
3734
3735    if (custom === null) {
3736        custom = TriangleMarkerCustomization();
3737    }
3738
3739    helper.setBaseValue(custom.markerPercent * percent, custom);
3740
3741    var arcBaseRadius = helper.sliceRadius * custom.arcBaseRadiusPercent;
3742    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
3743    var startAngle = helper.startAngle + helper.sliceAngle * 0.46;
3744    var endAngle = helper.startAngle + helper.sliceAngle * 0.54;
3745
3746    markerPathString = [helper.MoveTo(helper.navAngle, arcBaseRadius),
3747                 helper.LineTo(startAngle, arcRadius),
3748                 helper.LineTo(endAngle, arcRadius),
3749                 helper.Close()];
3750    
3751    return {
3752        markerPathString: markerPathString,
3753        titlePosX: helper.titlePosX,
3754        titlePosY: helper.titlePosY
3755    };
3756};
3757
3758
3759///#source 1 1 /js/source/marker/wheelnav.markerPath.PieLine.js
3760
3761this.PieLineMarkerCustomization = function () {
3762
3763    var custom = new markerPathCustomization();
3764    custom.arcBaseRadiusPercent = 1;
3765    custom.arcRadiusPercent = 1;
3766    custom.startRadiusPercent = 0;
3767    custom.sliceAngle = null;
3768    return custom;
3769};
3770
3771this.PieLineMarker = function (helper, percent, custom) {
3772
3773    if (custom === null) {
3774        custom = PieLineMarkerCustomization();
3775    }
3776
3777    helper.setBaseValue(custom.markerPercent * percent, custom);
3778
3779    var arcBaseRadius = helper.sliceRadius * custom.arcBaseRadiusPercent;
3780    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
3781
3782    if (custom.sliceAngle !== null) {
3783        helper.startAngle = helper.navAngle - (custom.sliceAngle / 2);
3784        helper.endAngle = helper.navAngle + (custom.sliceAngle / 2);
3785    }
3786
3787    markerPathString = [helper.MoveTo(helper.startAngle, arcBaseRadius),
3788                 helper.ArcTo(arcRadius, helper.endAngle, arcBaseRadius),
3789                 helper.ArcBackTo(arcRadius, helper.startAngle, arcBaseRadius),
3790                 helper.Close()];
3791
3792    return {
3793        markerPathString: markerPathString,
3794        titlePosX: helper.titlePosX,
3795        titlePosY: helper.titlePosY
3796    };
3797};
3798
3799
3800
3801
3802///#source 1 1 /js/source/marker/wheelnav.markerPath.Menu.js
3803
3804this.MenuMarkerCustomization = function () {
3805
3806    var custom = new markerPathCustomization();
3807    custom.menuRadius = 40;
3808    custom.titleRadiusPercent = 0.63;
3809    custom.lineBaseRadiusPercent = 0;
3810    return custom;
3811};
3812
3813this.MenuMarker = function (helper, percent, custom) {
3814
3815    if (custom === null) {
3816        custom = MenuMarkerCustomization();
3817    }
3818
3819    helper.setBaseValue(custom.markerPercent * percent, custom);
3820
3821    x = helper.centerX;
3822    y = helper.centerY;
3823
3824    helper.titleRadius = helper.wheelRadius * custom.titleRadiusPercent * percent;
3825    helper.setTitlePos();
3826
3827    var menuRadius = custom.menuRadius * percent;
3828    if (percent <= 0.05) { menuRadius = 11; }
3829
3830    middleTheta = helper.middleTheta;
3831
3832    markerPathString = [["M", helper.titlePosX - (menuRadius * Math.cos(middleTheta)), helper.titlePosY - (menuRadius * Math.sin(middleTheta))],
3833                ["A", menuRadius, menuRadius, 0, 0, 1, helper.titlePosX + (menuRadius * Math.cos(middleTheta)), helper.titlePosY + (menuRadius * Math.sin(middleTheta))],
3834                ["A", menuRadius, menuRadius, 0, 0, 1, helper.titlePosX - (menuRadius * Math.cos(middleTheta)), helper.titlePosY - (menuRadius * Math.sin(middleTheta))],
3835                ["z"]];
3836    
3837    return {
3838        markerPathString: markerPathString,
3839        titlePosX: helper.titlePosX,
3840        titlePosY: helper.titlePosY
3841    };
3842};
3843
3844
3845///#source 1 1 /js/source/marker/wheelnav.markerPath.Line.js
3846
3847this.LineMarkerCustomization = function () {
3848
3849    var custom = new markerPathCustomization();
3850    custom.arcBaseRadiusPercent = 1.05;
3851    custom.arcRadiusPercent = 1.2;
3852    custom.startRadiusPercent = 0;
3853    return custom;
3854};
3855
3856this.LineMarker = function (helper, percent, custom) {
3857
3858    if (custom === null) {
3859        custom = LineMarkerCustomization();
3860    }
3861
3862    helper.setBaseValue(custom.markerPercent * percent, custom);
3863
3864    var arcBaseRadius = helper.sliceRadius * custom.arcBaseRadiusPercent;
3865    var arcRadius = helper.sliceRadius * custom.arcRadiusPercent;
3866
3867    markerPathString = [helper.MoveTo(helper.navAngle, arcBaseRadius),
3868                 helper.LineTo(helper.navAngle, arcRadius),
3869                 helper.Close()];
3870    
3871    return {
3872        markerPathString: markerPathString,
3873        titlePosX: helper.titlePosX,
3874        titlePosY: helper.titlePosY
3875    };
3876};
3877
3878
3879///#source 1 1 /js/source/marker/wheelnav.markerPath.Drop.js
3880
3881this.DropMarkerCustomization = function () {
3882
3883    var custom = new markerPathCustomization();
3884    custom.dropBaseRadiusPercent = 0;
3885    custom.dropRadiusPercent = 0.15;
3886    return custom;
3887};
3888
3889this.DropMarker = function (helper, percent, custom) {
3890
3891    if (custom === null) {
3892        custom = DropMarkerCustomization();
3893    }
3894
3895    helper.setBaseValue(custom.markerPercent * percent, custom);
3896
3897    var arcBaseRadius = helper.sliceRadius * custom.dropBaseRadiusPercent;
3898    var startAngle = helper.startAngle + helper.sliceAngle * 0.2;
3899    var startAngle2 = helper.startAngle;
3900    var endAngle = helper.startAngle + helper.sliceAngle * 0.8;
3901    var endAngle2 = helper.startAngle + helper.sliceAngle;
3902    var dropRadius = helper.sliceRadius * custom.dropRadiusPercent;
3903
3904    markerPathString = [helper.MoveTo(0, dropRadius),
3905        helper.ArcTo(dropRadius, 180, dropRadius),
3906        helper.ArcTo(dropRadius, 360, dropRadius),
3907        helper.MoveTo(helper.navAngle, arcBaseRadius),
3908                helper.LineTo(startAngle, dropRadius),
3909                 helper.LineTo(startAngle2, dropRadius),
3910                 helper.LineTo(helper.navAngle, dropRadius * 1.6),
3911                helper.LineTo(endAngle2, dropRadius),
3912                 helper.LineTo(endAngle, dropRadius),
3913                 helper.Close()];
3914    return {
3915        markerPathString: markerPathString,
3916        titlePosX: helper.titlePosX,
3917        titlePosY: helper.titlePosY
3918    };
3919};
3920
3921
3922///#source 1 1 /js/source/marker/wheelnav.markerPathEnd.js
3923
3924    return this;
3925};
3926
3927
3928
3929
3930///#source 1 1 /js/source/wheelnav.colorPalettes.js
3931/* ======================================================================================== */
3932/* Color palettes for slices from http://www.colourlovers.com                               */
3933/* ======================================================================================== */
3934/* ======================================================================================== */
3935/* Documentation: http://wheelnavjs.softwaretailoring.net/documentation/colorPalettes.html  */
3936/* ======================================================================================== */
3937
3938var colorpalette = {
3939    defaultpalette: new Array("#2D9E46", "#F5BE41", "#F77604", "#D63C22", "#006BA6", "#92ADAF"),
3940    purple: new Array("#4F346B", "#623491", "#9657D6", "#AD74E7", "#CBA3F3"),
3941    greenred: new Array("#17B92A", "#FF3D00", "#17B92A", "#FF3D00"),
3942    greensilver: new Array("#1F700A", "#79CC3C", "#D4E178", "#E6D5C3", "#AC875D"),
3943    oceanfive: new Array("#00A0B0", "#6A4A3C", "#CC333F", "#EB6841", "#EDC951"),
3944    garden: new Array("#648A4F", "#2B2B29", "#DF6126", "#FFA337", "#F57C85"),
3945    gamebookers: new Array("#FF9900", "#DCDCDC", "#BCBCBC", "#3299BB", "#727272"),
3946    parrot: new Array("#D80351", "#F5D908", "#00A3EE", "#929292", "#3F3F3F"),
3947    pisycholand: new Array("#FF1919", "#FF5E19", "#FF9F19", "#E4FF19", "#29FF19"),
3948    makeLOVEnotWAR: new Array("#2C0EF0", "#B300FF", "#6751F0", "#FF006F", "#8119FF"),
3949    theworldismine: new Array("#F21D1D", "#FF2167", "#B521FF", "#7E2AA8", "#000000"),
3950    fractalloveone: new Array("#002EFF", "#00FFF7", "#00FF62", "#FFAA00", "#FFF700"),
3951    fractallovetwo: new Array("#FF9500", "#FF0000", "#FF00F3", "#AA00FF", "#002EFF"),
3952    fractallove: new Array("#002EFF", "#00FFF7", "#00FF62", "#FFAA00", "#F5D908", "#FF0000", "#FF00F3", "#AA00FF"),
3953    sprinkles: new Array("#272523", "#FFACAC", "#FFD700", "#00590C", "#08006D"),
3954    goldenyellow: new Array("#D8B597", "#8C4006", "#B6690F", "#E3C57F", "#FFEDBE"),
3955    hotaru: new Array("#364C4A", "#497C7F", "#92C5C0", "#858168", "#CCBCA5")
3956};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.