Built motion from commit bcd50b9.|0.0.29
[motion.git] / public / assets / plugins / jscripty / js / Shapes.js
1 /**
2  * $Id: Shapes.js,v 1.13 2013-02-02 06:44:30 gaudenz Exp $
3  * Copyright (c) 2006-2012, JGraph Ltd
4  */
5
6 /**
7  * Registers shapes.
8  */
9 (function()
10 {
11         // Cube Shape, supports size style
12         function CubeShape() { };
13         CubeShape.prototype = new mxCylinder();
14         CubeShape.prototype.constructor = CubeShape;
15         CubeShape.prototype.size = 20;
16         CubeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
17         {
18                 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
19
20                 if (isForeground)
21                 {
22                         path.moveTo(s, h);
23                         path.lineTo(s, s);
24                         path.lineTo(0, 0);
25                         path.moveTo(s, s);
26                         path.lineTo(w, s);
27                         path.end();
28                 }
29                 else
30                 {
31                         path.moveTo(0, 0);
32                         path.lineTo(w - s, 0);
33                         path.lineTo(w, s);
34                         path.lineTo(w, h);
35                         path.lineTo(s, h);
36                         path.lineTo(0, h - s);
37                         path.lineTo(0, 0);
38                         path.close();
39                         path.end();
40                 }
41         };
42
43         mxCellRenderer.prototype.defaultShapes['cube'] = CubeShape;
44
45         // Note Shape, supports size style
46         function NoteShape() { };
47         NoteShape.prototype = new mxCylinder();
48         NoteShape.prototype.constructor = NoteShape;
49         NoteShape.prototype.size = 30;
50         NoteShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
51         {
52                 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
53
54                 if (isForeground)
55                 {
56                         path.moveTo(w - s, 0);
57                         path.lineTo(w - s, s);
58                         path.lineTo(w, s);
59                         path.end();
60                 }
61                 else
62                 {
63                         path.moveTo(0, 0);
64                         path.lineTo(w - s, 0);
65                         path.lineTo(w, s);
66                         path.lineTo(w, h);
67                         path.lineTo(0, h);
68                         path.lineTo(0, 0);
69                         path.close();
70                         path.end();
71                 }
72         };
73
74         mxCellRenderer.prototype.defaultShapes['note'] = NoteShape;
75
76         // Folder Shape, supports tabWidth, tabHeight styles
77         function FolderShape() { };
78         FolderShape.prototype = new mxCylinder();
79         FolderShape.prototype.constructor = FolderShape;
80         FolderShape.prototype.tabWidth = 60;
81         FolderShape.prototype.tabHeight = 20;
82         FolderShape.prototype.tabPosition = 'right';
83         FolderShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
84         {
85                 var tw = mxUtils.getValue(this.style, 'tabWidth', this.tabWidth);
86                 var th = mxUtils.getValue(this.style, 'tabHeight', this.tabHeight);
87                 var tp = mxUtils.getValue(this.style, 'tabPosition', this.tabPosition);
88                 var dx = Math.min(w, tw);
89                 var dy = Math.min(h, th);
90
91                 if (isForeground)
92                 {
93                         if (tp == 'left')
94                         {
95                                 path.moveTo(0, dy);
96                                 path.lineTo(dx, dy);
97                         }
98                         // Right is default
99                         else
100                         {
101                                 path.moveTo(w - dx, dy);
102                                 path.lineTo(w, dy);
103                         }
104                         
105                         path.end();
106                 }
107                 else
108                 {
109                         if (tp == 'left')
110                         {
111                                 path.moveTo(0, 0);
112                                 path.lineTo(dx, 0);
113                                 path.lineTo(dx, dy);
114                                 path.lineTo(w, dy);
115                         }
116                         // Right is default
117                         else
118                         {
119                                 path.moveTo(0, dy);
120                                 path.lineTo(w - dx, dy);
121                                 path.lineTo(w - dx, 0);
122                                 path.lineTo(w, 0);
123                         }
124                         
125                         path.lineTo(w, h);
126                         path.lineTo(0, h);
127                         path.lineTo(0, dy);
128                         path.close();
129                         path.end();
130                 }
131         };
132
133         mxCellRenderer.prototype.defaultShapes['folder'] = FolderShape;
134
135         // Card Shape, supports size style
136         function CardShape() { };
137         CardShape.prototype = new mxCylinder();
138         CardShape.prototype.constructor = CardShape;
139         CardShape.prototype.size = 30;
140         CardShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
141         {
142                 var s = Math.min(w, Math.min(h, mxUtils.getValue(this.style, 'size', this.size)));
143
144                 if (!isForeground)
145                 {
146                         path.moveTo(s, 0);
147                         path.lineTo(w, 0);
148                         path.lineTo(w, h);
149                         path.lineTo(0, h);
150                         path.lineTo(0, s);
151                         path.lineTo(s, 0);
152                         path.close();
153                         path.end();
154                 }
155         };
156
157         mxCellRenderer.prototype.defaultShapes['card'] = CardShape;
158
159         // Tape Shape, supports size style
160         function TapeShape() { };
161         TapeShape.prototype = new mxCylinder();
162         TapeShape.prototype.constructor = TapeShape;
163         TapeShape.prototype.size = 0.4;
164         TapeShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
165         {
166                 var s = mxUtils.getValue(this.style, 'size', this.size);
167                 var dy = h * s;
168                 var fy = 1.4;
169
170                 if (!isForeground)
171                 {
172                         path.moveTo(0, dy / 2);
173                         path.quadTo(w / 4, dy * fy, w / 2, dy / 2);
174                         path.quadTo(w * 3 / 4, dy * (1 - fy), w, dy / 2);
175                         path.lineTo(w, h - dy / 2);
176                         path.quadTo(w * 3 / 4, h - dy * fy, w / 2, h - dy / 2);
177                         path.quadTo(w / 4, h - dy * (1 - fy), 0, h - dy / 2);
178                         path.lineTo(0, dy / 2);
179                         path.close();
180                         path.end();
181                 }
182         };
183
184         mxCellRenderer.prototype.defaultShapes['tape'] = TapeShape;
185
186         // Tape Shape, supports size style
187         function StepShape() { };
188         StepShape.prototype = new mxCylinder();
189         StepShape.prototype.constructor = StepShape;
190         StepShape.prototype.size = 0.2;
191         StepShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
192         {
193                 var s =  w * mxUtils.getValue(this.style, 'size', this.size);
194
195                 if (!isForeground)
196                 {
197                         path.moveTo(0, 0);
198                         path.lineTo(w - s, 0);
199                         path.lineTo(w, h / 2);
200                         path.lineTo(w - s, h);
201                         path.lineTo(0, h);
202                         path.lineTo(s, h / 2);
203                         path.close();
204                         path.end();
205                 }
206         };
207
208         mxCellRenderer.prototype.defaultShapes['step'] = StepShape;
209
210         // Plus Shape
211         function PlusShape()
212         {
213                 mxRectangleShape.call(this);
214         };
215         mxUtils.extend(PlusShape, mxRectangleShape);
216         PlusShape.prototype.isHtmlAllowed = function()
217         {
218                 return false;
219         };
220         PlusShape.prototype.paintForeground = function(c, x, y, w, h)
221         {
222                 var border = Math.min(w / 5, h / 5) + 1;
223                 
224                 c.begin();
225                 c.moveTo(x + w / 2, y + border);
226                 c.lineTo(x + w / 2, y + h - border);
227                 c.moveTo(x + border, y + h / 2);
228                 c.lineTo(x + w - border, y + h / 2);
229                 c.end();
230                 c.stroke();
231                 mxRectangleShape.prototype.paintForeground.apply(this, arguments);
232         };
233
234         mxCellRenderer.prototype.defaultShapes['plus'] = PlusShape;
235
236         // CompositeShape
237         function ExtendedShape()
238         {
239                 mxRectangleShape.call(this);
240         };
241         mxUtils.extend(ExtendedShape, mxRectangleShape);
242         ExtendedShape.prototype.isHtmlAllowed = function()
243         {
244                 return false;
245         };
246         ExtendedShape.prototype.paintForeground = function(c, x, y, w, h)
247         {
248                 if (this.style != null)
249                 {
250                         if (this.style['double'] == 1)
251                         {
252                                 var inset = Math.max(2, this.strokewidth + 1);
253         
254                                 mxRectangleShape.prototype.paintBackground.call(this, c, x + inset, y + inset, w - 2 * inset, h - 2 * inset);
255                                 mxRectangleShape.prototype.paintForeground.apply(this, arguments);
256                                 
257                                 x += inset;
258                                 y += inset;
259                                 w -= 2 * inset;
260                                 h -= 2 * inset;
261                         }
262                         
263                         c.setDashed(false);
264                         
265                         // Draws the symbols defined in the style. The symbols are
266                         // numbered from 1...n. Possible postfixes are align,
267                         // verticalAlign, spacing, arcSpacing, width, height
268                         var counter = 0;
269                         var shape = null;
270                         
271                         do
272                         {
273                                 shape = mxCellRenderer.prototype.defaultShapes[this.style['symbol' + counter]];
274                                 
275                                 if (shape != null)
276                                 {
277                                         var align = this.style['symbol' + counter + 'Align'];
278                                         var valign = this.style['symbol' + counter + 'VerticalAlign'];
279                                         var width = this.style['symbol' + counter + 'Width'];
280                                         var height = this.style['symbol' + counter + 'Height'];
281                                         var spacing = this.style['symbol' + counter + 'Spacing'] || 0;
282                                         var arcspacing = this.style['symbol' + counter + 'ArcSpacing'];
283                                         
284                                         if (arcspacing != null)
285                                         {
286                                                 spacing += this.getArcSize(w + this.strokewidth, h + this.strokewidth) * arcspacing;
287                                         }
288                                         
289                                         var x2 = x;
290                                         var y2 = y;
291                                         
292                                         if (align == mxConstants.ALIGN_CENTER)
293                                         {
294                                                 x2 += (w - width) / 2;
295                                         }
296                                         else if (align == mxConstants.ALIGN_RIGHT)
297                                         {
298                                                 x2 += w - width - spacing;
299                                         }
300                                         else
301                                         {
302                                                 x2 += spacing;
303                                         }
304                                         
305                                         if (valign == mxConstants.ALIGN_MIDDLE)
306                                         {
307                                                 y2 += (h - height) / 2;
308                                         }
309                                         else if (valign == mxConstants.ALIGN_BOTTOM)
310                                         {
311                                                 y2 += h - height - spacing;
312                                         }
313                                         else
314                                         {
315                                                 y2 += spacing;
316                                         }
317                                         
318                                         c.save();
319                                         
320                                         // Small hack to pass style along into subshape
321                                         var tmp = new shape();
322                                         // TODO: Clone style and override settings (eg. strokewidth)
323                                         tmp.style = this.style;
324                                         shape.prototype.paintVertexShape.call(tmp, c, x2, y2, width, height);
325                                         c.restore();
326                                 }
327                                 
328                                 counter++;
329                         }
330                         while (shape != null);
331                 }
332         };
333
334         mxCellRenderer.prototype.defaultShapes['ext'] = ExtendedShape;
335         
336         // Tape Shape, supports size style
337         function MessageShape() { };
338         MessageShape.prototype = new mxCylinder();
339         MessageShape.prototype.constructor = MessageShape;
340         MessageShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
341         {
342                 if (isForeground)
343                 {
344                         path.moveTo(0, 0);
345                         path.lineTo(w / 2, h / 2);
346                         path.lineTo(w, 0);
347                         path.end();
348                 }
349                 else
350                 {
351                         path.moveTo(0, 0);
352                         path.lineTo(w, 0);
353                         path.lineTo(w, h);
354                         path.lineTo(0, h);
355                         path.close();
356                 }
357         };
358
359         mxCellRenderer.prototype.defaultShapes['message'] = MessageShape;
360         
361         // New Actor Shape
362         function UmlActorShape() { };
363         UmlActorShape.prototype = new mxCylinder();
364         UmlActorShape.prototype.constructor = UmlActorShape;
365         UmlActorShape.prototype.addPipe = true;
366         UmlActorShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
367         {
368                 var width = w / 3;
369                 var height = h / 4;
370                 
371                 if (!isForeground)
372                 {
373                         path.moveTo(w / 2, height);
374                         path.curveTo(w / 2 - width, height, w / 2 - width, 0, w / 2, 0);
375                         path.curveTo(w / 2 + width, 0, w / 2 + width, height, w / 2, height);
376                         path.close();
377
378                         path.moveTo(w / 2, height);
379                         path.lineTo(w / 2, 2 * h / 3);
380                         
381                         // Arms
382                         path.moveTo(w / 2, h / 3);
383                         path.lineTo(0, h / 3);
384                         path.moveTo(w / 2, h / 3);
385                         path.lineTo(w, h / 3);
386                         
387                         // Legs
388                         path.moveTo(w / 2, 2 * h / 3);
389                         path.lineTo(0, h);
390                         path.moveTo(w / 2, 2 * h / 3);
391                         path.lineTo(w, h);
392                         path.end();
393                 }
394         };
395
396         // Replaces existing actor shape
397         mxCellRenderer.prototype.defaultShapes['umlActor'] = UmlActorShape;
398
399         // New Actor Shape
400         function LollipopShape() { };
401         LollipopShape.prototype = new mxCylinder();
402         LollipopShape.prototype.constructor = LollipopShape;
403         LollipopShape.prototype.size = 10;
404         LollipopShape.prototype.addPipe = true;
405         LollipopShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
406         {
407                 var ss = mxUtils.getValue(this.style, 'size', this.size);
408                 var width = ss * 2 / 3;
409                 var height = ss;
410                 
411                 if (!isForeground)
412                 {
413                         path.moveTo(w / 2, height);
414                         path.curveTo(w / 2 - width, height, w / 2 - width, 0, w / 2, 0);
415                         path.curveTo(w / 2 + width, 0, w / 2 + width, height, w / 2, height);
416                         path.close();
417
418                         path.moveTo(w / 2, height);
419                         path.lineTo(w / 2, h);
420                         path.end();
421                 }
422         };
423
424         // Replaces existing actor shape
425         mxCellRenderer.prototype.defaultShapes['lollipop'] = LollipopShape;
426         
427         // Folder Shape, supports tabWidth, tabHeight styles
428         function ComponentShape() { };
429         ComponentShape.prototype = new mxCylinder();
430         ComponentShape.prototype.constructor = ComponentShape;
431         ComponentShape.prototype.jettyWidth = 32;
432         ComponentShape.prototype.jettyHeight = 12;
433         ComponentShape.prototype.redrawPath = function(path, x, y, w, h, isForeground)
434         {
435                 var dx = mxUtils.getValue(this.style, 'jettyWidth', this.jettyWidth);
436                 var dy = mxUtils.getValue(this.style, 'jettyHeight', this.jettyHeight);
437                 var x0 = dx / 2;
438                 var x1 = x0 + dx / 2;
439                 var y0 = 0.3 * h - dy / 2;
440                 var y1 = 0.7 * h - dy / 2;
441
442                 if (isForeground)
443                 {
444                         path.moveTo(x0, y0);
445                         path.lineTo(x1, y0);
446                         path.lineTo(x1, y0 + dy);
447                         path.lineTo(x0, y0 + dy);
448                         path.moveTo(x0, y1);
449                         path.lineTo(x1, y1);
450                         path.lineTo(x1, y1 + dy);
451                         path.lineTo(x0, y1 + dy);
452                         path.end();
453                 }
454                 else
455                 {
456                         path.moveTo(x0, 0);
457                         path.lineTo(w, 0);
458                         path.lineTo(w, h);
459                         path.lineTo(x0, h);
460                         path.lineTo(x0, y1 + dy);
461                         path.lineTo(0, y1 + dy);
462                         path.lineTo(0, y1);
463                         path.lineTo(x0, y1);
464                         path.lineTo(x0, y0 + dy);
465                         path.lineTo(0, y0 + dy);
466                         path.lineTo(0, y0);
467                         path.lineTo(x0, y0);
468                         path.close();
469                         path.end();
470                 }
471         };
472
473         mxCellRenderer.prototype.defaultShapes['component'] = ComponentShape;
474         
475         // State Shapes derives from double ellipse
476         function StateShape() { };
477         StateShape.prototype = new mxDoubleEllipse();
478         StateShape.prototype.constructor = StateShape;
479         StateShape.prototype.outerStroke = true;
480         StateShape.prototype.paintVertexShape = function(c, x, y, w, h)
481         {
482                 var inset = Math.min(4, Math.min(w / 5, h / 5));
483                 
484                 if (w > 0 && h > 0)
485                 {
486                         c.ellipse(x + inset, y + inset, w - 2 * inset, h - 2 * inset);
487                         c.fillAndStroke();
488                 }
489                 
490                 c.setShadow(false);
491
492                 if (this.outerStroke)
493                 {
494                         c.ellipse(x, y, w, h);
495                         c.stroke();                     
496                 }
497         };
498
499         mxCellRenderer.prototype.defaultShapes['endState'] = StateShape;
500
501         function StartStateShape() { };
502         StartStateShape.prototype = new StateShape();
503         StartStateShape.prototype.constructor = StartStateShape;
504         StartStateShape.prototype.outerStroke = false;
505         
506         mxCellRenderer.prototype.defaultShapes['startState'] = StartStateShape;
507
508         // Image export for state shapes
509         var imageExportInitShapes = mxImageExport.prototype.initShapes;
510         mxImageExport.prototype.initShapes = function()
511         {
512                 imageExportInitShapes.apply(this, arguments);
513
514                 function createStateShape(outerStroke)
515                 {
516                         return {
517                                 drawShape: function(canvas, state, bounds, background)
518                                 {
519                                         var x = bounds.x;
520                                         var y = bounds.y;
521                                         var w = bounds.width;
522                                         var h = bounds.height;
523                                         
524                                         if (background)
525                                         {
526                                                 var inset = Math.min(4, Math.min(w / 5, h / 5));
527                                                 x += inset;
528                                                 y += inset;
529                                                 w -= 2 * inset;
530                                                 h -= 2 * inset;
531                                                 
532                                                 if (w > 0 && h > 0)
533                                                 {
534                                                         canvas.ellipse(x, y, w, h);
535                                                 }
536                                                 
537                                                 return true;
538                                         }
539                                         else
540                                         {
541                                                 canvas.fillAndStroke();
542                 
543                                                 if (outerStroke)
544                                                 {
545                                                         canvas.ellipse(x, y, w, h);
546                                                         canvas.stroke();
547                                                 }
548                                         }
549                                 }
550                         };
551                 };
552                 
553                 this.shapes['endState'] = createStateShape(true);
554                 this.shapes['startState'] = createStateShape(false);
555         };
556
557         // Defines custom edge shape
558         function LinkShape()
559         {
560                 mxArrow.call(this);
561         };
562         mxUtils.extend(LinkShape, mxArrow);
563         LinkShape.prototype.paintEdgeShape = function(c, pts)
564         {
565                 var width = 10;
566
567                 // Base vector (between end points)
568                 var p0 = pts[0];
569                 var pe = pts[pts.length - 1];
570                 
571                 var dx = pe.x - p0.x;
572                 var dy = pe.y - p0.y;
573                 var dist = Math.sqrt(dx * dx + dy * dy);
574                 var length = dist;
575                 
576                 // Computes the norm and the inverse norm
577                 var nx = dx / dist;
578                 var ny = dy / dist;
579                 var basex = length * nx;
580                 var basey = length * ny;
581                 var floorx = width * ny/3;
582                 var floory = -width * nx/3;
583                 
584                 // Computes points
585                 var p0x = p0.x - floorx / 2;
586                 var p0y = p0.y - floory / 2;
587                 var p1x = p0x + floorx;
588                 var p1y = p0y + floory;
589                 var p2x = p1x + basex;
590                 var p2y = p1y + basey;
591                 var p3x = p2x + floorx;
592                 var p3y = p2y + floory;
593                 // p4 not necessary
594                 var p5x = p3x - 3 * floorx;
595                 var p5y = p3y - 3 * floory;
596                 
597                 c.begin();
598                 c.moveTo(p1x, p1y);
599                 c.lineTo(p2x, p2y);
600                 c.moveTo(p5x + floorx, p5y + floory);
601                 c.lineTo(p0x, p0y);
602                 c.stroke();
603         };
604
605         // Registers the link shape
606         mxCellRenderer.prototype.defaultShapes['link'] = LinkShape;
607
608         // Registers and defines the custom marker
609         mxMarker.addMarker('dash', function(canvas, shape, type, pe, unitX, unitY, size, source, sw, filled)
610         {
611                 var nx = unitX * (size + sw + 1);
612                 var ny = unitY * (size + sw + 1);
613
614                 return function()
615                 {
616                         canvas.begin();
617                         canvas.moveTo(pe.x - nx / 2 - ny / 2, pe.y - ny / 2 + nx / 2);
618                         canvas.lineTo(pe.x + ny / 2 - 3 * nx / 2, pe.y - 3 * ny / 2 - nx / 2);
619                         canvas.stroke();
620                 };
621         });
622
623         // Implements custom handlers
624         var SPECIAL_HANDLE_INDEX = -99;
625
626         // Handlers are only added if mxVertexHandler is defined (ie. not in embedded graph)
627         if (typeof(mxVertexHandler) != 'undefined')
628         {
629                 function mxExtVertexHandler(state)
630                 {
631                         mxVertexHandler.call(this, state);
632                 };
633         
634                 mxUtils.extend(mxExtVertexHandler, mxVertexHandler);
635         
636                 mxExtVertexHandler.prototype.useGridForSpecialHandle = false;
637                 
638                 mxExtVertexHandler.prototype.init = function()
639                 {
640                         this.horizontal = mxUtils.getValue(this.state.style, mxConstants.STYLE_HORIZONTAL, true);
641                         var graph = this.state.view.graph;
642         
643                         if (this.handleImage != null)
644                         {
645                                 var bounds = new mxRectangle(0, 0, this.handleImage.width, this.handleImage.height);
646                                 this.specialHandle = new mxImageShape(bounds, this.handleImage.src);
647                         }
648                         else
649                         {
650                                 var size = 10;
651                                 var bounds = new mxRectangle(0, 0, size, size);
652                                 this.specialHandle = new mxRhombus(bounds, mxConstants.HANDLE_FILLCOLOR, mxConstants.HANDLE_STROKECOLOR);
653                         }
654                         
655                         this.specialHandle.dialect = (graph.dialect != mxConstants.DIALECT_SVG) ?
656                                         mxConstants.DIALECT_VML : mxConstants.DIALECT_SVG;
657                         this.specialHandle.init(graph.getView().getOverlayPane());
658                         this.specialHandle.node.style.cursor = this.getSpecialHandleCursor();
659         
660                         mxEvent.redirectMouseEvents(this.specialHandle.node, graph, this.state);
661                         mxVertexHandler.prototype.init.apply(this, arguments);
662                 };
663                 
664                 mxExtVertexHandler.prototype.getSpecialHandleCursor = function()
665                 {
666                         return 'default';
667                 };
668                 
669                 mxExtVertexHandler.prototype.redraw = function()
670                 {
671                         mxVertexHandler.prototype.redraw.apply(this, arguments);
672         
673                         var size = this.specialHandle.bounds.width;
674                         this.specialHandle.bounds = this.getSpecialHandleBounds(size);
675                         this.specialHandle.redraw();
676                 };
677
678                 mxExtVertexHandler.prototype.destroy = function()
679                 {
680                         mxVertexHandler.prototype.destroy.apply(this, arguments);
681                         
682                         if (this.specialHandle != null)
683                         {
684                                 this.specialHandle.destroy();
685                                 this.specialHandle = null;
686                         }
687                 };
688                 
689                 mxExtVertexHandler.prototype.getHandleForEvent = function(me)
690                 {
691                         if (me.isSource(this.specialHandle))
692                         {
693                                 return SPECIAL_HANDLE_INDEX;
694                         }
695                         
696                         return mxVertexHandler.prototype.getHandleForEvent.apply(this, arguments);
697                 };
698
699                 mxExtVertexHandler.prototype.mouseMove = function(sender, me)
700                 {
701                         if (!me.isConsumed() && this.index == SPECIAL_HANDLE_INDEX)
702                         {
703                                 var point = new mxPoint(me.getGraphX(), me.getGraphY());
704                                 this.constrainPoint(point);
705                                 var gridEnabled = this.graph.isGridEnabledEvent(me.getEvent());
706                                 var scale = this.graph.getView().scale;
707                                 
708                                 if (gridEnabled && this.useGridForSpecialHandle)
709                                 {
710                                         point.x = this.graph.snap(point.x / scale) * scale;
711                                         point.y = this.graph.snap(point.y / scale) * scale;
712                                 }
713                                 
714                                 this.updateStyle(point);                        
715                                 this.moveSizerTo(this.specialHandle, point.x, point.y);
716                                 this.state.view.graph.cellRenderer.redraw(this.state, true);
717                                 me.consume();
718                         }
719                         else
720                         {
721                                 mxVertexHandler.prototype.mouseMove.apply(this, arguments);
722                         }
723                 };
724
725                 mxExtVertexHandler.prototype.mouseUp = function(sender, me)
726                 {
727                         if (!me.isConsumed() && this.index == SPECIAL_HANDLE_INDEX)
728                         {
729                                 this.applyStyle();
730                                 this.reset();
731                                 me.consume();
732                         }
733                         else
734                         {
735                                 mxVertexHandler.prototype.mouseUp.apply(this, arguments);
736                         }
737                 };
738
739                 mxExtVertexHandler.prototype.getSpecialHandleBounds = function(size)
740                 {
741                         var rotation = this.state.shape.getShapeRotation();
742                         var alpha = mxUtils.toRadians(rotation);
743                         var cos = Math.cos(alpha);
744                         var sin = Math.sin(alpha);
745                         
746                         var bounds = new mxRectangle(this.state.x, this.state.y, this.state.width, this.state.height);
747                         
748                         if (this.state.shape.isPaintBoundsInverted())
749                         {
750                                 var t = (bounds.width - bounds.height) / 2;
751                                 bounds.x += t;
752                                 bounds.y -= t;
753                                 var tmp = bounds.width;
754                                 bounds.width = bounds.height;
755                                 bounds.height = tmp;
756                         }
757         
758                         var pt = this.getSpecialHandlePoint(bounds);
759
760                         if (this.state.shape.flipH)
761                         {
762                                 pt.x = 2 * bounds.x + bounds.width - pt.x;
763                         }
764                         
765                         if (this.state.shape.flipV)
766                         {
767                                 pt.y = 2 * bounds.y + bounds.height - pt.y;
768                         }
769                         
770                         pt = mxUtils.getRotatedPoint(pt, cos, sin,
771                                 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
772
773                         return new mxRectangle(pt.x - size / 2, pt.y - size / 2, size, size);
774                 };
775                 
776                 mxExtVertexHandler.prototype.getSpecialHandlePoint = function(bounds)
777                 {
778                         // Hook for subclassers
779                         return null;
780                 };
781         
782                 mxExtVertexHandler.prototype.updateStyle = function(point)
783                 {
784                         // Hook for subclassers
785                 };
786                 
787                 mxExtVertexHandler.prototype.constrainPoint = function(point)
788                 {
789                         point.x = Math.max(this.state.x, Math.min(this.state.x + this.state.width, point.x));
790                         point.y = Math.max(this.state.y, Math.min(this.state.y + this.state.height, point.y));
791                 };
792                 
793                 mxExtVertexHandler.prototype.applyStyle = function()
794                 {
795                         // Hook for subclassers
796                 };
797
798                 // Folder Handler
799                 function mxFolderHandler(state)
800                 {
801                         mxExtVertexHandler.call(this, state);
802                 };
803         
804                 mxUtils.extend(mxFolderHandler, mxExtVertexHandler);
805
806                 mxFolderHandler.prototype.getSpecialHandlePoint = function(bounds)
807                 {
808                         var scale = this.graph.getView().scale;
809                         var tw = Math.min(bounds.width, mxUtils.getValue(this.state.style, 'tabWidth', 60) * scale);
810                         var th = Math.min(bounds.height, mxUtils.getValue(this.state.style, 'tabHeight', 20) * scale);
811                         
812                         var tp = mxUtils.getValue(this.state.style, 'tabPosition', 'right');
813                         var x = (tp == 'left') ? bounds.x + tw : bounds.x + bounds.width - tw;
814         
815                         return new mxPoint(x, bounds.y + th);
816                 };
817                 
818                 mxFolderHandler.prototype.updateStyle = function(point)
819                 {
820                         var rotation = this.state.shape.getShapeRotation();
821                         var alpha = mxUtils.toRadians(rotation);
822                         var cos = Math.cos(-alpha);
823                         var sin = Math.sin(-alpha);
824
825                         var bounds = new mxRectangle(this.state.x, this.state.y, this.state.width, this.state.height);
826                         
827                         if (this.state.shape.isPaintBoundsInverted())
828                         {
829                                 var t = (bounds.width - bounds.height) / 2;
830                                 bounds.x += t;
831                                 bounds.y -= t;
832                                 var tmp = bounds.width;
833                                 bounds.width = bounds.height;
834                                 bounds.height = tmp;
835                         }
836         
837                         var pt = new mxPoint(point.x, point.y);
838                         pt = mxUtils.getRotatedPoint(pt, cos, sin,
839                                 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
840
841                         if (this.state.shape.flipH)
842                         {
843                                 pt.x = 2 * bounds.x + bounds.width - pt.x;
844                         }
845                         
846                         if (this.state.shape.flipV)
847                         {
848                                 pt.y = 2 * bounds.y + bounds.height - pt.y;
849                         }
850                         
851                         var result = this.updateStyleUnrotated(pt, bounds);
852                 
853                         // Modifies point to use rotated coordinates of return value
854                         if (result != null)
855                         {
856                                 if (this.state.shape.flipH)
857                                 {
858                                         result.x = 2 * bounds.x + bounds.width - result.x;
859                                 }
860                                 
861                                 if (this.state.shape.flipV)
862                                 {
863                                         result.y = 2 * bounds.y + bounds.height - result.y;
864                                 }
865                                 
866                                 cos = Math.cos(alpha);
867                                 sin = Math.sin(alpha);
868                                 result = mxUtils.getRotatedPoint(result, cos, sin,
869                                                 new mxPoint(this.state.getCenterX(), this.state.getCenterY()));
870                                 point.x = result.x;
871                                 point.y = result.y;
872                         }
873                 };
874                 
875                 mxFolderHandler.prototype.updateStyleUnrotated = function(pt, bounds)
876                 {
877                         var tp = mxUtils.getValue(this.state.style, 'tabPosition', 'right');
878                         var tw = (tp == 'left') ? pt.x - bounds.x : bounds.x + bounds.width - pt.x;
879                         var th = pt.y - bounds.y;
880                         
881                         var scale = this.graph.getView().scale;
882                         this.state.style['tabWidth'] = Math.round(Math.max(1, tw) / scale);
883                         this.state.style['tabHeight'] =  Math.round(Math.max(1, th) / scale);
884                 };
885                 
886                 mxFolderHandler.prototype.applyStyle = function()
887                 {
888                         var model = this.graph.getModel();
889                         model.beginUpdate();
890                         try
891                         {
892                                 this.state.view.graph.setCellStyles('tabWidth', this.state.style['tabWidth'], [this.state.cell]);
893                                 this.state.view.graph.setCellStyles('tabHeight', this.state.style['tabHeight'], [this.state.cell]);
894                         }
895                         finally
896                         {
897                                 model.endUpdate();
898                         }
899                 };
900                 
901                 // Swimlane Handler
902                 function mxSwimlaneHandler(state)
903                 {
904                         mxFolderHandler.call(this, state);
905                 };
906                 
907                 mxUtils.extend(mxSwimlaneHandler, mxFolderHandler);
908                 
909                 mxSwimlaneHandler.prototype.getSpecialHandlePoint = function(bounds)
910                 {
911                         var scale = this.graph.getView().scale;
912                         var startSize = mxUtils.getValue(this.state.style, mxConstants.STYLE_STARTSIZE, mxConstants.DEFAULT_STARTSIZE);
913
914                         return new mxPoint(bounds.x + bounds.width / 2, bounds.y + Math.min(bounds.height, startSize * scale));
915                 };
916                 
917                 mxSwimlaneHandler.prototype.updateStyleUnrotated = function(point, bounds)
918                 {
919                         point.x = bounds.x + bounds.width / 2;
920                         startSize = point.y - bounds.y;
921                         var scale = this.graph.getView().scale;
922                         this.state.style['startSize'] = Math.round(Math.max(1, startSize) / scale);
923                         
924                         return point;
925                 };
926                 
927                 mxSwimlaneHandler.prototype.applyStyle = function()
928                 {
929                         this.state.view.graph.setCellStyles('startSize', this.state.style['startSize'], [this.state.cell]);
930                 };
931
932                 // Cube Handler
933                 function mxCubeHandler(state)
934                 {
935                         mxFolderHandler.call(this, state);
936                 };
937         
938                 mxUtils.extend(mxCubeHandler, mxFolderHandler);
939                 
940                 mxCubeHandler.prototype.defaultValue = 20;
941         
942                 mxCubeHandler.prototype.scaleFactor = 1;
943                 
944                 mxCubeHandler.prototype.getSpecialHandlePoint = function(bounds)
945                 {
946                         var scale = this.graph.getView().scale;
947                         var sz = Math.min(bounds.width, Math.min(bounds.height,
948                                 mxUtils.getValue(this.state.style, 'size', this.defaultValue) * scale / this.scaleFactor));
949                         
950                         return new mxPoint(bounds.x + sz, bounds.y + sz);
951                 };
952         
953                 mxCubeHandler.prototype.updateStyleUnrotated = function(pt, bounds)
954                 {
955                         var size = Math.max(0, Math.min(Math.min(bounds.width / this.scaleFactor, pt.x - bounds.x),
956                                         Math.min(bounds.height / this.scaleFactor, pt.y - bounds.y)));
957                         var scale = this.graph.getView().scale;
958                         this.state.style['size'] = Math.round(Math.max(1, size) / scale) * this.scaleFactor;
959                         
960                         // Stays on the diagonal
961                         return new mxPoint(bounds.x + size, bounds.y + size);
962                 };
963                 
964                 mxCubeHandler.prototype.applyStyle = function()
965                 {
966                         this.state.view.graph.setCellStyles('size', this.state.style['size'], [this.state.cell]);
967                 };
968                 
969                 // Card Handler
970                 function mxCardHandler(state)
971                 {
972                         mxCubeHandler.call(this, state);
973                 };
974         
975                 mxUtils.extend(mxCardHandler, mxCubeHandler);
976                 
977                 mxCardHandler.prototype.defaultValue = 30;
978         
979                 mxCardHandler.prototype.scaleFactor = 2;
980                 
981                 // Note Handler
982                 function mxNoteHandler(state)
983                 {
984                         mxCubeHandler.call(this, state);
985                 };
986         
987                 mxUtils.extend(mxNoteHandler, mxCubeHandler);
988                 
989                 mxNoteHandler.prototype.defaultValue = 30;
990         
991                 mxNoteHandler.prototype.scaleFactor = 1;
992                 
993                 mxNoteHandler.prototype.getSpecialHandlePoint = function(bounds)
994                 {
995                         var scale = this.graph.getView().scale;
996                         var sz = Math.min(bounds.width, Math.min(bounds.height,
997                                         mxUtils.getValue(this.state.style, 'size', this.defaultValue) * scale / this.scaleFactor));
998                         
999                         return new mxPoint(bounds.x + bounds.width - sz, bounds.y + sz);
1000                 };
1001                 
1002                 mxNoteHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1003                 {
1004                         var size = Math.max(0, Math.min(Math.min(bounds.width / this.scaleFactor, pt.x - bounds.x + bounds.width),
1005                                         Math.min(bounds.height / this.scaleFactor, pt.y - bounds.y)));
1006                         var scale = this.graph.getView().scale;
1007                         this.state.style['size'] = Math.round(Math.max(1, size) / scale) * this.scaleFactor;
1008                         
1009                         // Stays on the diagonal
1010                         return new mxPoint(bounds.x + bounds.width - size, bounds.y + size);
1011                 };
1012                 
1013                 // Step Handler
1014                 function mxStepHandler(state)
1015                 {
1016                         mxCubeHandler.call(this, state);
1017                 };
1018         
1019                 mxUtils.extend(mxStepHandler, mxCubeHandler);
1020                 
1021                 mxStepHandler.prototype.defaultValue = 0.2;
1022         
1023                 mxStepHandler.prototype.scaleFactor = 1;
1024                 
1025                 mxStepHandler.prototype.getSpecialHandlePoint = function(bounds)
1026                 {
1027                         var sz = mxUtils.getValue(this.state.style, 'size', this.defaultValue);
1028                         
1029                         return new mxPoint(bounds.x + bounds.width * sz, bounds.y + bounds.height / 2);
1030                 };
1031         
1032                 mxStepHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1033                 {
1034                         var size = Math.min(1, (pt.x - bounds.x) / bounds.width);
1035                         this.state.style['size'] = size;
1036                         
1037                         return new mxPoint(bounds.x + size * bounds.width, bounds.y + bounds.height / 2);
1038                 };
1039                 
1040                 // Tape Handler
1041                 function mxTapeHandler(state)
1042                 {
1043                         mxCubeHandler.call(this, state);
1044                 };
1045         
1046                 mxUtils.extend(mxTapeHandler, mxCubeHandler);
1047                 
1048                 mxTapeHandler.prototype.defaultValue = 0.4;
1049         
1050                 mxTapeHandler.prototype.scaleFactor = 1;
1051                 
1052                 mxTapeHandler.prototype.getSpecialHandlePoint = function(bounds)
1053                 {
1054                         var sz = mxUtils.getValue(this.state.style, 'size', this.defaultValue);
1055         
1056                         return new mxPoint(bounds.x + bounds.width / 2, bounds.y + sz * bounds.height / 2);
1057                 };
1058         
1059                 mxTapeHandler.prototype.updateStyleUnrotated = function(pt, bounds)
1060                 {
1061                         var size = Math.max(0, Math.min(1, ((pt.y - bounds.y) / bounds.height) * 2));
1062                         this.state.style['size'] = size;
1063                         
1064                         return new mxPoint(bounds.x + bounds.width / 2, bounds.y + size * bounds.height / 2);
1065                 };
1066                 
1067                 var handlers = {'swimlane': mxSwimlaneHandler, 'folder': mxFolderHandler, 'cube': mxCubeHandler,
1068                                 'card': mxCardHandler, 'note': mxNoteHandler, 'step': mxStepHandler, 'tape': mxTapeHandler};
1069
1070                 var mxGraphCreateHandler = mxGraph.prototype.createHandler;
1071                 mxGraph.prototype.createHandler = function(state)
1072                 {
1073                         if (state != null)
1074                         {
1075                                 var ctor = handlers[state.style['shape']];
1076
1077                                 if (ctor != null)
1078                                 {
1079                                         return new ctor(state);
1080                                 }
1081                         }
1082                         
1083                         return mxGraphCreateHandler.apply(this, arguments);
1084                 };
1085         }
1086         
1087         // Constraints
1088         mxGraph.prototype.getAllConnectionConstraints = function(terminal, source)
1089         {
1090                 if (terminal != null && terminal.shape != null)
1091                 {
1092                         if (terminal.shape.stencil != null)
1093                         {
1094                                 if (terminal.shape.stencil != null)
1095                                 {
1096                                         return terminal.shape.stencil.constraints;
1097                                 }
1098                         }
1099                         else if (terminal.shape.constraints != null)
1100                         {
1101                                 return terminal.shape.constraints;
1102                         }
1103                 }
1104
1105                 return null;
1106         };
1107
1108         mxRectangleShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1109                                                   new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1110                                                   new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1111                                                  new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1112                                                  new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1113                                                  new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1114                                                  new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1115                                                  new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1116                                                  new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1117                                                  new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1118                                                  new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1119                                                  new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1120         mxLabel.prototype.constraints = mxRectangleShape.prototype.constraints;
1121         mxImageShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1122         mxSwimlane.prototype.constraints = mxRectangleShape.prototype.constraints;
1123         PlusShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1124         NoteShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1125         CardShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1126         CubeShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1127         FolderShape.prototype.constraints = mxRectangleShape.prototype.constraints;
1128         mxCylinder.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.15, 0.05), false),
1129                                         new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1130                                         new mxConnectionConstraint(new mxPoint(0.85, 0.05), false),
1131                                  new mxConnectionConstraint(new mxPoint(0, 0.3), true),
1132                                  new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1133                                  new mxConnectionConstraint(new mxPoint(0, 0.7), true),
1134                                  new mxConnectionConstraint(new mxPoint(1, 0.3), true),
1135                                  new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1136                                  new mxConnectionConstraint(new mxPoint(1, 0.7), true),
1137                                  new mxConnectionConstraint(new mxPoint(0.15, 0.95), false),
1138                                  new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1139                                  new mxConnectionConstraint(new mxPoint(0.85, 0.95), false)];
1140         UmlActorShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.1), false),
1141                                                   new mxConnectionConstraint(new mxPoint(0.5, 0), false),
1142                                                   new mxConnectionConstraint(new mxPoint(0.75, 0.1), false),
1143                                                  new mxConnectionConstraint(new mxPoint(0, 1/3), false),
1144                                                  new mxConnectionConstraint(new mxPoint(0, 1), false),
1145                                                  new mxConnectionConstraint(new mxPoint(1, 1/3), false),
1146                                                  new mxConnectionConstraint(new mxPoint(1, 1), false),
1147                                                  new mxConnectionConstraint(new mxPoint(0.5, 0.5), false)];
1148         ComponentShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1149                                                   new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1150                                                   new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1151                                                  new mxConnectionConstraint(new mxPoint(0, 0.3), true),
1152                                                  new mxConnectionConstraint(new mxPoint(0, 0.7), true),
1153                                                  new mxConnectionConstraint(new mxPoint(1, 0.25), true),
1154                                                  new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1155                                                  new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1156                                                  new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1157                                                  new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1158                                                  new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1159         mxActor.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1160                                  new mxConnectionConstraint(new mxPoint(0.25, 0.2), false),
1161                                  new mxConnectionConstraint(new mxPoint(0.1, 0.5), false),
1162                                  new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1163                                  new mxConnectionConstraint(new mxPoint(0.75, 0.25), false),
1164                                  new mxConnectionConstraint(new mxPoint(0.9, 0.5), false),
1165                                  new mxConnectionConstraint(new mxPoint(1, 0.75), true),
1166                                  new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1167                                  new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1168                                  new mxConnectionConstraint(new mxPoint(0.75, 1), true)];
1169         TapeShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.35), false),
1170                                            new mxConnectionConstraint(new mxPoint(0, 0.5), false),
1171                                            new mxConnectionConstraint(new mxPoint(0, 0.65), false),
1172                                            new mxConnectionConstraint(new mxPoint(1, 0.35), false),
1173                                                 new mxConnectionConstraint(new mxPoint(1, 0.5), false),
1174                                                 new mxConnectionConstraint(new mxPoint(1, 0.65), false),
1175                                                                                 new mxConnectionConstraint(new mxPoint(0.25, 1), false),
1176                                                                                 new mxConnectionConstraint(new mxPoint(0.75, 0), false)];
1177         // TODO: Relative ports
1178         StepShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0), true),
1179                                        new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1180                                        new mxConnectionConstraint(new mxPoint(0.75, 0), true),
1181                                        new mxConnectionConstraint(new mxPoint(0.25, 1), true),
1182                                                         new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1183                                                         new mxConnectionConstraint(new mxPoint(0.75, 1), true),
1184                                            new mxConnectionConstraint(new mxPoint(0.1, 0.25), false),
1185                                            new mxConnectionConstraint(new mxPoint(0.2, 0.5), false),
1186                                            new mxConnectionConstraint(new mxPoint(0.1, 0.75), false),
1187                                            new mxConnectionConstraint(new mxPoint(0.9, 0.25), false),
1188                                                 new mxConnectionConstraint(new mxPoint(1, 0.5), false),
1189                                                 new mxConnectionConstraint(new mxPoint(0.9, 0.75), false)];
1190         mxLine.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.5), false),
1191                                         new mxConnectionConstraint(new mxPoint(0.25, 0.5), false),
1192                                         new mxConnectionConstraint(new mxPoint(0.75, 0.5), false),
1193                                                                         new mxConnectionConstraint(new mxPoint(1, 0.5), false)];
1194         LollipopShape.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.5, 0), false),
1195                                                                                 new mxConnectionConstraint(new mxPoint(0.5, 1), false)];
1196         mxEllipse.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0), true), new mxConnectionConstraint(new mxPoint(1, 0), true),
1197                                            new mxConnectionConstraint(new mxPoint(0, 1), true), new mxConnectionConstraint(new mxPoint(1, 1), true),
1198                                            new mxConnectionConstraint(new mxPoint(0.5, 0), true), new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1199                                                    new mxConnectionConstraint(new mxPoint(0, 0.5), true), new mxConnectionConstraint(new mxPoint(1, 0.5))];
1200         mxDoubleEllipse.prototype.constraints = mxEllipse.prototype.constraints;
1201         mxRhombus.prototype.constraints = mxEllipse.prototype.constraints;
1202         mxTriangle.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0, 0.25), true),
1203                                             new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1204                                            new mxConnectionConstraint(new mxPoint(0, 0.75), true),
1205                                            new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1206                                            new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1207                                            new mxConnectionConstraint(new mxPoint(1, 0.5), true)];
1208         mxHexagon.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.375, 0), true),
1209                                             new mxConnectionConstraint(new mxPoint(0.5, 0), true),
1210                                            new mxConnectionConstraint(new mxPoint(0.625, 0), true),
1211                                            new mxConnectionConstraint(new mxPoint(0.125, 0.25), false),
1212                                            new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1213                                            new mxConnectionConstraint(new mxPoint(0.125, 0.75), false),
1214                                            new mxConnectionConstraint(new mxPoint(0.875, 0.25), false),
1215                                            new mxConnectionConstraint(new mxPoint(0, 0.5), true),
1216                                            new mxConnectionConstraint(new mxPoint(1, 0.5), true),
1217                                            new mxConnectionConstraint(new mxPoint(0.875, 0.75), false),
1218                                            new mxConnectionConstraint(new mxPoint(0.375, 1), true),
1219                                             new mxConnectionConstraint(new mxPoint(0.5, 1), true),
1220                                            new mxConnectionConstraint(new mxPoint(0.625, 1), true)];
1221         mxCloud.prototype.constraints = [new mxConnectionConstraint(new mxPoint(0.25, 0.25), false),
1222                                          new mxConnectionConstraint(new mxPoint(0.4, 0.1), false),
1223                                          new mxConnectionConstraint(new mxPoint(0.16, 0.55), false),
1224                                          new mxConnectionConstraint(new mxPoint(0.07, 0.4), false),
1225                                          new mxConnectionConstraint(new mxPoint(0.31, 0.8), false),
1226                                          new mxConnectionConstraint(new mxPoint(0.13, 0.77), false),
1227                                          new mxConnectionConstraint(new mxPoint(0.8, 0.8), false),
1228                                          new mxConnectionConstraint(new mxPoint(0.55, 0.95), false),
1229                                          new mxConnectionConstraint(new mxPoint(0.875, 0.5), false),
1230                                          new mxConnectionConstraint(new mxPoint(0.96, 0.7), false),
1231                                          new mxConnectionConstraint(new mxPoint(0.625, 0.2), false),
1232                                          new mxConnectionConstraint(new mxPoint(0.88, 0.25), false)];
1233         mxArrow.prototype.constraints = null;
1234 })();